Skip to content

Commit

Permalink
Allow to configure daemon actions
Browse files Browse the repository at this point in the history
  • Loading branch information
kitsunyan committed Jul 6, 2019
1 parent cee8ba4 commit ac5ae9a
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 16 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,5 @@ can be suppressed applying limits periodically. Some features like energy vesus
preference switch work in daemon mode only. Use `intel-undervolt daemon` to run intel-undervolt in
daemon mode, or use `intel-undervolt-loop` service. You can change the interval using
`interval ${interval_in_milliseconds}` configuration parameter.

You can specify which actions daemon should perform using `daemon` configuration parameter. You can use `once` option to ensure action will be performed only once.
74 changes: 63 additions & 11 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,18 @@ void free_config(struct config_t * config) {
static bool parse_power_limit_value(const char * line,
struct power_limit_value_t * value) {
char * tmp = NULL;
char * next = NULL;
int power = (int) strtol(line, &tmp, 10);
float time_window = -1;
bool enabled = true;
int n;
if (tmp && tmp[0] == '/' && tmp[1]) {
time_window = strtof(&tmp[1], &tmp);
if (tmp && tmp[0] && tmp[0] != ':') {
return false;
}
}
while (tmp && tmp[0] == ':' && tmp[1]) {
char * next = NULL;
int n;
tmp = &tmp[1];
next = strstr(tmp, ":");
n = next ? (int) (next - tmp) : (int) strlen(tmp);
Expand Down Expand Up @@ -311,6 +311,9 @@ struct config_t * load_config(struct config_t * old_config, bool * nl) {
if (config->hwp_hints) {
array_free(config->hwp_hints);
}
if (config->daemon_actions) {
array_free(config->daemon_actions);
}
} else {
config = malloc(sizeof(struct config_t));
if (!config) {
Expand All @@ -328,6 +331,7 @@ struct config_t * load_config(struct config_t * old_config, bool * nl) {
config->tjoffset_apply = false;
config->hwp_hints = NULL;
config->interval = -1;
config->daemon_actions = NULL;

int fd[2];
pipe(fd);
Expand All @@ -350,6 +354,7 @@ struct config_t * load_config(struct config_t * old_config, bool * nl) {
"tjoffset() { pz tjoffset \"$1\"; };"
"hwphint() { pz hwphint \"$1\" \"$2\" \"$3\" \"$4\"; };"
"interval() { pz interval \"$1\"; };"
"daemon() { pz daemon \"$1\"; };"
". " SYSCONFDIR "/intel-undervolt.conf",
"sh", fdarg, NULL);
exit(1);
Expand Down Expand Up @@ -462,15 +467,6 @@ struct config_t * load_config(struct config_t * old_config, bool * nl) {
}
config->tjoffset = tjoffset;
config->tjoffset_apply = true;
} else if (!strcmp(line, "interval")) {
int interval;
iuv_read_line_error();
tmp = NULL;
interval = (int) strtol(line, &tmp, 10);
if (!line[0] || (tmp && tmp[0])) {
iuv_print_break("Invalid interval: %s\n", line);
}
config->interval = interval;
} else if (!strcmp(line, "hwphint")) {
bool force = false;
int len;
Expand Down Expand Up @@ -551,6 +547,59 @@ struct config_t * load_config(struct config_t * old_config, bool * nl) {
hwp_hint->hwp_power_terms = hwp_power_terms;
hwp_hint->load_hint = load_hint;
hwp_hint->normal_hint = normal_hint;
} else if (!strcmp(line, "interval")) {
int interval;
iuv_read_line_error();
tmp = NULL;
interval = (int) strtol(line, &tmp, 10);
if (!line[0] || (tmp && tmp[0])) {
iuv_print_break("Invalid interval: %s\n", line);
}
config->interval = interval;
} else if (!strcmp(line, "daemon")) {
struct daemon_action_t * daemon_action;
bool once = false;
bool invalid_option = false;
enum daemon_action_kind kind;
char * tmp;
int n;
iuv_read_line_error();
tmp = strstr(line, ":");
n = tmp ? (int) (tmp - line) : (int) strlen(line);
if (strn_eq_const(line, "undervolt", n)) {
kind = DAEMON_ACTION_KIND_UNDERVOLT;
} else if (strn_eq_const(line, "power", n)) {
kind = DAEMON_ACTION_KIND_POWER;
} else if (strn_eq_const(line, "tjoffset", n)) {
kind = DAEMON_ACTION_KIND_TJOFFSET;
} else {
invalid_option = true;
}
while (!invalid_option && tmp && tmp[0] == ':' && tmp[1]) {
char * next = NULL;
tmp = &tmp[1];
next = strstr(tmp, ":");
n = next ? (int) (next - tmp) : (int) strlen(tmp);
if (strn_eq_const(tmp, "once", n)) {
once = true;
} else {
invalid_option = true;
break;
}
tmp = next ? next : NULL;
}
if (!line[0] || (tmp && tmp[0])) {
iuv_print_break("Invalid daemon action: %s\n", line);
}
if (!config->daemon_actions) {
config->daemon_actions = array_new(sizeof(struct daemon_action_t), NULL);
}
daemon_action = array_add(config->daemon_actions);
if (!daemon_action) {
iuv_print_break_nomem();
}
daemon_action->kind = kind;
daemon_action->once = once;
} else if (!strcmp(line, "apply")) {
if (!apply_deprecation) {
NEW_LINE(nl, nll);
Expand Down Expand Up @@ -709,6 +758,9 @@ struct config_t * load_config(struct config_t * old_config, bool * nl) {
if (config->hwp_hints) {
array_shrink(config->hwp_hints);
}
if (config->daemon_actions) {
array_shrink(config->daemon_actions);
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ struct hwp_hint_t {
char * normal_hint;
};

enum daemon_action_kind {
DAEMON_ACTION_KIND_UNDERVOLT,
DAEMON_ACTION_KIND_POWER,
DAEMON_ACTION_KIND_TJOFFSET
};

struct daemon_action_t {
enum daemon_action_kind kind;
bool once;
};

struct config_t {
int fd_msr;
int fd_mem;
Expand All @@ -66,6 +77,7 @@ struct config_t {
float tjoffset;
struct array_t * hwp_hints;
int interval;
struct array_t * daemon_actions;
};

void free_config(struct config_t * config);
Expand Down
9 changes: 9 additions & 0 deletions intel-undervolt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,12 @@ undervolt 4 'Analog I/O' 0
# Usage: interval ${interval_in_milliseconds}

interval 5000

# Daemon Actions
# Usage: daemon action[:option...]
# Actions: undervolt, power, tjoffset
# Options: once

daemon undervolt:once
daemon power
daemon tjoffset
35 changes: 31 additions & 4 deletions modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ static void sigusr1_handler(UNUSED int sig) {
int daemon_mode() {
struct config_t * config = load_config(NULL, NULL);
struct sigaction act;
unsigned int i = 0;
int i = 0;
bool undervolt_done = false;
bool power_done = false;
bool tjoffset_done = false;
struct cpu_policy_t * cpu_policy = NULL;

if (config && config->interval <= 0) {
Expand Down Expand Up @@ -68,10 +71,34 @@ int daemon_mode() {
cpu_policy = cpu_policy_init();
}

for (i = 0; i < ARRAY_SIZE(config->power); i++) {
power_limit(config, i, NULL, true);
for (i = 0; config->daemon_actions && i < config->daemon_actions->count; i++) {
struct daemon_action_t * daemon_action = array_get(config->daemon_actions, i);
switch (daemon_action->kind) {
case DAEMON_ACTION_KIND_UNDERVOLT: {
if (!daemon_action->once || !undervolt_done) {
undervolt(config, NULL, true);
}
undervolt_done = true;
break;
}
case DAEMON_ACTION_KIND_POWER: {
if (!daemon_action->once || !power_done) {
for (i = 0; i < (int) ARRAY_SIZE(config->power); i++) {
power_limit(config, i, NULL, true);
}
}
power_done = true;
break;
}
case DAEMON_ACTION_KIND_TJOFFSET: {
if (!daemon_action->once || !tjoffset_done) {
tjoffset(config, NULL, true);
}
tjoffset_done = true;
break;
}
}
}
tjoffset(config, NULL, true);

if (cpu_policy) {
if (config->hwp_hints) {
Expand Down
2 changes: 1 addition & 1 deletion undervolt.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ bool undervolt(struct config_t * config, bool * nl, bool write) {
if (errstr) {
success = false;
printf("%s (%d): %s\n", undervolt->title, undervolt->index, errstr);
} else {
} else if (nl) {
float val = ((mask - (rdval >> 21)) & (mask - 1)) / 1.024f;
printf("%s (%d): -%.02f mV\n", undervolt->title,
undervolt->index, val);
Expand Down

0 comments on commit ac5ae9a

Please sign in to comment.