未验证 提交 6ce8e9f4 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!841 【openEuler-1.0-LTS】cpufreq: conservative: Add a switch to enable fast mode

Merge Pull Request from: @xuesinian 
 
Frequency scaling strategy switch for fast mode. Enable conservative governor changing frequency a little bit quickly.

Conservative governor belongs to a slow frequency governor. In some scenarios where performance loss is significant. Therefore, endow the conservative governor with fast frequency scaling capability and add switches to use fast mode in these scenarios to reduce performance loss.

Related issue : #I78PCH 
 
Link:https://gitee.com/openeuler/kernel/pulls/841 

Reviewed-by: Xiongfeng Wang <wangxiongfeng2@huawei.com> 
Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com> 
Acked-by: Xie XiuQi <xiexiuqi@huawei.com> 
...@@ -587,6 +587,13 @@ This governor exposes the following tunables: ...@@ -587,6 +587,13 @@ This governor exposes the following tunables:
It effectively causes the frequency to go down ``sampling_down_factor`` It effectively causes the frequency to go down ``sampling_down_factor``
times slower than it ramps up. times slower than it ramps up.
``fast_mode``
Frequency scaling strategy switch for fast_mode. Enable `conservative`
governor changing frequency a little bit quickly.
If the user seeks to reduce performance loss, set it to 1(default 0) and
adopt fast mode; Otherwise, pursue greater power consumption benefits, set
it to 0 and adopt slow mode.
Frequency Boost Support Frequency Boost Support
======================= =======================
......
...@@ -28,6 +28,7 @@ static inline struct cs_policy_dbs_info *to_dbs_info(struct policy_dbs_info *pol ...@@ -28,6 +28,7 @@ static inline struct cs_policy_dbs_info *to_dbs_info(struct policy_dbs_info *pol
struct cs_dbs_tuners { struct cs_dbs_tuners {
unsigned int down_threshold; unsigned int down_threshold;
unsigned int freq_step; unsigned int freq_step;
unsigned int fast_mode;
}; };
/* Conservative governor macros */ /* Conservative governor macros */
...@@ -36,6 +37,8 @@ struct cs_dbs_tuners { ...@@ -36,6 +37,8 @@ struct cs_dbs_tuners {
#define DEF_FREQUENCY_STEP (5) #define DEF_FREQUENCY_STEP (5)
#define DEF_SAMPLING_DOWN_FACTOR (1) #define DEF_SAMPLING_DOWN_FACTOR (1)
#define MAX_SAMPLING_DOWN_FACTOR (10) #define MAX_SAMPLING_DOWN_FACTOR (10)
/* 50000 is the recommended hardware supported frequency step, 50MHz */
#define RECOMMAND_FREQUENCY_STEP (50000)
static inline unsigned int get_freq_step(struct cs_dbs_tuners *cs_tuners, static inline unsigned int get_freq_step(struct cs_dbs_tuners *cs_tuners,
struct cpufreq_policy *policy) struct cpufreq_policy *policy)
...@@ -49,6 +52,47 @@ static inline unsigned int get_freq_step(struct cs_dbs_tuners *cs_tuners, ...@@ -49,6 +52,47 @@ static inline unsigned int get_freq_step(struct cs_dbs_tuners *cs_tuners,
return freq_step; return freq_step;
} }
static unsigned int fast_dbs_update(struct cpufreq_policy *policy)
{
struct policy_dbs_info *policy_dbs = policy->governor_data;
struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
unsigned int requested_freq = dbs_info->requested_freq;
struct dbs_data *dbs_data = policy_dbs->dbs_data;
unsigned int load = dbs_update(policy);
unsigned int min_f, max_f;
/*
* If requested_freq is out of range, it is likely that the limits
* changed in the meantime, so fall back to current frequency in that
* case.
*/
if (requested_freq > policy->max || requested_freq < policy->min) {
requested_freq = policy->cur;
dbs_info->requested_freq = requested_freq;
}
/* Check for frequency increase */
if (load > dbs_data->up_threshold) {
/* If switching to max speed, apply sampling_down_factor */
if (policy->cur < policy->max)
policy_dbs->rate_mult = dbs_data->sampling_down_factor;
requested_freq = policy->max;
} else {
/* Calculate the next frequency proportional to load */
min_f = policy->cpuinfo.min_freq;
max_f = policy->cpuinfo.max_freq;
/* The range of load is 0 ~ 100, divide by 100 for percentage */
requested_freq = min_f + load * (max_f - min_f) / 100;
/* No longer fully busy, reset rate_mult */
policy_dbs->rate_mult = 1;
}
requested_freq = (requested_freq / RECOMMAND_FREQUENCY_STEP) * RECOMMAND_FREQUENCY_STEP;
__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_C);
return dbs_data->sampling_rate * policy_dbs->rate_mult;
}
/* /*
* Every sampling_rate, we check, if current idle time is less than 20% * Every sampling_rate, we check, if current idle time is less than 20%
* (default), then we try to increase frequency. Every sampling_rate * * (default), then we try to increase frequency. Every sampling_rate *
...@@ -75,6 +119,10 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy) ...@@ -75,6 +119,10 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy)
if (cs_tuners->freq_step == 0) if (cs_tuners->freq_step == 0)
goto out; goto out;
/* If seek to reduce performance loss */
if (cs_tuners->fast_mode == 1)
return fast_dbs_update(policy);
/* /*
* If requested_freq is out of range, it is likely that the limits * If requested_freq is out of range, it is likely that the limits
* changed in the meantime, so fall back to current frequency in that * changed in the meantime, so fall back to current frequency in that
...@@ -244,12 +292,30 @@ static ssize_t store_freq_step(struct gov_attr_set *attr_set, const char *buf, ...@@ -244,12 +292,30 @@ static ssize_t store_freq_step(struct gov_attr_set *attr_set, const char *buf,
return count; return count;
} }
static ssize_t store_fast_mode(struct gov_attr_set *attr_set,
const char *buf, size_t count)
{
struct dbs_data *dbs_data = to_dbs_data(attr_set);
struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
unsigned int input;
int ret;
ret = sscanf(buf, "%u", &input);
if (ret != 1 || (input != 0 && input != 1))
return -EINVAL;
cs_tuners->fast_mode = input;
return count;
}
gov_show_one_common(sampling_rate); gov_show_one_common(sampling_rate);
gov_show_one_common(sampling_down_factor); gov_show_one_common(sampling_down_factor);
gov_show_one_common(up_threshold); gov_show_one_common(up_threshold);
gov_show_one_common(ignore_nice_load); gov_show_one_common(ignore_nice_load);
gov_show_one(cs, down_threshold); gov_show_one(cs, down_threshold);
gov_show_one(cs, freq_step); gov_show_one(cs, freq_step);
gov_show_one(cs, fast_mode);
gov_attr_rw(sampling_rate); gov_attr_rw(sampling_rate);
gov_attr_rw(sampling_down_factor); gov_attr_rw(sampling_down_factor);
...@@ -257,6 +323,7 @@ gov_attr_rw(up_threshold); ...@@ -257,6 +323,7 @@ gov_attr_rw(up_threshold);
gov_attr_rw(ignore_nice_load); gov_attr_rw(ignore_nice_load);
gov_attr_rw(down_threshold); gov_attr_rw(down_threshold);
gov_attr_rw(freq_step); gov_attr_rw(freq_step);
gov_attr_rw(fast_mode);
static struct attribute *cs_attributes[] = { static struct attribute *cs_attributes[] = {
&sampling_rate.attr, &sampling_rate.attr,
...@@ -265,6 +332,7 @@ static struct attribute *cs_attributes[] = { ...@@ -265,6 +332,7 @@ static struct attribute *cs_attributes[] = {
&down_threshold.attr, &down_threshold.attr,
&ignore_nice_load.attr, &ignore_nice_load.attr,
&freq_step.attr, &freq_step.attr,
&fast_mode.attr,
NULL NULL
}; };
...@@ -293,6 +361,7 @@ static int cs_init(struct dbs_data *dbs_data) ...@@ -293,6 +361,7 @@ static int cs_init(struct dbs_data *dbs_data)
tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD; tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD;
tuners->freq_step = DEF_FREQUENCY_STEP; tuners->freq_step = DEF_FREQUENCY_STEP;
tuners->fast_mode = 0;
dbs_data->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; dbs_data->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
dbs_data->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR; dbs_data->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
dbs_data->ignore_nice_load = 0; dbs_data->ignore_nice_load = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册