public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Dominik Brodowski <linux@dominikbrodowski.de>
To: linux-kernel@vger.kernel.org, rusty@rustcorp.com.au
Cc: Zwane Mwaikambo <zwane@linuxpower.ca>
Subject: [PATCH] [CPU-HOTPLUG] convert cpucontrol to be a rwsem
Date: Mon, 1 Nov 2004 09:43:37 +0100	[thread overview]
Message-ID: <20041101084337.GA7824@dominikbrodowski.de> (raw)

[CPU-HOTPLUG] Use a rw-semaphore for serializing and locking

Currently, lock_cpu_hotplug serializes multiple calls to cpufreq->target()
on multiple CPUs even though that's unneccessary. Even further, it
serializes these calls with totally unrelated other parts of the kernel...
some ppc64 event reporting, some cache management, and so on. In my opinion
locking should be done subsystem (and normally data-)specific, and disabling
CPU hotplug should just do that.

This patch converts the semaphore cpucontrol to be a rwsem which allows us 
to use it for _both_ variants: locking (write) and (multiple) other parts 
disabling CPU hotplug (read).

Only problem I see with this approach is that lock_cpu_hotplug_interruptible()
needs to disappear as there is no down_write_interruptible() for rw-semaphores.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.de>

 include/linux/cpu.h |   19 ++++++++++++++-----
 kernel/cpu.c        |   19 ++++++++-----------
 2 files changed, 22 insertions(+), 16 deletions(-)

diff -ruN linux-original/include/linux/cpu.h linux/include/linux/cpu.h
--- linux-original/include/linux/cpu.h	2004-10-29 17:16:59.000000000 +0200
+++ linux/include/linux/cpu.h	2004-11-01 08:57:07.000000000 +0100
@@ -59,10 +59,18 @@
 
 #ifdef CONFIG_HOTPLUG_CPU
 /* Stop CPUs going up and down. */
-extern struct semaphore cpucontrol;
-#define lock_cpu_hotplug()	down(&cpucontrol)
-#define unlock_cpu_hotplug()	up(&cpucontrol)
-#define lock_cpu_hotplug_interruptible() down_interruptible(&cpucontrol)
+extern struct rw_semaphore cpucontrol;
+/* these just disable CPU hotplug events but don't
+ * serialize following code */
+#define disable_cpu_hotplug()	down_read(&cpucontrol)
+#define enable_cpu_hotplug()	up_read(&cpucontrol)
+
+/* these disable CPU hotplug events _and_ serialize
+ * any following code.
+ */
+#define lock_cpu_hotplug()	down_write(&cpucontrol)
+#define unlock_cpu_hotplug()	up_write(&cpucontrol)
+
 #define hotcpu_notifier(fn, pri) {				\
 	static struct notifier_block fn##_nb =			\
 		{ .notifier_call = fn, .priority = pri };	\
@@ -71,9 +79,10 @@
 int cpu_down(unsigned int cpu);
 #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu))
 #else
+#define disable_cpu_hotplug()	do { } while (0)
+#define enable_cpu_hotplug()	do { } while (0)
 #define lock_cpu_hotplug()	do { } while (0)
 #define unlock_cpu_hotplug()	do { } while (0)
-#define lock_cpu_hotplug_interruptible() 0
 #define hotcpu_notifier(fn, pri)
 
 /* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */
diff -ruN linux-original/kernel/cpu.c linux/kernel/cpu.c
--- linux-original/kernel/cpu.c	2004-10-29 17:17:11.000000000 +0200
+++ linux/kernel/cpu.c	2004-11-01 09:00:22.000000000 +0100
@@ -17,7 +17,7 @@
 #include <asm/semaphore.h>
 
 /* This protects CPUs going up and down... */
-DECLARE_MUTEX(cpucontrol);
+DECLARE_RWSEM(cpucontrol);
 
 static struct notifier_block *cpu_chain;
 
@@ -26,19 +26,18 @@
 {
 	int ret;
 
-	if ((ret = down_interruptible(&cpucontrol)) != 0)
-		return ret;
+	down_write(&cpucontrol);
 	ret = notifier_chain_register(&cpu_chain, nb);
-	up(&cpucontrol);
+	up_write(&cpucontrol);
 	return ret;
 }
 EXPORT_SYMBOL(register_cpu_notifier);
 
 void unregister_cpu_notifier(struct notifier_block *nb)
 {
-	down(&cpucontrol);
+	down_write(&cpucontrol);
 	notifier_chain_unregister(&cpu_chain, nb);
-	up(&cpucontrol);
+	up_write(&cpucontrol);
 }
 EXPORT_SYMBOL(unregister_cpu_notifier);
 
@@ -81,8 +80,7 @@
 	struct task_struct *p;
 	cpumask_t old_allowed, tmp;
 
-	if ((err = lock_cpu_hotplug_interruptible()) != 0)
-		return err;
+	lock_cpu_hotplug();
 
 	if (num_online_cpus() == 1) {
 		err = -EBUSY;
@@ -156,8 +154,7 @@
 	int ret;
 	void *hcpu = (void *)(long)cpu;
 
-	if ((ret = down_interruptible(&cpucontrol)) != 0)
-		return ret;
+	down_write(&cpucontrol);
 
 	if (cpu_online(cpu) || !cpu_present(cpu)) {
 		ret = -EINVAL;
@@ -185,6 +182,6 @@
 	if (ret != 0)
 		notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu);
 out:
-	up(&cpucontrol);
+	up_write(&cpucontrol);
 	return ret;
 }

             reply	other threads:[~2004-11-01  8:44 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-11-01  8:43 Dominik Brodowski [this message]
2004-11-01  9:05 ` [PATCH] [CPU-HOTPLUG] convert cpucontrol to be a rwsem Nick Piggin
2004-11-01 14:00 ` Zwane Mwaikambo
2004-11-01 18:04   ` Lee Revell
2004-11-01 23:48     ` Rusty Russell
2004-11-02 14:54       ` Lee Revell
2004-11-02  0:16     ` Zwane Mwaikambo
2004-11-02 22:28   ` Dominik Brodowski
2004-11-04  1:57     ` Rusty Russell

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=20041101084337.GA7824@dominikbrodowski.de \
    --to=linux@dominikbrodowski.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rusty@rustcorp.com.au \
    --cc=zwane@linuxpower.ca \
    /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