All of lore.kernel.org
 help / color / mirror / Atom feed
From: mark.rutland@arm.com (Mark Rutland)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC] arm64: Enforce observed order for spinlock and data
Date: Fri, 30 Sep 2016 20:32:32 +0100	[thread overview]
Message-ID: <20160930193231.GA2521@remoulade> (raw)
In-Reply-To: <1475257257-23072-1-git-send-email-bdegraaf@codeaurora.org>

On Fri, Sep 30, 2016 at 01:40:57PM -0400, Brent DeGraaf wrote:
> Prior spinlock code solely used load-acquire and store-release
> semantics to ensure ordering of the spinlock lock and the area it
> protects. However, store-release semantics and ordinary stores do
> not protect against accesses to the protected area being observed
> prior to the access that locks the lock itself.
> 
> While the load-acquire and store-release ordering is sufficient
> when the spinlock routines themselves are strictly used, other
> kernel code that references the lock values directly (e.g. lockrefs)
> could observe changes to the area protected by the spinlock prior
> to observance of the lock itself being in a locked state, despite
> the fact that the spinlock logic itself is correct.

If the spinlock logic is correct, why are we changing that, and not the lockref
code that you say has a problem?

What exactly goes wrong in the lockref code? Can you give a concrete example?

Why does the lockref code accesses lock-protected fields without taking the
lock first? Wouldn't concurrent modification be a problem regardless?

> +	/*
> +	 * Yes: The store done on this cpu was the one that locked the lock.
> +	 * Store-release one-way barrier on LL/SC means that accesses coming
> +	 * after this could be reordered into the critical section of the

I assume you meant s/store-release/load-acquire/ here. This does not make sense
to me otherwise.

> +	 * load-acquire/store-release, where we did not own the lock. On LSE,
> +	 * even the one-way barrier of the store-release semantics is missing,

Likewise (for the LSE case description).

> +	 * so LSE needs an explicit barrier here as well.  Without this, the
> +	 * changed contents of the area protected by the spinlock could be
> +	 * observed prior to the lock.
> +	 */

By whom? We generally expect that if data is protected by a lock, you take the
lock before accessing it. If you expect concurrent lockless readers, then
there's a requirement on the writer side to explicitly provide the ordering it
requires -- spinlocks are not expected to provide that.

So, why aren't those observers taking the lock?

What pattern of accesses are made by readers and writers such that there is a
problem?

What does this result in?

> +"	dmb	ish\n"
> +"	b	3f\n"
> +"4:\n"
>  	/*
>  	 * No: spin on the owner. Send a local event to avoid missing an
>  	 * unlock before the exclusive load.
> @@ -116,7 +129,15 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
>  "	ldaxrh	%w2, %4\n"
>  "	eor	%w1, %w2, %w0, lsr #16\n"
>  "	cbnz	%w1, 2b\n"
> -	/* We got the lock. Critical section starts here. */
> +	/*
> +	 * We got the lock and have observed the prior owner's store-release.
> +	 * In this case, the one-way barrier of the prior owner that we
> +	 * observed combined with the one-way barrier of our load-acquire is
> +	 * enough to ensure accesses to the protected area coming after this
> +	 * are not accessed until we own the lock.  In this case, other
> +	 * observers will not see our changes prior to observing the lock
> +	 * itself.  Critical locked section starts here.
> +	 */

Each of these comments ends up covers, and their repeated presence makes the
code harder to read. If there's a common problem, note it once at the top of
the file.

Thanks,
Mark.

WARNING: multiple messages have this Message-ID (diff)
From: Mark Rutland <mark.rutland@arm.com>
To: Brent DeGraaf <bdegraaf@codeaurora.org>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will.deacon@arm.com>,
	Timur Tabi <timur@codeaurora.org>,
	Nathan Lynch <nathan_lynch@mentor.com>,
	linux-kernel@vger.kernel.org,
	Christopher Covington <cov@codeaurora.org>,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [RFC] arm64: Enforce observed order for spinlock and data
Date: Fri, 30 Sep 2016 20:32:32 +0100	[thread overview]
Message-ID: <20160930193231.GA2521@remoulade> (raw)
In-Reply-To: <1475257257-23072-1-git-send-email-bdegraaf@codeaurora.org>

On Fri, Sep 30, 2016 at 01:40:57PM -0400, Brent DeGraaf wrote:
> Prior spinlock code solely used load-acquire and store-release
> semantics to ensure ordering of the spinlock lock and the area it
> protects. However, store-release semantics and ordinary stores do
> not protect against accesses to the protected area being observed
> prior to the access that locks the lock itself.
> 
> While the load-acquire and store-release ordering is sufficient
> when the spinlock routines themselves are strictly used, other
> kernel code that references the lock values directly (e.g. lockrefs)
> could observe changes to the area protected by the spinlock prior
> to observance of the lock itself being in a locked state, despite
> the fact that the spinlock logic itself is correct.

If the spinlock logic is correct, why are we changing that, and not the lockref
code that you say has a problem?

What exactly goes wrong in the lockref code? Can you give a concrete example?

