From: Peter Zijlstra <a.p.zijlstra@chello.nl>
To: Linus Torvalds <torvalds@linux-foundation.org>,
Nick Piggin <npiggin@suse.de>, Jens Axboe <jens.axboe@oracle.com>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
Ingo Molnar <mingo@elte.hu>,
Rusty Russell <rusty@rustcorp.com.au>,
Steven Rostedt <rostedt@goodmis.org>
Cc: linux-kernel@vger.kernel.org, Oleg Nesterov <oleg@redhat.com>,
Peter Zijlstra <a.p.zijlstra@chello.nl>
Subject: [PATCH 4/4] generic-smp: clean up some of the csd->flags fiddling
Date: Mon, 16 Feb 2009 17:38:51 +0100 [thread overview]
Message-ID: <20090216164114.700407913@chello.nl> (raw)
In-Reply-To: 20090216163847.431174825@chello.nl
[-- Attachment #1: smp-cleanup.patch --]
[-- Type: text/plain, Size: 4672 bytes --]
Break out the WAIT and LOCK bit operations into functions and provide some
extra comments.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
kernel/smp.c | 100 +++++++++++++++++++++++++++++++++++------------------------
1 file changed, 60 insertions(+), 40 deletions(-)
Index: linux-2.6/kernel/smp.c
===================================================================
--- linux-2.6.orig/kernel/smp.c
+++ linux-2.6/kernel/smp.c
@@ -100,14 +100,50 @@ static int __cpuinit init_call_single_da
}
early_initcall(init_call_single_data);
-static void csd_flag_wait(struct call_single_data *data)
+/*
+ * csd_wait/csd_complete are used for synchronous ipi calls
+ */
+static void csd_wait_prepare(struct call_single_data *data)
+{
+ data->flags |= CSD_FLAG_WAIT;
+}
+
+static void csd_complete(struct call_single_data *data)
+{
+ /*
+ * Serialize stores to data with the flag clear and wakeup.
+ */
+ smp_wmb();
+ data->flags &= ~CSD_FLAG_WAIT;
+}
+
+static void csd_wait(struct call_single_data *data)
+{
+ while (data->flags & CSD_FLAG_WAIT)
+ cpu_relax();
+}
+
+/*
+ * csd_lock/csd_unlock used to serialize access to per-cpu csd resources
+ *
+ * For non-synchronous ipi calls the csd can still be in use by the previous
+ * function call. For multi-cpu calls its even more interesting as we'll have
+ * to ensure no other cpu is observing our csd.
+ */
+static void csd_lock(struct call_single_data *data)
{
- /* Wait for response */
- do {
- if (!(data->flags & CSD_FLAG_WAIT))
- break;
+ while (data->flags & CSD_FLAG_LOCK)
cpu_relax();
- } while (1);
+ data->flags = CSD_FLAG_LOCK;
+}
+
+static void csd_unlock(struct call_single_data *data)
+{
+ /*
+ * Serialize stores to data with the flags clear.
+ */
+ smp_wmb();
+ data->flags &= ~CSD_FLAG_LOCK;
}
/*
@@ -134,7 +170,7 @@ static void generic_exec_single(int cpu,
arch_send_call_function_single_ipi(cpu);
if (wait)
- csd_flag_wait(data);
+ csd_wait(data);
}
/*
@@ -172,18 +208,17 @@ void generic_smp_call_function_interrupt
spin_lock(&call_function.lock);
list_add(&data->free_list, &call_function.free_list);
list_del_rcu(&data->csd.list);
+ /*
+ * When the global queue is empty, its guaranteed that no cpu
+ * is still observing any entry on the free_list, therefore
+ * we can go ahead and unlock them.
+ */
if (!--call_function.counter)
list_splice_init(&call_function.free_list, &free_list);
spin_unlock(&call_function.lock);
- if (data->csd.flags & CSD_FLAG_WAIT) {
- /*
- * serialize stores to data with the flag clear
- * and wakeup
- */
- smp_wmb();
- data->csd.flags &= ~CSD_FLAG_WAIT;
- }
+ if (data->csd.flags & CSD_FLAG_WAIT)
+ csd_complete(&data->csd);
while (!list_empty(&free_list)) {
struct call_function_data *free;
@@ -192,12 +227,7 @@ void generic_smp_call_function_interrupt
struct call_function_data, free_list);
list_del(&data->free_list);
- /*
- * serialize stores to data with the flags
- * clear
- */
- smp_wmb();
- free->csd.flags &= ~CSD_FLAG_LOCK;
+ csd_unlock(&free->csd);
}
}
@@ -242,13 +272,10 @@ void generic_smp_call_function_single_in
data->func(data->info);
- if (data_flags & CSD_FLAG_WAIT) {
- smp_wmb();
- data->flags &= ~CSD_FLAG_WAIT;
- } else if (data_flags & CSD_FLAG_LOCK) {
- smp_wmb();
- data->flags &= ~CSD_FLAG_LOCK;
- }
+ if (data_flags & CSD_FLAG_WAIT)
+ csd_complete(data);
+ else if (data_flags & CSD_FLAG_LOCK)
+ csd_unlock(data);
}
/*
* See comment on outer loop
@@ -308,12 +335,10 @@ int smp_call_function_single(int cpu, vo
* data before a new caller will use it.
*/
data = &per_cpu(csd_data, me);
- while (data->flags & CSD_FLAG_LOCK)
- cpu_relax();
- data->flags = CSD_FLAG_LOCK;
+ csd_lock(data);
} else {
data = &d;
- data->flags = CSD_FLAG_WAIT;
+ csd_wait_prepare(data);
}
data->func = func;
@@ -398,16 +423,11 @@ void smp_call_function_many(const struct
}
data = &per_cpu(cfd_data, me);
- /*
- * We need to wait for all previous users to go away.
- */
- while (data->csd.flags & CSD_FLAG_LOCK)
- cpu_relax();
- data->csd.flags = CSD_FLAG_LOCK;
+ csd_lock(&data->csd);
spin_lock_init(&data->lock);
if (wait)
- data->csd.flags |= CSD_FLAG_WAIT;
+ csd_wait_prepare(&data->csd);
data->csd.func = func;
data->csd.info = info;
cpumask_and(data->cpumask, mask, cpu_online_mask);
@@ -429,7 +449,7 @@ void smp_call_function_many(const struct
/* optionally wait for the CPUs to complete */
if (wait)
- csd_flag_wait(&data->csd);
+ csd_wait(&data->csd);
}
EXPORT_SYMBOL(smp_call_function_many);
--
prev parent reply other threads:[~2009-02-16 16:42 UTC|newest]
Thread overview: 101+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-16 16:38 [PATCH 0/4] generic smp helpers vs kmalloc Peter Zijlstra
2009-02-16 16:38 ` [PATCH 1/4] generic-smp: remove single ipi fallback for smp_call_function_many() Peter Zijlstra
2009-02-16 19:10 ` Oleg Nesterov
2009-02-16 19:41 ` Peter Zijlstra
2009-02-16 20:30 ` Oleg Nesterov
2009-02-16 20:55 ` Peter Zijlstra
2009-02-16 21:22 ` Oleg Nesterov
2009-02-17 12:25 ` Oleg Nesterov
2009-02-16 20:49 ` Q: smp.c && barriers (Was: [PATCH 1/4] generic-smp: remove single ipi fallback for smp_call_function_many()) Oleg Nesterov
2009-02-16 21:03 ` Peter Zijlstra
2009-02-16 21:32 ` Oleg Nesterov
2009-02-16 21:45 ` Peter Zijlstra
2009-02-16 22:02 ` Oleg Nesterov
2009-02-16 22:24 ` Peter Zijlstra
2009-02-16 23:19 ` Oleg Nesterov
2009-02-17 9:29 ` Peter Zijlstra
2009-02-17 10:11 ` Nick Piggin
2009-02-17 10:27 ` Peter Zijlstra
2009-02-17 10:39 ` Nick Piggin
2009-02-17 11:26 ` Nick Piggin
2009-02-17 11:48 ` Peter Zijlstra
2009-02-17 15:51 ` Paul E. McKenney
2009-02-18 2:15 ` Suresh Siddha
2009-02-18 2:40 ` Paul E. McKenney
2009-02-17 19:28 ` Q: " Oleg Nesterov
2009-02-17 21:32 ` Paul E. McKenney
2009-02-17 21:45 ` Oleg Nesterov
2009-02-17 22:39 ` Paul E. McKenney
2009-02-18 13:52 ` Nick Piggin
2009-02-18 16:09 ` Linus Torvalds
2009-02-18 16:21 ` Ingo Molnar
2009-02-18 16:33 ` Linus Torvalds
2009-02-18 16:58 ` Ingo Molnar
2009-02-18 17:05 ` Ingo Molnar
2009-02-18 17:10 ` Ingo Molnar
2009-02-18 17:17 ` Linus Torvalds
2009-02-18 17:23 ` Ingo Molnar
2009-02-18 17:14 ` Linus Torvalds
2009-02-18 17:47 ` Ingo Molnar
2009-02-18 18:33 ` Suresh Siddha
2009-02-18 16:37 ` Gleb Natapov
2009-02-19 0:12 ` Nick Piggin
2009-02-19 6:47 ` Benjamin Herrenschmidt
2009-02-19 13:11 ` Nick Piggin
2009-02-19 15:06 ` Ingo Molnar
2009-02-19 21:49 ` Benjamin Herrenschmidt
2009-02-18 2:21 ` Suresh Siddha
2009-02-18 13:59 ` Nick Piggin
2009-02-18 16:19 ` Linus Torvalds
2009-02-18 16:23 ` Ingo Molnar
2009-02-18 18:43 ` Suresh Siddha
2009-02-18 19:17 ` Ingo Molnar
2009-02-18 23:55 ` Suresh Siddha
2009-02-19 12:20 ` Ingo Molnar
2009-02-19 12:29 ` Nick Piggin
2009-02-19 12:45 ` Ingo Molnar
2009-02-19 22:00 ` Suresh Siddha
2009-02-20 10:56 ` Ingo Molnar
2009-02-20 18:56 ` Suresh Siddha
2009-02-20 19:40 ` Ingo Molnar
2009-02-20 23:28 ` Jack Steiner
2009-02-25 3:32 ` Nick Piggin
2009-02-25 12:47 ` Ingo Molnar
2009-02-25 18:25 ` Luck, Tony
2009-03-17 18:16 ` Suresh Siddha
2009-03-18 8:51 ` [tip:x86/x2apic] x86: add x2apic_wrmsr_fence() to x2apic flush tlb paths Suresh Siddha
2009-02-17 12:40 ` Q: smp.c && barriers (Was: [PATCH 1/4] generic-smp: remove single ipi fallback for smp_call_function_many()) Peter Zijlstra
2009-02-17 15:43 ` Paul E. McKenney
2009-02-17 15:40 ` [PATCH] generic-smp: remove kmalloc() Peter Zijlstra
2009-02-17 17:21 ` Oleg Nesterov
2009-02-17 17:40 ` Peter Zijlstra
2009-02-17 17:46 ` Peter Zijlstra
2009-02-17 18:30 ` Oleg Nesterov
2009-02-17 19:29 ` [PATCH -v4] generic-ipi: " Peter Zijlstra
2009-02-17 20:02 ` Oleg Nesterov
2009-02-17 20:11 ` Peter Zijlstra
2009-02-17 20:16 ` Peter Zijlstra
2009-02-17 20:44 ` Oleg Nesterov
2009-02-17 20:49 ` Peter Zijlstra
2009-02-17 22:09 ` Oleg Nesterov
2009-02-17 22:15 ` Peter Zijlstra
2009-02-17 21:30 ` Paul E. McKenney
2009-02-17 21:38 ` Peter Zijlstra
2009-02-16 16:38 ` [PATCH 2/4] generic-smp: remove kmalloc usage Peter Zijlstra
2009-02-17 0:40 ` Linus Torvalds
2009-02-17 8:24 ` Peter Zijlstra
2009-02-17 9:43 ` Ingo Molnar
2009-02-17 9:49 ` Peter Zijlstra
2009-02-17 10:56 ` Ingo Molnar
2009-02-18 4:50 ` Rusty Russell
2009-02-18 16:05 ` Ingo Molnar
2009-02-19 0:00 ` Jeremy Fitzhardinge
2009-02-19 12:21 ` Ingo Molnar
2009-02-19 4:31 ` Rusty Russell
2009-02-19 9:10 ` Peter Zijlstra
2009-02-19 11:04 ` Jens Axboe
2009-02-19 16:52 ` Linus Torvalds
2009-02-17 15:44 ` Linus Torvalds
2009-02-16 16:38 ` [PATCH 3/4] generic-smp: properly allocate the cpumasks Peter Zijlstra
2009-02-16 23:17 ` Rusty Russell
2009-02-16 16:38 ` Peter Zijlstra [this message]
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=20090216164114.700407913@chello.nl \
--to=a.p.zijlstra@chello.nl \
--cc=jens.axboe@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=npiggin@suse.de \
--cc=oleg@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=rostedt@goodmis.org \
--cc=rusty@rustcorp.com.au \
--cc=torvalds@linux-foundation.org \
/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;
as well as URLs for NNTP newsgroup(s).