diff options
author | Fabio Baltieri <fabio.baltieri@linaro.org> | 2012-12-27 09:55:41 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-02-01 18:01:13 -0500 |
commit | 66df2a01dfd715636f5c86f7afd05362e7e3fddd (patch) | |
tree | 419905e3de1dcb00787e277b85b2d8fcab350092 /drivers/cpufreq/cpufreq_conservative.c | |
parent | da53d61e21a5869b2e44247bb37deb8be387e063 (diff) |
cpufreq: conservative: call dbs_check_cpu only when necessary
Modify conservative timer to not resample CPU utilization if recently
sampled from another SW coordinated core.
Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/cpufreq_conservative.c')
-rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index b9d7f14d7d3d..5d8e8942ec97 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -111,22 +111,57 @@ static void cs_check_cpu(int cpu, unsigned int load) | |||
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | static void cs_dbs_timer(struct work_struct *work) | 114 | static void cs_timer_update(struct cs_cpu_dbs_info_s *dbs_info, bool sample, |
115 | struct delayed_work *dw) | ||
115 | { | 116 | { |
116 | struct cs_cpu_dbs_info_s *dbs_info = container_of(work, | ||
117 | struct cs_cpu_dbs_info_s, cdbs.work.work); | ||
118 | unsigned int cpu = dbs_info->cdbs.cpu; | 117 | unsigned int cpu = dbs_info->cdbs.cpu; |
119 | int delay = delay_for_sampling_rate(cs_tuners.sampling_rate); | 118 | int delay = delay_for_sampling_rate(cs_tuners.sampling_rate); |
120 | 119 | ||
120 | if (sample) | ||
121 | dbs_check_cpu(&cs_dbs_data, cpu); | ||
122 | |||
123 | schedule_delayed_work_on(smp_processor_id(), dw, delay); | ||
124 | } | ||
125 | |||
126 | static void cs_timer_coordinated(struct cs_cpu_dbs_info_s *dbs_info_local, | ||
127 | struct delayed_work *dw) | ||
128 | { | ||
129 | struct cs_cpu_dbs_info_s *dbs_info; | ||
130 | ktime_t time_now; | ||
131 | s64 delta_us; | ||
132 | bool sample = true; | ||
133 | |||
134 | /* use leader CPU's dbs_info */ | ||
135 | dbs_info = &per_cpu(cs_cpu_dbs_info, dbs_info_local->cdbs.cpu); | ||
121 | mutex_lock(&dbs_info->cdbs.timer_mutex); | 136 | mutex_lock(&dbs_info->cdbs.timer_mutex); |
122 | 137 | ||
123 | dbs_check_cpu(&cs_dbs_data, cpu); | 138 | time_now = ktime_get(); |
139 | delta_us = ktime_us_delta(time_now, dbs_info->cdbs.time_stamp); | ||
124 | 140 | ||
125 | schedule_delayed_work_on(smp_processor_id(), &dbs_info->cdbs.work, | 141 | /* Do nothing if we recently have sampled */ |
126 | delay); | 142 | if (delta_us < (s64)(cs_tuners.sampling_rate / 2)) |
143 | sample = false; | ||
144 | else | ||
145 | dbs_info->cdbs.time_stamp = time_now; | ||
146 | |||
147 | cs_timer_update(dbs_info, sample, dw); | ||
127 | mutex_unlock(&dbs_info->cdbs.timer_mutex); | 148 | mutex_unlock(&dbs_info->cdbs.timer_mutex); |
128 | } | 149 | } |
129 | 150 | ||
151 | static void cs_dbs_timer(struct work_struct *work) | ||
152 | { | ||
153 | struct delayed_work *dw = to_delayed_work(work); | ||
154 | struct cs_cpu_dbs_info_s *dbs_info = container_of(work, | ||
155 | struct cs_cpu_dbs_info_s, cdbs.work.work); | ||
156 | |||
157 | if (dbs_sw_coordinated_cpus(&dbs_info->cdbs)) { | ||
158 | cs_timer_coordinated(dbs_info, dw); | ||
159 | } else { | ||
160 | mutex_lock(&dbs_info->cdbs.timer_mutex); | ||
161 | cs_timer_update(dbs_info, true, dw); | ||
162 | mutex_unlock(&dbs_info->cdbs.timer_mutex); | ||
163 | } | ||
164 | } | ||
130 | static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | 165 | static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, |
131 | void *data) | 166 | void *data) |
132 | { | 167 | { |