From 3aa3f0c1fbf58d9e715a75e8d269a5c8794b1e12 Mon Sep 17 00:00:00 2001 From: Sultanxda Date: Wed, 29 Nov 2017 01:20:03 -0800 Subject: [PATCH] workqueue: Schedule workers on CPU0 or 0-3 by default For regular bound workers that don't request to be queued onto a specific CPU, just use CPU0 to save power. Additionally, adjust the CPU affinity of unbound workqueues to force their workers onto the power cluster (CPUs 0-3) to further improve power consumption. Signed-off-by: Sultanxda Signed-off-by: Panchajanya1999 Signed-off-by: Adithya R Signed-off-by: sohamxda7 Signed-off-by: RyuujiX Signed-off-by: wHo-EM-i Signed-off-by: Santhosh --- kernel/workqueue.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index f394bd81cb67..8475085301c5 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1425,6 +1425,9 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, if (unlikely(wq->flags & __WQ_DRAINING) && WARN_ON_ONCE(!is_chained_work(wq))) return; + + if (req_cpu == WORK_CPU_UNBOUND) + cpu = wq_select_unbound_cpu(0); retry: /* pwq which will be used unless @work is executing elsewhere */ if (wq->flags & WQ_UNBOUND) { @@ -1577,7 +1580,7 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq, if (unlikely(cpu != WORK_CPU_UNBOUND)) add_timer_on(timer, cpu); else - add_timer(timer); + add_timer_on(timer, 0); } /** @@ -3280,6 +3283,7 @@ void free_workqueue_attrs(struct workqueue_attrs *attrs) struct workqueue_attrs *alloc_workqueue_attrs(gfp_t gfp_mask) { struct workqueue_attrs *attrs; + const unsigned long allowed_cpus = 0xf; attrs = kzalloc(sizeof(*attrs), gfp_mask); if (!attrs) @@ -3287,7 +3291,7 @@ struct workqueue_attrs *alloc_workqueue_attrs(gfp_t gfp_mask) if (!alloc_cpumask_var(&attrs->cpumask, gfp_mask)) goto fail; - cpumask_copy(attrs->cpumask, cpu_possible_mask); + cpumask_copy(attrs->cpumask, to_cpumask(&allowed_cpus)); return attrs; fail: free_workqueue_attrs(attrs); @@ -4429,7 +4433,7 @@ bool workqueue_congested(int cpu, struct workqueue_struct *wq) rcu_read_lock_sched(); if (cpu == WORK_CPU_UNBOUND) - cpu = smp_processor_id(); + cpu = 0; if (!(wq->flags & WQ_UNBOUND)) pwq = per_cpu_ptr(wq->cpu_pwqs, cpu);