Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1223878 > unrolled thread

[PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics

Started byDavidlohr Bueso <dave@stgolabs.net>
First post2015-09-14 09:40 +0200
Last post2015-09-16 11:10 +0200
Articles 16 — 4 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Davidlohr Bueso <dave@stgolabs.net> - 2015-09-14 09:40 +0200
    Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Peter Zijlstra <peterz@infradead.org> - 2015-09-14 14:40 +0200
      Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Davidlohr Bueso <dave@stgolabs.net> - 2015-09-14 23:10 +0200
        Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Peter Zijlstra <peterz@infradead.org> - 2015-09-15 12:00 +0200
          Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Peter Zijlstra <peterz@infradead.org> - 2015-09-15 12:00 +0200
            Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Peter Zijlstra <peterz@infradead.org> - 2015-09-15 14:50 +0200
              Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2015-09-15 16:20 +0200
                Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Peter Zijlstra <peterz@infradead.org> - 2015-09-15 16:20 +0200
                  Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2015-09-15 17:40 +0200
                    Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Peter Zijlstra <peterz@infradead.org> - 2015-09-15 18:40 +0200
                      Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2015-09-15 19:10 +0200
                        Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2015-09-18 23:50 +0200
                          Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Martin Schwidefsky <schwidefsky@de.ibm.com> - 2015-09-21 11:30 +0200
            Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2015-09-15 14:50 +0200
            Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Davidlohr Bueso <dave@stgolabs.net> - 2015-09-15 22:00 +0200
              Re: [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics Peter Zijlstra <peterz@infradead.org> - 2015-09-16 11:10 +0200

#1223878 — [PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics

FromDavidlohr Bueso <dave@stgolabs.net>
Date2015-09-14 09:40 +0200
Subject[PATCH -tip 2/3] sched/wake_q: Relax to acquire semantics
Message-ID<q8wwO-7Ze-5@gated-at.bofh.it>
The barrier parings for wake-queues are very straightforward, and thus
we can ease the barrier requirements, for archs that support it, for
wake_q_add by relying on acquire semantics. As such, (i) we keep the
pairing structure/logic and (ii) users, such as mqueues, can continue to
rely on a full barrier after the successful [Rmw].

[Another alternative could be to just not try at all and fully downgrade
to cmpxchg_relaxed() and rely on users to enable their own synchronization.
But controlling this ourselves makes me sleep better at night.]

Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
---
 kernel/sched/core.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 6ab415a..7567603 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -523,14 +523,14 @@ void wake_q_add(struct wake_q_head *head, struct task_struct *task)
 	struct wake_q_node *node = &task->wake_q;
 
 	/*
-	 * Atomically grab the task, if ->wake_q is !nil already it means
-	 * its already queued (either by us or someone else) and will get the
-	 * wakeup due to that.
+	 * Atomically grab the task. If ->wake_q is non-nil (failed cmpxchg)
+	 * then the task is already queued (by us or someone else) and will
+	 * get the wakeup due to that.
 	 *
-	 * This cmpxchg() implies a full barrier, which pairs with the write
-	 * barrier implied by the wakeup in wake_up_list().
+	 * Use acquire semantics to add the next pointer, which pairs with the
+	 * write barrier implied by the wakeup in wake_up_list().
 	 */
-	if (cmpxchg(&node->next, NULL, WAKE_Q_TAIL))
+	if (cmpxchg_acquire(&node->next, NULL, WAKE_Q_TAIL))
 		return;
 
 	get_task_struct(task);
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1224098

FromPeter Zijlstra <peterz@infradead.org>
Date2015-09-14 14:40 +0200
Message-ID<q8Bd8-6hL-21@gated-at.bofh.it>
In reply to#1223878
On Mon, Sep 14, 2015 at 12:37:23AM -0700, Davidlohr Bueso wrote:
> The barrier parings for wake-queues are very straightforward, and thus
> we can ease the barrier requirements, for archs that support it, for
> wake_q_add by relying on acquire semantics. As such, (i) we keep the
> pairing structure/logic and (ii) users, such as mqueues, can continue to
> rely on a full barrier after the successful [Rmw].

> Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
> ---
>  kernel/sched/core.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 6ab415a..7567603 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -523,14 +523,14 @@ void wake_q_add(struct wake_q_head *head, struct task_struct *task)
>  	struct wake_q_node *node = &task->wake_q;
>  
>  	/*
> +	 * Atomically grab the task. If ->wake_q is non-nil (failed cmpxchg)
> +	 * then the task is already queued (by us or someone else) and will
> +	 * get the wakeup due to that.
>  	 *
> +	 * Use acquire semantics to add the next pointer, which pairs with the
> +	 * write barrier implied by the wakeup in wake_up_list().
>  	 */
> +	if (cmpxchg_acquire(&node->next, NULL, WAKE_Q_TAIL))
>  		return;
>  
>  	get_task_struct(task);

I'm not seeing a _why_ on the acquire semantics. Not saying the patch is
wrong, just saying I want words on why acquire is correct.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1224450

FromDavidlohr Bueso <dave@stgolabs.net>
Date2015-09-14 23:10 +0200
Message-ID<q8JaF-12P-7@gated-at.bofh.it>
In reply to#1224098
On Mon, 14 Sep 2015, Peter Zijlstra wrote:

>On Mon, Sep 14, 2015 at 12:37:23AM -0700, Davidlohr Bueso wrote:
>>	/*
>> +	 * Atomically grab the task. If ->wake_q is non-nil (failed cmpxchg)
>> +	 * then the task is already queued (by us or someone else) and will
>> +	 * get the wakeup due to that.
>>	 *
>> +	 * Use acquire semantics to add the next pointer, which pairs with the
>> +	 * write barrier implied by the wakeup in wake_up_list().
>>	 */
>> +	if (cmpxchg_acquire(&node->next, NULL, WAKE_Q_TAIL))
>>		return;
>>
>>	get_task_struct(task);
>
>I'm not seeing a _why_ on the acquire semantics. Not saying the patch is
>wrong, just saying I want words on why acquire is correct.

Well, I was just taking advantage of removing the upper barrier. Considering
that the formal semantics, you are right that we need not actual acquire per-se
(ie for node->next) but instead merely ensure a barrier in wake_q_add(). This is
kind of why I had hinted of going full _relaxed(). We could also rephrase the
comment, something like:

      * Use ACQUIRE semantics to add the next pointer, such that
      * wake_q_add() implies a full barrier. This pairs with the
      * write barrier implied by the wakeup in wake_up_list().
      */

What do you think?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1224951

FromPeter Zijlstra <peterz@infradead.org>
Date2015-09-15 12:00 +0200
Message-ID<q8VbQ-1dV-15@gated-at.bofh.it>
In reply to#1224450
On Mon, Sep 14, 2015 at 02:08:06PM -0700, Davidlohr Bueso wrote:
> On Mon, 14 Sep 2015, Peter Zijlstra wrote:
> 
> >On Mon, Sep 14, 2015 at 12:37:23AM -0700, Davidlohr Bueso wrote:
> >>	/*
> >>+	 * Atomically grab the task. If ->wake_q is non-nil (failed cmpxchg)
> >>+	 * then the task is already queued (by us or someone else) and will
> >>+	 * get the wakeup due to that.
> >>	 *
> >>+	 * Use acquire semantics to add the next pointer, which pairs with the
> >>+	 * write barrier implied by the wakeup in wake_up_list().
> >>	 */
> >>+	if (cmpxchg_acquire(&node->next, NULL, WAKE_Q_TAIL))
> >>		return;
> >>
> >>	get_task_struct(task);
> >
> >I'm not seeing a _why_ on the acquire semantics. Not saying the patch is
> >wrong, just saying I want words on why acquire is correct.
>
> Well, I was just taking advantage of removing the upper barrier. Considering
> that the formal semantics, you are right that we need not actual acquire per-se
> (ie for node->next) but instead merely ensure a barrier in wake_q_add(). This is
> kind of why I had hinted of going full _relaxed(). We could also rephrase the
> comment, something like:
>
>      * Use ACQUIRE semantics to add the next pointer, such that
>      * wake_q_add() implies a full barrier. This pairs with the
>      * write barrier implied by the wakeup in wake_up_list().
>      */
>
> What do you think?

Still befuddled. I'm thinking that if you want to remove a barrier,
you'd remove that second and keep the first. That is RELEASE.

That way, you know the stores prior to the wake queue are done by the
time you observe the queued entry, and therefore (transitively) know
those stores are done by the time you do the actual wakeup.

Two issues with that though; firstly RELEASE is not actually guaranteed
to be transitive -- now the only arch that does not implement it with a
full barrier is ARGH64, so we could just ask Will, but I'm not sure its
'good' to start relying on this.

Secondly, the wake queues are not concurrent, they're in context, so I
don't see ordering matter at all. The only reason its a cmpxchg() is
because there is the (small) possibility of two contexts wanting to wake
the same task, and we use task_struct storage for the queue.

Or am I mistaken and do we have concurrent users of wake queues?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1224954

FromPeter Zijlstra <peterz@infradead.org>
Date2015-09-15 12:00 +0200
Message-ID<q8VbR-1dV-31@gated-at.bofh.it>
In reply to#1224951
On Tue, Sep 15, 2015 at 11:49:49AM +0200, Peter Zijlstra wrote:
> On Mon, Sep 14, 2015 at 02:08:06PM -0700, Davidlohr Bueso wrote:
> > On Mon, 14 Sep 2015, Peter Zijlstra wrote:
> > 
> > >On Mon, Sep 14, 2015 at 12:37:23AM -0700, Davidlohr Bueso wrote:
> > >>	/*
> > >>+	 * Atomically grab the task. If ->wake_q is non-nil (failed cmpxchg)
> > >>+	 * then the task is already queued (by us or someone else) and will
> > >>+	 * get the wakeup due to that.
> > >>	 *
> > >>+	 * Use acquire semantics to add the next pointer, which pairs with the
> > >>+	 * write barrier implied by the wakeup in wake_up_list().
> > >>	 */
> > >>+	if (cmpxchg_acquire(&node->next, NULL, WAKE_Q_TAIL))
> > >>		return;
> > >>
> > >>	get_task_struct(task);
> > >
> > >I'm not seeing a _why_ on the acquire semantics. Not saying the patch is
> > >wrong, just saying I want words on why acquire is correct.
> >
> > Well, I was just taking advantage of removing the upper barrier. Considering
> > that the formal semantics, you are right that we need not actual acquire per-se
> > (ie for node->next) but instead merely ensure a barrier in wake_q_add(). This is
> > kind of why I had hinted of going full _relaxed(). We could also rephrase the
> > comment, something like:
> >
> >      * Use ACQUIRE semantics to add the next pointer, such that
> >      * wake_q_add() implies a full barrier. This pairs with the
> >      * write barrier implied by the wakeup in wake_up_list().
> >      */
> >
> > What do you think?
> 
> Still befuddled. I'm thinking that if you want to remove a barrier,
> you'd remove that second and keep the first. That is RELEASE.
> 
> That way, you know the stores prior to the wake queue are done by the
> time you observe the queued entry, and therefore (transitively) know
> those stores are done by the time you do the actual wakeup.
> 
> Two issues with that though; firstly RELEASE is not actually guaranteed
> to be transitive -- now the only arch that does not implement it with a
> full barrier is ARGH64, so we could just ask Will, but I'm not sure its
> 'good' to start relying on this.

Never mind, the PPC people will implement this with lwsync and that is
very much not transitive IIRC.

That said, you could do:

	smp_mb__before_atomic();
	cmpxchg_relaxed();

Which would still be a full barrier and therefore transitive. However
this point still stands:

> Secondly, the wake queues are not concurrent, they're in context, so I
> don't see ordering matter at all. The only reason its a cmpxchg() is
> because there is the (small) possibility of two contexts wanting to wake
> the same task, and we use task_struct storage for the queue.

I don't think we need _any_ barriers here, unless we have concurrent
users of the wake queues (or want to allow any, do we?).
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225046

FromPeter Zijlstra <peterz@infradead.org>
Date2015-09-15 14:50 +0200
Message-ID<q8XQm-55E-27@gated-at.bofh.it>
In reply to#1224954
On Tue, Sep 15, 2015 at 05:41:42AM -0700, Paul E. McKenney wrote:
> > Never mind, the PPC people will implement this with lwsync and that is
> > very much not transitive IIRC.
> 
> I am probably lost on context, but...
> 
> It turns out that lwsync is transitive in special cases.  One of them
> is a series of release-acquire pairs, which can extend indefinitely.
> 
> Does that help in this case?

Probably not, but good to know. I still don't think we want to rely on
ACQUIRE/RELEASE being transitive in general though.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225159

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2015-09-15 16:20 +0200
Message-ID<q8Zfr-7ex-11@gated-at.bofh.it>
In reply to#1225046
On Tue, Sep 15, 2015 at 02:48:00PM +0200, Peter Zijlstra wrote:
> On Tue, Sep 15, 2015 at 05:41:42AM -0700, Paul E. McKenney wrote:
> > > Never mind, the PPC people will implement this with lwsync and that is
> > > very much not transitive IIRC.
> > 
> > I am probably lost on context, but...
> > 
> > It turns out that lwsync is transitive in special cases.  One of them
> > is a series of release-acquire pairs, which can extend indefinitely.
> > 
> > Does that help in this case?
> 
> Probably not, but good to know. I still don't think we want to rely on
> ACQUIRE/RELEASE being transitive in general though.

OK, I will bite...  Why not?

							Thanx, Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225165

FromPeter Zijlstra <peterz@infradead.org>
Date2015-09-15 16:20 +0200
Message-ID<q8Zfs-7ex-25@gated-at.bofh.it>
In reply to#1225159
On Tue, Sep 15, 2015 at 07:09:22AM -0700, Paul E. McKenney wrote:
> On Tue, Sep 15, 2015 at 02:48:00PM +0200, Peter Zijlstra wrote:
> > On Tue, Sep 15, 2015 at 05:41:42AM -0700, Paul E. McKenney wrote:
> > > > Never mind, the PPC people will implement this with lwsync and that is
> > > > very much not transitive IIRC.
> > > 
> > > I am probably lost on context, but...
> > > 
> > > It turns out that lwsync is transitive in special cases.  One of them
> > > is a series of release-acquire pairs, which can extend indefinitely.
> > > 
> > > Does that help in this case?
> > 
> > Probably not, but good to know. I still don't think we want to rely on
> > ACQUIRE/RELEASE being transitive in general though.
> 
> OK, I will bite...  Why not?

It would mean us reviewing all archs (again) and documenting it I
suppose. Which is of course entirely possible.

That said, I don't think the case at hand requires it, so lets postpone
this for now ;-)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225322

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2015-09-15 17:40 +0200
Message-ID<q90uS-xv-15@gated-at.bofh.it>
In reply to#1225165
On Tue, Sep 15, 2015 at 04:14:39PM +0200, Peter Zijlstra wrote:
> On Tue, Sep 15, 2015 at 07:09:22AM -0700, Paul E. McKenney wrote:
> > On Tue, Sep 15, 2015 at 02:48:00PM +0200, Peter Zijlstra wrote:
> > > On Tue, Sep 15, 2015 at 05:41:42AM -0700, Paul E. McKenney wrote:
> > > > > Never mind, the PPC people will implement this with lwsync and that is
> > > > > very much not transitive IIRC.
> > > > 
> > > > I am probably lost on context, but...
> > > > 
> > > > It turns out that lwsync is transitive in special cases.  One of them
> > > > is a series of release-acquire pairs, which can extend indefinitely.
> > > > 
> > > > Does that help in this case?
> > > 
> > > Probably not, but good to know. I still don't think we want to rely on
> > > ACQUIRE/RELEASE being transitive in general though.
> > 
> > OK, I will bite...  Why not?
> 
> It would mean us reviewing all archs (again) and documenting it I
> suppose. Which is of course entirely possible.
> 
> That said, I don't think the case at hand requires it, so lets postpone
> this for now ;-)

