Loading drivers/cpufreq/cpufreq_interactive.c +60 −1 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ struct cpufreq_interactive_cpuinfo { unsigned int max_freq; u64 floor_validate_time; u64 hispeed_validate_time; u64 max_freq_idle_start_time; struct rw_semaphore enable_sem; int governor_enabled; struct cpufreq_interactive_tunables *cached_tunables; Loading Loading @@ -125,6 +126,12 @@ struct cpufreq_interactive_tunables { /* scheduler input related flags */ bool use_sched_load; bool use_migration_notif; /* * Stay at max freq for at least max_freq_hysteresis before dropping * frequency. */ unsigned int max_freq_hysteresis; }; /* For cases where we have single governor instance for system */ Loading Loading @@ -476,6 +483,16 @@ static void cpufreq_interactive_timer(unsigned long data) new_freq = pcpu->freq_table[index].frequency; if (pcpu->target_freq >= pcpu->policy->max && new_freq < pcpu->target_freq && now - pcpu->max_freq_idle_start_time < tunables->max_freq_hysteresis) { trace_cpufreq_interactive_notyet(data, cpu_load, pcpu->target_freq, pcpu->policy->cur, new_freq); spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); goto rearm; } /* * Do not scale below floor_freq unless we have been at or above the * floor frequency for the minimum sample time since last validated. Loading Loading @@ -544,6 +561,9 @@ static void cpufreq_interactive_idle_start(void) struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, smp_processor_id()); int pending; struct cpufreq_interactive_tunables *tunables; unsigned long flags; u64 now; if (!down_read_trylock(&pcpu->enable_sem)) return; Loading @@ -566,9 +586,23 @@ static void cpufreq_interactive_idle_start(void) if (!pending) { pcpu->last_evaluated_jiffy = get_jiffies_64(); cpufreq_interactive_timer_resched(smp_processor_id()); /* * If timer is cancelled because CPU is running at * policy->max, record the time CPU first goes to * idle. */ now = ktime_to_us(ktime_get()); tunables = pcpu->policy->governor_data; if (tunables->max_freq_hysteresis) { spin_lock_irqsave(&pcpu->target_freq_lock, flags); pcpu->max_freq_idle_start_time = now; spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); } } } up_read(&pcpu->enable_sem); } Loading Loading @@ -912,6 +946,27 @@ static ssize_t store_hispeed_freq(struct cpufreq_interactive_tunables *tunables, return count; } #define show_store_one(file_name) \ static ssize_t show_##file_name( \ struct cpufreq_interactive_tunables *tunables, char *buf) \ { \ return snprintf(buf, PAGE_SIZE, "%u\n", tunables->file_name); \ } \ static ssize_t store_##file_name( \ struct cpufreq_interactive_tunables *tunables, \ const char *buf, size_t count) \ { \ int ret; \ long unsigned int val; \ \ ret = kstrtoul(buf, 0, &val); \ if (ret < 0) \ return ret; \ tunables->file_name = val; \ return count; \ } show_store_one(max_freq_hysteresis); static ssize_t show_go_hispeed_load(struct cpufreq_interactive_tunables *tunables, char *buf) { Loading Loading @@ -1290,6 +1345,7 @@ show_store_gov_pol_sys(boostpulse_duration); show_store_gov_pol_sys(io_is_busy); show_store_gov_pol_sys(use_sched_load); show_store_gov_pol_sys(use_migration_notif); show_store_gov_pol_sys(max_freq_hysteresis); #define gov_sys_attr_rw(_name) \ static struct global_attr _name##_gov_sys = \ Loading @@ -1315,6 +1371,7 @@ gov_sys_pol_attr_rw(boostpulse_duration); gov_sys_pol_attr_rw(io_is_busy); gov_sys_pol_attr_rw(use_sched_load); gov_sys_pol_attr_rw(use_migration_notif); gov_sys_pol_attr_rw(max_freq_hysteresis); static struct global_attr boostpulse_gov_sys = __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_sys); Loading @@ -1337,6 +1394,7 @@ static struct attribute *interactive_attributes_gov_sys[] = { &io_is_busy_gov_sys.attr, &use_sched_load_gov_sys.attr, &use_migration_notif_gov_sys.attr, &max_freq_hysteresis_gov_sys.attr, NULL, }; Loading @@ -1360,6 +1418,7 @@ static struct attribute *interactive_attributes_gov_pol[] = { &io_is_busy_gov_pol.attr, &use_sched_load_gov_pol.attr, &use_migration_notif_gov_pol.attr, &max_freq_hysteresis_gov_pol.attr, NULL, }; Loading Loading
drivers/cpufreq/cpufreq_interactive.c +60 −1 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ struct cpufreq_interactive_cpuinfo { unsigned int max_freq; u64 floor_validate_time; u64 hispeed_validate_time; u64 max_freq_idle_start_time; struct rw_semaphore enable_sem; int governor_enabled; struct cpufreq_interactive_tunables *cached_tunables; Loading Loading @@ -125,6 +126,12 @@ struct cpufreq_interactive_tunables { /* scheduler input related flags */ bool use_sched_load; bool use_migration_notif; /* * Stay at max freq for at least max_freq_hysteresis before dropping * frequency. */ unsigned int max_freq_hysteresis; }; /* For cases where we have single governor instance for system */ Loading Loading @@ -476,6 +483,16 @@ static void cpufreq_interactive_timer(unsigned long data) new_freq = pcpu->freq_table[index].frequency; if (pcpu->target_freq >= pcpu->policy->max && new_freq < pcpu->target_freq && now - pcpu->max_freq_idle_start_time < tunables->max_freq_hysteresis) { trace_cpufreq_interactive_notyet(data, cpu_load, pcpu->target_freq, pcpu->policy->cur, new_freq); spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); goto rearm; } /* * Do not scale below floor_freq unless we have been at or above the * floor frequency for the minimum sample time since last validated. Loading Loading @@ -544,6 +561,9 @@ static void cpufreq_interactive_idle_start(void) struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, smp_processor_id()); int pending; struct cpufreq_interactive_tunables *tunables; unsigned long flags; u64 now; if (!down_read_trylock(&pcpu->enable_sem)) return; Loading @@ -566,9 +586,23 @@ static void cpufreq_interactive_idle_start(void) if (!pending) { pcpu->last_evaluated_jiffy = get_jiffies_64(); cpufreq_interactive_timer_resched(smp_processor_id()); /* * If timer is cancelled because CPU is running at * policy->max, record the time CPU first goes to * idle. */ now = ktime_to_us(ktime_get()); tunables = pcpu->policy->governor_data; if (tunables->max_freq_hysteresis) { spin_lock_irqsave(&pcpu->target_freq_lock, flags); pcpu->max_freq_idle_start_time = now; spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); } } } up_read(&pcpu->enable_sem); } Loading Loading @@ -912,6 +946,27 @@ static ssize_t store_hispeed_freq(struct cpufreq_interactive_tunables *tunables, return count; } #define show_store_one(file_name) \ static ssize_t show_##file_name( \ struct cpufreq_interactive_tunables *tunables, char *buf) \ { \ return snprintf(buf, PAGE_SIZE, "%u\n", tunables->file_name); \ } \ static ssize_t store_##file_name( \ struct cpufreq_interactive_tunables *tunables, \ const char *buf, size_t count) \ { \ int ret; \ long unsigned int val; \ \ ret = kstrtoul(buf, 0, &val); \ if (ret < 0) \ return ret; \ tunables->file_name = val; \ return count; \ } show_store_one(max_freq_hysteresis); static ssize_t show_go_hispeed_load(struct cpufreq_interactive_tunables *tunables, char *buf) { Loading Loading @@ -1290,6 +1345,7 @@ show_store_gov_pol_sys(boostpulse_duration); show_store_gov_pol_sys(io_is_busy); show_store_gov_pol_sys(use_sched_load); show_store_gov_pol_sys(use_migration_notif); show_store_gov_pol_sys(max_freq_hysteresis); #define gov_sys_attr_rw(_name) \ static struct global_attr _name##_gov_sys = \ Loading @@ -1315,6 +1371,7 @@ gov_sys_pol_attr_rw(boostpulse_duration); gov_sys_pol_attr_rw(io_is_busy); gov_sys_pol_attr_rw(use_sched_load); gov_sys_pol_attr_rw(use_migration_notif); gov_sys_pol_attr_rw(max_freq_hysteresis); static struct global_attr boostpulse_gov_sys = __ATTR(boostpulse, 0200, NULL, store_boostpulse_gov_sys); Loading @@ -1337,6 +1394,7 @@ static struct attribute *interactive_attributes_gov_sys[] = { &io_is_busy_gov_sys.attr, &use_sched_load_gov_sys.attr, &use_migration_notif_gov_sys.attr, &max_freq_hysteresis_gov_sys.attr, NULL, }; Loading @@ -1360,6 +1418,7 @@ static struct attribute *interactive_attributes_gov_pol[] = { &io_is_busy_gov_pol.attr, &use_sched_load_gov_pol.attr, &use_migration_notif_gov_pol.attr, &max_freq_hysteresis_gov_pol.attr, NULL, }; Loading