Why does the lockref code accesses lock-protected fields without taking the
lock first? Wouldn't concurrent modification be a problem regardless?

> +	/*
> +	 * Yes: The store done on this cpu was the one that locked the lock.
> +	 * Store-release one-way barrier on LL/SC means that accesses coming
> +	 * after this could be reordered into the critical section of the

I assume you meant s/store-release/load-acquire/ here. This does not make sense
to me otherwise.

> +	 * load-acquire/store-release, where we did not own the lock. On LSE,
> +	 * even the one-way barrier of the store-release semantics is missing,

Likewise (for the LSE case description).

> +	 * so LSE needs an explicit barrier here as well.  Without this, the
> +	 * changed contents of the area protected by the spinlock could be
> +	 * observed prior to the lock.
> +	 */

By whom? We generally expect that if data is protected by a lock, you take the
lock before accessing it. If you expect concurrent lockless readers, then
there's a requirement on the writer side to explicitly provide the ordering it
requires -- spinlocks are not expected to provide that.

So, why aren't those observers taking the lock?

What pattern of accesses are made by readers and writers such that there is a
problem?

What does this result in?

> +"	dmb	ish\n"
> +"	b	3f\n"
> +"4:\n"
>  	/*
>  	 * No: spin on the owner. Send a local event to avoid missing an
>  	 * unlock before the exclusive load.
> @@ -116,7 +129,15 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
>  "	ldaxrh	%w2, %4\n"
>  "	eor	%w1, %w2, %w0, lsr #16\n"
>  "	cbnz	%w1, 2b\n"
> -	/* We got the lock. Critical section starts here. */
> +	/*
> +	 * We got the lock and have observed the prior owner's store-release.
> +	 * In this case, the one-way barrier of the prior owner that we
> +	 * observed combined with the one-way barrier of our load-acquire is
> +	 * enough to ensure accesses to the protected area coming after this
> +	 * are not accessed until we own the lock.  In this case, other
> +	 * observers will not see our changes prior to observing the lock
> +	 * itself.  Critical locked section starts here.
> +	 */

Each of these comments ends up covers, and their repeated presence makes the
code harder to read. If there's a common problem, note it once at the top of
the file.

Thanks,
Mark.

  parent reply	other threads:[~2016-09-30 19:32 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-30 17:40 [RFC] arm64: Enforce observed order for spinlock and data Brent DeGraaf
2016-09-30 17:40 ` Brent DeGraaf
2016-09-30 18:43 ` Robin Murphy
2016-09-30 18:43   ` Robin Murphy
2016-10-01 15:45   ` bdegraaf at codeaurora.org
2016-10-01 15:45     ` bdegraaf
2016-09-30 18:52 ` Peter Zijlstra
2016-09-30 18:52   ` Peter Zijlstra
2016-09-30 19:05 ` Peter Zijlstra
2016-09-30 19:05   ` Peter Zijlstra
2016-10-01 15:59   ` bdegraaf at codeaurora.org
2016-10-01 15:59     ` bdegraaf
2016-09-30 19:32 ` Mark Rutland [this message]
2016-09-30 19:32   ` Mark Rutland
2016-10-01 16:11   ` bdegraaf at codeaurora.org
2016-10-01 16:11     ` bdegraaf
2016-10-01 18:11     ` Mark Rutland
2016-10-01 18:11       ` Mark Rutland
2016-10-03 19:20       ` bdegraaf at codeaurora.org
2016-10-03 19:20         ` bdegraaf
2016-10-04  6:50         ` Peter Zijlstra
2016-10-04  6:50           ` Peter Zijlstra
2016-10-04 10:12         ` Mark Rutland
2016-10-04 10:12           ` Mark Rutland
2016-10-04 17:53           ` bdegraaf at codeaurora.org
2016-10-04 17:53             ` bdegraaf
2016-10-04 18:28             ` bdegraaf at codeaurora.org
2016-10-04 18:28               ` bdegraaf
2016-10-04 19:12             ` Mark Rutland
2016-10-04 19:12               ` Mark Rutland
2016-10-05 14:55               ` bdegraaf at codeaurora.org
2016-10-05 14:55                 ` bdegraaf
2016-10-05 15:10                 ` Peter Zijlstra
2016-10-05 15:10                   ` Peter Zijlstra
2016-10-05 15:30                   ` bdegraaf at codeaurora.org
2016-10-05 15:30                     ` bdegraaf
2016-10-12 20:01                     ` bdegraaf at codeaurora.org
2016-10-12 20:01                       ` bdegraaf
2016-10-13 11:02                       ` Will Deacon
2016-10-13 11:02                         ` Will Deacon
2016-10-13 20:00                         ` bdegraaf at codeaurora.org
2016-10-13 20:00                           ` bdegraaf
2016-10-14  0:24                           ` Mark Rutland
2016-10-14  0:24                             ` Mark Rutland
2016-10-05 15:11                 ` bdegraaf at codeaurora.org
2016-10-05 15:11                   ` bdegraaf

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=20160930193231.GA2521@remoulade \
    --to=mark.rutland@arm.com \
    --cc=linux-arm-kernel@lists.infradead.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.