True enough, but in my experience smp_store_release() and
smp_load_acquire() are a -lot- easier to use than other barriers,
and transitivity will help promote their use.  So...

All the TSO architectures (x86, s390, SPARC, HPPA, ...) support transitive
smp_store_release()/smp_load_acquire() via their native ordering in
combination with barrier() macros.  x86 with CONFIG_X86_PPRO_FENCE=y,
which is not TSO, uses an mfence instruction.  Power supports this via
lwsync's partial cumulativity.  ARM64 supports it in SMP via the new ldar
and stlr instructions (in non-SMP, it uses barrier(), which suffices
in that case).  IA64 supports this via total ordering of all release
instructions in theory and by the actual full-barrier implementation
in practice (and the fact that gcc emits st.rel and ld.acq instructions
for volatile stores and loads).  All other architectures use smp_mb(),
which is transitive.

Did I miss anything?

							Thanx, Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225399

FromPeter Zijlstra <peterz@infradead.org>
Date2015-09-15 18:40 +0200
Message-ID<q91qW-1Tn-17@gated-at.bofh.it>
In reply to#1225322
On Tue, Sep 15, 2015 at 08:34:48AM -0700, Paul E. McKenney wrote:
> On Tue, Sep 15, 2015 at 04:14:39PM +0200, Peter Zijlstra wrote:
> > On Tue, Sep 15, 2015 at 07:09:22AM -0700, Paul E. McKenney wrote:
> > > On Tue, Sep 15, 2015 at 02:48:00PM +0200, Peter Zijlstra wrote:
> > > > On Tue, Sep 15, 2015 at 05:41:42AM -0700, Paul E. McKenney wrote:
> > > > > > Never mind, the PPC people will implement this with lwsync and that is
> > > > > > very much not transitive IIRC.
> > > > > 
> > > > > I am probably lost on context, but...
> > > > > 
> > > > > It turns out that lwsync is transitive in special cases.  One of them
> > > > > is a series of release-acquire pairs, which can extend indefinitely.
> > > > > 
> > > > > Does that help in this case?
> > > > 
> > > > Probably not, but good to know. I still don't think we want to rely on
> > > > ACQUIRE/RELEASE being transitive in general though.
> > > 
> > > OK, I will bite...  Why not?
> > 
> > It would mean us reviewing all archs (again) and documenting it I
> > suppose. Which is of course entirely possible.
> > 
> > That said, I don't think the case at hand requires it, so lets postpone
> > this for now ;-)
> 
> True enough, but in my experience smp_store_release() and
> smp_load_acquire() are a -lot- easier to use than other barriers,
> and transitivity will help promote their use.  So...
> 
> All the TSO architectures (x86, s390, SPARC, HPPA, ...) support transitive
> smp_store_release()/smp_load_acquire() via their native ordering in
> combination with barrier() macros.  x86 with CONFIG_X86_PPRO_FENCE=y,
> which is not TSO, uses an mfence instruction.  Power supports this via
> lwsync's partial cumulativity.  ARM64 supports it in SMP via the new ldar
> and stlr instructions (in non-SMP, it uses barrier(), which suffices
> in that case).  IA64 supports this via total ordering of all release
> instructions in theory and by the actual full-barrier implementation
> in practice (and the fact that gcc emits st.rel and ld.acq instructions
> for volatile stores and loads).  All other architectures use smp_mb(),
> which is transitive.
> 
> Did I miss anything?

