From 186383bcb948482f88b4c8ebc7f5b3c1aec3cd3a Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 10 Feb 2020 18:56:52 +0900 Subject: [PATCH 01/16] pass: thermal: Call resource monitor API directly without redundant function get_thermal_result() is called once. It is possible to be removed instead of calling resmon (resouce monitor) API directly without any middle step. Change-Id: Ib058d540056fe1a8fc7b206fb98c096272c17121 Signed-off-by: Chanwoo Choi --- src/pass/pass-thermal.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index 8e9e970..4cbfccf 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -145,11 +145,6 @@ static int thermal_monitor_func(void *result, void *user_data) return 0; } -static inline void *get_thermal_result(struct pass_resource *res) -{ - return pass_resmon_get_result(res, RESMON_SRC_THERMAL); -} - static int thermal_get_scenario(void *data, void *user_data) { void **scenario = data; @@ -159,7 +154,7 @@ static int thermal_get_scenario(void *data, void *user_data) int ret; /* Get thermal_result raw data by reading directly */ - thermal_result = get_thermal_result(res); + thermal_result = pass_resmon_get_result(res, RESMON_SRC_THERMAL); /* * Update thermal scenario by using both the monitored raw data -- 2.7.4 From bfe62cf7ac2fed733060768d74b082dc6a6d3ff0 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 28 Jan 2020 11:32:41 +0900 Subject: [PATCH 02/16] pass: rescon: Add new 'limit_max_cpu' property for CPU h/w resource 'limit_max_cpu' means the maximum number of online CPU. If pass_level contains 'limit_max_cpu' value, RESCON (Resource Controller) And remove the wrong comment from 'limit_min_cpu' comment because 'limit_max_cpu' and 'limit_min_cpu' are supported for only PASS_RESOURCE_CPU_ID h/w resource. Change-Id: Ice6033491532895c8f1e1a71d7229f9362b184bf Signed-off-by: Chanwoo Choi --- src/pass/pass-parser.c | 15 ++++++++++----- src/pass/pass-rescon.c | 16 ++++++++++++---- src/pass/pass.h | 8 ++++++-- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index 47b38d0..e72813a 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -178,16 +178,21 @@ static int parse_level(struct parse_result *result, if (ret < 0) return ret; level->limit_min_freq = ret; - } else if (MATCH(result->name, "limit_min_cpu")) { - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - level->limit_min_cpu = ret; /* * Properties for the following h/w resources: * - PASS_RESOURCE_CPU_ID */ + } else if (MATCH(result->name, "limit_max_cpu")) { + ret = sys_strtol(result->value); + if (ret < 0) + return ret; + level->limit_max_cpu = ret; + } else if (MATCH(result->name, "limit_min_cpu")) { + ret = sys_strtol(result->value); + if (ret < 0) + return ret; + level->limit_min_cpu = ret; } else if (MATCH(result->name, "num_down_cond")) { ret = sys_strtol(result->value); if (ret < 0) diff --git a/src/pass/pass-rescon.c b/src/pass/pass-rescon.c index 074e527..a2bfd97 100644 --- a/src/pass/pass-rescon.c +++ b/src/pass/pass-rescon.c @@ -46,10 +46,11 @@ */ static int rescon_set_level(struct pass_resource *res, int new_level) { - struct pass_level *levels = res->config_data.levels;; + struct pass_level *levels = res->config_data.levels; int curr_level = res->rescon.curr_level; int limit_max_freq; int limit_min_freq; + int limit_max_cpu; int limit_min_cpu; int fault_around_bytes; int ret, i; @@ -57,20 +58,27 @@ static int rescon_set_level(struct pass_resource *res, int new_level) /* Get the detailed resource value according to PASS level */ limit_max_freq = levels[new_level].limit_max_freq; limit_min_freq = levels[new_level].limit_min_freq; + limit_max_cpu = levels[new_level].limit_max_cpu; limit_min_cpu = levels[new_level].limit_min_cpu; fault_around_bytes = levels[new_level].fault_around_bytes; res->rescon.prev_level = curr_level; res->rescon.curr_level = new_level; - /* Turn on/off CPUs according demanded number of online CPU */ - if (limit_min_cpu >= 0) { + /* Turn on/off CPUs according to the required number of online CPU */ + if (limit_min_cpu >= 0 && limit_max_cpu >= 0) { + if (!limit_max_cpu || limit_max_cpu > res->config_data.num_cpus) + limit_max_cpu = res->config_data.num_cpus; if (limit_min_cpu > res->config_data.num_cpus) limit_min_cpu = res->config_data.num_cpus; + if (limit_min_cpu > limit_max_cpu) + limit_min_cpu = limit_max_cpu; + pass_set_online_min_num(res, limit_min_cpu); + pass_set_online_max_num(res, limit_max_cpu); - for (i = 0; i < res->config_data.num_cpus; i++) + for (i = 0; i < limit_max_cpu; i++) pass_set_online_state(res, res->config_data.cpu + i, (i < limit_min_cpu) ? 1 : 0); } diff --git a/src/pass/pass.h b/src/pass/pass.h index 0e4868e..83064de 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -133,11 +133,15 @@ struct pass_level { */ int limit_min_freq; /** + * The maximum number of online CPU + * and this property is used for the following resources: + * - PASS_RESOURCE_CPU_ID + */ + int limit_max_cpu; + /** * The minimum number of online CPU * and this property is used for the following resources: * - PASS_RESOURCE_CPU_ID - * - PASS_RESOURCE_BUS_ID - * - PASS_RESOURCE_GPU_ID */ int limit_min_cpu; /** -- 2.7.4 From c6c0e635afe1372f05d936da16ad9c95efa3c7e8 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 28 Jan 2020 13:40:38 +0900 Subject: [PATCH 03/16] pass: parser: Verify properties of pass_level before using Prior to that there are no any restrictions about adding properties to pass_level in the configuration file such as /etc/pass/pass-resource-*.conf for each h/w resource. Add some restrictions of pass_level as following: - In case of CPU, If there is either limit_min_cpu or limit_max_cpu in pass_level, have to add both limit_min_cpu and limit_max_cpu to pass_level. - In case of CPU/GPU/BUS, if there is either limit_min_freq or limit_max_freq in pass_level, have to add both limit_min_freq and limit_max_frewq to pass_level. Change-Id: I899121c433432ad92800f741f2b8df78dc135de0 Signed-off-by: Chanwoo Choi --- src/pass/pass-cpuhp-radiation.c | 8 ++-- src/pass/pass-cpuhp-step.c | 4 +- src/pass/pass-parser.c | 94 ++++++++++++++++++++++++++++++++++++++--- src/pass/pass-rescon.c | 6 +-- 4 files changed, 96 insertions(+), 16 deletions(-) diff --git a/src/pass/pass-cpuhp-radiation.c b/src/pass/pass-cpuhp-radiation.c index 058c251..f1af302 100644 --- a/src/pass/pass-cpuhp-radiation.c +++ b/src/pass/pass-cpuhp-radiation.c @@ -96,7 +96,7 @@ int pass_cpuhp_radiation_governor(struct pass_resource *res, void *result) up_condition = false; } - if (levels[level].num_up_cond && up_condition) { + if (levels[level].num_up_cond > 0 && up_condition) { up_count++; /* @@ -114,7 +114,7 @@ int pass_cpuhp_radiation_governor(struct pass_resource *res, void *result) down_condition = false; } - if (levels[level].num_down_cond && down_condition) { + if (levels[level].num_down_cond > 0 && down_condition) { down_count++; /* @@ -140,7 +140,7 @@ int pass_cpuhp_radiation_governor(struct pass_resource *res, void *result) right_condition = false; } - if (levels[level].num_right_cond && right_condition) { + if (levels[level].num_right_cond > 0 && right_condition) { right_count++; /* @@ -167,7 +167,7 @@ int pass_cpuhp_radiation_governor(struct pass_resource *res, void *result) left_condition = false; } - if (levels[level].num_left_cond && left_condition) { + if (levels[level].num_left_cond > 0 && left_condition) { left_count++; /* diff --git a/src/pass/pass-cpuhp-step.c b/src/pass/pass-cpuhp-step.c index 405deb5..06983c4 100644 --- a/src/pass/pass-cpuhp-step.c +++ b/src/pass/pass-cpuhp-step.c @@ -91,7 +91,7 @@ int pass_cpuhp_step_governor(struct pass_resource *res, void *result) up_condition = true; } - if (levels[level].num_up_cond && up_condition) { + if (levels[level].num_up_cond > 0 && up_condition) { up_count++; /* @@ -116,7 +116,7 @@ int pass_cpuhp_step_governor(struct pass_resource *res, void *result) down_condition = true; } - if (levels[level].num_down_cond && down_condition) { + if (levels[level].num_down_cond > 0 && down_condition) { down_count++; /* diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index e72813a..aec23f4 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -47,6 +47,7 @@ #define MAX_NUM 255 #define MIN_TIMEOUT_SEC 0.2 /* 200 millisecond */ #define MAX_TIMEOUT_SEC 3600.0 /* 1 hour */ +#define INIT_VALUE -1 static int compare_compatible_name(char *compatible, char *path_compatible) { @@ -145,12 +146,73 @@ static int parse_scenario(struct parse_result *result, return 0; } -/** - * @brief Parse pass_level section to get pass_level information - * @param [in] result Parsed raw data from configuration - * @param [in] level Parsed data of a pass_level will be saved to it - * @return @c 0 on success, otherwise error value - */ +static int verify_level(int res_type, int level_idx, struct pass_level *level) +{ + if (!level) + return -EINVAL; + + switch (res_type) { + case PASS_RESOURCE_CPU_ID: + if ((level->limit_min_cpu >= 0 || level->limit_max_cpu >= 0) + && !(level->limit_min_cpu >= 0 && level->limit_max_cpu >= 0)) { + _E("Level%d doesn't contain either " \ + "limit_min_cpu(%d) or limit_max_cpu(%d)", + level_idx, + level->limit_min_cpu, + level->limit_max_cpu); + return -EINVAL; + } + /* fall through */ + case PASS_RESOURCE_GPU_ID: + case PASS_RESOURCE_BUS_ID: + if ((level->limit_min_freq > 0 || level->limit_max_freq > 0) + && !(level->limit_min_freq > 0 && level->limit_max_freq > 0)) { + _E("Level%d doesn't contain either " \ + "limit_min_freq(%d) or limit_max_freq(%d)", + level_idx, + level->limit_min_freq, + level->limit_max_freq); + return -EINVAL; + } + break; + case PASS_RESOURCE_MEMORY_ID: + case PASS_RESOURCE_NONSTANDARD_ID: + break; + default: + return -EINVAL; + }; + + return 0; +} + +static void init_level(struct pass_level *level) +{ + level->limit_max_freq = INIT_VALUE; + level->limit_min_freq = INIT_VALUE; + level->limit_max_cpu = INIT_VALUE; + level->limit_min_cpu = INIT_VALUE; + + level->num_down_cond = INIT_VALUE; + level->down_cond[0].freq = INIT_VALUE; + level->down_cond[0].nr_running = INIT_VALUE; + level->down_cond[0].busy_cpu = INIT_VALUE; + level->num_up_cond = INIT_VALUE; + level->up_cond[0].freq = INIT_VALUE; + level->up_cond[0].nr_running = INIT_VALUE; + level->up_cond[0].busy_cpu = INIT_VALUE; + level->num_left_cond = INIT_VALUE; + level->left_cond[0].freq = INIT_VALUE; + level->left_cond[0].nr_running = INIT_VALUE; + level->left_cond[0].busy_cpu = INIT_VALUE; + level->num_right_cond = INIT_VALUE; + level->right_cond[0].freq = INIT_VALUE; + level->right_cond[0].nr_running = INIT_VALUE; + level->right_cond[0].busy_cpu = INIT_VALUE; + level->gov_timeout = INIT_VALUE; + + level->fault_around_bytes = INIT_VALUE; +} + static int parse_level(struct parse_result *result, struct pass_level *level) { @@ -492,12 +554,18 @@ static int parse_core(struct parse_result *result, void *user_data) } if (res->config_data.num_levels > 0 && !res->config_data.levels) { + int i; + res->config_data.levels = calloc(res->config_data.num_levels, sizeof(struct pass_level)); if (!res->config_data.levels) { _E("cannot allocate memory for levels\n"); return -EINVAL; } + + /* Initialize pass_level before parsing */ + for (i = 0; i < res->config_data.num_levels; i++) + init_level(&res->config_data.levels[i]); } return 0; @@ -832,7 +900,7 @@ int pass_get_each_resource_config(struct pass_resource *res, char *path) struct pass_cpuhp *cpuhp; struct pass_pmqos *pmqos; struct pass_thermal *thermal; - int ret; + int ret, i; if (!res) return -EINVAL; @@ -865,12 +933,24 @@ int pass_get_each_resource_config(struct pass_resource *res, char *path) /* Initialize the Thermal's data */ thermal->state = PASS_UNUSED; + /* Parse pass_level */ ret = config_parse(path, parse_each_resource, res); if (ret < 0) { _E("cannot parse %s\n", path); return -EINVAL; } + /* Verify the parsed pass_level */ + for (i = 0; i < res->config_data.num_levels; i++) + ret |= verify_level(res->config_data.res_type, + i, &res->config_data.levels[i]); + + if (ret < 0) { + _E("failed to verify Level of '%s' resource\n", + res->config_data.res_name); + return -EINVAL; + } + if (res->config_data.state == PASS_UNUSED) return -EINVAL; diff --git a/src/pass/pass-rescon.c b/src/pass/pass-rescon.c index a2bfd97..c156a17 100644 --- a/src/pass/pass-rescon.c +++ b/src/pass/pass-rescon.c @@ -84,7 +84,7 @@ static int rescon_set_level(struct pass_resource *res, int new_level) } /* Set maximum frequency */ - if (limit_max_freq) { + if (limit_max_freq > 0) { ret = pass_set_max_freq(res, limit_max_freq); if (ret < 0) { _E("cannot set the maximum frequency of %s", @@ -94,7 +94,7 @@ static int rescon_set_level(struct pass_resource *res, int new_level) } /* Set minimum frequency */ - if (limit_min_freq) { + if (limit_min_freq > 0) { ret = pass_set_min_freq(res, limit_min_freq); if (ret < 0) { _E("cannot set the minimum frequency of %s", @@ -104,7 +104,7 @@ static int rescon_set_level(struct pass_resource *res, int new_level) } /* Set fault_around_bytes for the memory h/w */ - if (fault_around_bytes) { + if (fault_around_bytes > 0) { ret = pass_set_fault_around_bytes(res, fault_around_bytes); if (ret < 0) { _E("cannot set the fault_around_bytes of %s", -- 2.7.4 From eef406453163717c34f9636fe717132755d17968 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 28 Jan 2020 14:02:30 +0900 Subject: [PATCH 04/16] pass: parser: Add support for parsing of scenario pass_level PASS provides multiple modules like CPUHP (CPU Hotplug Manager), PMQoS, Thermal Monitor and so on. Each module requires their own pass_level in order to change h/w resources such as the number of online CPU, the minimum/maximum frequency of GPU. Prior to that, PASS supports only 'pass_level'. If user of PASS want to set 'AppLaunch' scenario of PMQoS module, PMQoS only requires the range of 'pass_level' like the minimum and maximum 'pass_level'. It is not enough to meet the requirements from 'AppLaunch' scenario. Some scenario might require the more detailed changes than already defined 'pass_level'. In result of these requirements, add support for new 'scenario pass_level' for only scenario such as AppLaunch of PMQoS and WarningAction of Thermal Monitor. 'scenario pass_level' is possible to specify the detailed value of h/w resources such as the minimum/maximum frequency (limit_min/max_fre), the minimum/maximum number of online CPU (limit_min/max_cpu) and fault_around_bytes for memorh h/w resource. [Detailed new properties for 'scenario pass_level'] 1. - section name : [pass] - property name : pass_num_scenario_levels - property value type : integer - mandatory or optional : mandatory 2. - section name : [pass] - property name : pass_init_scenario_levels - property value type : integer - mandatory or optional : mandatory 3. - section name : [ScenarioLevel%d] - properties name in section : pass_level and scenario pass_level are to use common properties. 4. - section name : [Scenario%d] - property name : scenario_level - property value type : integer, it denotes the index of scenario pass_level. - mandatory or optional : mandatory For example, usecase of scenario pass_level by AppLaunch PMQoS scenario. [pass] pass_num_scenario_levels=2 pass_init_scenario_levels=0 [ScenarioLevel0] limit_min_freq=400000 limit_max_freq=1300000 limit_min_cpu=1 limit_max_cpu=4 [ScenarioLevel1] limit_min_freq=800000 limit_max_freq=1300000 limit_min_cpu=4 limit_max_cpu=4 [PassScenario] pass_scenario_support=yes pass_num_scenarios=1 [Scenario0] name=AppLaunch support=yes scenario_level=1 Change-Id: I8f058bf68278667ee68b821eb58c972aa298646f Signed-off-by: Chanwoo Choi --- src/pass/pass-parser.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++- src/pass/pass.h | 15 ++++++- 2 files changed, 123 insertions(+), 2 deletions(-) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index aec23f4..ac2d46f 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -93,6 +93,22 @@ static enum pass_state is_supported(char *value) return state; } +static void init_scenario(struct pass_scenario *scenario) +{ + scenario->state = PASS_UNUSED; + scenario->level = INIT_VALUE; + + /* Private data for PASS_MODULE_PMQOS */ + scenario->pmqos.locked = PASS_UNUSED; + scenario->pmqos.locked_time = 0; + scenario->pmqos.min_level = INIT_VALUE; + scenario->pmqos.max_level = INIT_VALUE; + + /* Private data for PASS_MODULE_THERMAL */ + scenario->thermal.temperature = INIT_VALUE; + scenario->thermal.timer_interval = INIT_VALUE; +} + /** * @brief Parse scenario section to get scenario name and information * @param [in] result Parsed raw data from configuration @@ -117,6 +133,11 @@ static int parse_scenario(struct parse_result *result, scenario->state = is_supported(result->value); if (scenario->state < 0) return -EINVAL; + } else if (MATCH(result->name, "scenario_level")) { + ret = sys_strtol(result->value); + if (ret < 0) + return ret; + scenario->level = ret; /* Parse properties for only PASS_MODULE_PMQOS */ } else if (MATCH(result->name, "min_level")) { @@ -400,6 +421,8 @@ static int parse_pmqos(struct parse_result *result, void *user_data) } if (num_scenarios > 0 && !pmqos->scenarios) { + int i; + pmqos->scenarios = calloc(num_scenarios, sizeof(struct pass_scenario)); if (!pmqos->scenarios) { @@ -408,6 +431,9 @@ static int parse_pmqos(struct parse_result *result, void *user_data) } pmqos->num_scenarios = num_scenarios; + + for (i = 0; i < num_scenarios; i++) + init_scenario(&pmqos->scenarios[i]); } } @@ -451,6 +477,8 @@ static int parse_thermal(struct parse_result *result, void *user_data) } if (num_scenarios > 0 && !thermal->scenarios) { + int i; + thermal->scenarios = calloc(num_scenarios, sizeof(struct pass_scenario)); if (!thermal->scenarios) { @@ -458,6 +486,9 @@ static int parse_thermal(struct parse_result *result, void *user_data) return -EINVAL; } thermal->num_scenarios = num_scenarios; + + for (i = 0; i < num_scenarios; i++) + init_scenario(&thermal->scenarios[i]); } } else if (MATCH(result->name, "thermal_timer_interval_ms")) { ret = sys_strtol(result->value); @@ -529,6 +560,31 @@ static int parse_core(struct parse_result *result, void *user_data) return ret; res->rescon.init_level = ret; + } else if (MATCH(result->name, "pass_num_scenario_levels")) { + int num_scenario_levels; + + num_scenario_levels = sys_strtol(result->value); + if (num_scenario_levels < 0) + return num_scenario_levels; + if (num_scenario_levels > MAX_NUM) { + _E("cannot parse %s\n", result->name); + return -EINVAL; + } + res->config_data.num_scenario_levels = num_scenario_levels; + } else if (MATCH(result->name, "pass_init_scenario_level")) { + unsigned int init_level; + + ret = sys_strtol(result->value); + if (ret < 0) + return ret; + init_level = ret; + + if (init_level > MAX_NUM) { + _E("cannot parse %s\n", result->name); + return -EINVAL; + } + res->rescon.init_scenario_level = init_level; + } else if (MATCH(result->name, "pass_cpu_threshold")) { ret = sys_strtol(result->value); if (ret < 0) @@ -566,6 +622,21 @@ static int parse_core(struct parse_result *result, void *user_data) /* Initialize pass_level before parsing */ for (i = 0; i < res->config_data.num_levels; i++) init_level(&res->config_data.levels[i]); + } else if (res->config_data.num_scenario_levels > 0 + && !res->config_data.scenario_levels) { + int i; + + res->config_data.scenario_levels = + calloc(res->config_data.num_scenario_levels, + sizeof(struct pass_level)); + if (!res->config_data.scenario_levels) { + _E("cannot allocate memory for levels\n"); + return -EINVAL; + } + + /* Initialize scenariop pass_level before parsing */ + for (i = 0; i < res->config_data.num_scenario_levels; i++) + init_level(&res->config_data.scenario_levels[i]); } return 0; @@ -582,6 +653,7 @@ static int parse_each_resource(struct parse_result *result, void *user_data) struct pass_resource *res = user_data; struct pass_pmqos *pmqos = &res->pmqos; struct pass_thermal *thermal = &res->thermal; + struct pass_level *level; char section_name[BUFF_MAX]; int i, ret; @@ -617,6 +689,23 @@ static int parse_each_resource(struct parse_result *result, void *user_data) } } + /* Parsing 'ScenarioLevel' section */ + for (i = 0; i < res->config_data.num_scenario_levels; i++) { + ret = snprintf(section_name, BUFF_MAX, "ScenarioLevel%d", i); + + if (MATCH(result->section, section_name)) { + level = &res->config_data.scenario_levels[i]; + + ret = parse_level(result, level); + if (ret < 0) { + _E("cannot parse 'ScenarioLevel%d' section\n", i); + return ret; + } + + goto out; + } + } + /* Parsing 'PassScenario' section */ if (MATCH(result->section, "PassScenario")) { ret = parse_pmqos(result, user_data); @@ -916,10 +1005,11 @@ int pass_get_each_resource_config(struct pass_resource *res, char *path) res->config_data.levels = NULL; /* Initialize the ResCon's data */ - res->rescon.init_level = 0; + res->rescon.init_level = INIT_VALUE; res->rescon.prev_level = 0; res->rescon.min_level = 0; res->rescon.max_level = 0; + res->rescon.init_scenario_level = INIT_VALUE; /* Initialize the CPUHP's data */ cpuhp->pass_cpu_threshold = 0; @@ -951,6 +1041,17 @@ int pass_get_each_resource_config(struct pass_resource *res, char *path) return -EINVAL; } + /* Verify the parsed scenario pass_level */ + for (i = 0; i < res->config_data.num_scenario_levels; i++) + ret |= verify_level(res->config_data.res_type, + i, &res->config_data.scenario_levels[i]); + + if (ret < 0) { + _E("failed to verify ScenarioLevel of '%s' resource\n", + res->config_data.res_name); + return -EINVAL; + } + if (res->config_data.state == PASS_UNUSED) return -EINVAL; @@ -977,6 +1078,13 @@ void pass_put_each_resource_config(struct pass_resource *res) if (res->config_data.levels) { free(res->config_data.levels); res->config_data.levels = NULL; + res->config_data.num_levels = 0; + } + + if (res->config_data.scenario_levels) { + free(res->config_data.scenario_levels); + res->config_data.scenario_levels = NULL; + res->config_data.num_scenario_levels = 0; } if (res->pmqos.scenarios) { diff --git a/src/pass/pass.h b/src/pass/pass.h index 83064de..22ced5b 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -224,6 +224,8 @@ struct pass_scenario { char name[BUFF_MAX]; /** State of the scenario */ enum pass_state state; + /** Level of the scenario */ + int level; /** Private data for PASS_MODULE_PMQOS */ struct { @@ -261,7 +263,7 @@ struct pass_rescon { /** * Initial level when initializing h/w resource by resource controller */ - unsigned int init_level; + int init_level; /** Current level controlled by resource controller */ unsigned int curr_level; /** Previous level controlled by resource controller */ @@ -270,6 +272,12 @@ struct pass_rescon { unsigned int min_level; /** Available maximum level controlled by resource controller */ unsigned int max_level; + + /** + * Initial level when initializing h/w resource by resource controller. + * If value is -1, it is not initialized by parser. + */ + int init_scenario_level; }; /** @@ -449,6 +457,11 @@ struct pass_resource_config_data { unsigned int num_levels; /** List of pass_levels */ struct pass_level *levels; + + /** The number of scenario pass_levels */ + int num_scenario_levels; + /** List of scenario pass_levels */ + struct pass_level *scenario_levels; }; /** -- 2.7.4 From d54cf9cc4588b52f41a420d268e976c35b45f957 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 28 Jan 2020 14:47:44 +0900 Subject: [PATCH 05/16] pass: rescon: Add support for multiple scenario pass_level PASS provides multiple modules like CPUHP (CPU Hotplug Manager), PMQoS, Thermal Monitor and so on. Each module requires their own pass_level in order to change h/w resources such as the number of online CPU, the minimum/maximum frequency of GPU. Prior to that, PASS supports only 'pass_level'. If user of PASS want to set 'AppLaunch' scenario of PMQoS module, PMQoS only requires the range of 'pass_level' like the minimum and maximum 'pass_level'. It is not enough to meet the requirements from 'AppLaunch' scenario. Some scenario might require the more detailed changes than already defined 'pass_level'. In result of these requirements, add support for new 'scenario pass_level' for scenarios such as AppLaunch of PMQoS and WarningAction of Thermal Monitor. 'scenario pass_level' is possible to specify the detailed value of h/w resources such as the minimum/maximum frequency (limit_(min|max)_freq), the minimum/maximum number of online CPU (limit_(min|max)_cpu) and fault_around_bytes for memorh h/w resource. In order to support the multiple scenario pass_level at the same time, RESCON (Resource Controller) module adds new following functions and then delete previous function. PMQoS will use new functions for supporting the 'scenario pass_level' and Thermal Monitor will use the new functions for 'scenario pass_level' for constrainting the h/w resouece to prevent the dangerous overheating. [Added new functions] - int pass_rescon_sync(struct pass_resource *res); - int pass_rescon_set_level_sync(struct pass_resource *res, int level); - int pass_rescon_set_scenario_level_sync(struct pass_resource *res, int scenario_level); - int pass_rescon_unset_scenario_level_sync(struct pass_resource *res, int scenario_level); - int pass_rescon_set_scenario_level(struct pass_resource *res, int scenario_level); - int pass_rescon_unset_scenario_level(struct pass_resource *res, int scenario_level); [Deleted functions] - int pass_rescon_set_level_scope(struct pass_resource *res, int new_level, int min_level, int max_level, void *data); [Deprecated functions. Because these functions are keeping for the compatibility with legacy feature. It should be used on PMQoS module.] - int pass_rescon_set_scenario_level_sync_with_data(struct pass_resource *res, int scenario_level, void *data); - int pass_rescon_unset_scenario_level_sync_with_data(struct pass_resource *res, int scenario_level, void *data); [Exmaple of multiple scenario pass_level on PMQoS and Thermal Monitor modules] Case 1. AppLaunch scenario of PMQoS , - 'AppLaunch' scenario contains 'scenario_level=1' property as following: [ScenarioLevel1] limit_min_freq=1300000 limit_max_freq=1300000 limit_min_cpu=3 limit_max_cpu=4 - In result, RESCON (Resource Controller) set h/w resource as following: The minimum frequency is 1300MHz. The maximum frequency is 1300MHz. The minimum number of online CPU is 3. The maximum number of online CPU is 4. -> It maintains 1300MHz and three online CPU. Case 2. Warning scenario of Thermal Monitor, - 'Warning' scenario contains 'scenario_level=2' property as following: [ScenarioLevel2] limit_min_freq=768000 limit_max_freq=1000000 limit_min_cpu=0 limit_max_cpu=2 - In result, RESCON (Resource Controller) set h/w resource as following: The minimum frequency is 768MHz. The maximum frequency is 1000MHz. The minimum number of online CPU has no any constraint. The maximum number of online CPU is 2. -> It maintain 768MHz and doesn't turn on more than 2 CPU. Case 3. AppLaunch scenario of PMQoS + Warning scenario of Thermal Monitor, - 'AppLaunch' scenario contains 'scenario_level=1' property and 'Warning' scenario contains 'scenario_level=2' property as following: [ScenarioLevel1] limit_min_freq=1300000 limit_max_freq=1300000 limit_min_cpu=3 limit_max_cpu=4 [ScenarioLevel2] limit_min_freq=768000 limit_max_freq=1000000 limit_min_cpu=0 limit_max_cpu=2 - In result, RESCON (Resource Controller) set h/w resource as following: The minimum frequency is 1000MHz because MAX(1300000, 768000) cannot be over thatn maximum frequency (1000MHz). The maximum frequency is 1000MHz. The minimum number of online CPU is 2. The maximum number of online CPU is 2. -> It maintain 1000MHz and doesn't turn on more than 2 CPU. [ScenarioLevel0] limit_min_freq=768000 limit_max_freq=1300000 limit_min_cpu=0 limit_max_cpu=4 [ScenarioLevel1] limit_min_freq=1300000 limit_max_freq=1300000 limit_min_cpu=3 limit_max_cpu=4 [ScenarioLevel2] limit_min_freq=768000 limit_max_freq=1000000 limit_min_cpu=0 limit_max_cpu=2 [PassScenario] pass_scenario_support=yes pass_num_scenarios=1 [Scenario0] name=AppLaunch support=yes scenario_level=1 <- It indicates 'ScenarioLevel1' for AppLaunch scenario. [thermal] thermal_support=yes thermal_number_of_scenario=2 thermal_timer_interval_ms=5000 [thermal.scenario0] support=yes name=Release temperature=25 timer_interval_ms=5000 scenario_level=0 [thermal.scenario1] support=yes name=Warning temperature=30 timer_interval_ms=3000 scenario_level=2 <- It indicates 'ScenarioLevel2' for Warning scenario. Change-Id: I45e99b1794b85342f29bf0decec6a859f56f8f58 Signed-off-by: Chanwoo Choi --- src/pass/pass-cpuhp.c | 2 +- src/pass/pass-parser.c | 6 +- src/pass/pass-pmqos.c | 62 ++---- src/pass/pass-rescon.c | 497 ++++++++++++++++++++++++++++++++++++++++--------- src/pass/pass-rescon.h | 23 ++- src/pass/pass.h | 36 +++- 6 files changed, 477 insertions(+), 149 deletions(-) diff --git a/src/pass/pass-cpuhp.c b/src/pass/pass-cpuhp.c index d659416..5345e03 100644 --- a/src/pass/pass-cpuhp.c +++ b/src/pass/pass-cpuhp.c @@ -192,7 +192,7 @@ static int cpuhp_timer_func(void *result, void *user_data) if (cpuhp->governor->governor) { level = cpuhp->governor->governor(res, result); - pass_rescon_set_level(res, level); + pass_rescon_set_level_sync(res, level); } else { _E("cannot call the governor function"); cpuhp_governor_update(res, PASS_OFF); diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index ac2d46f..26292a6 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -1006,9 +1006,9 @@ int pass_get_each_resource_config(struct pass_resource *res, char *path) /* Initialize the ResCon's data */ res->rescon.init_level = INIT_VALUE; - res->rescon.prev_level = 0; - res->rescon.min_level = 0; - res->rescon.max_level = 0; + res->rescon.prev_level = INIT_VALUE; + res->rescon.min_level = INIT_VALUE; + res->rescon.max_level = INIT_VALUE; res->rescon.init_scenario_level = INIT_VALUE; /* Initialize the CPUHP's data */ diff --git a/src/pass/pass-pmqos.c b/src/pass/pass-pmqos.c index dd96e8c..3fd69a8 100644 --- a/src/pass/pass-pmqos.c +++ b/src/pass/pass-pmqos.c @@ -74,9 +74,6 @@ static int pmqos_notifier_cb(void *data, void *user_data) struct pass_scenario *scn = NULL; enum pass_state locked = PASS_UNUSED; char name[BUFF_MAX] = {""}; - unsigned int new_level = 0; - unsigned int min_level = 0; - unsigned int max_level = 0; int index = -1; if (!res) @@ -140,52 +137,31 @@ static int pmqos_notifier_cb(void *data, void *user_data) scn->pmqos.locked = locked; if (scn->pmqos.locked) { - if (pmqos->num_locked_scenarios == 0) - new_level = pmqos->init_level = res->rescon.curr_level; - else - new_level = pmqos->curr_level; - min_level = MAX(scn->pmqos.min_level, pmqos->min_level); - max_level = MAX(scn->pmqos.max_level, pmqos->max_level); - - if (new_level < min_level) - new_level = min_level; - else if (new_level > max_level) - new_level = scn->pmqos.max_level; - - pmqos->curr_level = new_level; - pmqos->min_level = min_level; - pmqos->max_level = max_level; - - pmqos->num_locked_scenarios++; - } else { - pmqos->num_locked_scenarios--; - - if (pmqos->num_locked_scenarios == 0) { - new_level = pmqos->init_level; - min_level = res->config_data.default_min_level; - max_level = res->config_data.default_max_level; + pass_rescon_set_scenario_level_sync_with_data(res, scn->level, data); - pmqos->curr_level = 0; - pmqos->min_level = 0; - pmqos->max_level = 0; + if (scn->level < 0) { + _I("Lock '%s' scenario for '%s' resource\n", + name, config_data->res_name); } else { - new_level = pmqos->curr_level; - min_level = pmqos->min_level; - max_level = pmqos->max_level; + _I("Lock '%s' scenario with 'ScenarioLevel%d' " \ + "for '%s' resource\n", + name, scn->level, config_data->res_name); } - } - - pass_rescon_set_level_scope(res, new_level, min_level, max_level, data); - - if (scn->pmqos.locked) { - _I("Lock '%s' scenario for '%s' resource\n", - name, config_data->res_name); pmqos->scenarios[index].pmqos.locked_time = get_time_ms(); } else { - _I("UnLock '%s' scenario for '%s' resource (%"PRId64"ms)\n", - name, config_data->res_name, - (get_time_ms() - pmqos->scenarios[index].pmqos.locked_time)); + if (scn->level < 0) { + _I("UnLock '%s' scenario for '%s' resource (%"PRId64"ms)\n", + name, config_data->res_name, + (get_time_ms() - pmqos->scenarios[index].pmqos.locked_time)); + } else { + _I("UnLock '%s' scenario with 'ScenarioLevel%d' " \ + "for '%s' resource (%"PRId64"ms)\n", + name, scn->level, config_data->res_name, + (get_time_ms() - pmqos->scenarios[index].pmqos.locked_time)); + } + + pass_rescon_unset_scenario_level_sync_with_data(res, scn->level, data); pmqos->scenarios[index].pmqos.locked_time = 0; } diff --git a/src/pass/pass-rescon.c b/src/pass/pass-rescon.c index c156a17..0ff6328 100644 --- a/src/pass/pass-rescon.c +++ b/src/pass/pass-rescon.c @@ -33,37 +33,141 @@ #include "pass.h" #include "pass-hal.h" -/** - * @brief Set the next pass_level required from modules like - * PASS_MODULE_CPUHP, PASS_MODULE_PMQOS and so on. The demanded - * pass_level has the different h/w value such as minimum/maximum - * frequency, the number of online CPU, fault_around_bytes and son - * on. It changes the h/w value by using the data within the - * demanded pass_level and it is final step to change h/w value. - * @param [in] res Instance of h/w resource - * @param [in] new_level Index of demanded pass_level - * @return @c 0 on success, otherwise error value - */ -static int rescon_set_level(struct pass_resource *res, int new_level) +#define MAX_INT 1000000000 +#define MIN_INT 0 +#define MIN_FAULT_AROUND_BYTES 4096 +#define MAX_FAULT_AROUND_BYTES 65536 + +static void rescon_print_level(struct pass_resource *res, + struct pass_level *level) +{ + if (!res || !level) + return; + + /* Add blank line for improving the readability on dlog */ + _D(""); + + if (level->limit_min_freq > 0) { + _D("MIN Frequency is %10d of '%s' resource \n", + level->limit_min_freq, + res->config_data.res_name); + } + + if (level->limit_max_freq > 0) { + _D("MAX Frequency is %10d of '%s' resource\n", + level->limit_max_freq, + res->config_data.res_name); + } + + if (level->limit_min_cpu >= 0) { + _D("MIN CPU number is %10d of '%s' resource\n", + level->limit_min_cpu, + res->config_data.res_name); + } + + if (level->limit_max_cpu >= 0) { + _D("MAX CPU number is %10d of '%s' resource\n", + level->limit_max_cpu, + res->config_data.res_name); + } + + if (level->fault_around_bytes > 0) { + _D("fault_around_byte is %10d of '%s' resource\n", + level->fault_around_bytes, + res->config_data.res_name); + } +} + +static void rescon_adjust_level(struct pass_level *a, struct pass_level *b) +{ + /* Adjust limit_min_freq and limit_max_freq */ + a->limit_min_freq = MAX(a->limit_min_freq, b->limit_min_freq); + a->limit_max_freq = MIN(a->limit_max_freq, b->limit_max_freq); + + if (a->limit_min_freq > a->limit_max_freq) + a->limit_min_freq = a->limit_max_freq; + + /* Adjust limit_min_cpu and limit_max_cpu */ + a->limit_min_cpu = MAX(a->limit_min_cpu, b->limit_min_cpu); + a->limit_max_cpu = MIN(a->limit_max_cpu, b->limit_max_cpu); + + if (a->limit_min_cpu > a->limit_max_cpu) + a->limit_min_cpu = a->limit_max_cpu; + + /* Adjust fault_around_bytes */ + a->fault_around_bytes = MAX(a->fault_around_bytes, + b->fault_around_bytes); + + if (a->fault_around_bytes > 0) { + if (a->fault_around_bytes < MIN_FAULT_AROUND_BYTES) + a->fault_around_bytes = MIN_FAULT_AROUND_BYTES; + if (a->fault_around_bytes > MAX_FAULT_AROUND_BYTES) + a->fault_around_bytes = MAX_FAULT_AROUND_BYTES; + } +} + +static int rescon_update(struct pass_resource *res) { + struct pass_rescon *rescon = &res->rescon; struct pass_level *levels = res->config_data.levels; - int curr_level = res->rescon.curr_level; - int limit_max_freq; - int limit_min_freq; - int limit_max_cpu; - int limit_min_cpu; - int fault_around_bytes; + struct pass_level *scenario_levels = res->config_data.scenario_levels; + struct pass_level adjusted_level; + GList *list = rescon->scenario_level_list; + int res_type = res->config_data.res_type; + int limit_max_freq = -1; + int limit_min_freq = -1; + int limit_min_cpu = -1; + int limit_max_cpu = -1; + int fault_around_bytes = -1; int ret, i; + int failed = 0; - /* Get the detailed resource value according to PASS level */ - limit_max_freq = levels[new_level].limit_max_freq; - limit_min_freq = levels[new_level].limit_min_freq; - limit_max_cpu = levels[new_level].limit_max_cpu; - limit_min_cpu = levels[new_level].limit_min_cpu; - fault_around_bytes = levels[new_level].fault_around_bytes; - - res->rescon.prev_level = curr_level; - res->rescon.curr_level = new_level; + /* + * Multiple PASS modules can require the change of h/w resource by + * using pass_level at the same time. It means RESCON (Resource + * Controller) have to adjust the values of h/w resource among + * the required pass_levels. + */ + adjusted_level.limit_min_freq = MIN_INT; + adjusted_level.limit_max_freq = MAX_INT; + adjusted_level.limit_min_cpu = MIN_INT; + adjusted_level.limit_max_cpu = MAX_INT; + adjusted_level.fault_around_bytes = MIN_INT; + + /* Adjust with pass_level */ + if (res->rescon.curr_level >= 0) + rescon_adjust_level(&adjusted_level, &levels[rescon->curr_level]); + + /* Adjust with scenario pass_level */ + g_mutex_lock(&rescon->scenario_level_mutex); + while (list != NULL) { + i = GPOINTER_TO_INT(list->data); + list = g_list_next(list); + + if (i < 0) + continue; + rescon_adjust_level(&adjusted_level, &scenario_levels[i]); + } + g_mutex_unlock(&rescon->scenario_level_mutex); + + switch (res_type) { + case PASS_RESOURCE_CPU_ID: + limit_min_cpu = adjusted_level.limit_min_cpu; + limit_max_cpu = adjusted_level.limit_max_cpu; + /* fall through */ + case PASS_RESOURCE_GPU_ID: + case PASS_RESOURCE_BUS_ID: + limit_max_freq = adjusted_level.limit_max_freq; + limit_min_freq = adjusted_level.limit_min_freq; + break; + case PASS_RESOURCE_MEMORY_ID: + fault_around_bytes = adjusted_level.fault_around_bytes; + break; + case PASS_RESOURCE_NONSTANDARD_ID: + break; + default: + return -EINVAL; + } /* Turn on/off CPUs according to the required number of online CPU */ if (limit_min_cpu >= 0 && limit_max_cpu >= 0) { @@ -75,31 +179,78 @@ static int rescon_set_level(struct pass_resource *res, int new_level) if (limit_min_cpu > limit_max_cpu) limit_min_cpu = limit_max_cpu; - pass_set_online_min_num(res, limit_min_cpu); - pass_set_online_max_num(res, limit_max_cpu); + ret = pass_set_online_min_num(res, limit_min_cpu); + if (ret == -EPERM || ret == -ENODEV) { + /* + * If -EPERM, function is not supported according to + * h/w resource type. And if -ENODEV, function is not + * implemented on HAL package. It means that this + * function is not necessary on two error case + * when calling the HAL functions. + */ + ; + } else if (ret < 0) { + _W("failed to set the minimum number of cpu(%d) of %s", + limit_min_cpu, + res->config_data.res_name); + failed = 1; + } + + ret = pass_set_online_max_num(res, limit_max_cpu); + if (ret == -EPERM || ret == -ENODEV) { + ; + } else if (ret < 0) { + _W("failed to set the maximum number of cpu(%d) of %s", + limit_max_cpu, + res->config_data.res_name); + failed = 1; + } - for (i = 0; i < limit_max_cpu; i++) - pass_set_online_state(res, res->config_data.cpu + i, + for (i = 0; i < limit_max_cpu; i++) { + ret = pass_set_online_state(res, + res->config_data.cpu + i, (i < limit_min_cpu) ? 1 : 0); + if (ret == -EPERM || ret == -ENODEV) { + ; + } else if (ret < 0) { + _W("failed to turn %s of cpu%d of %s", + (i < limit_min_cpu) ? "on" : "off", + res->config_data.cpu + i, + res->config_data.res_name); + failed = 1; + } + } + } - /* Set maximum frequency */ - if (limit_max_freq > 0) { - ret = pass_set_max_freq(res, limit_max_freq); - if (ret < 0) { - _E("cannot set the maximum frequency of %s", + /* Set minimum and maximum frequency */ + if (limit_max_freq > 0 && limit_min_freq > 0) { + int curr_min_freq = pass_get_min_freq(res); + int curr_max_freq = pass_get_max_freq(res); + int ret_min; + int ret_max; + + if ((limit_max_freq > curr_min_freq) + && (limit_min_freq > curr_max_freq)) { + ret_max = pass_set_max_freq(res, limit_max_freq); + ret_min = pass_set_min_freq(res, limit_min_freq); + } else { + ret_min = pass_set_min_freq(res, limit_min_freq); + ret_max = pass_set_max_freq(res, limit_max_freq); + } + + if (ret_max < 0) { + _W("failed to set the maximum frequency(%d) of %s", + limit_max_freq, res->config_data.res_name); - return -EINVAL; + failed = 1; } - } - /* Set minimum frequency */ - if (limit_min_freq > 0) { - ret = pass_set_min_freq(res, limit_min_freq); - if (ret < 0) { - _E("cannot set the minimum frequency of %s", + if (ret_min < 0) { + _W("failed to set the minimum frequency(%d) of %s", + limit_min_freq, res->config_data.res_name); - return -EINVAL; + failed = 1; } } @@ -107,26 +258,67 @@ static int rescon_set_level(struct pass_resource *res, int new_level) if (fault_around_bytes > 0) { ret = pass_set_fault_around_bytes(res, fault_around_bytes); if (ret < 0) { - _E("cannot set the fault_around_bytes of %s", + _W("failed to set the fault_around_bytes(%d) of %s", + fault_around_bytes, res->config_data.res_name); - return -EINVAL; + failed = 1; } } - /* - _I("[PASS %s] Level %4s '%d->%d' : 'max %d | min %d'Hz/'%d'Core\n", - res->config_data.res_name, - (curr_level > new_level ? "DOWN" : "UP"), - curr_level, new_level, - limit_max_freq, limit_min_freq, limit_min_cpu); - */ + if (!failed) + rescon_print_level(res, &adjusted_level); + else + _W("failed to update %s h/w resource", + res->config_data.res_name); return 0; }; +static void rescon_set_scenario_level(struct pass_resource *res, + int scenario_level) +{ + struct pass_rescon *rescon = &res->rescon; + + if (scenario_level < 0) + return; + + g_mutex_lock(&rescon->scenario_level_mutex); + rescon->scenario_level_list = g_list_append(rescon->scenario_level_list, + GINT_TO_POINTER(scenario_level)); + + g_mutex_unlock(&rescon->scenario_level_mutex); +} + +static void rescon_unset_scenario_level(struct pass_resource *res, + int scenario_level) +{ + struct pass_rescon *rescon = &res->rescon; + + if (scenario_level < 0) + return; + + g_mutex_lock(&rescon->scenario_level_mutex); + rescon->scenario_level_list = g_list_remove(rescon->scenario_level_list, + GINT_TO_POINTER(scenario_level)); + g_mutex_unlock(&rescon->scenario_level_mutex); +} + +/* + * @brief Update pass_level with sync by all PASS_MODULE_* + * @param [in] res Instance of struct pass_resource + * @param [in] scenario_level Index of scenario level + * @scenario_level: the scenario level + */ +int pass_rescon_sync(struct pass_resource *res) +{ + if (!res) + return -EINVAL; + + return rescon_update(res); +} + /** - * @brief Adjust the demanded pass_level by using the supported minimum - * and maximum pass_level. + * @brief Set pass_level by PASS_MODULE_CPUHP * @param [in] res Instance of h/w resource * @param [in] new_level Index of demanded pass_level * @return @c 0 on success, otherwise error value @@ -136,6 +328,9 @@ int pass_rescon_set_level(struct pass_resource *res, int new_level) if (!res) return -EINVAL; + if (new_level < 0) + return 0; + if (new_level > res->rescon.max_level) new_level = res->rescon.max_level; @@ -145,25 +340,120 @@ int pass_rescon_set_level(struct pass_resource *res, int new_level) if (new_level == res->rescon.curr_level) return 0; - return rescon_set_level(res, new_level); + res->rescon.prev_level = res->rescon.curr_level; + res->rescon.curr_level = new_level; + + return 0; }; /** - * @brief Change the range of pass_level like the minimum and maximum - * pass_level. + * @brief Set pass_level with sync by PASS_MODULE_CPUHP * @param [in] res Instance of h/w resource - * @param [in] new_level Demanded pass_level - * @param [in] min_level Minimum pass_level - * @param [in] max_level Maximum pass_level - * @param [in] data PMQoS data containing the scenario name and lock state + * @param [in] new_level Index of demanded pass_level * @return @c 0 on success, otherwise error value */ -int pass_rescon_set_level_scope(struct pass_resource *res, int new_level, - int min_level, int max_level, void *data) +int pass_rescon_set_level_sync(struct pass_resource *res, int new_level) { if (!res) return -EINVAL; + if (new_level < 0) + return 0; + + if (new_level > res->rescon.max_level) + new_level = res->rescon.max_level; + + if (new_level < res->rescon.min_level) + new_level = res->rescon.min_level; + + if (new_level == res->rescon.curr_level) + return 0; + + res->rescon.prev_level = res->rescon.curr_level; + res->rescon.curr_level = new_level; + + return rescon_update(res); +}; + +/** + * @brief Set scenario pass_level with sync by PASS_MODULE_(PMQOS|THERMAL). + * @param [in] res Instance of h/w resource + * @param [in] scenario_level Index of demanded pass_level + * @return @c 0 on success, otherwise error value + */ +int pass_rescon_set_scenario_level(struct pass_resource *res, + int scenario_level) +{ + if (!res) + return -EINVAL; + + rescon_set_scenario_level(res, scenario_level); + + return 0; +} + +/* + * @brief Unset the scenario pass_level by PASS_MODULE_(PMQOS|THERMAL). + * @param [in] res Instance of struct pass_resource + * @param [in] scenario_level Index of scenario level + * @scenario_level: the scenario level + */ +int pass_rescon_unset_scenario_level(struct pass_resource *res, + int scenario_level) +{ + if (!res) + return -EINVAL; + + rescon_unset_scenario_level(res, scenario_level); + + return 0; +} + +/** + * @brief Set scenario pass_level with sync by PASS_MODULE_(PMQOS|THERMAL). + * @param [in] res Instance of h/w resource + * @param [in] scenario_level Index of demanded pass_level + * @return @c 0 on success, otherwise error value + */ +int pass_rescon_set_scenario_level_sync(struct pass_resource *res, + int scenario_level) +{ + if (!res) + return -EINVAL; + + rescon_set_scenario_level(res, scenario_level); + + return rescon_update(res); +} + +/* + * @brief Unset the scenario pass_level by PASS_MODULE_(PMQOS|THERMAL). + * @param [in] res Instance of struct pass_resource + * @param [in] scenario_level Index of scenario level + * @scenario_level: the scenario level + */ +int pass_rescon_unset_scenario_level_sync(struct pass_resource *res, + int scenario_level) +{ + if (!res) + return -EINVAL; + + rescon_unset_scenario_level(res, scenario_level); + + return rescon_update(res); +} + +/* + * @brief Deprecated function to support backward compatibility with sync. + * Set up the scenario pass_level by PASS_MODULE_PMQOS with data. + * @param [in] res Instance of struct pass_resource + * @param [in] scenario_level Index of scenario level + * @param [in] data PMQoS data containing the scenario name and lock state + * @return @c 0 on success, otherwise error value + */ +int pass_rescon_set_scenario_level_sync_with_data(struct pass_resource *res, + int scenario_level, void *data) +{ /* * FIXME: PMQoS core sends the raw data to the HAL in order to * support the backwards compatibility. This function call will @@ -172,23 +462,33 @@ int pass_rescon_set_level_scope(struct pass_resource *res, int new_level, if (data) pass_set_pmqos_data(res, data); - if (min_level > max_level) { - _E("min_level(%d) have to be smaller than max_level(%d)\n", - min_level, max_level); - return -EINVAL; - } + rescon_set_scenario_level(res, scenario_level); - if (min_level == res->rescon.min_level - && max_level == res->rescon.max_level) - return 0; + return rescon_update(res); +} - /* Change minimum/maximum pass level */ - res->rescon.min_level = min_level; - res->rescon.max_level = max_level; +/* + * @brief Deprecated function to support backward compatibility with sync. + * Unset the scenario pass_level by PASS_MODULE_PMQOS with data. + * @param [in] res Insstance of struct pass_resource + * @param [in] scenario_level Index of scenario level + * @param [in] data PMQoS data containing the scenario name and lock state + * @return @c 0 on success, otherwise error value + */ +int pass_rescon_unset_scenario_level_sync_with_data(struct pass_resource *res, + int scenario_level, void *data) +{ + /* + * FIXME: PMQoS core sends the raw data to the HAL in order to + * support the backwards compatibility. This function call will + * be removed after finding the proper method. + */ + if (data) + pass_set_pmqos_data(res, data); - pass_rescon_set_level(res, new_level); + rescon_unset_scenario_level(res, scenario_level); - return 0; + return rescon_update(res); } /** @@ -207,8 +507,8 @@ int pass_rescon_init(struct pass_resource *res) rescon = &res->rescon; /* Initialize the variables of resource-controller */ - rescon->curr_level = 0; - rescon->prev_level = 0; + rescon->curr_level = -1; + rescon->prev_level = -1; if (!rescon->min_level) rescon->min_level = 0; @@ -218,10 +518,9 @@ int pass_rescon_init(struct pass_resource *res) rescon->max_level = res->config_data.num_levels - 1; res->config_data.default_max_level = rescon->max_level; - if (!rescon->init_level) - rescon->init_level = rescon->min_level; - else if (rescon->init_level > rescon->max_level) - rescon->init_level = rescon->max_level; + /* Initialize g_list of scenario_level */ + rescon->scenario_level_list = NULL; + g_mutex_init(&rescon->scenario_level_mutex); /* * Save the current data of h/w resource. The saved data @@ -234,22 +533,33 @@ int pass_rescon_init(struct pass_resource *res) return ret; } - /* Set initial level according to init_level from configuration */ - ret = rescon_set_level(res, rescon->init_level); + /* + * Set initial pass level when starting pass + * - default pass level according to res->init_level + */ + ret = pass_rescon_set_level(res, rescon->init_level); if (ret < 0) { _E("failed to set level%d\n", rescon->init_level); return ret; } /* - * Set default pass level when starting pass - * - default pass level according to res->init_level + * Set initial scenario pass_level when starting pass + * - default pass level according to res->init_scenario_level */ - res->rescon.curr_level = -1; - if (res->rescon.init_level > res->rescon.max_level) - res->rescon.init_level = res->rescon.max_level; + ret = pass_rescon_set_scenario_level(res, rescon->init_scenario_level); + if (ret < 0) { + _E("failed to set scenario level%d\n", + rescon->init_scenario_level); + return ret; + } - pass_rescon_set_level(res, res->rescon.init_level); + ret = pass_rescon_sync(res); + if (ret < 0) { + _E("failed to synchronize of '%s' resource\n", + res->config_data.res_name); + return ret; + } rescon->state = PASS_ON; @@ -284,6 +594,11 @@ int pass_rescon_exit(struct pass_resource *res) rescon->max_level = 0; rescon->init_level = 0; + /* Free g_list of scenario_level */ + g_list_free(rescon->scenario_level_list); + rescon->scenario_level_list = NULL; + g_mutex_clear(&rescon->scenario_level_mutex); + rescon->state = PASS_OFF; return ret; diff --git a/src/pass/pass-rescon.h b/src/pass/pass-rescon.h index 383c8c6..8227edf 100644 --- a/src/pass/pass-rescon.h +++ b/src/pass/pass-rescon.h @@ -29,8 +29,27 @@ #ifndef __PASS_RESCON__ #define __PASS_RESCON__ +int pass_rescon_sync(struct pass_resource *res); + +int pass_rescon_set_level_sync(struct pass_resource *res, int new_level); +int pass_rescon_set_scenario_level_sync(struct pass_resource *res, + int scenario_level); +int pass_rescon_unset_scenario_level_sync(struct pass_resource *res, + int scenario_level); + int pass_rescon_set_level(struct pass_resource *res, int new_level); -int pass_rescon_set_level_scope(struct pass_resource *res, int new_level, - int min_level, int max_level, void *data); +int pass_rescon_set_scenario_level(struct pass_resource *res, + int scenario_level); +int pass_rescon_unset_scenario_level(struct pass_resource *res, + int scenario_level); + +/* + * Following APIs are deprecated. These functions are provided + * for keeping the compatibility with legacy feature. + */ +int pass_rescon_set_scenario_level_sync_with_data(struct pass_resource *res, + int scenario_level, void *data); +int pass_rescon_unset_scenario_level_sync_with_data(struct pass_resource *res, + int scenario_level, void *data); #endif /* __PASS_RESCON__ */ diff --git a/src/pass/pass.h b/src/pass/pass.h index 22ced5b..a88c61c 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -261,23 +261,41 @@ struct pass_rescon { enum pass_state state; /** - * Initial level when initializing h/w resource by resource controller + * Initial level when initializing h/w resource by resource controller. + * If value is -1, it is not initialized by parser. */ int init_level; - /** Current level controlled by resource controller */ - unsigned int curr_level; - /** Previous level controlled by resource controller */ - unsigned int prev_level; - /** Available minimum level controlled by resource controller */ - unsigned int min_level; - /** Available maximum level controlled by resource controller */ - unsigned int max_level; + /** + * Current level controlled by resource controller. + * If value is -1, it is not initialized by parser. + */ + int curr_level; + /** + * Previous level controlled by resource controller. + * If value is -1, it is not initialized by parser. + */ + int prev_level; + /** + * Available minimum level controlled by resource controller. + * If value is -1, it is not initialized by parser. + */ + int min_level; + /** + * Available maximum level controlled by resource controller. + * If value is -1, it is not initialized by parser. + */ + int max_level; /** * Initial level when initializing h/w resource by resource controller. * If value is -1, it is not initialized by parser. */ int init_scenario_level; + + /** Ondemanded scenario list */ + GList *scenario_level_list; + /** Mutex of ondemanded scenario list */ + GMutex scenario_level_mutex; }; /** -- 2.7.4 From b37d287b6349b80c4c5a8a13c47681b0483f6bf4 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 11 Feb 2020 21:45:12 +0900 Subject: [PATCH 06/16] pass: thermal: Add support for scenario_level for thermal scenario Prior to that thermal monitor has been monitoring the temperature and then decide current thermal scenario like 'Release', 'Warning'. And send the broadcast dbus message to inform the current thermal scenario to otther Tizen framework. It didn't support to change the value of the h/w resource like frequency, the number of online CPU. Finally, thermal monitor is able to change the value of h/w resource according to their own 'scenario_level' value on each thermal scenario. For example with following configuration example, - If thermal monitor decide the current thermal scenario as 'Release', 'Release' sceanrio has 'scenario_level=0'. It means that set 'ScenarioLeve0'. It allow max_freq as 1.3GHz and max_cpu as 4 core. - If thermal monitor decide the current thermal scenario as 'Warning', 'Warning' sceanrio has 'scenario_level=2'. It means that set 'ScenarioLeve2'. It allow max_freq as 768MHz and max_cpu as 2 core. This feature is important for preventing the dangerous overheating of h/w target and it is very easy to tune up the configuration of thermal monitor by editing the configuration files under '/etc/pass' path. [Example of configuraiton file for CPU h/w resource] (snip) [ScenarioLevel0] limit_min_freq=768000 limit_max_freq=1300000 limit_min_cpu=0 limit_max_cpu=4 [ScenarioLevel2] limit_min_freq=768000 limit_max_freq=768000 limit_min_cpu=0 limit_max_cpu=2 (snip) [thermal.scenario0] support=yes name=Release temperature=25 timer_interval_ms=5000 scenario_level=0 <- It means 'ScenarioLevel0' is used for 'Release'. Allow max_freq as 1.3GHz and max_cpu as 4 core. [thermal.scenario1] support=yes name=Warning temperature=30 timer_interval_ms=3000 scenario_level=2 <- It means 'ScenarioLevel2' is used for 'Warning'. Allow max_freq as 768MHz and max_cpu as 2 core. Change-Id: I3a5ff802e68f1452e90d766cfe1f04b4554413fd Signed-off-by: Chanwoo Choi --- src/pass/pass-thermal.c | 39 ++++++++++++++++++++++++++++++++++++--- src/pass/pass.h | 2 ++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index 4cbfccf..366c03e 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -30,6 +30,7 @@ #include #include "pass.h" +#include "pass-rescon.h" #include "pass-resmon.h" #define DEFAULT_TEMPERATURE (-1000) @@ -38,6 +39,7 @@ static int thermal_update(struct pass_resource *res, struct resmon_result_src_thermal *thermal_result) { struct pass_thermal *thermal = &res->thermal;; + struct pass_scenario *scenario; int timer_interval_of_scenario, timer_interval; int curr_temp, prev_temp, temp; int i, scenario_idx; @@ -77,10 +79,10 @@ static int thermal_update(struct pass_resource *res, if (thermal->curr_scenario_idx == scenario_idx) return 0; + scenario = &thermal->scenarios[scenario_idx]; /* Get the new timer interval of each scenario */ - timer_interval_of_scenario - = thermal->scenarios[scenario_idx].thermal.timer_interval; + timer_interval_of_scenario = scenario->thermal.timer_interval; if (timer_interval_of_scenario > 0) timer_interval = timer_interval_of_scenario; else @@ -94,11 +96,42 @@ static int thermal_update(struct pass_resource *res, res->config_data.res_name, RESMON_SRC_THERMAL); } + /* Update thermal information of each h/w resource */ thermal->curr_temp = curr_temp; + thermal->prev_scenario_idx = thermal->curr_scenario_idx; thermal->curr_scenario_idx = scenario_idx; + /* Set ScenarioLevel for current scenario */ + ret = pass_rescon_set_scenario_level(res, scenario->level); + if (ret < 0) { + _W("failed to set ScenarioLevel%d " \ + "(res_name:%s, src_type: 0x%x)\n", + scenario->level, + res->config_data.res_name, RESMON_SRC_THERMAL); + } + + /* Unset ScenarioLevel of previous scenario */ + if (thermal->prev_scenario_idx >= 0) { + struct pass_scenario *p_scenario = + &thermal->scenarios[thermal->prev_scenario_idx]; + ret = pass_rescon_unset_scenario_level(res, p_scenario->level); + if (ret < 0) { + _W("failed to unset ScenarioLevel%d " \ + "(res_name:%s, src_type: 0x%x)\n", + p_scenario->level, + res->config_data.res_name, RESMON_SRC_THERMAL); + } + } + + ret = pass_rescon_sync(res); + if (ret < 0) { + _W("failed to synchronize h/w resource " \ + "(res_name:%s, src_type: 0x%x)\n", + res->config_data.res_name, RESMON_SRC_THERMAL); + } + _I("Monitor '%-12s' of '%s' resource ('%3d' degrees,'%5d' ms)\n", - thermal->scenarios[scenario_idx].name, + scenario->name, res->config_data.res_name, curr_temp, timer_interval); diff --git a/src/pass/pass.h b/src/pass/pass.h index a88c61c..89a5494 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -384,6 +384,8 @@ struct pass_thermal { unsigned int timer_interval; /** Index of current thermal scenario */ int curr_scenario_idx; + /** Index of previous thermal scenario */ + int prev_scenario_idx; /** Current temperature */ int curr_temp; }; -- 2.7.4 From 8c52cba55819324fee7460836ab8e8e923f9137e Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 12 Feb 2020 17:59:54 +0900 Subject: [PATCH 07/16] pass: thermal: Change local variable name for readability Change local variable name for readability as following without any behavior changes: - curr_temp -> new_temp which is the measured temperature - timer_interval -> new_timer_interval of new thermal scenario - scenario -> new_scenario which is instance of new thermal scenario - scenario_idx -> new_scenario_idx which is index of new thernal scenario - timer_interval_of_scenario is removed due to unneeded Change-Id: Ie9fed6c3be9e3ad490c2d0eec3a02c839ab6be7d Signed-off-by: Chanwoo Choi --- src/pass/pass-thermal.c | 52 ++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/pass/pass-thermal.c b/src/pass/pass-thermal.c index 366c03e..fc3b088 100644 --- a/src/pass/pass-thermal.c +++ b/src/pass/pass-thermal.c @@ -39,10 +39,10 @@ static int thermal_update(struct pass_resource *res, struct resmon_result_src_thermal *thermal_result) { struct pass_thermal *thermal = &res->thermal;; - struct pass_scenario *scenario; - int timer_interval_of_scenario, timer_interval; - int curr_temp, prev_temp, temp; - int i, scenario_idx; + struct pass_scenario *new_scenario; + int new_timer_interval; + int new_temp, prev_temp; + int i, new_scenario_idx; int ret; if (!res || !thermal_result) { @@ -51,22 +51,22 @@ static int thermal_update(struct pass_resource *res, } prev_temp = thermal->curr_temp; - curr_temp = thermal_result->temp; + new_temp = thermal_result->temp; - if (prev_temp == curr_temp) + if (prev_temp == new_temp) return 0; - scenario_idx = -1; + new_scenario_idx = -1; for (i = 0; i < thermal->num_scenarios; i++) { - temp = thermal->scenarios[i].thermal.temperature; + int temp = thermal->scenarios[i].thermal.temperature; if (thermal->scenarios[i].state != PASS_ON) continue; - if (scenario_idx < 0 && curr_temp < temp) - scenario_idx = i; - else if (temp <= curr_temp) - scenario_idx = i; + if (new_scenario_idx < 0 && new_temp < temp) + new_scenario_idx = i; + else if (temp <= new_temp) + new_scenario_idx = i; } /* @@ -74,22 +74,20 @@ static int thermal_update(struct pass_resource *res, * or if there are no scenario with 'support=yes', * just return without notification. */ - if (scenario_idx < 0) + if (new_scenario_idx < 0) return 0; - if (thermal->curr_scenario_idx == scenario_idx) + if (thermal->curr_scenario_idx == new_scenario_idx) return 0; - scenario = &thermal->scenarios[scenario_idx]; + new_scenario = &thermal->scenarios[new_scenario_idx]; /* Get the new timer interval of each scenario */ - timer_interval_of_scenario = scenario->thermal.timer_interval; - if (timer_interval_of_scenario > 0) - timer_interval = timer_interval_of_scenario; - else - timer_interval = res->thermal.timer_interval; + new_timer_interval = new_scenario->thermal.timer_interval; + if (new_timer_interval < 0) + new_timer_interval = res->thermal.timer_interval; ret = pass_resmon_update_timer_interval(res, RESMON_SRC_THERMAL, - timer_interval); + new_timer_interval); if (ret < 0) { _W("failed to update interval of timer-based monitor " \ "(res_name:%s, src_type: 0x%x)\n", @@ -97,16 +95,16 @@ static int thermal_update(struct pass_resource *res, } /* Update thermal information of each h/w resource */ - thermal->curr_temp = curr_temp; + thermal->curr_temp = new_temp; thermal->prev_scenario_idx = thermal->curr_scenario_idx; - thermal->curr_scenario_idx = scenario_idx; + thermal->curr_scenario_idx = new_scenario_idx; /* Set ScenarioLevel for current scenario */ - ret = pass_rescon_set_scenario_level(res, scenario->level); + ret = pass_rescon_set_scenario_level(res, new_scenario->level); if (ret < 0) { _W("failed to set ScenarioLevel%d " \ "(res_name:%s, src_type: 0x%x)\n", - scenario->level, + new_scenario->level, res->config_data.res_name, RESMON_SRC_THERMAL); } @@ -131,9 +129,9 @@ static int thermal_update(struct pass_resource *res, } _I("Monitor '%-12s' of '%s' resource ('%3d' degrees,'%5d' ms)\n", - scenario->name, + new_scenario->name, res->config_data.res_name, - curr_temp, timer_interval); + new_temp, new_timer_interval); return 0; } -- 2.7.4 From 5e66576d353af4b79e52a6770b041bf12691c656 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 12 Feb 2020 18:05:47 +0900 Subject: [PATCH 08/16] pass: hal: Rename HAL API for the readability Rename all HAL API from "pass_*()" to "pass_hal_*()" to improve the readability. Usually, PASS modules used their own prefix on function name like 'pass_resmon_*', 'pass_rescon_*'. After that, anyone can know the kind of PASS module of functions. Change-Id: I275fc6154eeab2af1d0e6755c3e6ceae762548b6 Signed-off-by: Chanwoo Choi --- src/pass/pass-hal.c | 109 +++++++++++++++++++++--------------------- src/pass/pass-hal.h | 52 ++++++++++---------- src/pass/pass-rescon.c | 28 +++++------ src/pass/pass-resmon-source.c | 6 +-- src/pass/pass.c | 6 +-- unittest/pass_haltests.cpp | 64 ++++++++++++------------- 6 files changed, 133 insertions(+), 132 deletions(-) diff --git a/src/pass/pass-hal.c b/src/pass/pass-hal.c index 05909ec..0ba680f 100644 --- a/src/pass/pass-hal.c +++ b/src/pass/pass-hal.c @@ -106,7 +106,7 @@ static struct pass_resource_hotplug_ops *get_hotplug(struct pass_resource *res, * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_curr_governor(struct pass_resource *res, char *governor) +int pass_hal_get_curr_governor(struct pass_resource *res, char *governor) { struct pass_resource_dvfs_ops *dvfs; @@ -133,7 +133,7 @@ int pass_get_curr_governor(struct pass_resource *res, char *governor) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_set_curr_governor(struct pass_resource *res, char *governor) +int pass_hal_set_curr_governor(struct pass_resource *res, char *governor) { struct pass_resource_dvfs_ops *dvfs; @@ -159,7 +159,7 @@ int pass_set_curr_governor(struct pass_resource *res, char *governor) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_curr_freq(struct pass_resource *res) +int pass_hal_get_curr_freq(struct pass_resource *res) { struct pass_resource_dvfs_ops *dvfs; @@ -185,7 +185,7 @@ int pass_get_curr_freq(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_min_freq(struct pass_resource *res) +int pass_hal_get_min_freq(struct pass_resource *res) { struct pass_resource_dvfs_ops *dvfs; @@ -212,7 +212,7 @@ int pass_get_min_freq(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_set_min_freq(struct pass_resource *res, int freq) +int pass_hal_set_min_freq(struct pass_resource *res, int freq) { struct pass_resource_dvfs_ops *dvfs; @@ -238,7 +238,7 @@ int pass_set_min_freq(struct pass_resource *res, int freq) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_max_freq(struct pass_resource *res) +int pass_hal_get_max_freq(struct pass_resource *res) { struct pass_resource_dvfs_ops *dvfs; @@ -265,7 +265,7 @@ int pass_get_max_freq(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_set_max_freq(struct pass_resource *res, int freq) +int pass_hal_set_max_freq(struct pass_resource *res, int freq) { struct pass_resource_dvfs_ops *dvfs; @@ -291,7 +291,7 @@ int pass_set_max_freq(struct pass_resource *res, int freq) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_available_min_freq(struct pass_resource *res) +int pass_hal_get_available_min_freq(struct pass_resource *res) { struct pass_resource_dvfs_ops *dvfs; @@ -317,7 +317,7 @@ int pass_get_available_min_freq(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_available_max_freq(struct pass_resource *res) +int pass_hal_get_available_max_freq(struct pass_resource *res) { struct pass_resource_dvfs_ops *dvfs; @@ -343,7 +343,7 @@ int pass_get_available_max_freq(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_up_threshold(struct pass_resource *res) +int pass_hal_get_up_threshold(struct pass_resource *res) { struct pass_resource_dvfs_ops *dvfs; @@ -370,7 +370,7 @@ int pass_get_up_threshold(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_set_up_threshold(struct pass_resource *res, int up_threshold) +int pass_hal_set_up_threshold(struct pass_resource *res, int up_threshold) { struct pass_resource_dvfs_ops *dvfs; @@ -396,7 +396,7 @@ int pass_set_up_threshold(struct pass_resource *res, int up_threshold) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_online_state(struct pass_resource *res, int cpu) +int pass_hal_get_online_state(struct pass_resource *res, int cpu) { struct pass_resource_hotplug_ops *hotplug; @@ -423,7 +423,7 @@ int pass_get_online_state(struct pass_resource *res, int cpu) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_set_online_state(struct pass_resource *res, int cpu, int on) +int pass_hal_set_online_state(struct pass_resource *res, int cpu, int on) { struct pass_resource_hotplug_ops *hotplug; @@ -448,7 +448,7 @@ int pass_set_online_state(struct pass_resource *res, int cpu, int on) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_online_min_num(struct pass_resource *res) +int pass_hal_get_online_min_num(struct pass_resource *res) { struct pass_resource_hotplug_ops *hotplug; @@ -474,7 +474,7 @@ int pass_get_online_min_num(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_set_online_min_num(struct pass_resource *res, int num) +int pass_hal_set_online_min_num(struct pass_resource *res, int num) { struct pass_resource_hotplug_ops *hotplug; @@ -499,7 +499,7 @@ int pass_set_online_min_num(struct pass_resource *res, int num) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_online_max_num(struct pass_resource *res) +int pass_hal_get_online_max_num(struct pass_resource *res) { struct pass_resource_hotplug_ops *hotplug; @@ -525,7 +525,7 @@ int pass_get_online_max_num(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_set_online_max_num(struct pass_resource *res, int num) +int pass_hal_set_online_max_num(struct pass_resource *res, int num) { struct pass_resource_hotplug_ops *hotplug; @@ -550,7 +550,7 @@ int pass_set_online_max_num(struct pass_resource *res, int num) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_temp(struct pass_resource *res) +int pass_hal_get_temp(struct pass_resource *res) { struct pass_resource_tmu_ops *tmu; @@ -580,7 +580,7 @@ int pass_get_temp(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_tmu_policy(struct pass_resource *res, char *policy) +int pass_hal_get_tmu_policy(struct pass_resource *res, char *policy) { struct pass_resource_tmu_ops *tmu; @@ -611,7 +611,7 @@ int pass_get_tmu_policy(struct pass_resource *res, char *policy) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_set_fault_around_bytes(struct pass_resource *res, +int pass_hal_set_fault_around_bytes(struct pass_resource *res, int fault_around_bytes) { struct pass_resource_memory *memory; @@ -641,7 +641,7 @@ int pass_set_fault_around_bytes(struct pass_resource *res, * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_get_fault_around_bytes(struct pass_resource *res) +int pass_hal_get_fault_around_bytes(struct pass_resource *res) { struct pass_resource_memory *memory; @@ -670,7 +670,7 @@ int pass_get_fault_around_bytes(struct pass_resource *res) * @retval -1 Operation not permitted (-EPERM) * @retval -19 Operation not supported (-ENODEV) */ -int pass_set_pmqos_data(struct pass_resource *res, void *data) +int pass_hal_set_pmqos_data(struct pass_resource *res, void *data) { struct pass_resource_nonstandard *nonstandard = NULL; @@ -698,16 +698,16 @@ int pass_set_pmqos_data(struct pass_resource *res, void *data) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -static int pass_save_dvfs_initdata(struct pass_resource *res) +static int pass_hal_save_dvfs_initdata(struct pass_resource *res) { struct pass_resource_init_data *initdata = &res->init_data; int ret; - ret = pass_get_curr_governor(res, initdata->dvfs.governor); + ret = pass_hal_get_curr_governor(res, initdata->dvfs.governor); if (ret < 0) initdata->dvfs.governor = NULL; - initdata->dvfs.min_freq = pass_get_min_freq(res); + initdata->dvfs.min_freq = pass_hal_get_min_freq(res); /* * Since the current maximum frequency can be affected by other @@ -716,9 +716,9 @@ static int pass_save_dvfs_initdata(struct pass_resource *res) * in order to restore default maximum frequency we save available * maximum frequency instead of current maximum frequency. */ - initdata->dvfs.max_freq = pass_get_available_max_freq(res); + initdata->dvfs.max_freq = pass_hal_get_available_max_freq(res); - initdata->dvfs.up_threshold = pass_get_up_threshold(res); + initdata->dvfs.up_threshold = pass_hal_get_up_threshold(res); return 0; } @@ -729,7 +729,7 @@ static int pass_save_dvfs_initdata(struct pass_resource *res) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -static int pass_save_hotplug_initdata(struct pass_resource *res) +static int pass_hal_save_hotplug_initdata(struct pass_resource *res) { struct pass_resource_init_data *initdata = &res->init_data; struct pass_resource_config_data *config_data = &res->config_data; @@ -739,15 +739,15 @@ static int pass_save_hotplug_initdata(struct pass_resource *res) int i; int ret; - initdata->hotplug.online_min_num = pass_get_online_min_num(res); - initdata->hotplug.online_max_num = pass_get_online_max_num(res); + initdata->hotplug.online_min_num = pass_hal_get_online_min_num(res); + initdata->hotplug.online_max_num = pass_hal_get_online_max_num(res); online_state = (int *)calloc(num_cpus, sizeof(int)); if (!online_state) return -ENOMEM; for (i = 0; i < num_cpus; i++) { - ret = pass_get_online_state(res, first_cpu + i); + ret = pass_hal_get_online_state(res, first_cpu + i); if (ret < 0) { free(online_state); return 0; @@ -765,11 +765,12 @@ static int pass_save_hotplug_initdata(struct pass_resource *res) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -static int pass_save_memory_initdata(struct pass_resource *res) +static int pass_hal_save_memory_initdata(struct pass_resource *res) { struct pass_resource_init_data *initdata = &res->init_data; - initdata->memory.fault_around_bytes = pass_get_fault_around_bytes(res); + initdata->memory.fault_around_bytes + = pass_hal_get_fault_around_bytes(res); return 0; } @@ -781,31 +782,31 @@ static int pass_save_memory_initdata(struct pass_resource *res) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -static int pass_restore_dvfs_initdata(struct pass_resource *res) +static int pass_hal_restore_dvfs_initdata(struct pass_resource *res) { struct pass_resource_init_data *initdata = &res->init_data; int ret; if (initdata->dvfs.governor) { - ret = pass_set_curr_governor(res, initdata->dvfs.governor); + ret = pass_hal_set_curr_governor(res, initdata->dvfs.governor); if (ret < 0) return ret; } if (initdata->dvfs.min_freq >= 0) { - ret = pass_set_min_freq(res, initdata->dvfs.min_freq); + ret = pass_hal_set_min_freq(res, initdata->dvfs.min_freq); if (ret < 0) return ret; } if (initdata->dvfs.max_freq >= 0) { - ret = pass_set_max_freq(res, initdata->dvfs.max_freq); + ret = pass_hal_set_max_freq(res, initdata->dvfs.max_freq); if (ret < 0) return ret; } if (initdata->dvfs.up_threshold >= 0) { - ret = pass_set_up_threshold(res, initdata->dvfs.up_threshold); + ret = pass_hal_set_up_threshold(res, initdata->dvfs.up_threshold); if (ret < 0) return ret; } @@ -819,7 +820,7 @@ static int pass_restore_dvfs_initdata(struct pass_resource *res) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -static int pass_restore_hotplug_initdata(struct pass_resource *res) +static int pass_hal_restore_hotplug_initdata(struct pass_resource *res) { struct pass_resource_init_data *initdata = &res->init_data; struct pass_resource_config_data *config_data = &res->config_data; @@ -833,7 +834,7 @@ static int pass_restore_hotplug_initdata(struct pass_resource *res) if (online_state) { for (i = 0; i < num_cpus; i++) { - ret = pass_set_online_state(res, first_cpu + i, + ret = pass_hal_set_online_state(res, first_cpu + i, online_state[i]); if (ret < 0) { free(online_state); @@ -844,13 +845,13 @@ static int pass_restore_hotplug_initdata(struct pass_resource *res) } if (online_min_num >= 0) { - ret = pass_set_online_min_num(res, online_min_num); + ret = pass_hal_set_online_min_num(res, online_min_num); if (ret < 0) return ret; } if (online_max_num >= 0) { - ret = pass_set_online_max_num(res, online_max_num); + ret = pass_hal_set_online_max_num(res, online_max_num); if (ret < 0) return ret; } @@ -864,14 +865,14 @@ static int pass_restore_hotplug_initdata(struct pass_resource *res) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -static int pass_restore_memory_initdata(struct pass_resource *res) +static int pass_hal_restore_memory_initdata(struct pass_resource *res) { struct pass_resource_init_data *initdata = &res->init_data; int fault_around_bytes = initdata->memory.fault_around_bytes; int ret; if (fault_around_bytes >= 0) { - ret = pass_set_fault_around_bytes(res, fault_around_bytes); + ret = pass_hal_set_fault_around_bytes(res, fault_around_bytes); if (ret < 0) return ret; } @@ -885,7 +886,7 @@ static int pass_restore_memory_initdata(struct pass_resource *res) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -int pass_save_initdata(struct pass_resource *res) +int pass_hal_save_initdata(struct pass_resource *res) { int ret; @@ -894,7 +895,7 @@ int pass_save_initdata(struct pass_resource *res) switch (res->config_data.res_type) { case PASS_RESOURCE_CPU_ID: - ret = pass_save_hotplug_initdata(res); + ret = pass_hal_save_hotplug_initdata(res); if (ret < 0) { _E("Failed to save hp initdata for '%s' resource", res->config_data.res_name); @@ -903,7 +904,7 @@ int pass_save_initdata(struct pass_resource *res) /* fall through */ case PASS_RESOURCE_BUS_ID: case PASS_RESOURCE_GPU_ID: - ret = pass_save_dvfs_initdata(res); + ret = pass_hal_save_dvfs_initdata(res); if (ret < 0) { _E("Failed to save dvfs initdata for '%s' resource", res->config_data.res_name); @@ -911,7 +912,7 @@ int pass_save_initdata(struct pass_resource *res) } break; case PASS_RESOURCE_MEMORY_ID: - ret = pass_save_memory_initdata(res); + ret = pass_hal_save_memory_initdata(res); if (ret < 0) { _E("Failed to save memory initdata for '%s' resource", res->config_data.res_name); @@ -935,7 +936,7 @@ int pass_save_initdata(struct pass_resource *res) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -int pass_restore_initdata(struct pass_resource *res) +int pass_hal_restore_initdata(struct pass_resource *res) { int ret; @@ -944,7 +945,7 @@ int pass_restore_initdata(struct pass_resource *res) switch (res->config_data.res_type) { case PASS_RESOURCE_CPU_ID: - ret = pass_restore_hotplug_initdata(res); + ret = pass_hal_restore_hotplug_initdata(res); if (ret < 0) { _E("Failed to restore hp initdata for '%s' resource", res->config_data.res_name); @@ -953,7 +954,7 @@ int pass_restore_initdata(struct pass_resource *res) /* fall through */ case PASS_RESOURCE_BUS_ID: case PASS_RESOURCE_GPU_ID: - ret = pass_restore_dvfs_initdata(res); + ret = pass_hal_restore_dvfs_initdata(res); if (ret < 0) { _E("Failed to restore dvfs initdata for '%s' resource", res->config_data.res_name); @@ -961,7 +962,7 @@ int pass_restore_initdata(struct pass_resource *res) } break; case PASS_RESOURCE_MEMORY_ID: - ret = pass_restore_memory_initdata(res); + ret = pass_hal_restore_memory_initdata(res); if (ret < 0) { _E("Failed to restore memory data for '%s' resource", res->config_data.res_name); @@ -987,7 +988,7 @@ int pass_restore_initdata(struct pass_resource *res) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -int pass_get_resource(struct pass_resource *res) +int pass_hal_get_resource(struct pass_resource *res) { struct pass_resource_info *info; const char *name; @@ -1070,7 +1071,7 @@ int pass_get_resource(struct pass_resource *res) * @param [in] res Instance of h/w resource * @return @c 0 on success, otherwise error value */ -int pass_put_resource(struct pass_resource *res) +int pass_hal_put_resource(struct pass_resource *res) { struct pass_resource_common *common; struct pass_resource_info *info; diff --git a/src/pass/pass-hal.h b/src/pass/pass-hal.h index 3ff1b6e..6329602 100644 --- a/src/pass/pass-hal.h +++ b/src/pass/pass-hal.h @@ -37,62 +37,62 @@ * Functions for all H/W resources */ /* Get and put the h/w resource. */ -int pass_get_resource(struct pass_resource *res); -int pass_put_resource(struct pass_resource *res); +int pass_hal_get_resource(struct pass_resource *res); +int pass_hal_put_resource(struct pass_resource *res); /* Save and restore the initial data of the h/w resource. */ -int pass_save_initdata(struct pass_resource *pass_res); -int pass_restore_initdata(struct pass_resource *pass_res); +int pass_hal_save_initdata(struct pass_resource *pass_res); +int pass_hal_restore_initdata(struct pass_resource *pass_res); /*** * Functions for CPU/BUS/GPU H/W resources */ /* Get and the current governor. */ -int pass_get_curr_governor(struct pass_resource *res, char *governor); -int pass_set_curr_governor(struct pass_resource *res, char *governor); +int pass_hal_get_curr_governor(struct pass_resource *res, char *governor); +int pass_hal_set_curr_governor(struct pass_resource *res, char *governor); /* Get the current frequency. */ -int pass_get_curr_freq(struct pass_resource *res); +int pass_hal_get_curr_freq(struct pass_resource *res); /* Get and set the minimum frequency. */ -int pass_get_min_freq(struct pass_resource *res); -int pass_set_min_freq(struct pass_resource *res, int freq); +int pass_hal_get_min_freq(struct pass_resource *res); +int pass_hal_set_min_freq(struct pass_resource *res, int freq); /* Get and set the maximum frequency. */ -int pass_get_max_freq(struct pass_resource *res); -int pass_set_max_freq(struct pass_resource *res, int freq); +int pass_hal_get_max_freq(struct pass_resource *res); +int pass_hal_set_max_freq(struct pass_resource *res, int freq); /* Get the minimum/maximum frequency which can be set to resource. */ -int pass_get_available_min_freq(struct pass_resource *res); -int pass_get_available_max_freq(struct pass_resource *res); +int pass_hal_get_available_min_freq(struct pass_resource *res); +int pass_hal_get_available_max_freq(struct pass_resource *res); /* Get and set the up_threshold to support boosting. */ -int pass_get_up_threshold(struct pass_resource *res); -int pass_set_up_threshold(struct pass_resource *res, int up_threshold); +int pass_hal_get_up_threshold(struct pass_resource *res); +int pass_hal_set_up_threshold(struct pass_resource *res, int up_threshold); /* Get the temperature and policy of thermal unit on specific h/w. */ -int pass_get_temp(struct pass_resource *res); -int pass_get_tmu_policy(struct pass_resource *res, char *policy); +int pass_hal_get_temp(struct pass_resource *res); +int pass_hal_get_tmu_policy(struct pass_resource *res, char *policy); /*** * Functions for CPU H/W resources */ /* Get and set online state of cpu. */ -int pass_get_online_state(struct pass_resource *res, int cpu); -int pass_set_online_state(struct pass_resource *res, int cpu, int on); +int pass_hal_get_online_state(struct pass_resource *res, int cpu); +int pass_hal_set_online_state(struct pass_resource *res, int cpu, int on); /* Get and set the minimum number of online CPUs */ -int pass_get_online_min_num(struct pass_resource *res); -int pass_set_online_min_num(struct pass_resource *res, int num); +int pass_hal_get_online_min_num(struct pass_resource *res); +int pass_hal_set_online_min_num(struct pass_resource *res, int num); /* Get and set the maximum number of online CPUs */ -int pass_get_online_max_num(struct pass_resource *res); -int pass_set_online_max_num(struct pass_resource *res, int num); +int pass_hal_get_online_max_num(struct pass_resource *res); +int pass_hal_set_online_max_num(struct pass_resource *res, int num); /*** * Functions for Memory h/w resource */ /* Get and set the /sys/kernel/debug/fault_around_bytes */ -int pass_get_fault_around_bytes(struct pass_resource *res); -int pass_set_fault_around_bytes(struct pass_resource *res, +int pass_hal_get_fault_around_bytes(struct pass_resource *res); +int pass_hal_set_fault_around_bytes(struct pass_resource *res, int fault_around_bytes); /*** @@ -105,6 +105,6 @@ int pass_set_fault_around_bytes(struct pass_resource *res, * * This function will be removed after finding the proper method. */ -int pass_set_pmqos_data(struct pass_resource *res, void *data); +int pass_hal_set_pmqos_data(struct pass_resource *res, void *data); #endif /* __PASS_HAL__ */ diff --git a/src/pass/pass-rescon.c b/src/pass/pass-rescon.c index 0ff6328..4908916 100644 --- a/src/pass/pass-rescon.c +++ b/src/pass/pass-rescon.c @@ -179,7 +179,7 @@ static int rescon_update(struct pass_resource *res) if (limit_min_cpu > limit_max_cpu) limit_min_cpu = limit_max_cpu; - ret = pass_set_online_min_num(res, limit_min_cpu); + ret = pass_hal_set_online_min_num(res, limit_min_cpu); if (ret == -EPERM || ret == -ENODEV) { /* * If -EPERM, function is not supported according to @@ -196,7 +196,7 @@ static int rescon_update(struct pass_resource *res) failed = 1; } - ret = pass_set_online_max_num(res, limit_max_cpu); + ret = pass_hal_set_online_max_num(res, limit_max_cpu); if (ret == -EPERM || ret == -ENODEV) { ; } else if (ret < 0) { @@ -207,7 +207,7 @@ static int rescon_update(struct pass_resource *res) } for (i = 0; i < limit_max_cpu; i++) { - ret = pass_set_online_state(res, + ret = pass_hal_set_online_state(res, res->config_data.cpu + i, (i < limit_min_cpu) ? 1 : 0); if (ret == -EPERM || ret == -ENODEV) { @@ -225,18 +225,18 @@ static int rescon_update(struct pass_resource *res) /* Set minimum and maximum frequency */ if (limit_max_freq > 0 && limit_min_freq > 0) { - int curr_min_freq = pass_get_min_freq(res); - int curr_max_freq = pass_get_max_freq(res); + int curr_min_freq = pass_hal_get_min_freq(res); + int curr_max_freq = pass_hal_get_max_freq(res); int ret_min; int ret_max; if ((limit_max_freq > curr_min_freq) && (limit_min_freq > curr_max_freq)) { - ret_max = pass_set_max_freq(res, limit_max_freq); - ret_min = pass_set_min_freq(res, limit_min_freq); + ret_max = pass_hal_set_max_freq(res, limit_max_freq); + ret_min = pass_hal_set_min_freq(res, limit_min_freq); } else { - ret_min = pass_set_min_freq(res, limit_min_freq); - ret_max = pass_set_max_freq(res, limit_max_freq); + ret_min = pass_hal_set_min_freq(res, limit_min_freq); + ret_max = pass_hal_set_max_freq(res, limit_max_freq); } if (ret_max < 0) { @@ -256,7 +256,7 @@ static int rescon_update(struct pass_resource *res) /* Set fault_around_bytes for the memory h/w */ if (fault_around_bytes > 0) { - ret = pass_set_fault_around_bytes(res, fault_around_bytes); + ret = pass_hal_set_fault_around_bytes(res, fault_around_bytes); if (ret < 0) { _W("failed to set the fault_around_bytes(%d) of %s", fault_around_bytes, @@ -460,7 +460,7 @@ int pass_rescon_set_scenario_level_sync_with_data(struct pass_resource *res, * be removed after finding the proper method. */ if (data) - pass_set_pmqos_data(res, data); + pass_hal_set_pmqos_data(res, data); rescon_set_scenario_level(res, scenario_level); @@ -484,7 +484,7 @@ int pass_rescon_unset_scenario_level_sync_with_data(struct pass_resource *res, * be removed after finding the proper method. */ if (data) - pass_set_pmqos_data(res, data); + pass_hal_set_pmqos_data(res, data); rescon_unset_scenario_level(res, scenario_level); @@ -526,7 +526,7 @@ int pass_rescon_init(struct pass_resource *res) * Save the current data of h/w resource. The saved data * will be used for restoring the h/w resource on exit(). */ - ret = pass_save_initdata(res); + ret = pass_hal_save_initdata(res); if (ret < 0) { _E("failed to save initdata of '%s' resource (%d)\n", res->config_data.res_name, ret); @@ -582,7 +582,7 @@ int pass_rescon_exit(struct pass_resource *res) rescon = &res->rescon; /* Restore the h/w resource by using the saved data */ - ret = pass_restore_initdata(res); + ret = pass_hal_restore_initdata(res); if (ret < 0) _E("failed to restore initdata of '%s' resource (%d)\n", res->config_data.res_name, ret); diff --git a/src/pass/pass-resmon-source.c b/src/pass/pass-resmon-source.c index 6ea9e71..0248fb8 100644 --- a/src/pass/pass-resmon-source.c +++ b/src/pass/pass-resmon-source.c @@ -60,7 +60,7 @@ static int resmon_thermal_init(struct resmon *monitor) * resource monitor for thermal is ticked, get current temperature * in advance. */ - result->temp = pass_get_temp(res); + result->temp = pass_hal_get_temp(res); monitor->result = result; @@ -103,7 +103,7 @@ static int resmon_thermal_timer_handler(struct resmon *monitor, void *result) return -ENOMEM; /* Get temperature of h/w resource */ - temp = pass_get_temp(res); + temp = pass_hal_get_temp(res); if (temp < 0) return temp; @@ -133,7 +133,7 @@ static int resmon_thermal_uevent_handler(struct resmon *monitor, void *result, return -ENOMEM; /* Get temperature of h/w resource */ - temp = pass_get_temp(res); + temp = pass_hal_get_temp(res); if (temp < 0) return temp; diff --git a/src/pass/pass.c b/src/pass/pass.c index 8ce5876..9038f25 100644 --- a/src/pass/pass.c +++ b/src/pass/pass.c @@ -387,7 +387,7 @@ static int pass_init_done(void *data, void *user_data) struct pass_resource_config_data *config_data = &g_pass.res[i].config_data; - ret = pass_get_resource(res); + ret = pass_hal_get_resource(res); if (ret < 0) { _E("Cannot get the pass '%s' resource (%d)\n", config_data->res_name, ret); @@ -401,7 +401,7 @@ static int pass_init_done(void *data, void *user_data) _E("Cannot initialize the pass '%s' resource (%d)\n", config_data->res_name, ret); - ret = pass_put_resource(res); + ret = pass_hal_put_resource(res); if (ret < 0) _E("Cannot put the pass '%s' resource (%d)\n", config_data->res_name, ret); @@ -439,7 +439,7 @@ static void pass_exit_done(void) _E("Cannot exit the pass '%s' resource (%d)\n", config_data->res_name, ret); - ret = pass_put_resource(res); + ret = pass_hal_put_resource(res); if (ret < 0) { _E("Cannot put the pass '%s' resource (%d)\n", config_data->res_name, ret); diff --git a/unittest/pass_haltests.cpp b/unittest/pass_haltests.cpp index 53dfa40..4fbde96 100644 --- a/unittest/pass_haltests.cpp +++ b/unittest/pass_haltests.cpp @@ -69,7 +69,7 @@ TEST_F(PowerMgntHalTest, GetResourceConfig_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_resource(res); + ret = pass_hal_get_resource(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetResourceConfig Failed"; } @@ -85,7 +85,7 @@ TEST_F(PowerMgntHalTest, GetCurrGovernor_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_curr_governor(res, governor); + ret = pass_hal_get_curr_governor(res, governor); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetCurrGovernor Failed"; } @@ -101,12 +101,12 @@ TEST_F(PowerMgntHalTest, SetCurrGovernor_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_curr_governor(res, governor); + ret = pass_hal_get_curr_governor(res, governor); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetCurrGovernor Failed"; } - ret = pass_set_curr_governor(res, governor); + ret = pass_hal_set_curr_governor(res, governor); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "SetCurrGovernor Failed"; } @@ -121,7 +121,7 @@ TEST_F(PowerMgntHalTest, GetCurrFreq_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_curr_freq(res); + ret = pass_hal_get_curr_freq(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetCurrFreq Failed"; } @@ -136,7 +136,7 @@ TEST_F(PowerMgntHalTest, GetMinFreq_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_min_freq(res); + ret = pass_hal_get_min_freq(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetMinFreq Failed"; } @@ -152,13 +152,13 @@ TEST_F(PowerMgntHalTest, SetMinFreq_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - min_freq = pass_get_available_min_freq(res); + min_freq = pass_hal_get_available_min_freq(res); if (haltest_is_failed(res, min_freq)) { ASSERT_EQ(min_freq, 0) << "GetAvailableMinFreq Failed"; } if (min_freq >= 0) { - ret = pass_set_min_freq(res, min_freq); + ret = pass_hal_set_min_freq(res, min_freq); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "SetMinFreq Failed"; } @@ -174,7 +174,7 @@ TEST_F(PowerMgntHalTest, GetMaxFreq_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_max_freq(res); + ret = pass_hal_get_max_freq(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetMaxFreq Failed"; } @@ -190,13 +190,13 @@ TEST_F(PowerMgntHalTest, SetMaxFreq_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - max_freq = pass_get_available_max_freq(res); + max_freq = pass_hal_get_available_max_freq(res); if (haltest_is_failed(res, max_freq)) { ASSERT_EQ(max_freq, 0) << "GetAvailableMaxFreq Failed"; } if (max_freq >= 0) { - ret = pass_set_max_freq(res, max_freq); + ret = pass_hal_set_max_freq(res, max_freq); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "SetMaxFreq Failed"; } @@ -212,7 +212,7 @@ TEST_F(PowerMgntHalTest, GetAvailableMinFreq_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_available_min_freq(res); + ret = pass_hal_get_available_min_freq(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetAvailableMinFreq Failed"; } @@ -227,7 +227,7 @@ TEST_F(PowerMgntHalTest, GetAvailableMaxFreq_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_available_max_freq(res); + ret = pass_hal_get_available_max_freq(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetAvailableMaxFreq Failed"; } @@ -243,7 +243,7 @@ TEST_F(PowerMgntHalTest, GetUpThreshold_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_up_threshold(res); + ret = pass_hal_get_up_threshold(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetUpThreshold Failed"; } @@ -259,13 +259,13 @@ TEST_F(PowerMgntHalTest, SetUpThreshold_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - up_threshold = pass_get_up_threshold(res); + up_threshold = pass_hal_get_up_threshold(res); if (haltest_is_failed(res, up_threshold)) { ASSERT_EQ(up_threshold, 0) << "GetUpThreshold Failed"; } if (up_threshold >= 0) { - ret = pass_set_up_threshold(res, up_threshold); + ret = pass_hal_set_up_threshold(res, up_threshold); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "SetUpThreshold Failed"; } @@ -281,7 +281,7 @@ TEST_F(PowerMgntHalTest, GetTemperature_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_temp(res); + ret = pass_hal_get_temp(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetTemperature Failed"; } @@ -297,7 +297,7 @@ TEST_F(PowerMgntHalTest, GetTmuPolicy_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_tmu_policy(res, policy); + ret = pass_hal_get_tmu_policy(res, policy); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetTmuPolicy Failed"; } @@ -313,7 +313,7 @@ TEST_F(PowerMgntHalTest, GetOnlineState_HandlesValidInput) struct pass_resource *res = &g_pass.res[i]; for (j = 0; j < res->config_data.num_cpus; j++) { - ret = pass_get_online_state(res, j); + ret = pass_hal_get_online_state(res, j); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetOnlineState Failed"; } @@ -335,13 +335,13 @@ TEST_F(PowerMgntHalTest, SetOnlineState_HandlesValidInput) struct pass_resource *res = &g_pass.res[i]; for (j = 0; j < res->config_data.num_cpus; j++) { - online_state = pass_get_online_state(res, j); + online_state = pass_hal_get_online_state(res, j); if (haltest_is_failed(res, online_state)) { ASSERT_EQ(online_state, 0) << "GetOnlineState Failed"; } if (online_state >= 0) { - ret = pass_set_online_state(res, j, online_state); + ret = pass_hal_set_online_state(res, j, online_state); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "SetOnlineState Failed"; } @@ -359,7 +359,7 @@ TEST_F(PowerMgntHalTest, GetOnlineMinNum_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_online_min_num(res); + ret = pass_hal_get_online_min_num(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetOnlineMinNum Failed"; } @@ -375,13 +375,13 @@ TEST_F(PowerMgntHalTest, SetOnlineMinNum_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - online_min_num = pass_get_online_min_num(res); + online_min_num = pass_hal_get_online_min_num(res); if (haltest_is_failed(res, online_min_num)) { ASSERT_EQ(online_min_num, 0) << "GetOnlineMinNum Failed"; } if (online_min_num >= 0) { - ret = pass_set_online_min_num(res, online_min_num); + ret = pass_hal_set_online_min_num(res, online_min_num); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "SetOnlineMinNum Failed"; } @@ -397,7 +397,7 @@ TEST_F(PowerMgntHalTest, GetOnlineMaxNum_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_online_max_num(res); + ret = pass_hal_get_online_max_num(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetOnlineMaxNum Failed"; } @@ -413,13 +413,13 @@ TEST_F(PowerMgntHalTest, SetOnlineMaxNum_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - online_max_num = pass_get_online_max_num(res); + online_max_num = pass_hal_get_online_max_num(res); if (haltest_is_failed(res, online_max_num)) { ASSERT_EQ(online_max_num, 0) << "GetOnlineMaxNum Failed"; } if (online_max_num >= 0) { - ret = pass_set_online_max_num(res, online_max_num); + ret = pass_hal_set_online_max_num(res, online_max_num); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "SetOnlineMaxNum Failed"; } @@ -435,7 +435,7 @@ TEST_F(PowerMgntHalTest, GetFaultAroundBytes_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_get_fault_around_bytes(res); + ret = pass_hal_get_fault_around_bytes(res); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "GetFaultAroundBytes Failed"; } @@ -451,13 +451,13 @@ TEST_F(PowerMgntHalTest, SetFaultAroundBytes_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - fault_around_bytes = pass_get_fault_around_bytes(res); + fault_around_bytes = pass_hal_get_fault_around_bytes(res); if (haltest_is_failed(res, fault_around_bytes)) { ASSERT_EQ(fault_around_bytes, 0) << "GetFaultAroundBytes Failed"; } if (fault_around_bytes >= 0) { - ret = pass_set_fault_around_bytes(res, fault_around_bytes); + ret = pass_hal_set_fault_around_bytes(res, fault_around_bytes); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "SetFaultAroundBytes Failed"; } @@ -474,7 +474,7 @@ TEST_F(PowerMgntHalTest, SetPmqosData_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_set_pmqos_data(res, applaunch_scenario); + ret = pass_hal_set_pmqos_data(res, applaunch_scenario); if (haltest_is_failed(res, ret)) { ASSERT_EQ(ret, 0) << "SetPmqosData Failed"; } @@ -489,7 +489,7 @@ TEST_F(PowerMgntHalTest, PutResourceConfig_HandlesValidInput) for (i = 0; i < g_pass.num_resources; i++) { struct pass_resource *res = &g_pass.res[i]; - ret = pass_put_resource(res); + ret = pass_hal_put_resource(res); if (ret < 0) { pass_put_resource_config(&g_pass); ASSERT_EQ(ret, 0) << "PutResourceConfig Failed"; -- 2.7.4 From 3ad5462176ca02a32518148af5bf30fb44a7d203 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 11 Feb 2020 16:49:47 +0900 Subject: [PATCH 09/16] pass: parser: Rename parser API for the readability Rename all parser API from "pass_*()" to "pass_parser_*()" to improve the readability. Change-Id: Iade47afa9463093698612bb2d81004ae918695f9 Signed-off-by: Chanwoo Choi --- src/pass/pass-parser.c | 8 ++++---- src/pass/pass-parser.h | 8 ++++---- src/pass/pass.c | 8 ++++---- unittest/pass_haltests.cpp | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index 26292a6..acaca3c 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -961,7 +961,7 @@ static int parse_resource(struct parse_result *result, void *user_data) * @param [in] path Path of configuration files (/etc/pass/pass.conf) * @return @c 0 on success, otherwise error value */ -int pass_get_resource_config(struct pass *pass, char *path) +int pass_parser_get_resource_config(struct pass *pass, char *path) { return config_parse(path, parse_resource, pass); } @@ -971,7 +971,7 @@ int pass_get_resource_config(struct pass *pass, char *path) * @param [in] pass Instance of 'struct pass' contains all information * @return N/A */ -void pass_put_resource_config(struct pass *pass) +void pass_parser_put_resource_config(struct pass *pass) { free(pass->res); pass->res = NULL; @@ -984,7 +984,7 @@ void pass_put_resource_config(struct pass *pass) * @param [in] path Path of configuration file for each h/w resource * @return @c 0 on success, otherwise error value */ -int pass_get_each_resource_config(struct pass_resource *res, char *path) +int pass_parser_get_each_resource_config(struct pass_resource *res, char *path) { struct pass_cpuhp *cpuhp; struct pass_pmqos *pmqos; @@ -1068,7 +1068,7 @@ int pass_get_each_resource_config(struct pass_resource *res, char *path) * @param [in] res Instance of h/w resource * @return N/A */ -void pass_put_each_resource_config(struct pass_resource *res) +void pass_parser_put_each_resource_config(struct pass_resource *res) { if (!res) { _E("cannot put pass table\n"); diff --git a/src/pass/pass-parser.h b/src/pass/pass-parser.h index bd554b5..538c6d7 100644 --- a/src/pass/pass-parser.h +++ b/src/pass/pass-parser.h @@ -38,10 +38,10 @@ #include "pass.h" -int pass_get_resource_config(struct pass *pass, char *path); -void pass_put_resource_config(struct pass *pass); +int pass_parser_get_resource_config(struct pass *pass, char *path); +void pass_parser_put_resource_config(struct pass *pass); -int pass_get_each_resource_config(struct pass_resource *res, char *path); -void pass_put_each_resource_config(struct pass_resource *res); +int pass_parser_get_each_resource_config(struct pass_resource *res, char *path); +void pass_parser_put_each_resource_config(struct pass_resource *res); #endif /* __PASS_PARSER__ */ diff --git a/src/pass/pass.c b/src/pass/pass.c index 9038f25..764df84 100644 --- a/src/pass/pass.c +++ b/src/pass/pass.c @@ -205,7 +205,7 @@ static int pass_init_resource(struct pass_resource *res) int i; /* Get configuration of each resource from pass-resource*.conf */ - ret = pass_get_each_resource_config(res, res->config_data.path_conf_file); + ret = pass_parser_get_each_resource_config(res, res->config_data.path_conf_file); if (ret < 0) { _E("cannot parse %s\n", res->config_data.path_conf_file); return -1; @@ -300,7 +300,7 @@ static int pass_exit_resource(struct pass_resource *res) int ret; /* Put configuration of each resource from pass-resource*.conf */ - pass_put_each_resource_config(res); + pass_parser_put_each_resource_config(res); if (is_supported_module(res, PASS_MODULE_CPUHP)) { ret = pass_cpuhp_exit(res); @@ -361,7 +361,7 @@ static int pass_init_done(void *data, void *user_data) int i, ret; /* Get configuration of resource list from pass.conf */ - ret = pass_get_resource_config(&g_pass, PASS_CONF_PATH); + ret = pass_parser_get_resource_config(&g_pass, PASS_CONF_PATH); if (ret < 0) { _E("cannot parse %s\n", PASS_CONF_PATH); return ret; @@ -449,7 +449,7 @@ static void pass_exit_done(void) } /* Put configuration of resource list from pass.conf */ - pass_put_resource_config(&g_pass); + pass_parser_put_resource_config(&g_pass); g_pass.state = PASS_OFF; } diff --git a/unittest/pass_haltests.cpp b/unittest/pass_haltests.cpp index 4fbde96..de98ee0 100644 --- a/unittest/pass_haltests.cpp +++ b/unittest/pass_haltests.cpp @@ -63,7 +63,7 @@ TEST_F(PowerMgntHalTest, GetResourceConfig_HandlesValidInput) ret = system("/bin/systemctl stop pass.service"); ASSERT_EQ(ret, 0) << "PassServiceStop Failed"; - ret = pass_get_resource_config(&g_pass, path); + ret = pass_parser_get_resource_config(&g_pass, path); ASSERT_EQ(ret, 0) << "GetResourceConfig Failed"; for (i = 0; i < g_pass.num_resources; i++) { @@ -491,7 +491,7 @@ TEST_F(PowerMgntHalTest, PutResourceConfig_HandlesValidInput) ret = pass_hal_put_resource(res); if (ret < 0) { - pass_put_resource_config(&g_pass); + pass_parser_put_resource_config(&g_pass); ASSERT_EQ(ret, 0) << "PutResourceConfig Failed"; } } -- 2.7.4 From 87b2ae337e65f3bba41a25a2ac090fc95a98c515 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 24 Feb 2020 20:05:21 +0900 Subject: [PATCH 10/16] pass: parser: Clean-up code to remove warning from static code analyzer Change-Id: I627fc5e55497a34b318273bbb06af2664cdc2b03 Signed-off-by: Chanwoo Choi --- src/pass/pass-parser.c | 10 ++++------ src/pass/pass.h | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/pass/pass-parser.c b/src/pass/pass-parser.c index acaca3c..38c6392 100644 --- a/src/pass/pass-parser.c +++ b/src/pass/pass-parser.c @@ -532,13 +532,11 @@ static int parse_core(struct parse_result *result, void *user_data) return gov_type; res->config_data.gov_type = gov_type; } else if (MATCH(result->name, "pass_num_levels")) { - unsigned int num_levels; - - ret = sys_strtol(result->value); - if (ret < 0) - return ret; - num_levels = ret; + int num_levels; + num_levels = sys_strtol(result->value); + if (num_levels < 0) + return num_levels; if (num_levels > MAX_NUM) { _E("cannot parse %s\n", result->name); return -EINVAL; diff --git a/src/pass/pass.h b/src/pass/pass.h index 89a5494..2bf4a93 100644 --- a/src/pass/pass.h +++ b/src/pass/pass.h @@ -474,7 +474,7 @@ struct pass_resource_config_data { unsigned int default_max_level; /** The number of pass_levels */ - unsigned int num_levels; + int num_levels; /** List of pass_levels */ struct pass_level *levels; -- 2.7.4 From 285156de48918aebbd9d574d99eb4439ae9e0017 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 4 Aug 2020 11:05:41 +0900 Subject: [PATCH 11/16] scripts: dbus: Allow root to use d-bus interface Allow 'root' to use d-bus interface provided by PASS. The 'root' have to control all d-bus interface without any restrictions. Change-Id: I18d467f2745741c7c4b990b64210dfd16692d39c Signed-off-by: Chanwoo Choi --- scripts/pass.conf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/pass.conf b/scripts/pass.conf index 40c543e..b96f2af 100644 --- a/scripts/pass.conf +++ b/scripts/pass.conf @@ -1,6 +1,12 @@ + + + + -- 2.7.4 From 37ac960a5cbff46eb5536dfb6bc9c26c9584f58a Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 7 Aug 2020 15:03:47 +0900 Subject: [PATCH 12/16] pmqos: Fix wrong unlocked issue when pmqos list contains only one scenario The pmqos list contains only one scenario like UltraPowerSaving and when receiving the unmated scenario name like AppLaunch with unlock info with that duration is zero, the last scenario will be unlocked. In order to fix this issuse, correct the conditional statement. Change-Id: Ica2a3a3f44d02dfd07e3cb57e1dab300decee9d0 Signed-off-by: Chanwoo Choi --- src/pmqos/pmqos.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pmqos/pmqos.c b/src/pmqos/pmqos.c index de1f2a6..e14e882 100644 --- a/src/pmqos/pmqos.c +++ b/src/pmqos/pmqos.c @@ -332,11 +332,10 @@ static void pmqos_unlock_timeout_update(void) */ static int pmqos_cancel(const char *name) { - GList *elem; + GList *elem = NULL; struct pmqos_cpu *cpu; /* Find previous request */ - cpu = NULL; for (elem = pmqos_head; elem != NULL; elem = elem->next) { cpu = elem->data; if (!strcmp(cpu->name, name)) @@ -344,7 +343,7 @@ static int pmqos_cancel(const char *name) } /* no cpu */ - if (!cpu) + if (!elem) return 0; /* unlock cpu */ -- 2.7.4 From d34dc7968dedf5440decd21032cdb759cd0cb1c3 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 7 Aug 2020 15:22:56 +0900 Subject: [PATCH 13/16] pmqos: Fix issue when the part of scenario name is same with supported scenario If the part of scenario name sent from client is same with among the supported scenario name, strncmp() causes the issue. In order to fix this issue, compare the full scenario name with strcmp(): Change-Id: Ibc712b0b4be2cb752506ac7094b27abd88e587b5 Reported-by: Seung-Woo Kim Signed-off-by: Chanwoo Choi --- src/pmqos/pmqos.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pmqos/pmqos.c b/src/pmqos/pmqos.c index e14e882..2ed67f7 100644 --- a/src/pmqos/pmqos.c +++ b/src/pmqos/pmqos.c @@ -175,8 +175,7 @@ static gboolean dbus_cb_pmqos_legacy_scenario(SystemPassPmqos *obj, for (i = 0; i < g_pmqos->num; i++) { name = g_pmqos->list[i].name; support = g_pmqos->list[i].support; - if (!strncmp(name, name_from, strlen(name)) && - support) { + if (!strcmp(name, name_from) && support) { ret = 0; break; } @@ -352,7 +351,7 @@ static int pmqos_cancel(const char *name) pmqos_head = g_list_remove(pmqos_head, (gconstpointer)cpu); free(cpu); - if (strncmp(unlock_timer_owner.name, name, strlen(name))) + if (strcmp(unlock_timer_owner.name, name)) goto out; /* undata cpu */ pmqos_unlock_timeout_update(); -- 2.7.4 From dd8f02c59678ef2b72c496847248905df13b0014 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Thu, 6 Aug 2020 17:40:28 +0900 Subject: [PATCH 14/16] pmqos: Set max_duration_ms for each scenario Until now, only support global max_duration_ms time. But, if each scenario need to set the different maximum duration time, it is not supported. Allow each scenario to set the default maximume duration time. Change-Id: I6f294ab55d2157c251593c300cb04eefb598b751 Signed-off-by: Chanwoo Choi --- scripts/pass-pmqos.conf | 5 ++-- src/pmqos/pmqos-parser.c | 26 ++++++++++++--------- src/pmqos/pmqos.c | 59 ++++++++++++++++++------------------------------ src/pmqos/pmqos.h | 3 +-- 4 files changed, 41 insertions(+), 52 deletions(-) diff --git a/scripts/pass-pmqos.conf b/scripts/pass-pmqos.conf index a47733c..53c7377 100644 --- a/scripts/pass-pmqos.conf +++ b/scripts/pass-pmqos.conf @@ -1,19 +1,20 @@ [PassScenario] # set to "yes" scenario_support (Default value is no) # set scenario_num to be tested -# set scenario_max_timeout_ms (unit:millisecond, default timeout is 3000ms) scenario_support=yes scenario_num=2 -scenario_max_timeout_ms=3000 # describe the scenario section as follows #[Scenario0] #name=AppLaunch # (dbus method name) +#max_duration_ms=3000 # (unit:millisecond, max dururation is 3000ms) #support=yes [Scenario0] name=AppLaunch +max_duration_ms=3000 support=yes [Scenario1] name=UltraPowerSaving +max_duration_ms=3000 support=yes diff --git a/src/pmqos/pmqos-parser.c b/src/pmqos/pmqos-parser.c index 5b32bae..3e8ee97 100644 --- a/src/pmqos/pmqos-parser.c +++ b/src/pmqos/pmqos-parser.c @@ -90,15 +90,6 @@ static int pmqos_parse_scenario(struct parse_result *result, void *user_data, un scenarios->num = num; } - } else if (MATCH(result->name, "scenario_max_timeout_ms")) { - int max_timeout_ms; - - max_timeout_ms = sys_strtol(result->value); - if (max_timeout_ms < 0) { - _E("failed to get maximum timeout of scenario"); - return -ERANGE; - } - scenarios->max_timeout_ms = max_timeout_ms; } } @@ -120,6 +111,21 @@ static int pmqos_parse_scenario(struct parse_result *result, void *user_data, un "%s", result->value); else if (MATCH(result->name, "support")) scenarios->list[index].support = is_supported(result->value); + else if (MATCH(result->name, "max_duration_ms")) { + int max_duration_ms = sys_strtol(result->value); + + if (max_duration_ms < 0) { + _E("failed to parse max_duration_ms property (%d)\n", + max_duration_ms); + return -EINVAL; + } + + /* + * If maximum duration is zero, it measn that this scenario is + * mode without any maximum duration. + */ + scenarios->list[index].max_duration_ms = max_duration_ms; + } return 0; } @@ -186,7 +192,6 @@ int pmqos_put_scenario(struct pmqos_scenario *scenarios) if (scenarios->num > 0 && scenarios->list) { scenarios->num = 0; - scenarios->max_timeout_ms = 0; free(scenarios->list); scenarios->list = NULL; } @@ -207,7 +212,6 @@ int pmqos_get_scenario(const char *path, struct pmqos_scenario *scenarios) /* Initialize the variables before parsing the pass-pmqos.conf */ scenarios->num = 0; - scenarios->max_timeout_ms = 0; /* get configuration file */ ret = config_parse(path, pmqos_load_config, scenarios); diff --git a/src/pmqos/pmqos.c b/src/pmqos/pmqos.c index 2ed67f7..3deae6e 100644 --- a/src/pmqos/pmqos.c +++ b/src/pmqos/pmqos.c @@ -39,8 +39,6 @@ #include "pmqos.h" -#define DEFAULT_PMQOS_TIMER 3000 - #define PMQOS_CONF_PATH "/etc/pass/pass-pmqos.conf" #define MILLISECONDS(tv) ((tv.tv_sec)*1000 + (tv.tv_nsec)/1000000) #define DELTA(a, b) (MILLISECONDS(a) - MILLISECONDS(b)) @@ -64,7 +62,6 @@ struct pmqos_cpu { static GList *pmqos_head; guint g_unlock_timeout_id; -static int unlock_max_timeout_ms; static struct timespec unlock_timer_start_st; static struct timespec unlock_timer_end_st; static struct pmqos_cpu unlock_timer_owner = {"", 0}; @@ -161,6 +158,7 @@ static gboolean dbus_cb_pmqos_legacy_scenario(SystemPassPmqos *obj, const char *name_from; char *name; bool support; + int max_duration_ms; int i, ret = 0; gboolean ret_out = TRUE; @@ -168,26 +166,30 @@ static gboolean dbus_cb_pmqos_legacy_scenario(SystemPassPmqos *obj, _E("PASS PMQoS is stopped\n"); ret_out = FALSE; goto out; - } else { - name_from = g_dbus_method_invocation_get_method_name(invoc); - ret = -ENOTSUP; - if (g_pmqos) { - for (i = 0; i < g_pmqos->num; i++) { - name = g_pmqos->list[i].name; - support = g_pmqos->list[i].support; - if (!strcmp(name, name_from) && support) { - ret = 0; - break; - } + } + + name_from = g_dbus_method_invocation_get_method_name(invoc); + ret = -ENOTSUP; + if (g_pmqos) { + for (i = 0; i < g_pmqos->num; i++) { + name = g_pmqos->list[i].name; + support = g_pmqos->list[i].support; + max_duration_ms = g_pmqos->list[i].max_duration_ms; + + if (!strcmp(name, name_from) && support) { + ret = 0; + if (duration > max_duration_ms) + duration = max_duration_ms; + break; } } + } - if (ret < 0) { - _E("cannot set the PMQoS scenario: " - "%s is not supported\n", name_from); - ret_out = FALSE; - goto out_dbus; - } + if (ret < 0) { + _E("cannot set the PMQoS scenario: " + "%s is not supported\n", name_from); + ret_out = FALSE; + goto out_dbus; } if (duration) @@ -413,13 +415,6 @@ static int pmqos_request(const char *name, int val) int found = 0; int ret; - /* Check valid parameter */ - if (val > unlock_max_timeout_ms) { - _I("Timeout cannot be higher than maximum timeout (%d ms)", - unlock_max_timeout_ms); - val = unlock_max_timeout_ms; - } - /* find cpu */ for (elem = pmqos_head; elem != NULL; elem = elem->next) { cpu = elem->data; @@ -497,16 +492,6 @@ static int pmqos_init_done(void *data, void *user_data) g_pmqos->list[i].name); } - /* - * Set maximum timeout for the scenario by using the parsed data from - * pass-pmqos.conf. But, if there is no setting from pass-pmqos.conf - * pmqos uses the default timeout value (3000 millisecond). - */ - if (g_pmqos->max_timeout_ms) - unlock_max_timeout_ms = g_pmqos->max_timeout_ms; - else - unlock_max_timeout_ms = DEFAULT_PMQOS_TIMER; - return 0; } diff --git a/src/pmqos/pmqos.h b/src/pmqos/pmqos.h index 4058d4c..ffacd10 100644 --- a/src/pmqos/pmqos.h +++ b/src/pmqos/pmqos.h @@ -41,12 +41,11 @@ struct pmqos_scenario { struct scenario { char name[NAME_MAX]; /** Unique scenario name */ bool support; /** State is either supported or not */ + int max_duration_ms; /** Maximum duration */ } *list; /** The number of supported PMQoS scenarios */ int num; - /** Maximum duration */ - int max_timeout_ms; /** State of PMQoS feature is either supported or not*/ bool support; }; -- 2.7.4 From a6bf74920a269f150e4cb139e1f01b76171abc62 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Thu, 6 Aug 2020 18:14:27 +0900 Subject: [PATCH 15/16] pass: Adjust indentation to show current resource statues for readability Adjust indentation to show current resource statues and remove unneeded blank line for readability. And remove unneeded comment and blank line. Change-Id: Ibb2e660374626b942a2dd14c3bdb59caa5725162 Signed-off-by: Chanwoo Choi --- src/pass/pass-rescon.c | 11 ++++------- src/pmqos/pmqos.c | 11 +++-------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/pass/pass-rescon.c b/src/pass/pass-rescon.c index 4908916..be4e06d 100644 --- a/src/pass/pass-rescon.c +++ b/src/pass/pass-rescon.c @@ -44,29 +44,26 @@ static void rescon_print_level(struct pass_resource *res, if (!res || !level) return; - /* Add blank line for improving the readability on dlog */ - _D(""); - if (level->limit_min_freq > 0) { - _D("MIN Frequency is %10d of '%s' resource \n", + _D("MIN Frequency is %10d of '%s' resource \n", level->limit_min_freq, res->config_data.res_name); } if (level->limit_max_freq > 0) { - _D("MAX Frequency is %10d of '%s' resource\n", + _D("MAX Frequency is %10d of '%s' resource\n", level->limit_max_freq, res->config_data.res_name); } if (level->limit_min_cpu >= 0) { - _D("MIN CPU number is %10d of '%s' resource\n", + _D("MIN CPU number is %10d of '%s' resource\n", level->limit_min_cpu, res->config_data.res_name); } if (level->limit_max_cpu >= 0) { - _D("MAX CPU number is %10d of '%s' resource\n", + _D("MAX CPU number is %10d of '%s' resource\n", level->limit_max_cpu, res->config_data.res_name); } diff --git a/src/pmqos/pmqos.c b/src/pmqos/pmqos.c index 3deae6e..27a3e5f 100644 --- a/src/pmqos/pmqos.c +++ b/src/pmqos/pmqos.c @@ -343,19 +343,17 @@ static int pmqos_cancel(const char *name) break; } - /* no cpu */ if (!elem) return 0; - /* unlock cpu */ set_pmqos(cpu->name, false); - /* delete cpu */ + pmqos_head = g_list_remove(pmqos_head, (gconstpointer)cpu); free(cpu); if (strcmp(unlock_timer_owner.name, name)) goto out; - /* undata cpu */ + pmqos_unlock_timeout_update(); pmqos_unlock_timer_start(); out: @@ -415,7 +413,6 @@ static int pmqos_request(const char *name, int val) int found = 0; int ret; - /* find cpu */ for (elem = pmqos_head; elem != NULL; elem = elem->next) { cpu = elem->data; if (!strcmp(cpu->name, name)) { @@ -425,7 +422,6 @@ static int pmqos_request(const char *name, int val) } } - /* add cpu */ if (!found) { cpu = calloc(1, sizeof(struct pmqos_cpu)); if (!cpu) @@ -435,14 +431,13 @@ static int pmqos_request(const char *name, int val) cpu->timeout = val; pmqos_head = g_list_append(pmqos_head, (gpointer)cpu); } - /* sort cpu */ + pmqos_head = g_list_sort(pmqos_head, compare_timeout); ret = pmqos_unlock_timer_start(); if (ret < 0) goto err; - /* Set cpu lock */ set_pmqos(cpu->name, true); return 0; err: -- 2.7.4 From 6c5032e3886c05880ec169eef0707fa507892865 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Thu, 6 Aug 2020 18:57:01 +0900 Subject: [PATCH 16/16] pmqos: Add new SetScenario method for pmqos dbus interface When add new scenario to pmqos, it have to edit the code. It is not extensible. In order to improve the extensiblity without code changes, add new SetScenario method for pmqos dbus interface as following: When need to add new scenario, just add new scenario info. to scripts/pass-pmqos.conf (/etc/pass/pass-pmqos.conf) without any code changes. [Interface for new SetScenario method of pmqos dbus] - dbus interface : org.tizen.system.pass.pmqos.SetScenario - parameter 1: scenario name like AppLaunch - parameter 2: duration time like 3000 means 3 second Change-Id: I5ee8da4ec62a9cf1d55ea51f6c7fb8ca9ce7b9e7 Signed-off-by: Chanwoo Choi --- include/pass/gdbus-definition.h | 1 + scripts/pmqos-dbus.xml | 5 +++ src/pmqos/pmqos.c | 72 +++++++++++++++++++++++++++-------------- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/include/pass/gdbus-definition.h b/include/pass/gdbus-definition.h index fbf4afd..5072341 100644 --- a/include/pass/gdbus-definition.h +++ b/include/pass/gdbus-definition.h @@ -40,6 +40,7 @@ typedef enum { #define DBUS_PMQOS_I_STOP_HANDLER "handle_stop" #define DBUS_PMQOS_I_APPLAUNCH_HANDLER "handle_app_launch" #define DBUS_PMQOS_I_ULTRAPOWERSAVING_HANDLER "handle_ultra_power_saving" +#define DBUS_PMQOS_I_SET_SCENARIO_HANDLER "handle_set_scenario" #define DBUS_THERMAL_BUS_NAME "org.tizen.system.thermal" #define DBUS_THERMAL_INTERFACE "org.tizen.system.thermal" diff --git a/scripts/pmqos-dbus.xml b/scripts/pmqos-dbus.xml index f373ddd..271d775 100644 --- a/scripts/pmqos-dbus.xml +++ b/scripts/pmqos-dbus.xml @@ -7,6 +7,11 @@ + + + + + diff --git a/src/pmqos/pmqos.c b/src/pmqos/pmqos.c index 27a3e5f..7c95054 100644 --- a/src/pmqos/pmqos.c +++ b/src/pmqos/pmqos.c @@ -146,20 +146,18 @@ static gboolean dbus_cb_pmqos_stop(SystemPassPmqos *obj, * UltraPowerSaving through D-bus interface. * @param [in] obj Instance of SystemPassPmqos * @param [in] invoc Instance of GDBusMethodInvocation + * @param [in] name Specific scenario name or mode name * @param [in] duration Duration to keep scenario during demanded time * @param [in] user_data Unused parameter * @return @c true if success, otherwise @c false if fail */ -static gboolean dbus_cb_pmqos_legacy_scenario(SystemPassPmqos *obj, +static gboolean dbus_cb_pmqos_set_scenario(SystemPassPmqos *obj, GDBusMethodInvocation *invoc, + const char *name, int duration, gpointer user_data) { - const char *name_from; - char *name; - bool support; - int max_duration_ms; - int i, ret = 0; + int i, ret = -ENOTSUP; gboolean ret_out = TRUE; if (!g_pmqos) { @@ -168,43 +166,64 @@ static gboolean dbus_cb_pmqos_legacy_scenario(SystemPassPmqos *obj, goto out; } - name_from = g_dbus_method_invocation_get_method_name(invoc); - ret = -ENOTSUP; - if (g_pmqos) { - for (i = 0; i < g_pmqos->num; i++) { - name = g_pmqos->list[i].name; - support = g_pmqos->list[i].support; - max_duration_ms = g_pmqos->list[i].max_duration_ms; - - if (!strcmp(name, name_from) && support) { - ret = 0; - if (duration > max_duration_ms) - duration = max_duration_ms; - break; - } + for (i = 0; i < g_pmqos->num; i++) { + char *supported_name = g_pmqos->list[i].name; + bool support = g_pmqos->list[i].support; + + if (!strcmp(supported_name, name) && support) { + int max_duration_ms = g_pmqos->list[i].max_duration_ms; + + if (duration > max_duration_ms) + duration = max_duration_ms; + ret = 0; + break; } } if (ret < 0) { _E("cannot set the PMQoS scenario: " - "%s is not supported\n", name_from); + "%s is not supported\n", name); ret_out = FALSE; goto out_dbus; } if (duration) - ret = pmqos_request(name_from, duration); + ret = pmqos_request(name, duration); else - ret = pmqos_cancel(name_from); + ret = pmqos_cancel(name); out_dbus: g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret)); - out: return ret_out; } /** + * @brief Callback function when receive the scenario like AppLaunch, + * UltraPowerSaving through D-bus interface. + * @param [in] obj Instance of SystemPassPmqos + * @param [in] invoc Instance of GDBusMethodInvocation + * @param [in] duration Duration to keep scenario during demanded time + * @param [in] user_data Unused parameter + * @return @c true if success, otherwise @c false if fail + */ +static gboolean dbus_cb_pmqos_legacy_scenario(SystemPassPmqos *obj, + GDBusMethodInvocation *invoc, + int duration, + gpointer user_data) +{ + const char *name; + + if (!g_pmqos) { + _E("PASS PMQoS is stopped\n"); + return FALSE; + } + + name = g_dbus_method_invocation_get_method_name(invoc); + return dbus_cb_pmqos_set_scenario(obj, invoc, name, duration, user_data); +} + +/** * @brief Define the supported D-bus signal information for PMQoS * feature. It contains the signal name and callback function * pointer which is executed when receives the defined signal. @@ -221,6 +240,11 @@ static struct pass_gdbus_signal_info g_gdbus_signal_infos[] = { .cb_data = NULL, .ret_id = 0, }, { + .handler = DBUS_PMQOS_I_SET_SCENARIO_HANDLER, + .cb = G_CALLBACK(dbus_cb_pmqos_set_scenario), + .cb_data = NULL, + .ret_id = 0, + }, { .handler = DBUS_PMQOS_I_START_HANDLER, .cb = G_CALLBACK(dbus_cb_pmqos_start), .cb_data = NULL, -- 2.7.4