From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Oleg Nesterov <oleg@redhat.com>,
Jens Axboe <jens.axboe@oracle.com>,
Suresh Siddha <suresh.b.siddha@intel.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
Nick Piggin <npiggin@suse.de>, Ingo Molnar <mingo@elte.hu>,
Rusty Russell <rusty@rustcorp.com.au>,
Steven Rostedt <rostedt@goodmis.org>,
linux-kernel@vger.kernel.org
Subject: Re: Q: smp.c && barriers (Was: [PATCH 1/4] generic-smp: remove single ipi fallback for smp_call_function_many())
Date: Tue, 17 Feb 2009 07:43:45 -0800 [thread overview]
Message-ID: <20090217154345.GD6761@linux.vnet.ibm.com> (raw)
In-Reply-To: <1234862974.4744.31.camel@laptop>
On Tue, Feb 17, 2009 at 10:29:34AM +0100, Peter Zijlstra wrote:
> On Tue, 2009-02-17 at 00:19 +0100, Oleg Nesterov wrote:
> > On 02/16, Peter Zijlstra wrote:
> > >
> > > On Mon, 2009-02-16 at 23:02 +0100, Oleg Nesterov wrote:
> > > > On 02/16, Peter Zijlstra wrote:
> > > > >
> > > > > On Mon, 2009-02-16 at 22:32 +0100, Oleg Nesterov wrote:
> > > > > > > I was about to write a response, but found it to be a justification for
> > > > > > > the read_barrier_depends() at the end of the loop.
> > > > > >
> > > > > > I forgot to mention I don't understand the read_barrier_depends() at the
> > > > > > end of the loop as well ;)
> > > > >
> > > > > Suppose cpu0 adds to csd to cpu1:
> > > > >
> > > > >
> > > > > cpu0: cpu1:
> > > > >
> > > > > add entry1
> > > > > mb();
> > > > > send ipi
> > > > > run ipi handler
> > > > > read_barrier_depends()
> > > > > while (!list_empty()) [A]
> > > > > do foo
> > > > >
> > > > > add entry2
> > > > > mb();
> > > > > [no ipi -- we still observe entry1]
> > > > >
> > > > > remove foo
> > > > > read_barrier_depends()
> > > > > while (!list_empty()) [B]
> > > >
> > > > Still can't understand.
> > > >
> > > > cpu1 (generic_smp_call_function_single_interrupt) does
> > > > list_replace_init(q->lock), this lock is also taken by
> > > > generic_exec_single().
> > > >
> > > > Either cpu1 sees entry2 on list, or cpu0 sees list_empty()
> > > > and sends ipi.
> > >
> > > cpu0: cpu1:
> > >
> > > spin_lock_irqsave(&dst->lock, flags);
> > > ipi = list_empty(&dst->list);
> > > list_add_tail(&data->list, &dst->list);
> > > spin_unlock_irqrestore(&dst->lock, flags);
> > >
> > > ipi ----->
> > >
> > > while (!list_empty(&q->list)) {
> > > unsigned int data_flags;
> > >
> > > spin_lock(&q->lock);
> > > list_replace_init(&q->list, &list);
> > > spin_unlock(&q->lock);
> > >
> > >
> > > Strictly speaking the unlock() is semi-permeable, allowing the read of
> > > q->list to enter the critical section, allowing us to observe an empty
> > > list, never getting to q->lock on cpu1.
> >
> > Hmm. If we take &q->lock, then we alread saw !list_empty() ?
>
> That's how I read the above code.
>
> > And the question is, how can we miss list_empty() == F before spin_lock().
>
> Confusion... my explanation above covers exactly this case. The reads
> determining list_empty() can slip into the q->lock section on the other
> cpu, and observe an empty list.
>
> > > > Even if I missed something (very possible), then I can't understand
> > > > why we need rmb() only on alpha.
> > >
> > > Because only alpha is insane enough to do speculative reads? Dunno
> > > really :-)
> >
> > Perhaps...
> >
> > It would be nice to have a comment which explains how can we miss the
> > first addition without read_barrier_depends(). And why only on alpha.
>
> Paul, care to once again enlighten us? The best I can remember is that
> alpha has split caches, and the rmb is needed for them to become
> coherent -- no other arch is crazy in exactly that way.
Many architectures use split caches, but Alpha made them independent. :-/
Suppose that an Alpha system has a cache for each CPU, and that each CPU's
cache is split into banks so that even-numbered cache lines are placed
in one bank and odd-numbered cache lines in the other. Then suppose
that CPU 0 executes the following code:
p = malloc(sizeof(*p));
if (p == NULL)
deal_with_it();
p->a = 42;
smp_wmb(); /* this line and next same as rcu_assign_pointer(). */
global_p = p;
This code will ensure that CPU 0 will commit the assignment to p->a to
coherent memory before commiting the assignment to global_p.
Suppose further that global_p is located in an even-numbered cache line
and that the newly allocated structure pointed to by p is in an
odd-numbered cache line. Then suppose that CPU 1 executes the following
code:
q = global_p;
t = q->a;
Now, CPU 0 "published" the assignment to ->a before that to global_p,
but suppose that CPU 1's odd-numbered cache bank is very busy, so that
it has not yet processed the invalidation request corresponding to
CPU 0's assignment to p->a.
In this case, CPU 1 will see the new value of global_p, but the old
value of q->a.
This same result can be caused by certain types of value-speculation
compiler optimizations.
For more information, see:
http://www.rdrop.com/users/paulmck/scalability/paper/ordering.2007.09.19a.pdf
> But note that read_barrier_depends() is not quite a NOP for !alpha, it
> does that ACCESS_ONCE() thing, which very much makes a difference, even
> on x86.
You are thinking of rcu_dereference() rather than read_barrier_depends(),
right?
> > And arch/alpha/kernel/smp.c:handle_ipi() does mb() itself...
>
> Right, but arguing by our memory model, we cannot assume that.
I assert that things like smp_call_function() need to perform whatever
memory barriers are required to ensure that the called function sees
any memory references performed on the originating CPU prior to the
smp_call_function().
Thanx, Paul
next prev parent reply other threads:[~2009-02-17 15:44 UTC|newest]
Thread overview: 103+ 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:21 ` Ingo Molnar
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 [this message]
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 ` [PATCH 4/4] generic-smp: clean up some of the csd->flags fiddling Peter Zijlstra
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=20090217154345.GD6761@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=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=rostedt@goodmis.org \
--cc=rusty@rustcorp.com.au \
--cc=suresh.b.siddha@intel.com \
--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 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.