I think that about covers it.. the only odd duckling might be s390 which
is documented as TSO but recently grew smp_mb__{before,after}_atomic(),
which seems to confuse matters.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225450

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2015-09-15 19:10 +0200
Message-ID<q91TY-2GF-9@gated-at.bofh.it>
In reply to#1225399
On Tue, Sep 15, 2015 at 06:30:28PM +0200, Peter Zijlstra wrote:
> On Tue, Sep 15, 2015 at 08:34:48AM -0700, Paul E. McKenney wrote:
> > On Tue, Sep 15, 2015 at 04:14:39PM +0200, Peter Zijlstra wrote:
> > > On Tue, Sep 15, 2015 at 07:09:22AM -0700, Paul E. McKenney wrote:
> > > > On Tue, Sep 15, 2015 at 02:48:00PM +0200, Peter Zijlstra wrote:
> > > > > On Tue, Sep 15, 2015 at 05:41:42AM -0700, Paul E. McKenney wrote:
> > > > > > > Never mind, the PPC people will implement this with lwsync and that is
> > > > > > > very much not transitive IIRC.
> > > > > > 
> > > > > > I am probably lost on context, but...
> > > > > > 
> > > > > > It turns out that lwsync is transitive in special cases.  One of them
> > > > > > is a series of release-acquire pairs, which can extend indefinitely.
> > > > > > 
> > > > > > Does that help in this case?
> > > > > 
> > > > > Probably not, but good to know. I still don't think we want to rely on
> > > > > ACQUIRE/RELEASE being transitive in general though.
> > > > 
> > > > OK, I will bite...  Why not?
> > > 
> > > It would mean us reviewing all archs (again) and documenting it I
> > > suppose. Which is of course entirely possible.
> > > 
> > > That said, I don't think the case at hand requires it, so lets postpone
> > > this for now ;-)
> > 
> > True enough, but in my experience smp_store_release() and
> > smp_load_acquire() are a -lot- easier to use than other barriers,
> > and transitivity will help promote their use.  So...
> > 
> > All the TSO architectures (x86, s390, SPARC, HPPA, ...) support transitive
> > smp_store_release()/smp_load_acquire() via their native ordering in
> > combination with barrier() macros.  x86 with CONFIG_X86_PPRO_FENCE=y,
> > which is not TSO, uses an mfence instruction.  Power supports this via
> > lwsync's partial cumulativity.  ARM64 supports it in SMP via the new ldar
> > and stlr instructions (in non-SMP, it uses barrier(), which suffices
> > in that case).  IA64 supports this via total ordering of all release
> > instructions in theory and by the actual full-barrier implementation
> > in practice (and the fact that gcc emits st.rel and ld.acq instructions
> > for volatile stores and loads).  All other architectures use smp_mb(),
> > which is transitive.
> > 
> > Did I miss anything?
> 
> I think that about covers it.. the only odd duckling might be s390 which
> is documented as TSO but recently grew smp_mb__{before,after}_atomic(),
> which seems to confuse matters.

