mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 04:12:04 -04:00
Merge "ANDROID: cpufreq/schedutil: add up/down frequency transition rate limits"
This commit is contained in:
commit
1f6a7259ef
1 changed files with 95 additions and 16 deletions
|
|
@ -18,7 +18,8 @@
|
|||
|
||||
struct sugov_tunables {
|
||||
struct gov_attr_set attr_set;
|
||||
unsigned int rate_limit_us;
|
||||
unsigned int up_rate_limit_us;
|
||||
unsigned int down_rate_limit_us;
|
||||
unsigned int hispeed_load;
|
||||
unsigned int hispeed_freq;
|
||||
unsigned int rtg_boost_freq;
|
||||
|
|
@ -40,7 +41,9 @@ struct sugov_policy {
|
|||
|
||||
raw_spinlock_t update_lock; /* For shared policies */
|
||||
u64 last_freq_update_time;
|
||||
s64 freq_update_delay_ns;
|
||||
s64 min_rate_limit_ns;
|
||||
s64 up_rate_delay_ns;
|
||||
s64 down_rate_delay_ns;
|
||||
unsigned int next_freq;
|
||||
unsigned int cached_raw_freq;
|
||||
|
||||
|
|
@ -113,9 +116,32 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* No need to recalculate next freq for min_rate_limit_us
|
||||
* at least. However we might still decide to further rate
|
||||
* limit once frequency change direction is decided, according
|
||||
* to the separate rate limits.
|
||||
*/
|
||||
|
||||
delta_ns = time - sg_policy->last_freq_update_time;
|
||||
return delta_ns >= sg_policy->min_rate_limit_ns;
|
||||
}
|
||||
|
||||
static bool sugov_up_down_rate_limit(struct sugov_policy *sg_policy, u64 time,
|
||||
unsigned int next_freq)
|
||||
{
|
||||
s64 delta_ns;
|
||||
|
||||
delta_ns = time - sg_policy->last_freq_update_time;
|
||||
|
||||
return delta_ns >= sg_policy->freq_update_delay_ns;
|
||||
if (next_freq > sg_policy->next_freq &&
|
||||
delta_ns < sg_policy->up_rate_delay_ns)
|
||||
return true;
|
||||
|
||||
if (next_freq < sg_policy->next_freq &&
|
||||
delta_ns < sg_policy->down_rate_delay_ns)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool use_pelt(void)
|
||||
|
|
@ -142,6 +168,9 @@ static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time,
|
|||
if (sg_policy->next_freq == next_freq)
|
||||
return false;
|
||||
|
||||
if (sugov_up_down_rate_limit(sg_policy, time, next_freq))
|
||||
return false;
|
||||
|
||||
sg_policy->next_freq = next_freq;
|
||||
sg_policy->last_freq_update_time = time;
|
||||
|
||||
|
|
@ -822,15 +851,32 @@ static inline struct sugov_tunables *to_sugov_tunables(struct gov_attr_set *attr
|
|||
return container_of(attr_set, struct sugov_tunables, attr_set);
|
||||
}
|
||||
|
||||
static ssize_t rate_limit_us_show(struct gov_attr_set *attr_set, char *buf)
|
||||
static DEFINE_MUTEX(min_rate_lock);
|
||||
|
||||
static void update_min_rate_limit_ns(struct sugov_policy *sg_policy)
|
||||
{
|
||||
mutex_lock(&min_rate_lock);
|
||||
sg_policy->min_rate_limit_ns = min(sg_policy->up_rate_delay_ns,
|
||||
sg_policy->down_rate_delay_ns);
|
||||
mutex_unlock(&min_rate_lock);
|
||||
}
|
||||
|
||||
static ssize_t up_rate_limit_us_show(struct gov_attr_set *attr_set, char *buf)
|
||||
{
|
||||
struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%u\n", tunables->rate_limit_us);
|
||||
return scnprintf(buf, PAGE_SIZE, "%u\n", tunables->up_rate_limit_us);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
rate_limit_us_store(struct gov_attr_set *attr_set, const char *buf, size_t count)
|
||||
static ssize_t down_rate_limit_us_show(struct gov_attr_set *attr_set, char *buf)
|
||||
{
|
||||
struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%u\n", tunables->down_rate_limit_us);
|
||||
}
|
||||
|
||||
static ssize_t up_rate_limit_us_store(struct gov_attr_set *attr_set,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
|
||||
struct sugov_policy *sg_policy;
|
||||
|
|
@ -839,15 +885,35 @@ rate_limit_us_store(struct gov_attr_set *attr_set, const char *buf, size_t count
|
|||
if (kstrtouint(buf, 10, &rate_limit_us))
|
||||
return -EINVAL;
|
||||
|
||||
tunables->rate_limit_us = rate_limit_us;
|
||||
tunables->up_rate_limit_us = rate_limit_us;
|
||||
|
||||
list_for_each_entry(sg_policy, &attr_set->policy_list, tunables_hook)
|
||||
sg_policy->freq_update_delay_ns = rate_limit_us * NSEC_PER_USEC;
|
||||
list_for_each_entry(sg_policy, &attr_set->policy_list, tunables_hook) {
|
||||
sg_policy->up_rate_delay_ns = rate_limit_us * NSEC_PER_USEC;
|
||||
update_min_rate_limit_ns(sg_policy);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct governor_attr rate_limit_us = __ATTR_RW(rate_limit_us);
|
||||
static ssize_t down_rate_limit_us_store(struct gov_attr_set *attr_set,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sugov_tunables *tunables = to_sugov_tunables(attr_set);
|
||||
struct sugov_policy *sg_policy;
|
||||
unsigned int rate_limit_us;
|
||||
|
||||
if (kstrtouint(buf, 10, &rate_limit_us))
|
||||
return -EINVAL;
|
||||
|
||||
tunables->down_rate_limit_us = rate_limit_us;
|
||||
|
||||
list_for_each_entry(sg_policy, &attr_set->policy_list, tunables_hook) {
|
||||
sg_policy->down_rate_delay_ns = rate_limit_us * NSEC_PER_USEC;
|
||||
update_min_rate_limit_ns(sg_policy);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t hispeed_load_show(struct gov_attr_set *attr_set, char *buf)
|
||||
{
|
||||
|
|
@ -949,13 +1015,16 @@ static ssize_t pl_store(struct gov_attr_set *attr_set, const char *buf,
|
|||
return count;
|
||||
}
|
||||
|
||||
static struct governor_attr up_rate_limit_us = __ATTR_RW(up_rate_limit_us);
|
||||
static struct governor_attr down_rate_limit_us = __ATTR_RW(down_rate_limit_us);
|
||||
static struct governor_attr hispeed_load = __ATTR_RW(hispeed_load);
|
||||
static struct governor_attr hispeed_freq = __ATTR_RW(hispeed_freq);
|
||||
static struct governor_attr rtg_boost_freq = __ATTR_RW(rtg_boost_freq);
|
||||
static struct governor_attr pl = __ATTR_RW(pl);
|
||||
|
||||
static struct attribute *sugov_attrs[] = {
|
||||
&rate_limit_us.attr,
|
||||
&up_rate_limit_us.attr,
|
||||
&down_rate_limit_us.attr,
|
||||
&hispeed_load.attr,
|
||||
&hispeed_freq.attr,
|
||||
&rtg_boost_freq.attr,
|
||||
|
|
@ -1075,7 +1144,8 @@ static void sugov_tunables_save(struct cpufreq_policy *policy,
|
|||
cached->hispeed_load = tunables->hispeed_load;
|
||||
cached->rtg_boost_freq = tunables->rtg_boost_freq;
|
||||
cached->hispeed_freq = tunables->hispeed_freq;
|
||||
cached->rate_limit_us = tunables->rate_limit_us;
|
||||
cached->up_rate_limit_us = tunables->up_rate_limit_us;
|
||||
cached->down_rate_limit_us = tunables->down_rate_limit_us;
|
||||
}
|
||||
|
||||
static void sugov_tunables_free(struct sugov_tunables *tunables)
|
||||
|
|
@ -1099,7 +1169,11 @@ static void sugov_tunables_restore(struct cpufreq_policy *policy)
|
|||
tunables->hispeed_load = cached->hispeed_load;
|
||||
tunables->rtg_boost_freq = cached->rtg_boost_freq;
|
||||
tunables->hispeed_freq = cached->hispeed_freq;
|
||||
tunables->rate_limit_us = cached->rate_limit_us;
|
||||
tunables->up_rate_limit_us = cached->up_rate_limit_us;
|
||||
tunables->down_rate_limit_us = cached->down_rate_limit_us;
|
||||
sg_policy->up_rate_delay_ns = cached->up_rate_limit_us;
|
||||
sg_policy->down_rate_delay_ns = cached->down_rate_limit_us;
|
||||
update_min_rate_limit_ns(sg_policy);
|
||||
}
|
||||
|
||||
static int sugov_init(struct cpufreq_policy *policy)
|
||||
|
|
@ -1145,7 +1219,8 @@ static int sugov_init(struct cpufreq_policy *policy)
|
|||
goto stop_kthread;
|
||||
}
|
||||
|
||||
tunables->rate_limit_us = cpufreq_policy_transition_delay_us(policy);
|
||||
tunables->up_rate_limit_us = cpufreq_policy_transition_delay_us(policy);
|
||||
tunables->down_rate_limit_us = cpufreq_policy_transition_delay_us(policy);
|
||||
tunables->hispeed_load = DEFAULT_HISPEED_LOAD;
|
||||
tunables->hispeed_freq = 0;
|
||||
|
||||
|
|
@ -1228,7 +1303,11 @@ static int sugov_start(struct cpufreq_policy *policy)
|
|||
struct sugov_policy *sg_policy = policy->governor_data;
|
||||
unsigned int cpu;
|
||||
|
||||
sg_policy->freq_update_delay_ns = sg_policy->tunables->rate_limit_us * NSEC_PER_USEC;
|
||||
sg_policy->up_rate_delay_ns =
|
||||
sg_policy->tunables->up_rate_limit_us * NSEC_PER_USEC;
|
||||
sg_policy->down_rate_delay_ns =
|
||||
sg_policy->tunables->down_rate_limit_us * NSEC_PER_USEC;
|
||||
update_min_rate_limit_ns(sg_policy);
|
||||
sg_policy->last_freq_update_time = 0;
|
||||
sg_policy->next_freq = 0;
|
||||
sg_policy->work_in_progress = false;
|
||||
|
|
|
|||
Loading…
Reference in a new issue