aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2013-04-08 07:15:40 -0400
committerTejun Heo <tj@kernel.org>2013-05-14 13:50:06 -0400
commitcee22a15052faa817e3ec8985a28154d3fabc7aa (patch)
tree506028de7bd3bf7de08a7933b5601355f27c5262
parentf722406faae2d073cc1d01063d1123c35425939e (diff)
workqueues: Introduce new flag WQ_POWER_EFFICIENT for power oriented workqueues
Workqueues can be performance or power-oriented. Currently, most workqueues are bound to the CPU they were created on. This gives good performance (due to cache effects) at the cost of potentially waking up otherwise idle cores (Idle from scheduler's perspective. Which may or may not be physically idle) just to process some work. To save power, we can allow the work to be rescheduled on a core that is already awake. Workqueues created with the WQ_UNBOUND flag will allow some power savings. However, we don't change the default behaviour of the system. To enable power-saving behaviour, a new config option CONFIG_WQ_POWER_EFFICIENT needs to be turned on. This option can also be overridden by the workqueue.power_efficient boot parameter. tj: Updated config description and comments. Renamed CONFIG_WQ_POWER_EFFICIENT to CONFIG_WQ_POWER_EFFICIENT_DEFAULT. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--Documentation/kernel-parameters.txt15
-rw-r--r--include/linux/workqueue.h27
-rw-r--r--kernel/power/Kconfig20
-rw-r--r--kernel/workqueue.c13
4 files changed, 75 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index c3bfacb92910..37dfd720de79 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -3320,6 +3320,21 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
3320 that this also can be controlled per-workqueue for 3320 that this also can be controlled per-workqueue for
3321 workqueues visible under /sys/bus/workqueue/. 3321 workqueues visible under /sys/bus/workqueue/.
3322 3322
3323 workqueue.power_efficient
3324 Per-cpu workqueues are generally preferred because
3325 they show better performance thanks to cache
3326 locality; unfortunately, per-cpu workqueues tend to
3327 be more power hungry than unbound workqueues.
3328
3329 Enabling this makes the per-cpu workqueues which
3330 were observed to contribute significantly to power
3331 consumption unbound, leading to measurably lower
3332 power usage at the cost of small performance
3333 overhead.
3334
3335 The default value of this parameter is determined by
3336 the config option CONFIG_WQ_POWER_EFFICIENT_DEFAULT.
3337
3323 x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of 3338 x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of
3324 default x2apic cluster mode on platforms 3339 default x2apic cluster mode on platforms
3325 supporting x2apic. 3340 supporting x2apic.
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 623488fdc1f5..fc0136b604f2 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -303,6 +303,33 @@ enum {
303 WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ 303 WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */
304 WQ_SYSFS = 1 << 6, /* visible in sysfs, see wq_sysfs_register() */ 304 WQ_SYSFS = 1 << 6, /* visible in sysfs, see wq_sysfs_register() */
305 305
306 /*
307 * Per-cpu workqueues are generally preferred because they tend to
308 * show better performance thanks to cache locality. Per-cpu
309 * workqueues exclude the scheduler from choosing the CPU to
310 * execute the worker threads, which has an unfortunate side effect
311 * of increasing power consumption.
312 *
313 * The scheduler considers a CPU idle if it doesn't have any task
314 * to execute and tries to keep idle cores idle to conserve power;
315 * however, for example, a per-cpu work item scheduled from an
316 * interrupt handler on an idle CPU will force the scheduler to
317 * excute the work item on that CPU breaking the idleness, which in
318 * turn may lead to more scheduling choices which are sub-optimal
319 * in terms of power consumption.
320 *
321 * Workqueues marked with WQ_POWER_EFFICIENT are per-cpu by default
322 * but become unbound if workqueue.power_efficient kernel param is
323 * specified. Per-cpu workqueues which are identified to
324 * contribute significantly to power-consumption are identified and
325 * marked with this flag and enabling the power_efficient mode
326 * leads to noticeable power saving at the cost of small
327 * performance disadvantage.
328 *
329 * http://thread.gmane.org/gmane.linux.kernel/1480396
330 */
331 WQ_POWER_EFFICIENT = 1 << 7,
332
306 __WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */ 333 __WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */
307 __WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */ 334 __WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */
308 335
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 5dfdc9ea180b..46455961a88f 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -263,6 +263,26 @@ config PM_GENERIC_DOMAINS
263 bool 263 bool
264 depends on PM 264 depends on PM
265 265
266config WQ_POWER_EFFICIENT_DEFAULT
267 bool "Enable workqueue power-efficient mode by default"
268 depends on PM
269 default n
270 help
271 Per-cpu workqueues are generally preferred because they show
272 better performance thanks to cache locality; unfortunately,
273 per-cpu workqueues tend to be more power hungry than unbound
274 workqueues.
275
276 Enabling workqueue.power_efficient kernel parameter makes the
277 per-cpu workqueues which were observed to contribute
278 significantly to power consumption unbound, leading to measurably
279 lower power usage at the cost of small performance overhead.
280
281 This config option determines whether workqueue.power_efficient
282 is enabled by default.
283
284 If in doubt, say N.
285
266config PM_GENERIC_DOMAINS_SLEEP 286config PM_GENERIC_DOMAINS_SLEEP
267 def_bool y 287 def_bool y
268 depends on PM_SLEEP && PM_GENERIC_DOMAINS 288 depends on PM_SLEEP && PM_GENERIC_DOMAINS
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 4aa9f5bc6b2d..8068d97ce141 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -272,6 +272,15 @@ static cpumask_var_t *wq_numa_possible_cpumask;
272static bool wq_disable_numa; 272static bool wq_disable_numa;
273module_param_named(disable_numa, wq_disable_numa, bool, 0444); 273module_param_named(disable_numa, wq_disable_numa, bool, 0444);
274 274
275/* see the comment above the definition of WQ_POWER_EFFICIENT */
276#ifdef CONFIG_WQ_POWER_EFFICIENT_DEFAULT
277static bool wq_power_efficient = true;
278#else
279static bool wq_power_efficient;
280#endif
281
282module_param_named(power_efficient, wq_power_efficient, bool, 0444);
283
275static bool wq_numa_enabled; /* unbound NUMA affinity enabled */ 284static bool wq_numa_enabled; /* unbound NUMA affinity enabled */
276 285
277/* buf for wq_update_unbound_numa_attrs(), protected by CPU hotplug exclusion */ 286/* buf for wq_update_unbound_numa_attrs(), protected by CPU hotplug exclusion */
@@ -4085,6 +4094,10 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
4085 struct workqueue_struct *wq; 4094 struct workqueue_struct *wq;
4086 struct pool_workqueue *pwq; 4095 struct pool_workqueue *pwq;
4087 4096
4097 /* see the comment above the definition of WQ_POWER_EFFICIENT */
4098 if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient)
4099 flags |= WQ_UNBOUND;
4100
4088 /* allocate wq and format name */ 4101 /* allocate wq and format name */
4089 if (flags & WQ_UNBOUND) 4102 if (flags & WQ_UNBOUND)
4090 tbl_size = wq_numa_tbl_len * sizeof(wq->numa_pwq_tbl[0]); 4103 tbl_size = wq_numa_tbl_len * sizeof(wq->numa_pwq_tbl[0]);