Fair point, adding Martin and Heiko on CC for their thoughts.

It looks like this applies to recent mainframes that have new atomic
instructions, which, yes, might need something to make them work with
fully transitive smp_load_acquire() and smp_store_release().

Martin, Heiko, the question is whether or not the current s390
smp_store_release() and smp_load_acquire() can be transitive.
For example, if all the Xi variables below are initially zero,
is it possible for all the r0, r1, r2, ... rN variables to
have the value 1 at the end of the test.

CPU 0
	r0 = smp_load_acquire(&X0);
	smp_store_release(&X1, 1);

CPU 1
	r1 = smp_load_acquire(&X1);
	smp_store_release(&X2, 1);

CPU 2
	r2 = smp_load_acquire(&X2);
	smp_store_release(&X3, 1);

...

CPU N
	rN = smp_load_acquire(&XN);
	smp_store_release(&X0, 1);

If smp_store_release() and smp_load_acquire() are transitive, the
answer would be "no".

A similar litmus test involving atomics would be as follows, again
with all Xi initially zero:

CPU 0
	atomic_inc(&X0);
	smp_store_release(&X1, 1);

CPU 1
	r1 = smp_load_acquire(&X1);
	smp_store_release(&X2, 1);

CPU 2
	r2 = smp_load_acquire(&X2);
	smp_store_release(&X3, 1);

