Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1680474 > unrolled thread
| Started by | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| First post | 2017-07-03 18:20 +0200 |
| Last post | 2017-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.
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
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2017-07-03 18:20 +0200 |
| Subject | Re: [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]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2017-07-03 18:50 +0200 |
| Subject | Re: [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]
| From | Will Deacon <will.deacon@arm.com> |
|---|---|
| Date | 2017-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]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2017-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]
| From | Linus Torvalds <torvalds@linux-foundation.org> |
|---|---|
| Date | 2017-07-04 01:00 +0200 |
| Subject | Re: [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]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2017-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]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2017-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]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2017-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