From: Lai Jiangshan <laijs@cn.fujitsu.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>,
Ingo Molnar <mingo@elte.hu>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
LKML <linux-kernel@vger.kernel.org>
Subject: [PATCH 1/2] cpuhotplug: use rw_semaphore for cpu_hotplug
Date: Fri, 29 May 2009 16:29:30 +0800 [thread overview]
Message-ID: <4A1F9CEA.1070705@cn.fujitsu.com> (raw)
Current get_online_cpus()/put_online_cpus() re-implement
a rw_semaphore, so it is converted to a real rw_semaphore in this fix.
It simplifies codes, and is good for read.
And misc fix:
1) Add comments for cpu_hotplug.active_writer.
2) The theoretical disadvantage described in cpu_hotplug_begin()'s
comments is no longer existed when we use rw_semaphore,
so this part of comments was removed.
[Impact: improve get_online_cpus()/put_online_cpus() ]
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 395b697..62198ec 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -14,6 +14,7 @@
#include <linux/kthread.h>
#include <linux/stop_machine.h>
#include <linux/mutex.h>
+#include <linux/rwsem.h>
#ifdef CONFIG_SMP
/* Serializes the updates to cpu_online_mask, cpu_present_mask */
@@ -27,20 +28,21 @@ static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
static int cpu_hotplug_disabled;
static struct {
- struct task_struct *active_writer;
- struct mutex lock; /* Synchronizes accesses to refcount, */
/*
- * Also blocks the new readers during
- * an ongoing cpu hotplug operation.
+ * active_writer makes get_online_cpus()/put_online_cpus() are allowd
+ * to be nested in cpu_hotplug_begin()/cpu_hotplug_done().
+ *
+ * Thus, get_online_cpus()/put_online_cpus() can be called in
+ * CPU notifiers.
*/
- int refcount;
+ struct task_struct *active_writer;
+ struct rw_semaphore rwlock;
} cpu_hotplug;
void __init cpu_hotplug_init(void)
{
cpu_hotplug.active_writer = NULL;
- mutex_init(&cpu_hotplug.lock);
- cpu_hotplug.refcount = 0;
+ init_rwsem(&cpu_hotplug.rwlock);
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -50,9 +52,7 @@ void get_online_cpus(void)
might_sleep();
if (cpu_hotplug.active_writer == current)
return;
- mutex_lock(&cpu_hotplug.lock);
- cpu_hotplug.refcount++;
- mutex_unlock(&cpu_hotplug.lock);
+ down_read(&cpu_hotplug.rwlock);
}
EXPORT_SYMBOL_GPL(get_online_cpus);
@@ -61,10 +61,7 @@ void put_online_cpus(void)
{
if (cpu_hotplug.active_writer == current)
return;
- mutex_lock(&cpu_hotplug.lock);
- if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
- wake_up_process(cpu_hotplug.active_writer);
- mutex_unlock(&cpu_hotplug.lock);
+ up_read(&cpu_hotplug.rwlock);
}
EXPORT_SYMBOL_GPL(put_online_cpus);
@@ -86,45 +83,25 @@ void cpu_maps_update_done(void)
}
/*
- * This ensures that the hotplug operation can begin only when the
- * refcount goes to zero.
+ * This ensures that the hotplug operation can begin only when
+ * there is no reader.
*
* Note that during a cpu-hotplug operation, the new readers, if any,
- * will be blocked by the cpu_hotplug.lock
+ * will be blocked by the cpu_hotplug.rwlock
*
* Since cpu_hotplug_begin() is always called after invoking
* cpu_maps_update_begin(), we can be sure that only one writer is active.
- *
- * Note that theoretically, there is a possibility of a livelock:
- * - Refcount goes to zero, last reader wakes up the sleeping
- * writer.
- * - Last reader unlocks the cpu_hotplug.lock.
- * - A new reader arrives at this moment, bumps up the refcount.
- * - The writer acquires the cpu_hotplug.lock finds the refcount
- * non zero and goes to sleep again.
- *
- * However, this is very difficult to achieve in practice since
- * get_online_cpus() not an api which is called all that often.
- *
*/
static void cpu_hotplug_begin(void)
{
+ down_write(&cpu_hotplug.rwlock);
cpu_hotplug.active_writer = current;
-
- for (;;) {
- mutex_lock(&cpu_hotplug.lock);
- if (likely(!cpu_hotplug.refcount))
- break;
- __set_current_state(TASK_UNINTERRUPTIBLE);
- mutex_unlock(&cpu_hotplug.lock);
- schedule();
- }
}
static void cpu_hotplug_done(void)
{
cpu_hotplug.active_writer = NULL;
- mutex_unlock(&cpu_hotplug.lock);
+ up_write(&cpu_hotplug.rwlock);
}
/* Need to know about CPUs going up/down? */
int __ref register_cpu_notifier(struct notifier_block *nb)
next reply other threads:[~2009-05-29 8:33 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-29 8:29 Lai Jiangshan [this message]
2009-05-29 20:23 ` [PATCH 1/2] cpuhotplug: use rw_semaphore for cpu_hotplug Andrew Morton
2009-05-29 21:07 ` Oleg Nesterov
2009-05-29 21:17 ` Oleg Nesterov
2009-06-01 1:04 ` Lai Jiangshan
2009-06-01 0:52 ` Lai Jiangshan
2009-06-01 2:22 ` Lai Jiangshan
2009-05-30 1:53 ` Paul E. McKenney
2009-05-30 4:37 ` Gautham R Shenoy
2009-06-04 6:58 ` [PATCH] cpuhotplug: introduce try_get_online_cpus() take 2 Lai Jiangshan
2009-06-04 20:49 ` Oleg Nesterov
2009-06-05 1:32 ` Lai Jiangshan
2009-06-05 2:14 ` Oleg Nesterov
2009-06-05 15:37 ` Paul E. McKenney
2009-06-08 2:36 ` Lai Jiangshan
2009-06-08 4:19 ` Gautham R Shenoy
2009-06-08 14:25 ` Paul E. McKenney
2009-06-09 12:07 ` [PATCH -mm] cpuhotplug: introduce try_get_online_cpus() take 3 Lai Jiangshan
2009-06-09 19:34 ` Andrew Morton
2009-06-09 23:47 ` Paul E. McKenney
2009-06-10 1:13 ` [PATCH -mm resend] " Lai Jiangshan
2009-06-10 1:42 ` Andrew Morton
2009-06-11 8:41 ` Lai Jiangshan
2009-06-11 18:50 ` Paul E. McKenney
2009-06-15 4:04 ` Gautham R Shenoy
2009-06-10 0:57 ` [PATCH -mm] " Lai Jiangshan
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=4A1F9CEA.1070705@cn.fujitsu.com \
--to=laijs@cn.fujitsu.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=paulmck@linux.vnet.ibm.com \
--cc=rusty@rustcorp.com.au \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.