...

CPU N
	rN = smp_load_acquire(&XN);
	r0 = atomic_read(&X0);

Here, the question is whether r0 can be zero, but r1, r2, ... rN all
being 1 at the end of the test.

Thoughts?

							Thanx, Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1228298

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2015-09-18 23:50 +0200
Message-ID<qabHz-6x4-1@gated-at.bofh.it>
In reply to#1225450
On Tue, Sep 15, 2015 at 10:09:41AM -0700, Paul E. McKenney wrote:
> On Tue, Sep 15, 2015 at 06:30:28PM +0200, Peter Zijlstra wrote:
> > On Tue, Sep 15, 2015 at 08:34:48AM -0700, Paul E. McKenney wrote:
> > > On Tue, Sep 15, 2015 at 04:14:39PM +0200, Peter Zijlstra wrote:
> > > > On Tue, Sep 15, 2015 at 07:09:22AM -0700, Paul E. McKenney wrote:
> > > > > On Tue, Sep 15, 2015 at 02:48:00PM +0200, Peter Zijlstra wrote:
> > > > > > On Tue, Sep 15, 2015 at 05:41:42AM -0700, Paul E. McKenney wrote:
> > > > > > > > Never mind, the PPC people will implement this with lwsync and that is
> > > > > > > > very much not transitive IIRC.
> > > > > > > 
> > > > > > > I am probably lost on context, but...
> > > > > > > 
> > > > > > > It turns out that lwsync is transitive in special cases.  One of them
> > > > > > > is a series of release-acquire pairs, which can extend indefinitely.
> > > > > > > 
> > > > > > > Does that help in this case?
> > > > > > 
> > > > > > Probably not, but good to know. I still don't think we want to rely on
> > > > > > ACQUIRE/RELEASE being transitive in general though.
> > > > > 
> > > > > OK, I will bite...  Why not?
> > > > 
> > > > It would mean us reviewing all archs (again) and documenting it I
> > > > suppose. Which is of course entirely possible.
> > > > 
> > > > That said, I don't think the case at hand requires it, so lets postpone
> > > > this for now ;-)
> > > 
> > > True enough, but in my experience smp_store_release() and
> > > smp_load_acquire() are a -lot- easier to use than other barriers,
> > > and transitivity will help promote their use.  So...
> > > 
> > > All the TSO architectures (x86, s390, SPARC, HPPA, ...) support transitive
> > > smp_store_release()/smp_load_acquire() via their native ordering in
> > > combination with barrier() macros.  x86 with CONFIG_X86_PPRO_FENCE=y,
> > > which is not TSO, uses an mfence instruction.  Power supports this via
> > > lwsync's partial cumulativity.  ARM64 supports it in SMP via the new ldar
> > > and stlr instructions (in non-SMP, it uses barrier(), which suffices
> > > in that case).  IA64 supports this via total ordering of all release
> > > instructions in theory and by the actual full-barrier implementation
> > > in practice (and the fact that gcc emits st.rel and ld.acq instructions
> > > for volatile stores and loads).  All other architectures use smp_mb(),
> > > which is transitive.
> > > 
> > > Did I miss anything?
> > 
> > I think that about covers it.. the only odd duckling might be s390 which
> > is documented as TSO but recently grew smp_mb__{before,after}_atomic(),
> > which seems to confuse matters.
> 
> Fair point, adding Martin and Heiko on CC for their thoughts.
> 
> It looks like this applies to recent mainframes that have new atomic
> instructions, which, yes, might need something to make them work with
> fully transitive smp_load_acquire() and smp_store_release().
> 
> Martin, Heiko, the question is whether or not the current s390
> smp_store_release() and smp_load_acquire() can be transitive.
> For example, if all the Xi variables below are initially zero,
> is it possible for all the r0, r1, r2, ... rN variables to
> have the value 1 at the end of the test.

