Introduction

Workqueues can be performance or power oriented. For performance we may want to keep them running on a single cpu, so that it remains cache hot. For power we can give scheduler the liberty to choose target cpu for running work handler. Depending on scheduling policy, it could choose a non-idle cpu for scheduling the work and preventing unnecessary wakeups of idle cores.

Later one (Power oriented WQ) can be achieved if the workqueue is allocated with WQ_UNBOUND flag. Enabling CONFIG_WQ_POWER_EFFICIENT will set 'wq_power_efficient' to 'true'. When 'wq_power_efficient' is set to 'true', we will convert WQ_POWER_EFFICIENT flag to WQ_UNBOUND on wq allocation. And so scheduler will have the liberty to choose where to run this work and if policy allows will choose a non-idle CPU.

The 'power_efficient=' boot parameter can be used to override value of 'wq_power_efficient' variable.

The feature was merged here.

Usage

Just enable CONFIG_WQ_POWER_EFFICIENT in your configuration to get a quieter system with respect to workqueues.

Examples

Using system level workqueues

commit a85f1a41f020bc2c97611060bcfae6f48a1db28d
Author: Viresh Kumar <viresh.kumar@linaro.org>
Date:   Wed Apr 24 17:12:57 2013 +0530

    fbcon: queue work on power efficient wq
    
    fbcon uses workqueues and it has no real dependency of scheduling these on the
    cpu which scheduled them.
    
    On a idle system, it is observed that and idle cpu wakes up many times just to
    service this work. It would be better if we can schedule it on a cpu which the
    scheduler believes to be the most appropriate one.
    
    This patch replaces system_wq with system_power_efficient_wq.
    
    Cc: Dave Airlie <airlied@redhat.com>
    Cc: linux-fbdev@vger.kernel.org
    Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
    Signed-off-by: Tejun Heo <tj@kernel.org>
---
 drivers/video/console/fbcon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index a92783e..0d8f98c 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -404,7 +404,7 @@ static void cursor_timer_handler(unsigned long dev_addr)
        struct fb_info *info = (struct fb_info *) dev_addr;
        struct fbcon_ops *ops = info->fbcon_par;
 
-       schedule_work(&info->queue);
+       queue_work(system_power_efficient_wq, &info->queue);
        mod_timer(&ops->cursor_timer, jiffies + HZ/5);
 }

Using personal workqueues

commit 695588f9454bdbc7c1a2fbb8a6bfdcfba6183348
Author: Viresh Kumar <viresh.kumar@linaro.org>
Date:   Wed Apr 24 17:12:56 2013 +0530

    block: queue work on power efficient wq
    
    Block layer uses workqueues for multiple purposes. There is no real dependency
    of scheduling these on the cpu which scheduled them.
    
    On a idle system, it is observed that and idle cpu wakes up many times just to
    service this work. It would be better if we can schedule it on a cpu which the
    scheduler believes to be the most appropriate one.
    
    This patch replaces normal workqueues with power efficient versions.
    
    Cc: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
    Signed-off-by: Tejun Heo <tj@kernel.org>
---
 block/blk-core.c |  3 ++-
 block/blk-ioc.c  |  3 ++-
 block/genhd.c    | 12 ++++++++----
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 33c33bc..f0deb8b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -3180,7 +3180,8 @@ int __init blk_dev_init(void)
 
        /* used for unplugging and affects IO latency/throughput - HIGHPRI */
        kblockd_workqueue = alloc_workqueue("kblockd",
-                                           WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
+                                           WQ_MEM_RECLAIM | WQ_HIGHPRI |
+                                           WQ_POWER_EFFICIENT, 0);
        if (!kblockd_workqueue)
                panic("Failed to create kblockd\n");
 

Known Users

These are the subsystems/drivers that have already been converted to enable the flag. If you see wakeups from these, try enabling CONFIG_WQ_POWER_EFFICIENT in your kernel.

- block/blk-core.c
- block/blk-ioc.c
- block/genhd.c
- drivers/extcon/extcon-adc-jack.c
- drivers/extcon/extcon-arizona.c
- drivers/extcon/extcon-gpio.c
- drivers/extcon/extcon-max14577.c
- drivers/mfd/tps65010.c
- drivers/net/phy/phy.c
- drivers/regulator/core.c
- drivers/video/console/fbcon.c
- kernel/time/ntp.c
- net/core/neighbour.c
- net/ipv4/devinet.c
- sound/soc/codecs/max98090.c
- sound/soc/codecs/sta32x.c
- sound/soc/codecs/twl6040.c
- sound/soc/codecs/wm8350.c
- sound/soc/codecs/wm8753.c
- sound/soc/codecs/wm8962.c
- sound/soc/codecs/wm8994.c
- sound/soc/soc-compress.c
- sound/soc/soc-jack.c
- sound/soc/soc-pcm.c

WorkingGroups/PowerManagement/Doc/PowerEfficientWorkqueues (last modified 2014-04-08 10:33:46)