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


Groups > linux.kernel > #1680474 > unrolled thread

Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic definitions

Started by"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
First post2017-07-03 18:20 +0200
Last post2017-07-03 23:20 +0200
Articles 8 — 3 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

  Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic  definitions "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2017-07-03 18:20 +0200
    Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic definitions Linus Torvalds <torvalds@linux-foundation.org> - 2017-07-03 18:50 +0200
      Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic  definitions Will Deacon <will.deacon@arm.com> - 2017-07-03 19:20 +0200
        Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic  definitions "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2017-07-04 00:40 +0200
          Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic definitions Linus Torvalds <torvalds@linux-foundation.org> - 2017-07-04 01:00 +0200
            Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic  definitions "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2017-07-04 02:50 +0200
              Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic  definitions "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2017-07-04 03:00 +0200
      Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic  definitions "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2017-07-03 23:20 +0200

#1680474 — Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic definitions

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2017-07-03 18:20 +0200
SubjectRe: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic definitions
Message-ID<tZceT-3TE-43@gated-at.bofh.it>
On Mon, Jul 03, 2017 at 02:15:14PM +0100, Will Deacon wrote:
> On Fri, Jun 30, 2017 at 03:18:40PM -0700, Paul E. McKenney wrote:
> > On Fri, Jun 30, 2017 at 02:13:39PM +0100, Will Deacon wrote:
> > > On Fri, Jun 30, 2017 at 05:38:15AM -0700, Paul E. McKenney wrote:
> > > > I also need to check all uses of spin_is_locked().  There might no
> > > > longer be any that rely on any particular ordering...
> > > 
> > > Right. I think we're looking for the "insane case" as per 38b850a73034
> > > (which was apparently used by ipc/sem.c at the time, but no longer).
> > > 
> > > There's a usage in kernel/debug/debug_core.c, but it doesn't fill me with
> > > joy.
> > 
> > That is indeed an interesting one...  But my first round will be what
> > semantics the implementations seem to provide:
> > 
> > Acquire courtesy of TSO: s390, sparc, x86.
> > Acquire: ia64 (in reality fully ordered).
> > Control dependency: alpha, arc, arm, blackfin, hexagon, m32r, mn10300, tile,
> > 	xtensa.
> > Control dependency plus leading full barrier: arm64, powerpc.
> > UP-only: c6x, cris, frv, h8300, m68k, microblaze nios2, openrisc, um, unicore32.
> > 
> > Special cases:
> > 	metag: Acquire if !CONFIG_METAG_SMP_WRITE_REORDERING.
> > 	       Otherwise control dependency?
> > 	mips: Control dependency, acquire if CONFIG_CPU_CAVIUM_OCTEON.
> > 	parisc: Acquire courtesy of TSO, but why barrier in smp_load_acquire?
> > 	sh: Acquire if one of SH4A, SH5, or J2, otherwise acquire?  UP-only?
> > 
> > Are these correct, or am I missing something with any of them?
> 
> That looks about right but, at least on ARM, I think we have to consider
> the semantics of spin_is_locked with respect to the other spin_* functions,
> rather than in isolation.
> 
> For example, ARM only has a control dependency, but spin_lock has a trailing
> smp_mb() and spin_unlock has both leading and trailing smp_mb().

Agreed, and my next step is to look at spin_lock() followed by
spin_is_locked(), not necessarily the same lock.

							Thanx, Paul

[toc] | [next] | [standalone]


#1680490 — Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic definitions

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2017-07-03 18:50 +0200
SubjectRe: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic definitions
Message-ID<tZcHT-43W-11@gated-at.bofh.it>
In reply to#1680474
On Mon, Jul 3, 2017 at 9:18 AM, Paul E. McKenney
<paulmck@linux.vnet.ibm.com> wrote:
>
> Agreed, and my next step is to look at spin_lock() followed by
> spin_is_locked(), not necessarily the same lock.