Right...  This time actually adding Martin and Heiko on CC...

							Thanx, Paul

> CPU 0
> 	r0 = smp_load_acquire(&X0);
> 	smp_store_release(&X1, 1);
> 
> CPU 1
> 	r1 = smp_load_acquire(&X1);
> 	smp_store_release(&X2, 1);
> 
> CPU 2
> 	r2 = smp_load_acquire(&X2);
> 	smp_store_release(&X3, 1);
> 
> ...
> 
> CPU N
> 	rN = smp_load_acquire(&XN);
> 	smp_store_release(&X0, 1);
> 
> If smp_store_release() and smp_load_acquire() are transitive, the
> answer would be "no".
> 
> A similar litmus test involving atomics would be as follows, again
> with all Xi initially zero:
> 
> CPU 0
> 	atomic_inc(&X0);
> 	smp_store_release(&X1, 1);
> 
> CPU 1
> 	r1 = smp_load_acquire(&X1);
> 	smp_store_release(&X2, 1);
> 
> CPU 2
> 	r2 = smp_load_acquire(&X2);
> 	smp_store_release(&X3, 1);
> 
> ...
> 
> CPU N
> 	rN = smp_load_acquire(&XN);
> 	r0 = atomic_read(&X0);
> 
> Here, the question is whether r0 can be zero, but r1, r2, ... rN all
> being 1 at the end of the test.
> 
> Thoughts?
> 
> 							Thanx, Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1229140

FromMartin Schwidefsky <schwidefsky@de.ibm.com>
Date2015-09-21 11:30 +0200
Message-ID<qb5A6-2vD-5@gated-at.bofh.it>
In reply to#1228298
On Fri, 18 Sep 2015 14:41:20 -0700
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com> wrote:

