Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757437Ab2ECO6e (ORCPT ); Thu, 3 May 2012 10:58:34 -0400 Received: from mail-wg0-f44.google.com ([74.125.82.44]:55935 "EHLO mail-wg0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757199Ab2ECO5R (ORCPT ); Thu, 3 May 2012 10:57:17 -0400 From: Gilad Ben-Yossef To: linux-kernel@vger.kernel.org Cc: Gilad Ben-Yossef , Thomas Gleixner , Tejun Heo , John Stultz , Andrew Morton , KOSAKI Motohiro , Mel Gorman , Mike Frysinger , David Rientjes , Hugh Dickins , Minchan Kim , Konstantin Khlebnikov , Christoph Lameter , Chris Metcalf , Hakan Akkan , Max Krasnyansky , Frederic Weisbecker , linux-mm@kvack.org Subject: [PATCH v1 3/6] workqueue: introduce schedule_on_each_cpu_cond Date: Thu, 3 May 2012 17:55:59 +0300 Message-Id: <1336056962-10465-4-git-send-email-gilad@benyossef.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1336056962-10465-1-git-send-email-gilad@benyossef.com> References: <1336056962-10465-1-git-send-email-gilad@benyossef.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3483 Lines: 102 Introduce the schedule_on_each_cpu_cond() function that schedules a work item on each online CPU for which the supplied condition function returns true. This function should be used instead of schedule_on_each_cpu() when only some of the CPUs have actual work to do and a predicate function can tell if a certain CPU does or does not have work to do, thus saving unneeded wakeups and schedules. Signed-off-by: Gilad Ben-Yossef CC: Thomas Gleixner CC: Tejun Heo CC: John Stultz CC: Andrew Morton CC: KOSAKI Motohiro CC: Mel Gorman CC: Mike Frysinger CC: David Rientjes CC: Hugh Dickins CC: Minchan Kim CC: Konstantin Khlebnikov CC: Christoph Lameter CC: Chris Metcalf CC: Hakan Akkan CC: Max Krasnyansky CC: Frederic Weisbecker CC: linux-kernel@vger.kernel.org CC: linux-mm@kvack.org --- include/linux/workqueue.h | 2 ++ kernel/workqueue.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 20da95a..d7bb104 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -385,6 +385,8 @@ extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, extern int schedule_on_each_cpu(work_func_t func); extern int schedule_on_each_cpu_mask(work_func_t func, const struct cpumask *mask); +extern int schedule_on_each_cpu_cond(work_func_t func, + bool (*cond_func)(int cpu)); extern int keventd_up(void); int execute_in_process_context(work_func_t fn, struct execute_work *); diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 1c9782b..3322d30 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2828,6 +2828,43 @@ int schedule_on_each_cpu_mask(work_func_t func, const struct cpumask *mask) } /** + * schedule_on_each_cpu_cond - execute a function synchronously on each + * online CPU for which the supplied condition function returns true + * @func: the function to run on the selected CPUs + * @cond_func: the function to call to select the CPUs + * + * schedule_on_each_cpu_cond() executes @func on each online CPU for + * @cond_func returns true using the system workqueue and blocks until + * all CPUs have completed. + * schedule_on_each_cpu_cond() is very slow. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +int schedule_on_each_cpu_cond(work_func_t func, bool (*cond_func)(int cpu)) +{ + int cpu, ret; + cpumask_var_t mask; + + if (unlikely(!zalloc_cpumask_var(&mask, GFP_KERNEL))) + return -ENOMEM; + + get_online_cpus(); + + for_each_online_cpu(cpu) + if (cond_func(cpu)) + cpumask_set_cpu(cpu, mask); + + ret = schedule_on_each_cpu_mask(func, mask); + + put_online_cpus(); + + free_cpumask_var(mask); + + return ret; +} + +/** * schedule_on_each_cpu - execute a function synchronously on each online CPU * @func: the function to call * -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/