From cc250f2517525b1a96ec0605581cf7ef2ea523cd Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 25 May 2021 16:24:42 +0200 Subject: Add syslog support + more stuff Signed-off-by: Daniel Lezcano --- src/dtpm/Makefile | 3 +- src/dtpm/balance.c | 98 +++++++-------- src/dtpm/conf.c | 45 ++++--- src/dtpm/conf.h | 4 +- src/dtpm/dtpm.c | 323 ++++++++++++++++++++++++++++++++++++++++-------- src/dtpm/log.c | 20 +++ src/dtpm/log.h | 21 ++-- src/libthermal/Makefile | 2 +- 8 files changed, 389 insertions(+), 127 deletions(-) create mode 100644 src/dtpm/log.c diff --git a/src/dtpm/Makefile b/src/dtpm/Makefile index 18631fd..794553a 100644 --- a/src/dtpm/Makefile +++ b/src/dtpm/Makefile @@ -25,7 +25,8 @@ LDFLAGS?=-lconfig -lncurses -lthermal -L../libthermal CC=gcc -OBJS = dtpm.o display.o mainloop.o conf.o +#OBJS = dtpm.o display.o mainloop.o conf.o balance.o +OBJS = dtpm.o display.o mainloop.o conf.o log.o default: dtpm diff --git a/src/dtpm/balance.c b/src/dtpm/balance.c index 0917d0b..964db60 100644 --- a/src/dtpm/balance.c +++ b/src/dtpm/balance.c @@ -23,7 +23,7 @@ struct dtpm_balance { u64 dynamic_power_limit; }; -u64 powercap_em_get_power(struct powercap_em *pcem) +u64 dtpm_balance_get_power(struc dtpm *dtpm) { u64 power = 0; int i; @@ -32,46 +32,46 @@ u64 powercap_em_get_power(struct powercap_em *pcem) * Only the leaves of the tree can return the real power, * otherwise we return the sum of the children power. */ - if (!pcem->nr_children) - return pcem->cur_power; + if (!dtpm->nr_children) + return dtpm->cur_power; - for (i = 0; i < pcem->nr_children; i++) - power += powercap_em_get_power(pcem->children[i]); + for (i = 0; i < dtpm->nr_children; i++) + power += dtpm_balance_get_power(dtpm->children[i]); return power; } -int powercap_em_rebalance_weight(struct powercap_em *pcem) +int dtpm_balance_rebalance_weight(struc dtpm *dtpm) { - struct powercap_em *child; + struc dtpm *child; int i; - for (i = 0; i < pcem->nr_children; i++) { - child = pcem->children[i]; + for (i = 0; i < dtpm->nr_children; i++) { + child = dtpm->children[i]; child->weight = DIV_ROUND_CLOSEST(child->max_power * 1024, - pcem->max_power); + dtpm->max_power); } return 0; } -int powercap_em_set_static_power_limit(struct powercap_em *pcem, u64 power); +int dtpm_balance_set_static_power_limit(struc dtpm *dtpm, u64 power); -int powercap_em_rebalance_limit(struct powercap_em *pcem) +int dtpm_balance_rebalance_limit(struc dtpm *dtpm) { - if (!pcem) + if (!dtpm) BUG(); - if (pcem->power_limit) - return powercap_em_set_static_power_limit(pcem, pcem->power_limit); + if (dtpm->power_limit) + return dtpm_balance_set_static_power_limit(dtpm, dtpm->power_limit); - return powercap_em_rebalance_limit(pcem->parent); + return dtpm_balance_rebalance_limit(dtpm->parent); } -int powercap_em_rebalance_power(struct powercap_em *pcem) +int dtpm_balance_rebalance_power(struc dtpm *dtpm) { - struct powercap_em *donees[MAX_CHILDREN]; - struct powercap_em *donors[MAX_CHILDREN]; + struc dtpm *donees[MAX_CHILDREN]; + struc dtpm *donors[MAX_CHILDREN]; int nr_donee, nr_donor, sum_weight; u64 power, power_free; int i, j; @@ -83,11 +83,11 @@ again: * This first pass build the list of the donees and the sum of * their weights. */ - for (i = 0; i < pcem->nr_children; i++) { - struct powercap_em *child; + for (i = 0; i < dtpm->nr_children; i++) { + struc dtpm *child; - child = pcem->children[i]; - power = powercap_em_get_power(child); + child = dtpm->children[i]; + power = dtpm_balance_get_power(child); if (power > child->dynamic_power_limit) { @@ -101,7 +101,7 @@ again: * limit and do the rebalancing again. */ if (power < child->static_power_limit) { - powercap_em_rebalance_limit(pcem); + dtpm_balance_rebalance_limit(dtpm); goto again; } @@ -146,9 +146,9 @@ again: */ for (i = 0; i < nr_donor; i++) { - struct powercap_em *donor = donors[i]; + struc dtpm *donor = donors[i]; - power = powercap_em_get_power(donor); + power = dtpm_balance_get_power(donor); /* * Compute the unused power ... @@ -182,7 +182,7 @@ again: return -EINVAL; } -int powercap_em_set_power(struct powercap_em *pcem, u64 power) +int dtpm_balance_set_power(struc dtpm *dtpm, u64 power) { /* * This function can only be called by the leaves of the @@ -190,48 +190,48 @@ int powercap_em_set_power(struct powercap_em *pcem, u64 power) * system. Other nodes in the tree are aggregating the * constraints and power information of the children. */ - if (pcem->nr_children) + if (dtpm->nr_children) return -EINVAL; - if (power < pcem->min_power || power > pcem->max_power) + if (power < dtpm->min_power || power > dtpm->max_power) return -EINVAL; - pcem->cur_power = power; + dtpm->cur_power = power; /* * The power of this device changed, let's check if there is a * limit to rebalance the power. */ - while (pcem) { + while (dtpm) { - if (pcem->power_limit) - return powercap_em_rebalance_power(pcem); + if (dtpm->power_limit) + return dtpm_balance_rebalance_power(dtpm); - pcem = pcem->parent; + dtpm = dtpm->parent; } return 0; } -int powercap_em_set_static_power_limit(struct powercap_em *pcem, u64 power_limit) +int dtpm_balance_set_static_power_limit(struc dtpm *dtpm, u64 power_limit) { - struct powercap_em *child; + struc dtpm *child; u64 static_power_limit; int i, ret; - if (!pcem->nr_children) { - pcem->dynamic_power_limit = power_limit; - pcem->static_power_limit = power_limit; + if (!dtpm->nr_children) { + dtpm->dynamic_power_limit = power_limit; + dtpm->static_power_limit = power_limit; return 0; } - for (i = 0; i < pcem->nr_children; i++) { - child = pcem->children[i]; + for (i = 0; i < dtpm->nr_children; i++) { + child = dtpm->children[i]; static_power_limit = DIV_ROUND_CLOSEST( power_limit * child->weight, 1024); - ret = powercap_em_set_static_power_limit(child, + ret = dtpm_balance_set_static_power_limit(child, static_power_limit); if (ret) return ret; @@ -240,31 +240,31 @@ int powercap_em_set_static_power_limit(struct powercap_em *pcem, u64 power_limit return 0; } -int powercap_em_set_power_limit(struct powercap_em *pcem, u64 power_limit) +int dtpm_balance_set_power_limit(struc dtpm *dtpm, u64 power_limit) { int ret; /* * A power limit set to zero means we remove the constraint */ - if (power_limit && (power_limit < pcem->min_power || - power_limit > pcem->max_power)) + if (power_limit && (power_limit < dtpm->min_power || + power_limit > dtpm->max_power)) return -EINVAL; - ret = powercap_em_set_static_power_limit(pcem, power_limit); + ret = dtpm_balance_set_static_power_limit(dtpm, power_limit); if (ret) return ret; - ret = powercap_em_rebalance_power(pcem); + ret = dtpm_balance_rebalance_power(dtpm); if (ret) goto out_undo; - pcem->power_limit = power_limit; + dtpm->power_limit = power_limit; return 0; out_undo: - powercap_em_set_static_power_limit(pcem, 0); + dtpm_balance_set_static_power_limit(dtpm, 0); return ret; } diff --git a/src/dtpm/conf.c b/src/dtpm/conf.c index 7288e10..a8ac339 100644 --- a/src/dtpm/conf.c +++ b/src/dtpm/conf.c @@ -19,6 +19,8 @@ #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) #endif +typedef unsigned long long u64; + #define DTPM_CONFIG_PATH "dtpm" #define DTPM_PATH "devices/virtual/powercap/dtpm/dtpm:0" @@ -28,6 +30,7 @@ static char *dtpm_config_path; struct dtpm_constraint { const char *name; const char *tz; + u64 power_limit; }; struct dtpm_config { @@ -185,7 +188,7 @@ static struct dtpm_config *dtpm_get_constraints_config(config_setting_t *constra goto out_free_1; memset(dtpm_config->cstr, 0, sizeof(*dtpm_config->cstr) * (length + 1)); - + for (i = 0; i < length; i++) { config_setting_t *node = config_setting_get_elem(constraints, i); @@ -195,23 +198,22 @@ static struct dtpm_config *dtpm_get_constraints_config(config_setting_t *constra ERROR("Missing 'name' entry\n"); goto out_free_2; } - - if (!config_setting_lookup_string(node, "thermal-zone", - &dtpm_config->cstr[i].tz)) { - ERROR("Mising 'thermal-zone' entry\n"); - goto out_free_2; - } + if (config_setting_lookup_string(node, "thermal-zone", + &dtpm_config->cstr[i].tz)) + DEBUG("Found '%s' belongs to thermal-zone '%s'\n", + dtpm_config->cstr[i].name, + dtpm_config->cstr[i].tz); + + if (config_setting_lookup_int64(node, "power-limit", + (long long *)&dtpm_config->cstr[i].power_limit)) + DEBUG("Found power_limit '%llu' uW for '%s'\n", + dtpm_config->cstr[i].power_limit, + dtpm_config->cstr[i].name); } dtpm_config->cstr[i].name = NULL; - for (i = 0; i < length; i++) { - DEBUG("Found '%s'->'%s' association\n", - dtpm_config->cstr[i].name, - dtpm_config->cstr[i].tz); - } - return dtpm_config; out_free_2: @@ -261,7 +263,22 @@ static struct dtpm_config *dtpm_get_model_config(config_t *cfg, return NULL; } -const char *dtpm_get_thermal_zone(struct dtpm_config *cfg, const char *name) +u64 dtpm_conf_get_power_limit(struct dtpm_config *cfg, const char *name) +{ + int i; + + if (!cfg) + return 0ULL; + + for (i = 0; cfg->cstr[i].name; i++) { + if (!strcmp(name, cfg->cstr[i].name)) + return cfg->cstr[i].power_limit; + } + + return 0ULL; +} + +const char *dtpm_conf_get_thermal_zone(struct dtpm_config *cfg, const char *name) { int i; diff --git a/src/dtpm/conf.h b/src/dtpm/conf.h index 0c5f706..136067b 100644 --- a/src/dtpm/conf.h +++ b/src/dtpm/conf.h @@ -3,8 +3,10 @@ struct dtpm_config; -char *dtpm_get_thermal_zone(struct dtpm_config *cfg, const char *name); +typedef unsigned long long u64; +u64 dtpm_conf_get_power_limit(struct dtpm_config *cfg, const char *name); +char *dtpm_conf_get_thermal_zone(struct dtpm_config *cfg, const char *name); char *dtpm_config_path(void); char *dtpm_path(); diff --git a/src/dtpm/dtpm.c b/src/dtpm/dtpm.c index 5865f23..4d5367d 100644 --- a/src/dtpm/dtpm.c +++ b/src/dtpm/dtpm.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,18 @@ typedef unsigned long long u64; +#define DIV_ROUND_CLOSEST(x, divisor)( \ +{ \ + typeof(x) __x = x; \ + typeof(divisor) __d = divisor; \ + (((typeof(x))-1) > 0 || \ + ((typeof(divisor))-1) > 0 || \ + (((__x) > 0) == ((__d) > 0))) ? \ + (((__x) + ((__d) / 2)) / (__d)) : \ + (((__x) - ((__d) / 2)) / (__d)); \ +} \ +) + struct dtpm_field { FILE *file; const char *filename; @@ -45,13 +58,16 @@ struct dtpm_constraint { struct dtpm_field max_power_uw; }; -struct dtpm_node { +struct dtpm { int level; char *path; + u64 power_limit; u64 static_power_limit; u64 dynamic_power_limit; - struct dtpm_node *parent; - struct dtpm_node *children[DTPM_CHILDREN_MAX]; + int nr_children; + int weight; + struct dtpm *parent; + struct dtpm *children[DTPM_CHILDREN_MAX]; struct dtpm_constraint constraints[DTPM_CONSTRAINT_MAX]; struct dtpm_field max_power_range_uw; struct dtpm_field power_uw; @@ -63,7 +79,7 @@ struct cb_param { struct thermal_handler *th; struct thermal_zone *tz; struct dtpm_config *cfg; - struct dtpm_node *root; + struct dtpm *root; struct timeval tv; int line; }; @@ -75,14 +91,216 @@ struct open_param { typedef int (*filter_t)(const char *); typedef int (*dtpm_file_cb_t)(const char *, void *); -typedef int (*dtpm_node_cb_t)(struct dtpm_node *, void *); +typedef int (*dtpm_node_cb_t)(struct dtpm *, void *); + +#define dtpm_power_limit(__dtpm) (__dtpm->constraints[0].power_limit_uw.u64val) +#define dtpm_power_max(__dtpm) (__dtpm->constraints[0].max_power_uw.u64val) +#define dtpm_power(__dtpm) (__dtpm->power_uw.u64val) +#define dtpm_name(__dtpm) (__dtpm->name.name) + +int dtpm_set_power_limit(struct dtpm *dtpm, u64 power_limit) +{ + struct dtpm_field *field = &dtpm->constraints[0].power_limit_uw; + + DEBUG("Setting hardware power limit to '%llu' for '%s'", + power_limit, dtpm_name(dtpm)); + + if (lseek(fileno(field->file), 0L, SEEK_SET) < 0) + ERROR("Failed to lseek file: %d\n", errno); + + if (fprintf(field->file, "%llu", power_limit) < 0) + ERROR("Failed to write power limit: %d\n", errno); + + return 0; +} + +static int dtpm_read_field(struct dtpm_field *field) +{ + lseek(fileno(field->file), 0L, SEEK_SET); + + return fscanf(field->file, field->fmt, field->ptr) == EOF ? -1 : 0; +} -int dtpm_node_add_child(struct dtpm_node *node, struct dtpm_node *child) +int dtpm_balance_set_static_power_limit(struct dtpm *dtpm, u64 power_limit) +{ + struct dtpm *child; + u64 static_power_limit; + int i, ret; + + DEBUG("Set static power limit %llu uW to '%s'", + power_limit, dtpm_name(dtpm)); + + if (!dtpm->nr_children) { + dtpm->dynamic_power_limit = power_limit; + dtpm->static_power_limit = power_limit; + return 0; + } + + for (i = 0; i < dtpm->nr_children; i++) { + child = dtpm->children[i]; + + static_power_limit = DIV_ROUND_CLOSEST( + power_limit * child->weight, 1024); + + ret = dtpm_balance_set_static_power_limit(child, static_power_limit); + if (ret) + return ret; + } + + return 0; +} + +static int dtpm_balance_rebalance_limit(struct dtpm *dtpm) +{ + if (dtpm->power_limit) + return dtpm_balance_set_static_power_limit(dtpm, dtpm->power_limit); + + return dtpm_balance_rebalance_limit(dtpm->parent); +} + +int dtpm_balance_rebalance_power(struct dtpm *dtpm) +{ + struct dtpm *donees[DTPM_CHILDREN_MAX]; + struct dtpm *donors[DTPM_CHILDREN_MAX]; + int nr_donee, nr_donor, sum_weight; + u64 power, power_free; + int i, j; + +again: + nr_donee = nr_donor = sum_weight = 0; + + /* + * This first pass build the list of the donees and the sum of + * their weights. + */ + for (i = 0; i < dtpm->nr_children; i++) { + struct dtpm *child; + + child = dtpm->children[i]; + power = dtpm_power(child); + + if (power > child->dynamic_power_limit) { + + DEBUG("'%s' exceeding power consumption (%llu/%llu)", + dtpm_name(child), power, child->dynamic_power_limit); + + /* + * We have one device which is consuming more + * energy than allocated but actually it + * donated the free power it had to another + * device. Now it is requesting more power, so + * it must get back the power it gave. Reset + * the dynamic power limit to the static power + * limit and do the rebalancing again. + */ + if (power < dtpm->power_limit) { + dtpm_balance_rebalance_limit(dtpm); + goto again; + } + + donees[nr_donee++] = child; + sum_weight += child->weight; + continue; + } + + if (power < child->dynamic_power_limit) + donors[nr_donor++] = child; + } + + /* + * There are no donees, so no need to rebalance the power + * across the actors, this is done, bail out. + */ + if (!nr_donee) + return 0; + + /* + * We are in a situation where there is no more free power for + * the donees, so we need to reduce their power. + */ + if (!nr_donor) { + + /* + * We are in the situation where all the power was + * rebalanced along the actors but more power is + * consumed, in this case we need to cap their power. + */ + for (i = 0; i < nr_donee; i++) + dtpm_set_power_limit(donees[i], + donees[i]->dynamic_power_limit); + + return 0; + } + + /* + * One or more actors are consuming more than the allocated + * power. Let's distribute the free power not used by the + * other actors which are below their limit. + */ + for (i = 0; i < nr_donor; i++) { + + struct dtpm *donor = donors[i]; + + power = dtpm_power(donor); + + /* + * Compute the unused power ... + */ + power_free = donor->dynamic_power_limit - power; + + /* + * ... and as it will be given to the donees, + * remove this power from the allocated budget from + * the donor. + */ + donor->dynamic_power_limit = power; + + /* + * Redistribute the unused power to the donees. + */ + for (j = 0; j < nr_donee; j++) { + donees[j]->dynamic_power_limit += + DIV_ROUND_CLOSEST( + power_free * donees[j]->weight, + sum_weight); + } + } + + /* + * Let's find out new donees and new donors + */ + goto again; + + /* Never reached */ + return -1; +} + +int dtpm_balance_rebalance_weight(struct dtpm *dtpm) +{ + struct dtpm *child; + u64 max_power, pmax_power = dtpm_power_max(dtpm); + int i; + + for (i = 0; i < dtpm->nr_children; i++) { + + child = dtpm->children[i]; + max_power = dtpm_power_max(child); + + child->weight = DIV_ROUND_CLOSEST(max_power * 1024, pmax_power); + } + + return 0; +} + +int dtpm_node_add_child(struct dtpm *node, struct dtpm *child) { int i; if (!node) return 0; + + if (node->nr_children == DTPM_CHILDREN_MAX) + return -1; for (i = 0; i < DTPM_CHILDREN_MAX; i++) { @@ -90,6 +308,9 @@ int dtpm_node_add_child(struct dtpm_node *node, struct dtpm_node *child) continue; node->children[i] = child; + node->nr_children++; + + dtpm_balance_rebalance_weight(node); return 0; } @@ -97,9 +318,9 @@ int dtpm_node_add_child(struct dtpm_node *node, struct dtpm_node *child) return -1; } -struct dtpm_node *dtpm_node_alloc(void) +struct dtpm *dtpm_node_alloc(void) { - struct dtpm_node *node; + struct dtpm *node; int i; node = malloc(sizeof(*node)); @@ -141,7 +362,7 @@ struct dtpm_node *dtpm_node_alloc(void) return node; } -void dtpm_node_free(struct dtpm_node *node) +void dtpm_node_free(struct dtpm *node) { free(node); } @@ -163,7 +384,7 @@ static unsigned int hash(const char* key) } #endif -int for_each_dtpm_node(struct dtpm_node *node, dtpm_node_cb_t cb, void *data) +int for_each_dtpm_node(struct dtpm *node, dtpm_node_cb_t cb, void *data) { int i, ret; @@ -180,14 +401,7 @@ int for_each_dtpm_node(struct dtpm_node *node, dtpm_node_cb_t cb, void *data) return ret; } -static int dtpm_read_field(struct dtpm_field *field) -{ - lseek(fileno(field->file), 0L, SEEK_SET); - - return fscanf(field->file, field->fmt, field->ptr) == EOF ? -1 : 0; -} - -int dtpm_read(struct dtpm_node *node) +int dtpm_read(struct dtpm *node) { int i, ret; @@ -207,7 +421,7 @@ int dtpm_read(struct dtpm_node *node) return ret < 0 ? -1 : 0; } -int dtpm_open_field(struct dtpm_node *node, struct dtpm_field *field, +int dtpm_open_field(struct dtpm *node, struct dtpm_field *field, const char *mode) { char path[PATH_MAX]; @@ -219,7 +433,7 @@ int dtpm_open_field(struct dtpm_node *node, struct dtpm_field *field, return field->file ? 0 : -1; } -void dtpm_close(struct dtpm_node *node) +void dtpm_close(struct dtpm *node) { int i; @@ -236,7 +450,7 @@ void dtpm_close(struct dtpm_node *node) fclose(dtpm_fields[i].field->file); } -int dtpm_open(struct dtpm_node *node) +int dtpm_open(struct dtpm *node) { int i; int ret = 0; @@ -258,7 +472,7 @@ int dtpm_open(struct dtpm_node *node) return ret; } -int dtpm_init(const char *dirname, struct dtpm_node *node) +int dtpm_init(const char *dirname, struct dtpm *node) { node->path = strdup(dirname); if (!node->path) { @@ -279,12 +493,12 @@ int dtpm_init(const char *dirname, struct dtpm_node *node) return 0; } -struct dtpm_node *dtpm_build_tree(const char *dirname, struct dtpm_node *parent) +struct dtpm *dtpm_build_tree(const char *dirname, struct dtpm *parent) { DIR *dir; int ret = -1; struct dirent *direntp; - struct dtpm_node *new_node; + struct dtpm *new_node; DEBUG("Building tree from '%s'\n", dirname); @@ -310,7 +524,7 @@ struct dtpm_node *dtpm_build_tree(const char *dirname, struct dtpm_node *parent) while ((direntp = readdir(dir)) != NULL) { char *subdir; - struct dtpm_node *child; + struct dtpm *child; if (strncmp(direntp->d_name, "dtpm", strlen("dtpm"))) continue; @@ -477,36 +691,39 @@ static struct thermal_ops ops = { .events.gov_change = gov_change }; -int show_power_uw(struct dtpm_node *node, void *arg) +int show_power_uw(struct dtpm *node, void *arg) { struct cb_param *cb_param = arg; struct thermal_handler *th = cb_param->th; char buffer[4096]; size_t len; + int bold = 0; dtpm_read_field(&node->power_uw); dtpm_read_field(&node->constraints[0].power_limit_uw); dtpm_read_field(&node->constraints[0].max_power_uw); - len = snprintf(buffer, sizeof(buffer) - 1, "%*s%s: power=%llu uW", - node->level, "", node->name.name, - node->power_uw.u64val); + len = snprintf(buffer, sizeof(buffer) - 1, "%*s%s: power=%llu uW (max=%llu uW)", + node->level, "", dtpm_name(node), dtpm_power(node), dtpm_power_max(node)); if (node->tz) { if (thermal_cmd_get_temp(th, node->tz) < 0) return -1; - len = snprintf(buffer + len, sizeof(buffer) + len - 1, - " / temp=%d mC°", node->tz->temp); + len += snprintf(buffer + len, sizeof(buffer) + len - 1, + " / temp=%d mC°", node->tz->temp); } - if (node->constraints[0].max_power_uw.u64val != - node->constraints[0].power_limit_uw.u64val) - len = snprintf(buffer + len, sizeof(buffer) + len - 1, " (%llu/%llu uW)", - node->constraints[0].power_limit_uw.u64val, - node->constraints[0].max_power_uw.u64val); + if (node->power_limit) + len = snprintf(buffer + len, sizeof(buffer) + len - 1, " (limit=%llu uW)", + node->power_limit); - display_print_line(0, cb_param->line++, buffer, 0, arg); + if (node->power_limit && dtpm_power(node) > node->power_limit) { + bold = 1; + dtpm_balance_rebalance_power(node); + } + + display_print_line(0, cb_param->line++, buffer, bold, arg); return 0; } @@ -532,7 +749,7 @@ static int event_callback(__maybe_unused int fd, void *arg) static int timer_callback(int fd, void *arg) { struct cb_param *cb_param = arg; - struct dtpm_node *root = cb_param->root; + struct dtpm *root = cb_param->root; struct thermal_zone *tz = cb_param->tz; char buf[8]; @@ -552,25 +769,22 @@ static int timer_callback(int fd, void *arg) return 0; } -static int dtpm_bind_thermal_zone(struct dtpm_node *node, void *arg) +static int dtpm_configure(struct dtpm *node, void *arg) { struct cb_param *cbp = arg; - struct thermal_zone *tz; const char *name; - name = dtpm_get_thermal_zone(cbp->cfg, node->name.ptr); - if (!name) - return 0; + name = dtpm_conf_get_thermal_zone(cbp->cfg, dtpm_name(node)); + if (name) + node->tz = thermal_zone_find_by_name(cbp->tz, name); - tz = thermal_zone_find_by_name(cbp->tz, name); - if (!tz) - return 0; - - node->tz = tz; + node->power_limit = dtpm_conf_get_power_limit(cbp->cfg, dtpm_name(node)); + if (node->power_limit) { + dtpm_balance_set_static_power_limit(node, node->power_limit); + DEBUG("'%s' has a power limit of %llu\n", + dtpm_name(node), node->power_limit); + } - DEBUG("'%s' belongs to the thermal zone '%s'\n", - (char *)node->name.ptr, name); - return 0; } @@ -587,7 +801,7 @@ static struct timespec sec_to_timespec(float delay) int main(void) { struct cb_param cb_param; - struct dtpm_node *root; + struct dtpm *root; struct thermal_zone *tz; struct thermal_handler *th; struct itimerspec timer_it = { 0 }; @@ -603,6 +817,9 @@ int main(void) } */ + if (dtpm_log_init(LOG_DEBUG)) + fprintf(stderr, "Failed to initialize logging facility\n"); + cfg = dtpm_config(config_path); if (!cfg) WARN("No configuration file\n"); @@ -624,7 +841,7 @@ int main(void) cb_param.th = th; cb_param.tz = tz; - if (for_each_dtpm_node(root, dtpm_bind_thermal_zone, &cb_param)) + if (for_each_dtpm_node(root, dtpm_configure, &cb_param)) return -1; if (mainloop_init()) diff --git a/src/dtpm/log.c b/src/dtpm/log.c new file mode 100644 index 0000000..15c12b2 --- /dev/null +++ b/src/dtpm/log.c @@ -0,0 +1,20 @@ +#include + +#include + +int dtpm_log_init(int level) +{ + if (level > LOG_DEBUG) + return -1; + + setlogmask(LOG_UPTO(level)); + + openlog("dtpm", LOG_CONS | LOG_NDELAY, LOG_DAEMON); + + return 0; +} + +void dtpm_log_exit(void) +{ + closelog(); +} diff --git a/src/dtpm/log.h b/src/dtpm/log.h index b520cf6..780b893 100644 --- a/src/dtpm/log.h +++ b/src/dtpm/log.h @@ -1,15 +1,20 @@ #ifndef __DTPM_LOG_H #define __DTPM_LOG_H +#include + #define __maybe_unused __attribute__((__unused__)) -#define DEBUG(fmt, ...) fprintf(stdout, "DEBUG %s(%d): " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) -#define INFO(fmt, ...) fprintf(stdout, "INFO: " fmt, ##__VA_ARGS__) -#define NOTICE(fmt, ...) fprintf(stdout, "NOTICE: " fmt, ##__VA_ARGS__) -#define WARN(fmt, ...) fprintf(stderr, "WARN: " fmt, ##__VA_ARGS__) -#define ERROR(fmt, ...) fprintf(stderr, "ERROR: " fmt, ##__VA_ARGS__) -#define CRITICAL(fmt, ...) fprintf(stderr, "CRITICAL: " fmt, ##__VA_ARGS__) -#define ALERT(fmt, ...) fprintf(stderr, "ALERT: " fmt, ##__VA_ARGS__) -#define FATAL(fmt, ...) fprintf(stderr, "FATAL: " fmt, ##__VA_ARGS__) +#define DEBUG(fmt, ...) syslog(LOG_DEBUG, "%s(%d): " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define INFO(fmt, ...) syslog(LOG_INFO, fmt, ##__VA_ARGS__) +#define NOTICE(fmt, ...) syslog(LOG_NOTICE, fmt, ##__VA_ARGS__) +#define WARN(fmt, ...) syslog(LOG_WARNING, fmt, ##__VA_ARGS__) +#define ERROR(fmt, ...) syslog(LOG_ERR, fmt, ##__VA_ARGS__) +#define CRITICAL(fmt, ...) syslog(LOG_CRIT, fmt, ##__VA_ARGS__) +#define ALERT(fmt, ...) syslog(LOG_ALERT, fmt, ##__VA_ARGS__) +#define EMERG(fmt, ...) syslog(LOG_EMERG, fmt, ##__VA_ARGS__) + +int dtpm_log_init(int level); +void dtpm_log_exit(void); #endif diff --git a/src/libthermal/Makefile b/src/libthermal/Makefile index 838bcb1..078fbae 100644 --- a/src/libthermal/Makefile +++ b/src/libthermal/Makefile @@ -2,7 +2,7 @@ CC=gcc CFLAGS=-g -Wall -I/usr/include/libnl3 -fPIC -Wextra -O2 LDFLAGS=-lnl-genl-3 -lnl-3 -shared DEPS = thermal.h -OBJS = thermal.o events.o sampling.o commands.o netlink.o +OBJS = thermal.o events.o sampling.o commands.o netlink.o pid.o LIB=libthermal.so default: libthermal.so tst_thermal -- cgit v1.2.3