From: Cliff Wickman <cpw@sgi.com>
To: akpm@linux-foundation.org, ego@in.ibm.com, mingo@elte.hu,
vatsa@in.ibm.com, oleg@tv-sign.ru, pj@sgi.com
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH 1/1] hotplug cpu: migrate a task within its cpuset
Date: Fri, 24 Aug 2007 17:18:06 -0500 [thread overview]
Message-ID: <20070824221806.GA3602@sgi.com> (raw)
When a cpu is disabled, move_task_off_dead_cpu() is called for tasks
that have been running on that cpu.
Currently, such a task is migrated:
1) to any cpu on the same node as the disabled cpu, which is both online
and among that task's cpus_allowed
2) to any cpu which is both online and among that task's cpus_allowed
It is typical of a multithreaded application running on a large NUMA system
to have its tasks confined to a cpuset so as to cluster them near the
memory that they share. Furthermore, it is typical to explicitly place such
a task on a specific cpu in that cpuset. And in that case the task's
cpus_allowed includes only a single cpu.
This patch would insert a preference to migrate such a task to some cpu within
its cpuset (and set its cpus_allowed to its entire cpuset).
With this patch, migrate the task to:
1) to any cpu on the same node as the disabled cpu, which is both online
and among that task's cpus_allowed
2) to any online cpu within the task's cpuset
3) to any cpu which is both online and among that task's cpus_allowed
In order to do this, move_task_off_dead_cpu() must make a call to
cpuset_cpus_allowed_lock(), a new variant of cpuset_cpus_allowed() that
will not block.
Calls are made to cpuset_lock() and cpuset_unlock() in migration_call()
to set the cpuset mutex during the whole migrate_live_tasks() and
migrate_dead_tasks() procedure.
This patch depends on 2 patches from Oleg Nesterov:
[PATCH 1/2] do CPU_DEAD migrating under read_lock(tasklist) instead of write_lock_irq(tasklist)
[PATCH 2/2] migration_call(CPU_DEAD): use spin_lock_irq() instead of task_rq_lock()
Diffed against 2.6.23-rc3
Signed-off-by: Cliff Wickman <cpw@sgi.com>
---
include/linux/cpuset.h | 5 +++++
kernel/cpuset.c | 19 +++++++++++++++++++
kernel/sched.c | 14 ++++++++++++++
3 files changed, 38 insertions(+)
Index: linus.070821/kernel/sched.c
===================================================================
--- linus.070821.orig/kernel/sched.c
+++ linus.070821/kernel/sched.c
@@ -61,6 +61,7 @@
#include <linux/delayacct.h>
#include <linux/reciprocal_div.h>
#include <linux/unistd.h>
+#include <linux/cpuset.h>
#include <asm/tlb.h>
@@ -5091,6 +5092,17 @@ restart:
if (dest_cpu == NR_CPUS)
dest_cpu = any_online_cpu(p->cpus_allowed);
+ /* try to stay on the same cpuset */
+ if (dest_cpu == NR_CPUS) {
+ /*
+ * The cpuset_cpus_allowed_lock() variant of
+ * cpuset_cpus_allowed() will not block
+ * It must be called within calls to cpuset_lock/cpuset_unlock.
+ */
+ p->cpus_allowed = cpuset_cpus_allowed_lock(p);
+ dest_cpu = any_online_cpu(p->cpus_allowed);
+ }
+
/* No more Mr. Nice Guy. */
if (dest_cpu == NR_CPUS) {
rq = task_rq_lock(p, &flags);
@@ -5412,6 +5424,7 @@ migration_call(struct notifier_block *nf
case CPU_DEAD:
case CPU_DEAD_FROZEN:
+ cpuset_lock(); /* around calls to cpuset_cpus_allowed_lock() */
migrate_live_tasks(cpu);
rq = cpu_rq(cpu);
kthread_stop(rq->migration_thread);
@@ -5425,6 +5438,7 @@ migration_call(struct notifier_block *nf
rq->idle->sched_class = &idle_sched_class;
migrate_dead_tasks(cpu);
spin_unlock_irq(&rq->lock);
+ cpuset_unlock();
migrate_nr_uninterruptible(rq);
BUG_ON(rq->nr_running != 0);
Index: linus.070821/include/linux/cpuset.h
===================================================================
--- linus.070821.orig/include/linux/cpuset.h
+++ linus.070821/include/linux/cpuset.h
@@ -22,6 +22,7 @@ extern void cpuset_init_smp(void);
extern void cpuset_fork(struct task_struct *p);
extern void cpuset_exit(struct task_struct *p);
extern cpumask_t cpuset_cpus_allowed(struct task_struct *p);
+extern cpumask_t cpuset_cpus_allowed_lock(struct task_struct *p);
extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
#define cpuset_current_mems_allowed (current->mems_allowed)
void cpuset_init_current_mems_allowed(void);
@@ -87,6 +88,10 @@ static inline cpumask_t cpuset_cpus_allo
{
return cpu_possible_map;
}
+static inline cpumask_t cpuset_cpus_allowed_lock(struct task_struct *p)
+{
+ return cpu_possible_map;
+}
static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
{
Index: linus.070821/kernel/cpuset.c
===================================================================
--- linus.070821.orig/kernel/cpuset.c
+++ linus.070821/kernel/cpuset.c
@@ -2333,6 +2333,25 @@ cpumask_t cpuset_cpus_allowed(struct tas
return mask;
}
+/**
+ * cpuset_cpus_allowed_lock - return cpus_allowed mask from a tasks cpuset.
+ * @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
+ *
+ * Description: Same as cpuset_cpus_allowed, but called with callback_mutex
+ * already held.
+ **/
+
+cpumask_t cpuset_cpus_allowed_lock(struct task_struct *tsk)
+{
+ cpumask_t mask;
+
+ task_lock(tsk);
+ guarantee_online_cpus(tsk->cpuset, &mask);
+ task_unlock(tsk);
+
+ return mask;
+}
+
void cpuset_init_current_mems_allowed(void)
{
current->mems_allowed = NODE_MASK_ALL;
--
Cliff Wickman
Silicon Graphics, Inc.
cpw@sgi.com
(651) 683-3824
next reply other threads:[~2007-08-24 22:18 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-08-24 22:18 Cliff Wickman [this message]
2007-08-24 22:54 ` [PATCH 1/1] hotplug cpu: migrate a task within its cpuset Andrew Morton
2007-08-25 9:47 ` Oleg Nesterov
2007-08-26 0:16 ` Gautham R Shenoy
2007-08-26 0:47 ` Rusty Russell
2007-08-26 8:09 ` Andrew Morton
2007-08-27 7:01 ` Rusty Russell
2007-08-25 9:58 ` Oleg Nesterov
2007-08-25 11:18 ` Oleg Nesterov
-- strict thread matches above, loose matches on Subject: below --
2007-05-23 21:29 Oleg Nesterov
2007-05-23 22:56 ` Cliff Wickman
2007-05-23 23:32 ` Oleg Nesterov
2007-05-21 20:08 Cliff Wickman
2007-05-23 17:43 ` Andrew Morton
2007-05-24 7:56 ` Ingo Molnar
2007-05-29 19:32 ` Andrew Morton
2007-03-09 19:39 Cliff Wickman
2007-03-09 23:58 ` Nathan Lynch
2007-03-15 0:36 ` Robin Holt
2007-03-15 7:32 ` Nathan Lynch
2007-03-10 9:19 ` Ingo Molnar
2007-03-10 15:51 ` Nathan Lynch
2007-03-10 17:08 ` Ingo Molnar
2007-03-07 14:24 Cliff Wickman
2007-03-07 18:25 ` Randy Dunlap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070824221806.GA3602@sgi.com \
--to=cpw@sgi.com \
--cc=akpm@linux-foundation.org \
--cc=ego@in.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=oleg@tv-sign.ru \
--cc=pj@sgi.com \
--cc=vatsa@in.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox