All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nicholas Piggin" <npiggin@gmail.com>
To: "Rohan McLure" <rmclure@linux.ibm.com>, <linuxppc-dev@lists.ozlabs.org>
Cc: Rohan McLure <rmclure@ibm.com>, arnd@arndb.de
Subject: Re: [PATCH 07/12] powerpc: powernv: Fix KCSAN datarace warnings on idle_state contention
Date: Tue, 09 May 2023 12:26:49 +1000	[thread overview]
Message-ID: <CSHE3ZGL9GZJ.QSN86CUY0BQ4@wheely> (raw)
In-Reply-To: <20230508020120.218494-8-rmclure@linux.ibm.com>

On Mon May 8, 2023 at 12:01 PM AEST, Rohan McLure wrote:
> The idle_state entry in the PACA on PowerNV features a bit which is
> atomically tested and set through ldarx/stdcx. to be used as a spinlock.
> This lock then guards access to other bit fields of idle_state. KCSAN
> cannot differentiate between any of these bitfield accesses as they all
> are implemented by 8-byte store/load instructions, thus cores contending
> on the bit-lock appear to data race with modifications to idle_state.
>
> Separate the bit-lock entry from the data guarded by the lock to avoid
> the possibility of data races being detected by KCSAN.
>
> Suggested-by: Nicholas Piggin <npiggin@gmail.com>
> Signed-off-by: Rohan McLure <rmclure@ibm.com>
> ---
>  arch/powerpc/include/asm/paca.h       |  1 +
>  arch/powerpc/platforms/powernv/idle.c | 20 +++++++++++---------
>  2 files changed, 12 insertions(+), 9 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
> index da0377f46597..cb325938766a 100644
> --- a/arch/powerpc/include/asm/paca.h
> +++ b/arch/powerpc/include/asm/paca.h
> @@ -191,6 +191,7 @@ struct paca_struct {
>  #ifdef CONFIG_PPC_POWERNV
>  	/* PowerNV idle fields */
>  	/* PNV_CORE_IDLE_* bits, all siblings work on thread 0 paca */
> +	unsigned long idle_lock; /* A value of 1 means acquired */
>  	unsigned long idle_state;
>  	union {
>  		/* P7/P8 specific fields */
> diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
> index 841cb7f31f4f..97dbb7bc2b00 100644
> --- a/arch/powerpc/platforms/powernv/idle.c
> +++ b/arch/powerpc/platforms/powernv/idle.c
> @@ -246,9 +246,9 @@ static inline void atomic_lock_thread_idle(void)
>  {
>  	int cpu = raw_smp_processor_id();
>  	int first = cpu_first_thread_sibling(cpu);
> -	unsigned long *state = &paca_ptrs[first]->idle_state;
> +	unsigned long *lock = &paca_ptrs[first]->idle_lock;
>  
> -	while (unlikely(test_and_set_bit_lock(NR_PNV_CORE_IDLE_LOCK_BIT, state)))
> +	while (unlikely(test_and_set_bit_lock(NR_PNV_CORE_IDLE_LOCK_BIT, lock)))
>  		barrier();
>  }
>  
> @@ -258,29 +258,31 @@ static inline void atomic_unlock_and_stop_thread_idle(void)
>  	int first = cpu_first_thread_sibling(cpu);
>  	unsigned long thread = 1UL << cpu_thread_in_core(cpu);
>  	unsigned long *state = &paca_ptrs[first]->idle_state;
> +	unsigned long *lock = &paca_ptrs[first]->idle_lock;
>  	u64 s = READ_ONCE(*state);
>  	u64 new, tmp;
>  
> -	BUG_ON(!(s & PNV_CORE_IDLE_LOCK_BIT));
> +	BUG_ON(!(READ_ONCE(*lock) & PNV_CORE_IDLE_LOCK_BIT));
>  	BUG_ON(s & thread);
>  
>  again:
> -	new = (s | thread) & ~PNV_CORE_IDLE_LOCK_BIT;
> +	new = s | thread;
>  	tmp = cmpxchg(state, s, new);
>  	if (unlikely(tmp != s)) {
>  		s = tmp;
>  		goto again;
>  	}
> +	clear_bit_unlock(NR_PNV_CORE_IDLE_LOCK_BIT, lock);

Sigh, another atomic. It's in a slow path though so I won't get too
upset. Would be nice to add a comment here and revert it when KCSCAN
can be taught about this pattern though, so we don't lose it.

>  }
>  
>  static inline void atomic_unlock_thread_idle(void)
>  {
>  	int cpu = raw_smp_processor_id();
>  	int first = cpu_first_thread_sibling(cpu);
> -	unsigned long *state = &paca_ptrs[first]->idle_state;
> +	unsigned long *lock = &paca_ptrs[first]->idle_lock;
>  
> -	BUG_ON(!test_bit(NR_PNV_CORE_IDLE_LOCK_BIT, state));
> -	clear_bit_unlock(NR_PNV_CORE_IDLE_LOCK_BIT, state);
> +	BUG_ON(!test_bit(NR_PNV_CORE_IDLE_LOCK_BIT, lock));
> +	clear_bit_unlock(NR_PNV_CORE_IDLE_LOCK_BIT, lock);
>  }
>  
>  /* P7 and P8 */
> @@ -380,9 +382,9 @@ static unsigned long power7_idle_insn(unsigned long type)
>  		sprs.uamor	= mfspr(SPRN_UAMOR);
>  	}
>  
> -	local_paca->thread_idle_state = type;
> +	WRITE_ONCE(local_paca->thread_idle_state, type);
>  	srr1 = isa206_idle_insn_mayloss(type);		/* go idle */
> -	local_paca->thread_idle_state = PNV_THREAD_RUNNING;
> +	WRITE_ONCE(local_paca->thread_idle_state, PNV_THREAD_RUNNING);

Where is the thread_idle_state concurrency coming from?

Thanks,
Nick

  reply	other threads:[~2023-05-09  2:27 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-08  2:01 [PATCH 00/12] powerpc: KCSAN fix warnings and mark accesses Rohan McLure
2023-05-08  2:01 ` [PATCH 01/12] powerpc: qspinlock: Fix qnode->locked value interpretation Rohan McLure
2023-05-09  2:01   ` Nicholas Piggin
2023-05-09  4:26     ` Rohan McLure
2023-05-08  2:01 ` [PATCH 02/12] powerpc: qspinlock: Mark accesses to qnode lock checks Rohan McLure
2023-05-09  2:02   ` Nicholas Piggin
2023-05-08  2:01 ` [PATCH 03/12] powerpc: qspinlock: Enforce qnode writes prior to publishing to queue Rohan McLure
2023-05-09  2:04   ` Nicholas Piggin
2023-05-09  5:26     ` Rohan McLure
2023-05-09  6:45       ` Nicholas Piggin
2023-05-08  2:01 ` [PATCH 04/12] asm-generic/mmiowb: Mark accesses to fix KCSAN warnings Rohan McLure
2023-05-08  6:30   ` Arnd Bergmann
2023-05-08 15:44   ` [PATCH 4/12] " Gautam Menghani
2023-05-09  2:16   ` [PATCH 04/12] " Nicholas Piggin
2023-05-08  2:01 ` [PATCH 05/12] powerpc: Mark [h]ssr_valid accesses in check_return_regs_valid Rohan McLure
2023-05-09  2:17   ` Nicholas Piggin
2023-05-08  2:01 ` [PATCH 06/12] powerpc: Mark accesses to power_save callback in arch_cpu_idle Rohan McLure
2023-05-09  2:21   ` Nicholas Piggin
2023-05-08  2:01 ` [PATCH 07/12] powerpc: powernv: Fix KCSAN datarace warnings on idle_state contention Rohan McLure
2023-05-09  2:26   ` Nicholas Piggin [this message]
2023-05-10  2:00     ` Rohan McLure
2023-05-08  2:01 ` [PATCH 08/12] powerpc: Annotate accesses to ipi message flags Rohan McLure
2023-05-09  2:28   ` Nicholas Piggin
2023-05-08  2:01 ` [PATCH 09/12] powerpc: Mark writes registering ipi to host cpu through kvm Rohan McLure
2023-05-09  2:30   ` Nicholas Piggin
2023-05-08  2:01 ` [PATCH 10/12] powerpc: powernv: Annotate data races in opal events Rohan McLure
2023-05-09  2:31   ` Nicholas Piggin
2023-05-08  2:01 ` [PATCH 11/12] powerpc: powernv: Annotate asynchronous access to opal tokens Rohan McLure
2023-05-08  2:01 ` [PATCH 12/12] powerpc: Mark asynchronous accesses to irq_data Rohan McLure

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=CSHE3ZGL9GZJ.QSN86CUY0BQ4@wheely \
    --to=npiggin@gmail.com \
    --cc=arnd@arndb.de \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=rmclure@ibm.com \
    --cc=rmclure@linux.ibm.com \
    /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.