lkml.org 
[lkml]   [2008]   [Apr]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH 1/3] stop_machine: short exit path for if we cannot create enough threads
stop_machine_run() invokes kthread 'kstopmachine' and the kthread
creates its children for every other cpus.

The current implementation migrates the child thread to its target
cpu as soon as it is created. It means that the children always
bother some of other cpus even if we cannot create enough threads.

This patch enable us to skip the migration of children if we
cannot have enough threads.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
---
kernel/stop_machine.c | 29 +++++++++++++++++++----------
1 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index 0101aee..5331ee5 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -20,6 +20,7 @@
/* Thread to stop each CPU in user context. */
enum stopmachine_state {
STOPMACHINE_WAIT,
+ STOPMACHINE_DEPLOY,
STOPMACHINE_PREPARE,
STOPMACHINE_DISABLE_IRQ,
STOPMACHINE_EXIT,
@@ -34,9 +35,16 @@ static int stopmachine(void *cpu)
int irqs_disabled = 0;
int prepared = 0;

+ /* Wait sisters */
+ while (stopmachine_state == STOPMACHINE_WAIT)
+ yield();
+ /* short path for cancel */
+ if (stopmachine_state == STOPMACHINE_EXIT)
+ goto exit;
+
set_cpus_allowed_ptr(current, &cpumask_of_cpu((int)(long)cpu));

- /* Ack: we are alive */
+ /* Ack: we arrived */
smp_mb(); /* Theoretically the ack = 0 might not be on this CPU yet. */
atomic_inc(&stopmachine_thread_ack);

@@ -65,7 +73,7 @@ static int stopmachine(void *cpu)
else
cpu_relax();
}
-
+exit:
/* Ack: we are exiting. */
smp_mb(); /* Must read state first. */
atomic_inc(&stopmachine_thread_ack);
@@ -101,20 +109,15 @@ static int stop_machine(void)
continue;
ret = kernel_thread(stopmachine, (void *)(long)i,CLONE_KERNEL);
if (ret < 0)
- break;
+ goto exit_threads;
stopmachine_num_threads++;
}

- /* Wait for them all to come to life. */
+ /* Wait for them all to come to life on the target. */
+ stopmachine_state = STOPMACHINE_DEPLOY;
while (atomic_read(&stopmachine_thread_ack) != stopmachine_num_threads)
yield();

- /* If some failed, kill them all. */
- if (ret < 0) {
- stopmachine_set_state(STOPMACHINE_EXIT);
- return ret;
- }
-
/* Now they are all started, make them hold the CPUs, ready. */
preempt_disable();
stopmachine_set_state(STOPMACHINE_PREPARE);
@@ -125,6 +128,12 @@ static int stop_machine(void)
stopmachine_set_state(STOPMACHINE_DISABLE_IRQ);

return 0;
+
+exit_threads:
+ /* Wait for them all to exit, since stop is canceled */
+ stopmachine_set_state(STOPMACHINE_EXIT);
+
+ return ret;
}

static void restart_machine(void)


\
 
 \ /
  Last update: 2008-04-29 03:33    [W:0.050 / U:0.032 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site