> On Tue, Sep 15, 2015 at 10:09:41AM -0700, Paul E. McKenney wrote:
> > On Tue, Sep 15, 2015 at 06:30:28PM +0200, Peter Zijlstra wrote:
> > > On Tue, Sep 15, 2015 at 08:34:48AM -0700, Paul E. McKenney wrote:
> > > > On Tue, Sep 15, 2015 at 04:14:39PM +0200, Peter Zijlstra wrote:
> > > > > On Tue, Sep 15, 2015 at 07:09:22AM -0700, Paul E. McKenney wrote:
> > > > > > On Tue, Sep 15, 2015 at 02:48:00PM +0200, Peter Zijlstra wrote:
> > > > > > > On Tue, Sep 15, 2015 at 05:41:42AM -0700, Paul E. McKenney wrote:
> > > > > > > > > Never mind, the PPC people will implement this with lwsync and that is
> > > > > > > > > very much not transitive IIRC.
> > > > > > > > 
> > > > > > > > I am probably lost on context, but...
> > > > > > > > 
> > > > > > > > It turns out that lwsync is transitive in special cases.  One of them
> > > > > > > > is a series of release-acquire pairs, which can extend indefinitely.
> > > > > > > > 
> > > > > > > > Does that help in this case?
> > > > > > > 
> > > > > > > Probably not, but good to know. I still don't think we want to rely on
> > > > > > > ACQUIRE/RELEASE being transitive in general though.
> > > > > > 
> > > > > > OK, I will bite...  Why not?
> > > > > 
> > > > > It would mean us reviewing all archs (again) and documenting it I
> > > > > suppose. Which is of course entirely possible.
> > > > > 
> > > > > That said, I don't think the case at hand requires it, so lets postpone
> > > > > this for now ;-)
> > > > 
> > > > True enough, but in my experience smp_store_release() and
> > > > smp_load_acquire() are a -lot- easier to use than other barriers,
> > > > and transitivity will help promote their use.  So...
> > > > 
> > > > All the TSO architectures (x86, s390, SPARC, HPPA, ...) support transitive
> > > > smp_store_release()/smp_load_acquire() via their native ordering in
> > > > combination with barrier() macros.  x86 with CONFIG_X86_PPRO_FENCE=y,
> > > > which is not TSO, uses an mfence instruction.  Power supports this via
> > > > lwsync's partial cumulativity.  ARM64 supports it in SMP via the new ldar
> > > > and stlr instructions (in non-SMP, it uses barrier(), which suffices
> > > > in that case).  IA64 supports this via total ordering of all release
> > > > instructions in theory and by the actual full-barrier implementation
> > > > in practice (and the fact that gcc emits st.rel and ld.acq instructions
> > > > for volatile stores and loads).  All other architectures use smp_mb(),
> > > > which is transitive.
> > > > 
> > > > Did I miss anything?
> > > 
> > > I think that about covers it.. the only odd duckling might be s390 which
> > > is documented as TSO but recently grew smp_mb__{before,after}_atomic(),
> > > which seems to confuse matters.
> > 
> > Fair point, adding Martin and Heiko on CC for their thoughts.

Well we always had the full memory barrier for the various versions of
smp_mb__xxx, they just have moved around and renamed several times.

After discussing this with Heiko we came to the conclusion that we can use
a simple barrier() for smp_mb__before_atomic() and smp_mb__after_atomic().

> > It looks like this applies to recent mainframes that have new atomic
> > instructions, which, yes, might need something to make them work with
> > fully transitive smp_load_acquire() and smp_store_release().
> > 
> > Martin, Heiko, the question is whether or not the current s390
> > smp_store_release() and smp_load_acquire() can be transitive.
> > For example, if all the Xi variables below are initially zero,
> > is it possible for all the r0, r1, r2, ... rN variables to
> > have the value 1 at the end of the test.
> 
> Right...  This time actually adding Martin and Heiko on CC...
> 
> 							Thanx, Paul
> 
> > CPU 0
> > 	r0 = smp_load_acquire(&X0);
> > 	smp_store_release(&X1, 1);
> > 
> > CPU 1
> > 	r1 = smp_load_acquire(&X1);
> > 	smp_store_release(&X2, 1);
> > 
> > CPU 2
> > 	r2 = smp_load_acquire(&X2);
> > 	smp_store_release(&X3, 1);
> > 
> > ...
> > 
> > CPU N
> > 	rN = smp_load_acquire(&XN);
> > 	smp_store_release(&X0, 1);
> > 
> > If smp_store_release() and smp_load_acquire() are transitive, the
> > answer would be "no".

The answer is "no". Christian recently summarized what the principles of
operation has to say about the CPU read / write behavior. If you consider
the sequential order of instructions then

1) reads are in order
2) writes are in order
3) reads can happen earlier
4) writes can happen later

> > A similar litmus test involving atomics would be as follows, again
> > with all Xi initially zero:
> > 
> > CPU 0
> > 	atomic_inc(&X0);
> > 	smp_store_release(&X1, 1);
> > 
> > CPU 1
> > 	r1 = smp_load_acquire(&X1);
> > 	smp_store_release(&X2, 1);
> > 
> > CPU 2
> > 	r2 = smp_load_acquire(&X2);
> > 	smp_store_release(&X3, 1);
> > 
> > ...
> > 
> > CPU N
> > 	rN = smp_load_acquire(&XN);
> > 	r0 = atomic_read(&X0);
> > 
> > Here, the question is whether r0 can be zero, but r1, r2, ... rN all
> > being 1 at the end of the test.

