summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@linaro.org>2021-05-25 16:24:42 +0200
committerDaniel Lezcano <daniel.lezcano@linaro.org>2021-05-25 16:24:42 +0200
commitcc250f2517525b1a96ec0605581cf7ef2ea523cd (patch)
tree28c82faa96a7aa2d846fc3bb6bf036055fa03362
parent099c28fb1fe6c3f95296badb66b6e969d3c310c4 (diff)
Add syslog support + more stuff
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r--src/dtpm/Makefile3
-rw-r--r--src/dtpm/balance.c98
-rw-r--r--src/dtpm/conf.c45
-rw-r--r--src/dtpm/conf.h4
-rw-r--r--src/dtpm/dtpm.c323
-rw-r--r--src/dtpm/log.c20
-rw-r--r--src/dtpm/log.h21
-rw-r--r--src/libthermal/Makefile2
8 files changed, 389 insertions, 127 deletions
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 <sys/stat.h>
#include <sys/timerfd.h>
#include <sys/types.h>
+#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
@@ -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 <stdio.h>
+
+#include <syslog.h>
+
+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 <syslog.h>
+
#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