From 8290d9ec9a6f95ddbb1a226fe6d9a30946d963f2 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Wed, 11 Aug 2021 11:15:41 +0900 Subject: [PATCH 01/16] pass: thermal: Fix missing unregister operation DEVICE_NOTIFIER_THERMAL is registered during probe, but it is not unregistered during exit. So this adds missing unregister to exit. Change-Id: I035547932abed44a255b0701f2290e3e74d7d3a3 Signed-off-by: Dongwoo Lee --- src/thermal/thermal.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/thermal/thermal.c b/src/thermal/thermal.c index cca20dc..3551e46 100644 --- a/src/thermal/thermal.c +++ b/src/thermal/thermal.c @@ -321,6 +321,8 @@ static void thermal_init(void *data) */ static void thermal_exit(void *data) { + unregister_notifier(DEVICE_NOTIFIER_THERMAL, thermal_notifier_cb, NULL); + unregister_notifier(DEVICE_NOTIFIER_INIT_DONE, thermal_init_done, NULL); -- 2.7.4 From 509a31f23888cec1cd1d8bfb4f250f60684154d1 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Fri, 30 Jul 2021 16:50:28 +0900 Subject: [PATCH 02/16] pass: thermal: Send scenario with additional information In order to prepare the case that pass can have multiple thermal monitors, each monitor sends additional information which includes resource name as a key. Change-Id: I47b9fca69c9580774ddffd065bf86e4eef09ee56 Signed-off-by: Dongwoo Lee --- include/pass/device-notifier.h | 6 ++++++ src/pass/pass-thermal.c | 8 ++++++-- src/thermal/thermal.c | 12 ++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/pass/device-notifier.h b/include/pass/device-notifier.h index 2c67f60..e1165ea 100644 --- a/include/pass/device-notifier.h +++ b/include/pass/device-notifier.h @@ -37,6 +37,12 @@ struct device_notifier { void *user_data; }; +/* data structure for DEVICE_NOTIFIER_THERMAL */ +struct device_notifier_thermal_data { + char *name; + char *scenario; +}; + /* * This is for internal callback method. */ diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index 5ef9eb3..2a122ac 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -152,6 +152,7 @@ static int thermal_monitor_func(void *result, void *user_data) struct pass_resource *res = user_data; struct pass_thermal *thermal = &res->thermal;; struct resmon_result_src_thermal *thermal_result; + struct device_notifier_thermal_data thermal_data; int ret; /* Get thermal_result raw data by monitoring */ @@ -166,12 +167,15 @@ static int thermal_monitor_func(void *result, void *user_data) if (ret < 0) return ret; + thermal_data.name = res->config_data.res_thermal_name; + thermal_data.scenario = + thermal->scenarios[thermal->curr_scenario_idx].name; + /* * Send notification with thermal scenario name according to * measured temperature of each h/w resource. */ - device_notify(DEVICE_NOTIFIER_THERMAL, - (void *)thermal->scenarios[thermal->curr_scenario_idx].name); + device_notify(DEVICE_NOTIFIER_THERMAL, (void *)&thermal_data); return 0; } diff --git a/src/thermal/thermal.c b/src/thermal/thermal.c index 3551e46..e4a5549 100644 --- a/src/thermal/thermal.c +++ b/src/thermal/thermal.c @@ -258,7 +258,9 @@ static struct pass_gdbus_signal_info g_gdbus_signal_infos[] = { */ static int thermal_notifier_cb(void *data, void *user_data) { + struct device_notifier_thermal_data *thermal_data = data; GVariant *gvar; + const char *scenario; int ret; int i; @@ -267,27 +269,29 @@ static int thermal_notifier_cb(void *data, void *user_data) return 0; } - if (!data) + if (!thermal_data) return -EINVAL; + scenario = thermal_data->scenario; + /* Find the available thermal scenario */ for (i = 0; i < g_thermal->num; i++) { if (!g_thermal->list[i].support) continue; - if (!strncmp(g_thermal->list[i].name, data, strlen(data))) + if (!strncmp(g_thermal->list[i].name, scenario, strlen(scenario))) break; } /* If there is no available thermal scenario, just return */ if (i >= g_thermal->num) { - _I("Not supported \'%s\' scenario", (char*)data); + _I("Not supported \'%s\' scenario", scenario); return 0; } g_thermal->cur_scenario_idx = i; /* If there is available thermal scenario, send the broadcast signal */ - gvar = g_variant_new("(s)", data); + gvar = g_variant_new("(s)", scenario); ret = pass_gdbus_send_broadcast_signal(PASS_DBUS_THERMAL, DBUS_THERMAL_PATH, DBUS_THERMAL_INTERFACE, -- 2.7.4 From 0164e547f229da60875a11346fed1c36fe29714a Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 3 Aug 2021 16:44:49 +0900 Subject: [PATCH 03/16] thermal: Support multiple thermal resources To handle thermal scenario from multiple resources, manage the thermal data along with its own property. Change-Id: I933205f17dd7dc2e264fa2322b3a301b8f8e01d5 Signed-off-by: Dongwoo Lee --- include/pass/device-notifier.h | 1 + src/pass/pass-thermal.c | 2 + src/thermal/thermal.c | 106 +++++++++++++++++++++++++++++++++++++---- src/thermal/thermal.h | 5 ++ 4 files changed, 104 insertions(+), 10 deletions(-) diff --git a/include/pass/device-notifier.h b/include/pass/device-notifier.h index e1165ea..e72907a 100644 --- a/include/pass/device-notifier.h +++ b/include/pass/device-notifier.h @@ -41,6 +41,7 @@ struct device_notifier { struct device_notifier_thermal_data { char *name; char *scenario; + int priority; }; /* diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index 2a122ac..f6ae26a 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -34,6 +34,7 @@ #include "pass-resmon.h" #define DEFAULT_TEMPERATURE (-1000) +#define DEFAULT_THERMAL_PRIORITY (INT_MAX) static int thermal_update(struct pass_resource *res, struct resmon_result_src_thermal *thermal_result) @@ -170,6 +171,7 @@ static int thermal_monitor_func(void *result, void *user_data) thermal_data.name = res->config_data.res_thermal_name; thermal_data.scenario = thermal->scenarios[thermal->curr_scenario_idx].name; + thermal_data.priority = DEFAULT_THERMAL_PRIORITY; /* * Send notification with thermal scenario name according to diff --git a/src/thermal/thermal.c b/src/thermal/thermal.c index e4a5549..6b9a04e 100644 --- a/src/thermal/thermal.c +++ b/src/thermal/thermal.c @@ -91,6 +91,8 @@ static void thermal_free(void) if (ret < 0) _E("failed to pet Thermal Monitor scenario\n"); + g_ptr_array_free(g_thermal->resources, TRUE); + free(g_thermal); g_thermal = NULL; } @@ -134,16 +136,26 @@ static int thermal_init_done(void *data, void *user_data) return ret; } + g_thermal->resources = g_ptr_array_new_with_free_func(free); + for (i = 0; i < g_thermal->num; i++) { if (g_thermal->list[i].support) _I("Support \'%-12s\' thermal scenario", g_thermal->list[i].name); } + /* FIXME: + * Currently, initial thermal scenario among multiple resources are not + * settled properly; it is rather determined by one of scenario initialized + * lastly. So, it is required that the method for retrieving the current + * state of each device here. + */ + device_notify(DEVICE_NOTIFIER_THERMAL_GET_SCENARIO, &scenario); if (!scenario) { _E("failed to get current scenario for thermal\n"); + g_ptr_array_free(g_thermal->resources, TRUE); free(g_thermal); g_thermal = NULL; return -EINVAL; @@ -163,6 +175,7 @@ static int thermal_init_done(void *data, void *user_data) ret = thermal_put_scenario(g_thermal); if (ret < 0) { _E("failed to put Thermal Monitor scenario\n"); + g_ptr_array_free(g_thermal->resources, TRUE); free(g_thermal); g_thermal = NULL; } @@ -250,6 +263,60 @@ static struct pass_gdbus_signal_info g_gdbus_signal_infos[] = { }; /** + * @brief Add thermal devices using key as thermal_device_name from + * thermal data, or update current scenario of each thermal device + * + * @param [in] data thermal data from thermal monitors + */ +static int thermal_handle_notifier_data(struct device_notifier_thermal_data *data) +{ + struct device_notifier_thermal_data *entry = NULL; + int priority = data->priority; + int i; + + if (priority < 0) + return -EINVAL; + + /* + * If current notification has highest priority, then discards + * previous ones and makes the new list. Otherwise, check existence + * of current thermal data and if so, updates scenario, or else adds + * data into current resource list. + */ + if (priority > g_thermal->cur_priority) { + g_thermal->cur_priority = priority; + g_ptr_array_free(g_thermal->resources, TRUE); + g_thermal->resources = g_ptr_array_new_with_free_func(free); + } else { + int n = strlen(data->name); + + for (i = 0; i < g_thermal->resources->len; i++) { + struct device_notifier_thermal_data *e; + + e = g_ptr_array_index(g_thermal->resources, i); + if (!strncmp(e->name, data->name, n)) { + entry = e; + break; + } + } + } + + if (entry) { + strncpy(entry->scenario, data->scenario, strlen(data->scenario) + 1); + } else { + entry = malloc(sizeof(*data)); + if (!entry) + return -ENOMEM; + + memcpy(entry, data, sizeof(*data)); + + g_ptr_array_add(g_thermal->resources, entry); + } + + return 0; +} + +/** * @brief Send broadcasting signal with the decided scenario name from * pass-thermal before checking whether the scenario is supported * or not.. @@ -260,9 +327,10 @@ static int thermal_notifier_cb(void *data, void *user_data) { struct device_notifier_thermal_data *thermal_data = data; GVariant *gvar; - const char *scenario; + const char *scenario = "Undefined"; + int scenario_idx = -1; int ret; - int i; + int i, j; if (!g_thermal || !g_thermal->support || g_thermal->num <= 0) { _I("Thermal Monitor is stopped\n"); @@ -274,21 +342,39 @@ static int thermal_notifier_cb(void *data, void *user_data) scenario = thermal_data->scenario; - /* Find the available thermal scenario */ - for (i = 0; i < g_thermal->num; i++) { - if (!g_thermal->list[i].support) - continue; - if (!strncmp(g_thermal->list[i].name, scenario, strlen(scenario))) - break; + /* Ignore the notification of lower priority resources */ + if (thermal_data->priority < g_thermal->cur_priority) + return 0; + + ret = thermal_handle_notifier_data(thermal_data); + if (ret) + return ret; + + /* Find the highest scenario among available thermal resources */ + for (i = 0; i < g_thermal->resources->len; i++) { + struct device_notifier_thermal_data *e; + + e = (g_ptr_array_index(g_thermal->resources, i)); + for (j = 0; j < g_thermal->num; j++) { + if (!strncmp(g_thermal->list[j].name, + e->scenario, strlen(e->scenario))) { + if (j > scenario_idx) { + if (g_thermal->list[j].support) + scenario_idx = j; + scenario = e->scenario; + } + break; + } + } } /* If there is no available thermal scenario, just return */ - if (i >= g_thermal->num) { + if (scenario_idx < 0) { _I("Not supported \'%s\' scenario", scenario); return 0; } - g_thermal->cur_scenario_idx = i; + g_thermal->cur_scenario_idx = scenario_idx; /* If there is available thermal scenario, send the broadcast signal */ gvar = g_variant_new("(s)", scenario); diff --git a/src/thermal/thermal.h b/src/thermal/thermal.h index c65ec75..4257bbb 100644 --- a/src/thermal/thermal.h +++ b/src/thermal/thermal.h @@ -32,6 +32,7 @@ #include #include +#include /** * @brief Represent Thermal Monitor feature of PASS(Power Aware System @@ -50,6 +51,10 @@ struct thermal_scenario { bool support; /** Represent current idx of thermal scenario */ int cur_scenario_idx; + /** List of state of thermal devices */ + GPtrArray *resources; + /** Represent current highest priority level of thermal devices */ + int cur_priority; }; int thermal_get_scenario(const char *path, struct thermal_scenario *scenarios); -- 2.7.4 From fbf9018d55ab0c2413746065032e69b77d78e2a0 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Wed, 4 Aug 2021 15:20:59 +0900 Subject: [PATCH 04/16] pass: thermal: Set priority of thermal device through config file Now, the priority of each thermal device is can be determined by configuration file in pass-hal with 'thermal_priority' section. Change-Id: I677dd719672dea43c6675ccf774e646b492914d5 Signed-off-by: Dongwoo Lee --- src/pass/pass-parser.c | 7 +++++++ src/pass/pass-thermal.c | 3 +-- src/pass/pass.h | 10 ++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index 0aeb97b..b772276 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -699,6 +699,7 @@ static int parse_resource_data(struct pass *pass, int id, json_object *obj) const char *cpu_load_path; int number_of_cpus; int first_cpu; + int thermal_priority; /* Get property values */ /* - mandatory properties */ @@ -709,6 +710,10 @@ static int parse_resource_data(struct pass *pass, int id, json_object *obj) /* - optional properties */ thermal_device_name = get_string_from_object(obj, "thermal_device_name"); cooling_device_name = get_string_from_object(obj, "cooling_device_name"); + thermal_priority = get_int_from_object(obj, "thermal_priority"); + /* if thermal_priority is not set, set default */ + if (thermal_priority < 0) + thermal_priority = INT_MAX; /* - optional properties for only CPU */ cpu_load_path = get_string_from_object(obj, "cpu,cpu_load_path"); @@ -763,6 +768,8 @@ static int parse_resource_data(struct pass *pass, int id, json_object *obj) snprintf(config_data->res_name, BUFF_MAX, "%s", device_name); snprintf(config_data->res_thermal_name, BUFF_MAX, "%s", thermal_device_name); snprintf(config_data->res_cooling_name, BUFF_MAX, "%s", cooling_device_name); + config_data->res_thermal_priority = thermal_priority; + snprintf(config_data->path_conf_file, BUFF_MAX, "%s", device_config_path); snprintf(config_data->path_load_table, BUFF_MAX, "%s", cpu_load_path); config_data->num_cpus = number_of_cpus; diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index f6ae26a..9f21123 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -34,7 +34,6 @@ #include "pass-resmon.h" #define DEFAULT_TEMPERATURE (-1000) -#define DEFAULT_THERMAL_PRIORITY (INT_MAX) static int thermal_update(struct pass_resource *res, struct resmon_result_src_thermal *thermal_result) @@ -171,7 +170,7 @@ static int thermal_monitor_func(void *result, void *user_data) thermal_data.name = res->config_data.res_thermal_name; thermal_data.scenario = thermal->scenarios[thermal->curr_scenario_idx].name; - thermal_data.priority = DEFAULT_THERMAL_PRIORITY; + thermal_data.priority = res->config_data.res_thermal_priority; /* * Send notification with thermal scenario name according to diff --git a/src/pass/pass.h b/src/pass/pass.h index e5be2a7..1149d27 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -463,6 +463,16 @@ struct pass_resource_config_data { * res_cooling_name is 'cooling_device0'. */ char res_cooling_name[BUFF_MAX]; + + /** + * [optional] Priority of thermal information(1~INT_MAX) + * - When thermal state of multiple resources are monitored, the scenario of + * the device that has highest priority is used for dbus notification. + * If there are multiple resources has same highest priority, the highest + * level of scenario will be selected. + */ + int res_thermal_priority; + /** [mandatory] Path fo configuration for each h/w resource */ char path_conf_file[BUFF_MAX]; -- 2.7.4 From d3d8dd3b409a62508025c0a00e7c016afa8ff180 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 9 Aug 2021 12:26:26 +0900 Subject: [PATCH 05/16] pass: thermal: Notify scenario only when it changed Since this, thermal monitor notify scenario when it is different with previous on. To this end, set callback to thermal_result for notifying scenario, and it called when the scenario is changed. And this also enables to do different notification process for both thermal_monitor and get_scenario handler. Change-Id: Ib0e7cda2926f4402563b00e94125511954b2a043 Signed-off-by: Dongwoo Lee --- src/pass/pass-thermal.c | 62 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index 9f21123..07a1b95 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -36,7 +36,8 @@ #define DEFAULT_TEMPERATURE (-1000) static int thermal_update(struct pass_resource *res, - struct resmon_result_src_thermal *thermal_result) + struct resmon_result_src_thermal *thermal_result, + void (*post_fn)(void *, void *), void *post_data) { struct pass_thermal *thermal = &res->thermal;; struct pass_scenario *new_scenario; @@ -128,6 +129,13 @@ static int thermal_update(struct pass_resource *res, res->config_data.res_name, RESMON_SRC_THERMAL); } + /* + * After update thermal, if post process such as notification is + * required, do those jobs here. + */ + if (post_fn) + post_fn(res, post_data); + _I("Monitor '%-12s' of '%s' resource ('%3d' degrees,'%5d' ms)\n", new_scenario->name, res->config_data.res_name, @@ -136,6 +144,26 @@ static int thermal_update(struct pass_resource *res, return 0; } +static void notify_thermal_data(void *data, void *user_data) +{ + struct pass_resource *res = data; + struct pass_thermal *thermal = &res->thermal; + struct device_notifier_thermal_data thermal_data; + + thermal_data.name = res->config_data.res_thermal_name; + thermal_data.scenario = + thermal->scenarios[thermal->curr_scenario_idx].name; + thermal_data.priority = res->config_data.res_thermal_priority; + + /* + * Send notification with thermal scenario name according to + * measured temperature of each h/w resource. + */ + device_notify(DEVICE_NOTIFIER_THERMAL, (void *)&thermal_data); + + return 0; +} + /** * @brief Decide the proper thermal scenario by using both the monitored * raw data of thermal information and the parsed thermal @@ -150,9 +178,7 @@ static int thermal_update(struct pass_resource *res, static int thermal_monitor_func(void *result, void *user_data) { struct pass_resource *res = user_data; - struct pass_thermal *thermal = &res->thermal;; struct resmon_result_src_thermal *thermal_result; - struct device_notifier_thermal_data thermal_data; int ret; /* Get thermal_result raw data by monitoring */ @@ -163,29 +189,31 @@ static int thermal_monitor_func(void *result, void *user_data) * of thermal information and the parsed thermal information * from scenario section. */ - ret = thermal_update(res, thermal_result); + ret = thermal_update(res, thermal_result, notify_thermal_data, NULL); if (ret < 0) return ret; - thermal_data.name = res->config_data.res_thermal_name; - thermal_data.scenario = - thermal->scenarios[thermal->curr_scenario_idx].name; - thermal_data.priority = res->config_data.res_thermal_priority; + return 0; +} + +static void response_scenario(void *data, void *user_data) +{ + struct pass_resource *res = data; + struct pass_thermal *thermal = &res->thermal; + void **scenario = user_data; /* - * Send notification with thermal scenario name according to - * measured temperature of each h/w resource. + * Inform the thermal scenario name to + * DEVICE_NOTIFIER_THERMAL_GET_SCENARIO client. */ - device_notify(DEVICE_NOTIFIER_THERMAL, (void *)&thermal_data); + *scenario = (void *)thermal->scenarios[thermal->curr_scenario_idx].name; return 0; } static int thermal_get_scenario(void *data, void *user_data) { - void **scenario = data; struct pass_resource *res = user_data; - struct pass_thermal *thermal = &res->thermal;; struct resmon_result_src_thermal *thermal_result; int ret; @@ -197,16 +225,10 @@ static int thermal_get_scenario(void *data, void *user_data) * of thermal information and the parsed thermal information * from scenario section. */ - ret = thermal_update(res, thermal_result); + ret = thermal_update(res, thermal_result, response_scenario, data); if (ret < 0) return ret; - /* - * Inform the thermal scenario name to - * DEVICE_NOTIFIER_THERMAL_GET_SCENARIO client. - */ - *scenario = (void *)thermal->scenarios[thermal->curr_scenario_idx].name; - return 0; } -- 2.7.4 From 2b137c93b487859d1d2549697c254b73a403874e Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Fri, 20 Aug 2021 11:45:41 +0900 Subject: [PATCH 06/16] pass: thermal: Supprot mupltiple resources for 'thermal_get_scenario' To response 'getCoolDownStatus' dbus method call during boot, initial scenario state should be set before thermal monitor works once. When there are multiple resources which have thermal data, the final state of thermal scenario should be determined theirs priority. For this, this enables supporting multiple resources on 'thermal_get_scenario' handler. Change-Id: I920de0440efac9706405bcf63b0c110b407ddd60 Signed-off-by: Dongwoo Lee --- src/pass/pass-thermal.c | 20 ++++++++++++++++++-- src/thermal/thermal.c | 7 ------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index 07a1b95..f882041 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -198,15 +198,31 @@ static int thermal_monitor_func(void *result, void *user_data) static void response_scenario(void *data, void *user_data) { + static int cur_priority = INT_MAX; struct pass_resource *res = data; struct pass_thermal *thermal = &res->thermal; - void **scenario = user_data; + char **resp = user_data; + int priority = res->config_data.res_thermal_priority; + char *scenario = thermal->scenarios[thermal->curr_scenario_idx].name; /* * Inform the thermal scenario name to * DEVICE_NOTIFIER_THERMAL_GET_SCENARIO client. */ - *scenario = (void *)thermal->scenarios[thermal->curr_scenario_idx].name; + if (priority < cur_priority || !*resp) { + cur_priority = priority; + *resp = scenario; + } else if (priority == cur_priority) { + int i; + + for (i = 0; i < thermal->num_scenarios; i++) { + if (!strncmp(thermal->scenarios[i].name, *resp, strlen(*resp))) { + if (i < thermal->curr_scenario_idx) + *resp = scenario; + break; + } + } + } return 0; } diff --git a/src/thermal/thermal.c b/src/thermal/thermal.c index 6b9a04e..a58772c 100644 --- a/src/thermal/thermal.c +++ b/src/thermal/thermal.c @@ -144,13 +144,6 @@ static int thermal_init_done(void *data, void *user_data) g_thermal->list[i].name); } - /* FIXME: - * Currently, initial thermal scenario among multiple resources are not - * settled properly; it is rather determined by one of scenario initialized - * lastly. So, it is required that the method for retrieving the current - * state of each device here. - */ - device_notify(DEVICE_NOTIFIER_THERMAL_GET_SCENARIO, &scenario); if (!scenario) { -- 2.7.4 From d3616e261249caa6544d36d6cdd0a7678450a04a Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Fri, 27 Aug 2021 14:46:45 +0900 Subject: [PATCH 07/16] pass: thermal: Fix invalid return value This fixes to not return value for void functions. Change-Id: Ic341a80a69da983ffc5d76905c190957a6148632 Signed-off-by: Dongwoo Lee --- src/pass/pass-thermal.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index f882041..badfc9c 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -160,8 +160,6 @@ static void notify_thermal_data(void *data, void *user_data) * measured temperature of each h/w resource. */ device_notify(DEVICE_NOTIFIER_THERMAL, (void *)&thermal_data); - - return 0; } /** @@ -223,8 +221,6 @@ static void response_scenario(void *data, void *user_data) } } } - - return 0; } static int thermal_get_scenario(void *data, void *user_data) -- 2.7.4 From 1f64ee46b2c4721a529236d5dfa0e3983223bddf Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Fri, 27 Aug 2021 14:49:49 +0900 Subject: [PATCH 08/16] pass: thermal: Fix to handle priority of initial state properly At first, priority is intended to treat lower value as higher priority, but it is not handled intentionally when monitoring devices. So this fixes to handle it properly and to this end it is required to retrieve highest priority from the corresponding thermal device. Finally, instead of plain scenario string the notifer_data structure is passed as THERMAL_GET_SCENARIO parameter to get both scenario and priority. Change-Id: I330729be2890cdcb89ee7a677af2c0b8d4905fb0 Signed-off-by: Dongwoo Lee --- src/pass/pass-thermal.c | 18 +++++++++--------- src/thermal/thermal.c | 17 +++++++++++++---- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index badfc9c..26d7b74 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -196,10 +196,9 @@ static int thermal_monitor_func(void *result, void *user_data) static void response_scenario(void *data, void *user_data) { - static int cur_priority = INT_MAX; struct pass_resource *res = data; struct pass_thermal *thermal = &res->thermal; - char **resp = user_data; + struct device_notifier_thermal_data *thermal_data = user_data; int priority = res->config_data.res_thermal_priority; char *scenario = thermal->scenarios[thermal->curr_scenario_idx].name; @@ -207,16 +206,17 @@ static void response_scenario(void *data, void *user_data) * Inform the thermal scenario name to * DEVICE_NOTIFIER_THERMAL_GET_SCENARIO client. */ - if (priority < cur_priority || !*resp) { - cur_priority = priority; - *resp = scenario; - } else if (priority == cur_priority) { + if (priority < thermal_data->priority || !thermal_data->scenario) { + thermal_data->priority = priority; + thermal_data->scenario = scenario; + } else if (priority == thermal_data->priority) { + char *cur = thermal_data->scenario; int i; for (i = 0; i < thermal->num_scenarios; i++) { - if (!strncmp(thermal->scenarios[i].name, *resp, strlen(*resp))) { - if (i < thermal->curr_scenario_idx) - *resp = scenario; + if (!strncmp(thermal->scenarios[i].name, cur, strlen(cur))) { + if (i > thermal->curr_scenario_idx) + thermal_data->scenario = scenario; break; } } diff --git a/src/thermal/thermal.c b/src/thermal/thermal.c index a58772c..06b0d65 100644 --- a/src/thermal/thermal.c +++ b/src/thermal/thermal.c @@ -106,7 +106,12 @@ static void thermal_free(void) */ static int thermal_init_done(void *data, void *user_data) { - char *scenario = NULL; + struct device_notifier_thermal_data initial_state = { + .scenario = NULL, + .priority = INT_MAX, + }; + char *scenario; + int priority; int ret, i; if (g_thermal) @@ -144,7 +149,10 @@ static int thermal_init_done(void *data, void *user_data) g_thermal->list[i].name); } - device_notify(DEVICE_NOTIFIER_THERMAL_GET_SCENARIO, &scenario); + device_notify(DEVICE_NOTIFIER_THERMAL_GET_SCENARIO, &initial_state); + + scenario = initial_state.scenario; + priority = initial_state.priority; if (!scenario) { _E("failed to get current scenario for thermal\n"); @@ -177,6 +185,7 @@ static int thermal_init_done(void *data, void *user_data) } g_thermal->cur_scenario_idx = i; + g_thermal->cur_priority = priority; return 0; } @@ -276,7 +285,7 @@ static int thermal_handle_notifier_data(struct device_notifier_thermal_data *dat * of current thermal data and if so, updates scenario, or else adds * data into current resource list. */ - if (priority > g_thermal->cur_priority) { + if (priority < g_thermal->cur_priority) { g_thermal->cur_priority = priority; g_ptr_array_free(g_thermal->resources, TRUE); g_thermal->resources = g_ptr_array_new_with_free_func(free); @@ -336,7 +345,7 @@ static int thermal_notifier_cb(void *data, void *user_data) scenario = thermal_data->scenario; /* Ignore the notification of lower priority resources */ - if (thermal_data->priority < g_thermal->cur_priority) + if (thermal_data->priority > g_thermal->cur_priority) return 0; ret = thermal_handle_notifier_data(thermal_data); -- 2.7.4 From aa5cc25ffa06cc3c82d86d9f113a1e96253c7bc1 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 27 Aug 2021 15:35:02 +0900 Subject: [PATCH 09/16] pass: parser: Fix uninitialized value of number_of_cpus property If json configuraiton file doesn't contain the 'number_of_cpus' property, number_of_cpus has the minus value. It causes the problem. So that fix uninitialized value of number_of_cpus property when value is out of range. Change-Id: Ibac93e89b3cd85181287773b0bf0cf7f4aa6f692 Signed-off-by: Chanwoo Choi --- src/pass/pass-parser.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index b772276..8b14c01 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -747,6 +747,8 @@ static int parse_resource_data(struct pass *pass, int id, json_object *obj) break; } + number_of_cpus = number_of_cpus < 0 ? 0 : number_of_cpus; + /* Initialize config_data from property values of confiugartion file */ if (!strncmp(device_type, PASS_RESOURCE_CPU_NAME, strlen(device_type))) config_data->res_type = PASS_RESOURCE_CPU_ID; -- 2.7.4 From febcef5651baf9081206bb44321248237fe32b01 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 27 Aug 2021 16:00:25 +0900 Subject: [PATCH 10/16] unittest: power-haltests: Restart PASS daemon when PutResource tc is failed Even if PutResource tc is failed, need to restore the status of PASS daemon. So that restart PASS daemon. Change-Id: I3c4dab4f30a16660f0718bc1cd579afa15f75fbf Signed-off-by: Chanwoo Choi --- unittest/power-haltests.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/unittest/power-haltests.cpp b/unittest/power-haltests.cpp index 0e0e828..bc9bb68 100644 --- a/unittest/power-haltests.cpp +++ b/unittest/power-haltests.cpp @@ -543,6 +543,10 @@ TEST_F(PowerHaltest, PutResourceConfig_HandlesValidInput) ret = pass_hal_put_resource(res); if (ret < 0) { pass_parser_put_resource_config(&g_pass); + + /* Even if tc is failed, need to restart PASS daemon */ + pass_test_method_call(DBUS_CORE_PATH, DBUS_CORE_INTERFACE, + "start", NULL); ASSERT_EQ(ret, 0) << "PutResourceConfig Failed"; } } -- 2.7.4 From 1ee862602764f90cca7ae82b3bb1a136b5934dd9 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 30 Aug 2021 09:46:21 +0900 Subject: [PATCH 11/16] pass: thermal: Fix build warning Since the third agrument of strncpy means maximum permitted size of destination, using length of source string cause warning as like "specified bound depends on the length of the source argument". This fixes warning to use NAME_MAX instead of source length. Change-Id: I07399700ea454100ca0924c93eca6a99cb54b8cd Signed-off-by: Dongwoo Lee --- src/thermal/thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thermal/thermal.c b/src/thermal/thermal.c index 06b0d65..ae6c7f9 100644 --- a/src/thermal/thermal.c +++ b/src/thermal/thermal.c @@ -304,7 +304,7 @@ static int thermal_handle_notifier_data(struct device_notifier_thermal_data *dat } if (entry) { - strncpy(entry->scenario, data->scenario, strlen(data->scenario) + 1); + strncpy(entry->scenario, data->scenario, NAME_MAX); } else { entry = malloc(sizeof(*data)); if (!entry) -- 2.7.4 From f105ed76d4bb404de0e7dca22fd2a78e5aede65e Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 31 Aug 2021 20:59:30 +0900 Subject: [PATCH 12/16] pass: Add JSON API for getting object from object Since JSON object can have another object, now pass can parse object from object. Change-Id: I962fc8464e6cae895f178d19bcee095178157c08 Signed-off-by: Dongwoo Lee --- include/pass/common.h | 1 + src/core/common.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/include/pass/common.h b/include/pass/common.h index 25d079e..9cade8b 100644 --- a/include/pass/common.h +++ b/include/pass/common.h @@ -99,4 +99,5 @@ const char *get_string_from_object(json_object *obj, const char *key); const int get_int_from_object(json_object *obj, const char *key); const double get_double_from_object(json_object *obj, const char *key); const int get_boolean_from_object(json_object *obj, const char *key); +json_object *get_object_from_object(json_object *obj, const char *key); #endif /* __CORE_COMMON_H__ */ diff --git a/src/core/common.c b/src/core/common.c index 17f9f23..0497e28 100644 --- a/src/core/common.c +++ b/src/core/common.c @@ -112,3 +112,13 @@ const int get_boolean_from_object(json_object *obj, const char *key) return (int)json_object_get_boolean(tmp); } + +json_object *get_object_from_object(json_object *obj, const char *key) +{ + json_object *tmp = NULL; + + if (!json_object_object_get_ex(obj, key, &tmp)) + return NULL; + + return tmp; +} -- 2.7.4 From 2aa4e34e1f992cda9df5601dc8f732378b5b7862 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 31 Aug 2021 12:40:48 +0900 Subject: [PATCH 13/16] pass: thermal: Determine scenario with range value To prevent to be confused for determining scenario as following the temperature, now it is settled with range of temperature. Change-Id: Ic605a9b629da79129cbac8c5750316e16cc1c47e Signed-off-by: Dongwoo Lee --- src/pass/pass-parser.c | 22 ++++++++++++++++++---- src/pass/pass-thermal.c | 9 +++++---- src/pass/pass.h | 8 ++++++-- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index 8b14c01..3235530 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -88,7 +88,8 @@ static void init_scenario(struct pass_scenario *scenario) scenario->pmqos.max_level = INIT_VALUE; /* Private data for PASS_MODULE_THERMAL */ - scenario->thermal.temperature = INIT_VALUE; + scenario->thermal.temp_start = INIT_VALUE; + scenario->thermal.temp_end = INIT_VALUE; scenario->thermal.timer_interval = INIT_VALUE; } @@ -107,7 +108,9 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, int target_level; int cpuhp_min_level; int cpuhp_max_level; - int temperature; + json_object *temperature; + int temp_start; + int temp_end; int timer_interval_ms; /* Get property values */ @@ -120,7 +123,14 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, cpuhp_max_level = get_int_from_object(obj, "cpuhp_max_level"); /* - property for only thermal module */ - temperature = get_int_from_object(obj, "temperature"); + temperature = get_object_from_object(obj, "temperature"); + if (temperature) { + temp_start = get_int_from_object(temperature, "start"); + temp_end = get_int_from_object(temperature, "end"); + } else { + temp_start = temp_end = 0; + } + timer_interval_ms = get_int_from_object(obj, "timer_interval_ms"); /* Check the mandatory property values are valid or not */ @@ -130,6 +140,9 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, } else if (target_level < 0) { _E("Failed to get 'target_level' property in scenario section\n"); return -EINVAL; + } else if (temp_start < 0 || temp_end < 0 || temp_end < temp_start) { + _E("Invalid values for temperature property\n"); + return -EINVAL; } /* Initialize config_data from property values of confiugartion file */ @@ -142,7 +155,8 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, scenario->pmqos.max_level = cpuhp_max_level; /* - property for only thermal module */ - scenario->thermal.temperature = temperature; + scenario->thermal.temp_start = temp_start; + scenario->thermal.temp_end = temp_end; scenario->thermal.timer_interval = timer_interval_ms; return 0; diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index 26d7b74..585cd8c 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -59,15 +59,16 @@ static int thermal_update(struct pass_resource *res, new_scenario_idx = -1; for (i = 0; i < thermal->num_scenarios; i++) { - int temp = thermal->scenarios[i].thermal.temperature; + int temp_start = thermal->scenarios[i].thermal.temp_start; + int temp_end = thermal->scenarios[i].thermal.temp_end; if (thermal->scenarios[i].state != PASS_ON) continue; - if (new_scenario_idx < 0 && new_temp < temp) - new_scenario_idx = i; - else if (temp <= new_temp) + if (temp_start < new_temp && new_temp <= temp_end) { new_scenario_idx = i; + break; + } } /* diff --git a/src/pass/pass.h b/src/pass/pass.h index 1149d27..b2104f0 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -259,8 +259,12 @@ struct pass_scenario { /** Private data for PASS_MODULE_THERMAL */ struct { - /** Temperature of the scenario */ - int temperature; + /** + * Range of temperature to determine scenario level represented + * as (temp_start, temp_end]. + */ + int temp_start; + int temp_end; /** Interval of timer-based monitor (unit: millisecond) */ int timer_interval; } thermal; -- 2.7.4 From caf3641d9918ae2c58069f858f210c3823455979 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 14 Sep 2021 13:22:42 +0900 Subject: [PATCH 14/16] pass: thermal: Set a separate threshold for warning level reduction To prevent warning level is continuously changing at the edge of the temperature range, this adds distinct thresholds for warning level reduction. Change-Id: I0f0e911c1b3a6ee88fa7b26162d076f811a8ffea Signed-off-by: Dongwoo Lee --- src/pass/pass-parser.c | 19 +++++++++++++++---- src/pass/pass-thermal.c | 15 ++++++++++++--- src/pass/pass.h | 6 +++++- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index 3235530..357ab1d 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -111,6 +111,7 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, json_object *temperature; int temp_start; int temp_end; + int threshold; int timer_interval_ms; /* Get property values */ @@ -127,8 +128,12 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, if (temperature) { temp_start = get_int_from_object(temperature, "start"); temp_end = get_int_from_object(temperature, "end"); + threshold = get_int_from_object(temperature, "threshold"); + /* if threshold is not presented, using temp_end as default */ + if (threshold < 0) + threshold = temp_end; } else { - temp_start = temp_end = 0; + temp_start = temp_end = threshold = 0; } timer_interval_ms = get_int_from_object(obj, "timer_interval_ms"); @@ -140,9 +145,14 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, } else if (target_level < 0) { _E("Failed to get 'target_level' property in scenario section\n"); return -EINVAL; - } else if (temp_start < 0 || temp_end < 0 || temp_end < temp_start) { - _E("Invalid values for temperature property\n"); - return -EINVAL; + } else if (temperature) { + if (temp_start < 0 || temp_end < 0 || temp_end < temp_start) { + _E("Invalid temperature range in scenario section\n"); + return -EINVAL; + } else if (threshold < temp_start || threshold > temp_end) { + _W("Invalid thermal 'threshold', using default as range 'end'\n"); + threshold = temp_end; + } } /* Initialize config_data from property values of confiugartion file */ @@ -157,6 +167,7 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, /* - property for only thermal module */ scenario->thermal.temp_start = temp_start; scenario->thermal.temp_end = temp_end; + scenario->thermal.threshold = threshold; scenario->thermal.timer_interval = timer_interval_ms; return 0; diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index 585cd8c..fb3f159 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -61,13 +61,22 @@ static int thermal_update(struct pass_resource *res, for (i = 0; i < thermal->num_scenarios; i++) { int temp_start = thermal->scenarios[i].thermal.temp_start; int temp_end = thermal->scenarios[i].thermal.temp_end; + int threshold = thermal->scenarios[i].thermal.threshold; if (thermal->scenarios[i].state != PASS_ON) continue; - if (temp_start < new_temp && new_temp <= temp_end) { - new_scenario_idx = i; - break; + /* check if scenario level can be lower */ + if (i < thermal->curr_scenario_idx) { + if (temp_start < new_temp && new_temp <= threshold) { + new_scenario_idx = i; + break; + } + } else { + if (temp_start < new_temp && new_temp <= temp_end) { + new_scenario_idx = i; + break; + } } } diff --git a/src/pass/pass.h b/src/pass/pass.h index b2104f0..0fb09d0 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -261,10 +261,14 @@ struct pass_scenario { struct { /** * Range of temperature to determine scenario level represented - * as (temp_start, temp_end]. + * as (temp_start, temp_end]. For scenario level reduction, + * temperature should be in range of (temp_start, threshold] to + * prevent scenario is repeatedly changed at edge of original + * range. */ int temp_start; int temp_end; + int threshold; /** Interval of timer-based monitor (unit: millisecond) */ int timer_interval; } thermal; -- 2.7.4 From dcc05cecb87ba42e37041c0e2c6b0d681215ca20 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 13 Sep 2021 14:18:15 +0900 Subject: [PATCH 15/16] pass: thermal: Fix to copy scenario name for thermal_data Scenario name in thermal_data can be modified by thermal module, so it has side-effect intruding supported scenario list. This fixes to copy scenario instead of assigning pointer to prevent side-effect. Change-Id: I21fde12fed6bcd72fb83a6171e1b0a6d350261bd Signed-off-by: Dongwoo Lee --- include/pass/common.h | 1 + include/pass/device-notifier.h | 3 ++- src/pass/pass-thermal.c | 10 +++++----- src/pass/pass.h | 1 - src/thermal/thermal.c | 5 +++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/pass/common.h b/include/pass/common.h index 9cade8b..d0f0100 100644 --- a/include/pass/common.h +++ b/include/pass/common.h @@ -32,6 +32,7 @@ typedef unsigned int uint32; typedef unsigned long long uint64; +#define BUFF_MAX 255 #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) /* diff --git a/include/pass/device-notifier.h b/include/pass/device-notifier.h index e72907a..4af325a 100644 --- a/include/pass/device-notifier.h +++ b/include/pass/device-notifier.h @@ -21,6 +21,7 @@ #define __DEVICE_NOTIFIER_H__ #include +#include enum device_notifier_type { DEVICE_NOTIFIER_INIT_DONE, @@ -40,7 +41,7 @@ struct device_notifier { /* data structure for DEVICE_NOTIFIER_THERMAL */ struct device_notifier_thermal_data { char *name; - char *scenario; + char scenario[BUFF_MAX]; int priority; }; diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index fb3f159..efde403 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -159,10 +159,10 @@ static void notify_thermal_data(void *data, void *user_data) struct pass_resource *res = data; struct pass_thermal *thermal = &res->thermal; struct device_notifier_thermal_data thermal_data; + char *scenario = thermal->scenarios[thermal->curr_scenario_idx].name; thermal_data.name = res->config_data.res_thermal_name; - thermal_data.scenario = - thermal->scenarios[thermal->curr_scenario_idx].name; + memcpy(thermal_data.scenario, scenario, BUFF_MAX); thermal_data.priority = res->config_data.res_thermal_priority; /* @@ -216,9 +216,9 @@ static void response_scenario(void *data, void *user_data) * Inform the thermal scenario name to * DEVICE_NOTIFIER_THERMAL_GET_SCENARIO client. */ - if (priority < thermal_data->priority || !thermal_data->scenario) { + if (priority < thermal_data->priority || strlen(thermal_data->scenario) == 0) { thermal_data->priority = priority; - thermal_data->scenario = scenario; + memcpy(thermal_data->scenario, scenario, BUFF_MAX); } else if (priority == thermal_data->priority) { char *cur = thermal_data->scenario; int i; @@ -226,7 +226,7 @@ static void response_scenario(void *data, void *user_data) for (i = 0; i < thermal->num_scenarios; i++) { if (!strncmp(thermal->scenarios[i].name, cur, strlen(cur))) { if (i > thermal->curr_scenario_idx) - thermal_data->scenario = scenario; + memcpy(thermal_data->scenario, scenario, BUFF_MAX); break; } } diff --git a/src/pass/pass.h b/src/pass/pass.h index 0fb09d0..6afb875 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -39,7 +39,6 @@ #include #include -#define BUFF_MAX 255 #define PASS_LEVEL_COND_MAX 3 struct pass_resource; diff --git a/src/thermal/thermal.c b/src/thermal/thermal.c index ae6c7f9..4788e33 100644 --- a/src/thermal/thermal.c +++ b/src/thermal/thermal.c @@ -107,7 +107,6 @@ static void thermal_free(void) static int thermal_init_done(void *data, void *user_data) { struct device_notifier_thermal_data initial_state = { - .scenario = NULL, .priority = INT_MAX, }; char *scenario; @@ -149,12 +148,14 @@ static int thermal_init_done(void *data, void *user_data) g_thermal->list[i].name); } + memset(&initial_state.scenario, 0, BUFF_MAX); + device_notify(DEVICE_NOTIFIER_THERMAL_GET_SCENARIO, &initial_state); scenario = initial_state.scenario; priority = initial_state.priority; - if (!scenario) { + if (strlen(scenario) == 0) { _E("failed to get current scenario for thermal\n"); g_ptr_array_free(g_thermal->resources, TRUE); free(g_thermal); -- 2.7.4 From fac2959bd0a619b59183fd7ac004555d3358b072 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 19 Oct 2021 20:54:46 -0700 Subject: [PATCH 16/16] pass: thermal: Add overridable property To represent scenario overridable which means that the resource is allowed or disallowed to be changed by other modules such as PMQoS. Change-Id: I8871b013ff93882c8cb0656f94e1e450e864e4ac Signed-off-by: Dongwoo Lee --- src/pass/pass-parser.c | 3 +++ src/pass/pass.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index 357ab1d..1dacf07 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -113,11 +113,13 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, int temp_end; int threshold; int timer_interval_ms; + int overridable; /* Get property values */ name = get_string_from_object(obj, "name"); support = get_boolean_from_object(obj, "support"); target_level= get_int_from_object(obj, "target_level"); + overridable = get_boolean_from_object(obj, "overridable"); /* - property for only pmqos module */ cpuhp_min_level = get_int_from_object(obj, "cpuhp_min_level"); @@ -169,6 +171,7 @@ static int parse_scenario(struct pass_resource *res, json_object *obj, scenario->thermal.temp_end = temp_end; scenario->thermal.threshold = threshold; scenario->thermal.timer_interval = timer_interval_ms; + scenario->thermal.overridable = (overridable < 0) ? 1 : overridable; return 0; } diff --git a/src/pass/pass.h b/src/pass/pass.h index 6afb875..e50aa9a 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -270,6 +270,8 @@ struct pass_scenario { int threshold; /** Interval of timer-based monitor (unit: millisecond) */ int timer_interval; + /** Represents this scenario can be overridden */ + int overridable; } thermal; }; -- 2.7.4