From patchwork Wed May 19 00:04:51 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sridhar Samudrala X-Patchwork-Id: 100647 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o4J06F9E026332 for ; Wed, 19 May 2010 00:06:15 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755189Ab0ESAFL (ORCPT ); Tue, 18 May 2010 20:05:11 -0400 Received: from e39.co.us.ibm.com ([32.97.110.160]:60982 "EHLO e39.co.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753804Ab0ESAFI (ORCPT ); Tue, 18 May 2010 20:05:08 -0400 Received: from d03relay05.boulder.ibm.com (d03relay05.boulder.ibm.com [9.17.195.107]) by e39.co.us.ibm.com (8.14.3/8.13.1) with ESMTP id o4INuMcd004650; Tue, 18 May 2010 17:56:23 -0600 Received: from d03av06.boulder.ibm.com (d03av06.boulder.ibm.com [9.17.195.245]) by d03relay05.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o4J04sZv076566; Tue, 18 May 2010 18:04:57 -0600 Received: from d03av06.boulder.ibm.com (loopback [127.0.0.1]) by d03av06.boulder.ibm.com (8.14.3/8.13.1/NCO v10.0 AVout) with ESMTP id o4J07l1I030181; Tue, 18 May 2010 18:07:47 -0600 Received: from [9.47.18.19] (w-sridhar.beaverton.ibm.com [9.47.18.19]) by d03av06.boulder.ibm.com (8.14.3/8.13.1/NCO v10.0 AVin) with ESMTP id o4J07kHd030153; Tue, 18 May 2010 18:07:46 -0600 Subject: [PATCH 2/3] workqueue: Add an API to create a singlethread workqueue attached to the current task's cgroup From: Sridhar Samudrala To: "Michael S. Tsirkin" , netdev , lkml , "kvm@vger.kernel.org" Date: Tue, 18 May 2010 17:04:51 -0700 Message-Id: <1274227491.2370.110.camel@w-sridhar.beaverton.ibm.com> Mime-Version: 1.0 X-Mailer: Evolution 2.26.3 (2.26.3-1.fc11) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 19 May 2010 00:06:16 +0000 (UTC) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 9466e86..6d6f301 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -211,6 +211,7 @@ __create_workqueue_key(const char *name, int singlethread, #define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1, 0) #define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0, 0) +extern struct workqueue_struct *create_singlethread_workqueue_in_current_cg(char *name); extern void destroy_workqueue(struct workqueue_struct *wq); extern int queue_work(struct workqueue_struct *wq, struct work_struct *work); diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 5bfb213..6ba226e 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -35,6 +35,7 @@ #include #define CREATE_TRACE_POINTS #include +#include /* * The per-CPU workqueue (if single thread, we always use the first @@ -193,6 +194,45 @@ static const struct cpumask *cpu_singlethread_map __read_mostly; */ static cpumask_var_t cpu_populated_map __read_mostly; +static struct task_struct *get_singlethread_wq_task(struct workqueue_struct *wq) +{ + return (per_cpu_ptr(wq->cpu_wq, singlethread_cpu))->thread; +} + +/* Create a singlethread workqueue and attach it's task to the current task's + * cgroup and set it's cpumask to the current task's cpumask. + */ +struct workqueue_struct *create_singlethread_workqueue_in_current_cg(char *name) +{ + struct workqueue_struct *wq; + struct task_struct *task; + cpumask_var_t mask; + + wq = create_singlethread_workqueue(name); + if (!wq) + goto out; + + if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + goto err; + + if (sched_getaffinity(current->pid, mask)) + goto err; + + task = get_singlethread_wq_task(wq); + if (sched_setaffinity(task->pid, mask)) + goto err; + + if (cgroup_attach_task_current_cg(task)) + goto err; +out: + return wq; +err: + destroy_workqueue(wq); + wq = NULL; + goto out; +} +EXPORT_SYMBOL_GPL(create_singlethread_workqueue_in_current_cg); + /* If it's single threaded, it isn't in the list of workqueues. */ static inline int is_wq_single_threaded(struct workqueue_struct *wq) {