Hmm. Most (all?) "spin_is_locked()" really should be about the same
thread that took the lock (ie it's about asserts and lock debugging).

The optimistic ABBA avoidance pattern for spinlocks *should* be

    spin_lock(inner)
    ...
    if (!try_lock(outer)) {
           spin_unlock(inner);
           .. do them in the right order ..

so I don't think spin_is_locked() should have any memory barriers.

In fact, the core function for spin_is_locked() is arguably
arch_spin_value_unlocked() which doesn't even do the access itself.

                       Linus

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


#1680508

FromWill Deacon <will.deacon@arm.com>
Date2017-07-03 19:20 +0200
Message-ID<tZdaW-4tv-9@gated-at.bofh.it>
In reply to#1680490
On Mon, Jul 03, 2017 at 09:40:22AM -0700, Linus Torvalds wrote:
> On Mon, Jul 3, 2017 at 9:18 AM, Paul E. McKenney
> <paulmck@linux.vnet.ibm.com> wrote:
> >
> > Agreed, and my next step is to look at spin_lock() followed by
> > spin_is_locked(), not necessarily the same lock.
> 
> Hmm. Most (all?) "spin_is_locked()" really should be about the same
> thread that took the lock (ie it's about asserts and lock debugging).
> 
> The optimistic ABBA avoidance pattern for spinlocks *should* be
> 
>     spin_lock(inner)
>     ...
>     if (!try_lock(outer)) {
>            spin_unlock(inner);
>            .. do them in the right order ..
> 
> so I don't think spin_is_locked() should have any memory barriers.
> 
> In fact, the core function for spin_is_locked() is arguably
> arch_spin_value_unlocked() which doesn't even do the access itself.

Yeah, but there's some spaced-out stuff going on in kgdb_cpu_enter where
it looks to me like raw_spin_is_locked is used for synchronization. My
eyes are hurting looking at it, though.

Will

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


#1680606

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2017-07-04 00:40 +0200
Message-ID<tZiaC-7Qj-7@gated-at.bofh.it>
In reply to#1680508
On Mon, Jul 03, 2017 at 06:13:38PM +0100, Will Deacon wrote:
> On Mon, Jul 03, 2017 at 09:40:22AM -0700, Linus Torvalds wrote:
> > On Mon, Jul 3, 2017 at 9:18 AM, Paul E. McKenney
> > <paulmck@linux.vnet.ibm.com> wrote:
> > >
> > > Agreed, and my next step is to look at spin_lock() followed by
> > > spin_is_locked(), not necessarily the same lock.
> > 
> > Hmm. Most (all?) "spin_is_locked()" really should be about the same
> > thread that took the lock (ie it's about asserts and lock debugging).
> > 
> > The optimistic ABBA avoidance pattern for spinlocks *should* be
> > 
> >     spin_lock(inner)
> >     ...
> >     if (!try_lock(outer)) {
> >            spin_unlock(inner);
> >            .. do them in the right order ..
> > 
> > so I don't think spin_is_locked() should have any memory barriers.
> > 
> > In fact, the core function for spin_is_locked() is arguably
> > arch_spin_value_unlocked() which doesn't even do the access itself.
> 
> Yeah, but there's some spaced-out stuff going on in kgdb_cpu_enter where
> it looks to me like raw_spin_is_locked is used for synchronization. My
> eyes are hurting looking at it, though.

That certainly is one interesting function, isn't it?  I wonder what
happens if you replace the raw_spin_is_locked() calls with an
unlock under a trylock check?  ;-)

							Thanx, Paul

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


#1680610 — Re: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic definitions

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2017-07-04 01:00 +0200
SubjectRe: [PATCH RFC 08/26] locking: Remove spin_unlock_wait() generic definitions
Message-ID<tZitZ-7Ys-9@gated-at.bofh.it>
In reply to#1680606
On Mon, Jul 3, 2017 at 3:30 PM, Paul E. McKenney
<paulmck@linux.vnet.ibm.com> wrote:
>
> That certainly is one interesting function, isn't it?  I wonder what
> happens if you replace the raw_spin_is_locked() calls with an
> unlock under a trylock check?  ;-)

Deadlock due to interrupts again?

Didn't your spin_unlock_wait() patches teach you anything? Checking
state is fundamentally different from taking the lock. Even a trylock.

I guess you could try with the irqsave versions. But no, we're not doing that.

                Linus

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


#1680627

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2017-07-04 02:50 +0200
Message-ID<tZkcp-FC-5@gated-at.bofh.it>
In reply to#1680610
On Mon, Jul 03, 2017 at 03:49:42PM -0700, Linus Torvalds wrote:
> On Mon, Jul 3, 2017 at 3:30 PM, Paul E. McKenney
> <paulmck@linux.vnet.ibm.com> wrote:
> >
> > That certainly is one interesting function, isn't it?  I wonder what
> > happens if you replace the raw_spin_is_locked() calls with an
> > unlock under a trylock check?  ;-)
> 
> Deadlock due to interrupts again?

Unless I am missing something subtle, the kgdb_cpu_enter() function in
question has a local_irq_save() over the "interesting" portion of its
workings, so interrupt-handler self-deadlock should not happen.

> Didn't your spin_unlock_wait() patches teach you anything? Checking
> state is fundamentally different from taking the lock. Even a trylock.

That was an embarrassing bug, no two ways about it.  :-/

> I guess you could try with the irqsave versions. But no, we're not doing that.

Again, no need in this case.

But I agree with Will's assessment of this function...

The raw_spin_is_locked() looks to be asking if -any- CPU holds the
dbg_slave_lock, and the answer could of course change immediately
on return from raw_spin_is_locked().  Perhaps the theory is that
if other CPU holds the lock, this CPU is supposed to be subjected to
kgdb_roundup_cpus().  Except that the CPU that held dbg_slave_lock might
be just about to release that lock.  Odd.

Seems like there should be a get_online_cpus() somewhere, but maybe
that constraint is to be manually enforced.

							Thanx, Paul

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


#1680629

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2017-07-04 03:00 +0200
Message-ID<tZkm5-IN-5@gated-at.bofh.it>
In reply to#1680627
On Mon, Jul 03, 2017 at 05:39:36PM -0700, Paul E. McKenney wrote:
> On Mon, Jul 03, 2017 at 03:49:42PM -0700, Linus Torvalds wrote:
> > On Mon, Jul 3, 2017 at 3:30 PM, Paul E. McKenney
> > <paulmck@linux.vnet.ibm.com> wrote:
> > >
> > > That certainly is one interesting function, isn't it?  I wonder what
> > > happens if you replace the raw_spin_is_locked() calls with an
> > > unlock under a trylock check?  ;-)
> > 
> > Deadlock due to interrupts again?
> 
> Unless I am missing something subtle, the kgdb_cpu_enter() function in
> question has a local_irq_save() over the "interesting" portion of its
> workings, so interrupt-handler self-deadlock should not happen.
> 
> > Didn't your spin_unlock_wait() patches teach you anything? Checking
> > state is fundamentally different from taking the lock. Even a trylock.
> 
> That was an embarrassing bug, no two ways about it.  :-/
> 
> > I guess you could try with the irqsave versions. But no, we're not doing that.
> 
> Again, no need in this case.
> 
> But I agree with Will's assessment of this function...
> 
> The raw_spin_is_locked() looks to be asking if -any- CPU holds the
> dbg_slave_lock, and the answer could of course change immediately
> on return from raw_spin_is_locked().  Perhaps the theory is that
> if other CPU holds the lock, this CPU is supposed to be subjected to
> kgdb_roundup_cpus().  Except that the CPU that held dbg_slave_lock might
> be just about to release that lock.  Odd.
> 
> Seems like there should be a get_online_cpus() somewhere, but maybe
> that constraint is to be manually enforced.

Except that invoking get_online_cpus() from an exception handler would
be of course be a spectacularly bad idea.  I would feel better if the
num_online_cpus() was under the local_irq_save(), but perhaps this code
is relying on the stop_machine().  Except that it appears we could
deadlock with offline waiting for stop_machine() to complete and kdbg
waiting for all CPUs to report, including those in stop_machine().

Looks like the current situation is "Don't use kdbg if there is any
possibility of CPU-hotplug operations."  Not necessarily an unreasonable
restriction.

But I need to let me eyes heal a bit before looking at this more.

							Thanx, Paul

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


#1680576

From"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Date2017-07-03 23:20 +0200
Message-ID<tZgVb-7a5-5@gated-at.bofh.it>
In reply to#1680490
On Mon, Jul 03, 2017 at 09:40:22AM -0700, Linus Torvalds wrote:
> On Mon, Jul 3, 2017 at 9:18 AM, Paul E. McKenney
> <paulmck@linux.vnet.ibm.com> wrote:
> >
> > Agreed, and my next step is to look at spin_lock() followed by
> > spin_is_locked(), not necessarily the same lock.
> 
> Hmm. Most (all?) "spin_is_locked()" really should be about the same
> thread that took the lock (ie it's about asserts and lock debugging).

Good to know, that does make things easier.  ;-)

I am not certain that it is feasible to automatically recognize
non-assert/non-debugging use cases of spin_is_locked(), but there is
aways manual inspection.

> The optimistic ABBA avoidance pattern for spinlocks *should* be
> 
>     spin_lock(inner)
>     ...
>     if (!try_lock(outer)) {
>            spin_unlock(inner);
>            .. do them in the right order ..
> 
> so I don't think spin_is_locked() should have any memory barriers.
> 
> In fact, the core function for spin_is_locked() is arguably
> arch_spin_value_unlocked() which doesn't even do the access itself.

OK, so we should rework any cases where people are relying on acquisition
of one spin_lock() being ordered with a later spin_is_locked() on some
other lock by that same thread.

							Thanx, Paul

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web