r0 = 0 and all r1, r2, ... rN = 1 can not happen on s390.

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225054

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2015-09-15 14:50 +0200
Message-ID<q8XQm-55E-29@gated-at.bofh.it>
In reply to#1224954
On Tue, Sep 15, 2015 at 11:55:12AM +0200, Peter Zijlstra wrote:
> On Tue, Sep 15, 2015 at 11:49:49AM +0200, Peter Zijlstra wrote:
> > On Mon, Sep 14, 2015 at 02:08:06PM -0700, Davidlohr Bueso wrote:
> > > On Mon, 14 Sep 2015, Peter Zijlstra wrote:
> > > 
> > > >On Mon, Sep 14, 2015 at 12:37:23AM -0700, Davidlohr Bueso wrote:
> > > >>	/*
> > > >>+	 * Atomically grab the task. If ->wake_q is non-nil (failed cmpxchg)
> > > >>+	 * then the task is already queued (by us or someone else) and will
> > > >>+	 * get the wakeup due to that.
> > > >>	 *
> > > >>+	 * Use acquire semantics to add the next pointer, which pairs with the
> > > >>+	 * write barrier implied by the wakeup in wake_up_list().
> > > >>	 */
> > > >>+	if (cmpxchg_acquire(&node->next, NULL, WAKE_Q_TAIL))
> > > >>		return;
> > > >>
> > > >>	get_task_struct(task);
> > > >
> > > >I'm not seeing a _why_ on the acquire semantics. Not saying the patch is
> > > >wrong, just saying I want words on why acquire is correct.
> > >
> > > Well, I was just taking advantage of removing the upper barrier. Considering
> > > that the formal semantics, you are right that we need not actual acquire per-se
> > > (ie for node->next) but instead merely ensure a barrier in wake_q_add(). This is
> > > kind of why I had hinted of going full _relaxed(). We could also rephrase the
> > > comment, something like:
> > >
> > >      * Use ACQUIRE semantics to add the next pointer, such that
> > >      * wake_q_add() implies a full barrier. This pairs with the
> > >      * write barrier implied by the wakeup in wake_up_list().
> > >      */
> > >
> > > What do you think?
> > 
> > Still befuddled. I'm thinking that if you want to remove a barrier,
> > you'd remove that second and keep the first. That is RELEASE.
> > 
> > That way, you know the stores prior to the wake queue are done by the
> > time you observe the queued entry, and therefore (transitively) know
> > those stores are done by the time you do the actual wakeup.
> > 
> > Two issues with that though; firstly RELEASE is not actually guaranteed
> > to be transitive -- now the only arch that does not implement it with a
> > full barrier is ARGH64, so we could just ask Will, but I'm not sure its
> > 'good' to start relying on this.
> 
> Never mind, the PPC people will implement this with lwsync and that is
> very much not transitive IIRC.

I am probably lost on context, but...

It turns out that lwsync is transitive in special cases.  One of them
is a series of release-acquire pairs, which can extend indefinitely.

Does that help in this case?

							Thanx, Paul

> That said, you could do:
> 
> 	smp_mb__before_atomic();
> 	cmpxchg_relaxed();
> 
> Which would still be a full barrier and therefore transitive. However
> this point still stands:
> 
> > Secondly, the wake queues are not concurrent, they're in context, so I
> > don't see ordering matter at all. The only reason its a cmpxchg() is
> > because there is the (small) possibility of two contexts wanting to wake
> > the same task, and we use task_struct storage for the queue.
> 
> I don't think we need _any_ barriers here, unless we have concurrent
> users of the wake queues (or want to allow any, do we?).
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225527

FromDavidlohr Bueso <dave@stgolabs.net>
Date2015-09-15 22:00 +0200
Message-ID<q94yt-6L6-5@gated-at.bofh.it>
In reply to#1224954
On Tue, 15 Sep 2015, Peter Zijlstra wrote:

>> Secondly, the wake queues are not concurrent, they're in context, so I
>> don't see ordering matter at all. The only reason its a cmpxchg() is
>> because there is the (small) possibility of two contexts wanting to wake
>> the same task, and we use task_struct storage for the queue.
>
>I don't think we need _any_ barriers here, unless we have concurrent
>users of the wake queues (or want to allow any, do we?).

Exactly, the queues are not concurent and do not need barriers, but some of
our callers do expect them.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225847

FromPeter Zijlstra <peterz@infradead.org>
Date2015-09-16 11:10 +0200
Message-ID<q9gSZ-8o1-9@gated-at.bofh.it>
In reply to#1225527
On Tue, Sep 15, 2015 at 12:49:46PM -0700, Davidlohr Bueso wrote:
> On Tue, 15 Sep 2015, Peter Zijlstra wrote:
> 
> >>Secondly, the wake queues are not concurrent, they're in context, so I
> >>don't see ordering matter at all. The only reason its a cmpxchg() is
> >>because there is the (small) possibility of two contexts wanting to wake
> >>the same task, and we use task_struct storage for the queue.
> >
> >I don't think we need _any_ barriers here, unless we have concurrent
> >users of the wake queues (or want to allow any, do we?).
> 
> Exactly, the queues are not concurent and do not need barriers, but some of
> our callers do expect them.

Ah, that is what you were saying. In that case, I think we should remove
all our barriers and make them explicit in the callers where needed.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web