All of lore.kernel.org
 help / color / mirror / Atom feed
From: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
To: paulmck@kernel.org
Cc: frederic@kernel.org, rcu@vger.kernel.org,
	linux-kernel@vger.kernel.org, kernel-team@meta.com,
	rostedt@goodmis.org, kernel test robot <oliver.sang@intel.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Kent Overstreet <kent.overstreet@linux.dev>,
	bpf@vger.kernel.org
Subject: Re: [PATCH rcu 06/12] srcu: Add srcu_read_lock_lite() and srcu_read_unlock_lite()
Date: Mon, 11 Nov 2024 22:21:58 +0530	[thread overview]
Message-ID: <c15d4a80-2f27-4588-af87-9cf7cf3ad79e@amd.com> (raw)
In-Reply-To: <71a72bcc-ba85-4f86-9d41-cccfd433fa09@paulmck-laptop>



On 11/11/2024 8:56 PM, Paul E. McKenney wrote:
> On Mon, Nov 11, 2024 at 06:24:58PM +0530, Neeraj Upadhyay wrote:
>>
>>>  
>>>  /*
>>> - * Returns approximate total of the readers' ->srcu_lock_count[] values
>>> - * for the rank of per-CPU counters specified by idx.
>>> + * Computes approximate total of the readers' ->srcu_lock_count[] values
>>> + * for the rank of per-CPU counters specified by idx, and returns true if
>>> + * the caller did the proper barrier (gp), and if the count of the locks
>>> + * matches that of the unlocks passed in.
>>>   */
>>> -static unsigned long srcu_readers_lock_idx(struct srcu_struct *ssp, int idx)
>>> +static bool srcu_readers_lock_idx(struct srcu_struct *ssp, int idx, bool gp, unsigned long unlocks)
>>>  {
>>>  	int cpu;
>>> +	unsigned long mask = 0;
>>>  	unsigned long sum = 0;
>>>  
>>>  	for_each_possible_cpu(cpu) {
>>>  		struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);
>>>  
>>>  		sum += atomic_long_read(&sdp->srcu_lock_count[idx]);
>>> +		if (IS_ENABLED(CONFIG_PROVE_RCU))
>>> +			mask = mask | READ_ONCE(sdp->srcu_reader_flavor);
>>>  	}
>>> -	return sum;
>>> +	WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) && (mask & (mask - 1)),
>>> +		  "Mixed reader flavors for srcu_struct at %ps.\n", ssp);
>>
>> I am trying to understand the (unlikely) case where synchronize_srcu() is done before any
>> srcu reader lock/unlock lite call is done. Can new SRCU readers fail to observe the
>> updates?
> 
> If a SRCU reader fail to observe the index flip, then isn't it the case
> that the synchronize_rcu() invoked from srcu_readers_active_idx_check()
> must wait on it?
> 

Below is the sequence of operations I was thinking of, where at step 4 CPU2
reads old pointer

ptr = old


CPU1                                         CPU2

1. Update ptr = new

2. synchronize_srcu()

<Does not use synchronize_rcu()
 as SRCU_READ_FLAVOR_LITE is not
 set for any sdp as srcu_read_lock_lite()
 hasn't been called by any CPU>

                                      3. srcu_read_lock_lite()
                                        <No smp_mb() ordering>

                                      4.  Can read ptr == old ?


>>> +	if (mask & SRCU_READ_FLAVOR_LITE && !gp)
>>> +		return false;
>>
>> So, srcu_readers_active_idx_check() can potentially return false for very long
>> time, until the CPU executing srcu_readers_active_idx_check() does
>> at least one read lock/unlock lite call?
> 
> That is correct.  The theory is that until after an srcu_read_lock_lite()
> has executed, there is no need to wait on it.  Does the practice match the
> theory in this case, or is there some sequence of events that I missed?
> 

Below sequence

CPU1                     CPU2     
                       1. srcu_read_lock_lite()
                       
                       
                       2. srcu_read_unlock_lite()

3. synchronize_srcu()

3.1 srcu_readers_lock_idx() is
called with gp = false as
srcu_read_lock_lite() was never
called on this CPU for this
srcu_struct. So
ssp->sda->srcu_reader_flavor is not
set for CPU1's sda.

3.2 Inside srcu_readers_lock_idx()
"mask" contains SRCU_READ_FLAVOR_LITE
as CPU2's sdp->srcu_reader_flavor has it.

3.3 CPU1 keeps returning false from
below check until CPU1 does at least
one srcu_read_lock_lite() call or
the thread migrates.

if (mask & SRCU_READ_FLAVOR_LITE && !gp)
  return false;


>>> +	return sum == unlocks;
>>>  }
>>>  
>>>  /*
>>> @@ -473,6 +482,7 @@ static unsigned long srcu_readers_unlock_idx(struct srcu_struct *ssp, int idx)
>>>   */
>>>  static bool srcu_readers_active_idx_check(struct srcu_struct *ssp, int idx)
>>>  {
>>> +	bool did_gp = !!(raw_cpu_read(ssp->sda->srcu_reader_flavor) & SRCU_READ_FLAVOR_LITE);
>>
>> sda->srcu_reader_flavor is only set when CONFIG_PROVE_RCU is enabled. But we
>> need the reader flavor information for srcu lite variant to work. So, lite
>> variant does not work when CONFIG_PROVE_RCU is disabled. Am I missing something
>> obvious here?
> 
> At first glance, it appears that I am the one who missed something obvious.
> Including in testing, which failed to uncover this issue.
> 
> Thank you for the careful reviews!
> 

Sure thing, no problem!


- Neeraj

> 							Thanx, Paul
> 
>> - Neeraj
>>
>>>  	unsigned long unlocks;
>>>  
>>>  	unlocks = srcu_readers_unlock_idx(ssp, idx);
>>> @@ -482,13 +492,16 @@ static bool srcu_readers_active_idx_check(struct srcu_struct *ssp, int idx)
>>>  	 * unlock is counted. Needs to be a smp_mb() as the read side may
>>>  	 * contain a read from a variable that is written to before the
>>>  	 * synchronize_srcu() in the write side. In this case smp_mb()s
>>> -	 * A and B act like the store buffering pattern.
>>> +	 * A and B (or X and Y) act like the store buffering pattern.
>>>  	 *
>>> -	 * This smp_mb() also pairs with smp_mb() C to prevent accesses
>>> -	 * after the synchronize_srcu() from being executed before the
>>> -	 * grace period ends.
>>> +	 * This smp_mb() also pairs with smp_mb() C (or, in the case of X,
>>> +	 * Z) to prevent accesses after the synchronize_srcu() from being
>>> +	 * executed before the grace period ends.
>>>  	 */
>>> -	smp_mb(); /* A */
>>> +	if (!did_gp)
>>> +		smp_mb(); /* A */
>>> +	else
>>> +		synchronize_rcu(); /* X */
>>>  
>>>  	/*
>>>  	 * If the locks are the same as the unlocks, then there must have
>>> @@ -546,7 +559,7 @@ static bool srcu_readers_active_idx_check(struct srcu_struct *ssp, int idx)
>>>  	 * which are unlikely to be configured with an address space fully
>>>  	 * populated with memory, at least not anytime soon.
>>>  	 */
>>> -	return srcu_readers_lock_idx(ssp, idx) == unlocks;
>>> +	return srcu_readers_lock_idx(ssp, idx, did_gp, unlocks);
>>>  }
>>>  
>>

  reply	other threads:[~2024-11-11 16:52 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-09 18:07 [PATCH rcu 0/12] SRCU-lite changes for v6.13 Paul E. McKenney
2024-10-09 18:07 ` [PATCH rcu 01/12] srcu: Rename srcu_might_be_idle() to srcu_should_expedite() Paul E. McKenney
2024-10-14  8:56   ` Neeraj Upadhyay
2024-10-09 18:07 ` [PATCH rcu 02/12] srcu: Introduce srcu_gp_is_expedited() helper function Paul E. McKenney
2024-10-14  8:57   ` Neeraj Upadhyay
2024-10-09 18:07 ` [PATCH rcu 03/12] srcu: Renaming in preparation for additional reader flavor Paul E. McKenney
2024-10-14  9:10   ` Neeraj Upadhyay
2024-10-14 16:52     ` Paul E. McKenney
2024-10-15  3:25       ` Neeraj Upadhyay
2024-10-09 18:07 ` [PATCH rcu 04/12] srcu: Bit manipulation changes " Paul E. McKenney
2024-10-14  9:12   ` Neeraj Upadhyay
2024-10-14 16:51     ` Paul E. McKenney
2024-10-15  3:32       ` Neeraj Upadhyay
2024-10-09 18:07 ` [PATCH rcu 05/12] srcu: Standardize srcu_data pointers to "sdp" and similar Paul E. McKenney
2024-10-14  9:15   ` Neeraj Upadhyay
2024-10-14 16:49     ` Paul E. McKenney
2024-10-15  0:29       ` Paul E. McKenney
2024-10-15  5:10         ` Neeraj Upadhyay
2024-10-09 18:07 ` [PATCH rcu 06/12] srcu: Add srcu_read_lock_lite() and srcu_read_unlock_lite() Paul E. McKenney
2024-11-11 12:54   ` Neeraj Upadhyay
2024-11-11 15:26     ` Paul E. McKenney
2024-11-11 16:51       ` Neeraj Upadhyay [this message]
2024-11-12  1:28         ` Paul E. McKenney
2024-11-12  1:31           ` [PATCH rcu 1/3] srcu: Remove smp_mb() from srcu_read_unlock_lite() Paul E. McKenney
2024-11-12  3:17             ` Neeraj Upadhyay
2024-11-12  1:31           ` [PATCH rcu 2/3] srcu: Check for srcu_read_lock_lite() across all CPUs Paul E. McKenney
2024-11-12  3:28             ` Neeraj Upadhyay
2024-11-12  5:48               ` Paul E. McKenney
2024-11-12  1:31           ` [PATCH rcu 3/3] srcu: Unconditionally record srcu_read_lock_lite() in ->srcu_reader_flavor Paul E. McKenney
2024-11-12  4:32             ` Neeraj Upadhyay
2024-11-12  3:15           ` [PATCH rcu 06/12] srcu: Add srcu_read_lock_lite() and srcu_read_unlock_lite() Neeraj Upadhyay
2024-10-09 18:07 ` [PATCH rcu 07/12] srcu: Allow inlining of __srcu_read_{,un}lock_lite() Paul E. McKenney
2024-10-09 18:07 ` [PATCH rcu 08/12] rcutorture: Expand RCUTORTURE_RDR_MASK_[12] to eight bits Paul E. McKenney
2024-10-09 18:07 ` [PATCH rcu 09/12] rcutorture: Add reader_flavor parameter for SRCU readers Paul E. McKenney
2024-10-09 18:07 ` [PATCH rcu 10/12] rcutorture: Add srcu_read_lock_lite() support to rcutorture.reader_flavor Paul E. McKenney
2024-10-09 18:07 ` [PATCH rcu 11/12] rcutorture: Add light-weight SRCU scenario Paul E. McKenney
2024-10-09 18:07 ` [PATCH rcu 12/12] refscale: Add srcu_read_lock_lite() support using "srcu-lite" Paul E. McKenney
2024-10-10 15:38   ` Frederic Weisbecker
2024-10-10 16:06     ` Paul E. McKenney
2024-10-11 17:39 ` [PATCH v2 rcu 0/13] SRCU-lite changes for v6.13 Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 01/13] srcu: Rename srcu_might_be_idle() to srcu_should_expedite() Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 02/13] srcu: Introduce srcu_gp_is_expedited() helper function Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 03/13] srcu: Renaming in preparation for additional reader flavor Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 04/13] srcu: Bit manipulation changes " Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 05/13] srcu: Standardize srcu_data pointers to "sdp" and similar Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 06/13] srcu: Add srcu_read_lock_lite() and srcu_read_unlock_lite() Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 07/13] srcu: Allow inlining of __srcu_read_{,un}lock_lite() Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 08/13] rcutorture: Expand RCUTORTURE_RDR_MASK_[12] to eight bits Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 09/13] rcutorture: Add reader_flavor parameter for SRCU readers Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 10/13] rcutorture: Add srcu_read_lock_lite() support to rcutorture.reader_flavor Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 11/13] rcutorture: Add light-weight SRCU scenario Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 12/13] refscale: Add srcu_read_lock_lite() support using "srcu-lite" Paul E. McKenney
2024-10-11 17:39   ` [PATCH v2 rcu 13/13] srcu: Improve srcu_read_lock_lite() kernel-doc comment Paul E. McKenney
2024-10-11 17:57     ` Andrii Nakryiko
2024-10-15 15:59       ` Paul E. McKenney
2024-10-15 16:11   ` [PATCH v3 rcu 0/13] SRCU-lite changes for v6.13 Paul E. McKenney
2024-10-15 16:10     ` [PATCH rcu 01/15] srcu: Rename srcu_might_be_idle() to srcu_should_expedite() Paul E. McKenney
2024-10-15 16:10     ` [PATCH rcu 02/15] srcu: Introduce srcu_gp_is_expedited() helper function Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 03/15] srcu: Renaming in preparation for additional reader flavor Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 04/15] srcu: Bit manipulation changes " Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 05/15] srcu: Standardize srcu_data pointers to "sdp" and similar Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 06/15] srcu: Improve srcu_read_lock{,_nmisafe}() comments Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 07/15] srcu: Create CPP macros for normal and NMI-safe SRCU readers Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 08/15] srcu: Add srcu_read_lock_lite() and srcu_read_unlock_lite() Paul E. McKenney
2024-11-04 23:27       ` Frederic Weisbecker
2024-11-05  0:39         ` Paul E. McKenney
2024-11-11 11:17       ` Neeraj Upadhyay
2024-11-11 15:17         ` Paul E. McKenney
2024-11-11 17:46           ` Andrii Nakryiko
2024-11-11 17:51             ` Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 09/15] srcu: Allow inlining of __srcu_read_{,un}lock_lite() Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 10/15] rcutorture: Expand RCUTORTURE_RDR_MASK_[12] to eight bits Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 11/15] rcutorture: Add reader_flavor parameter for SRCU readers Paul E. McKenney
2024-11-12  4:42       ` Neeraj Upadhyay
2024-11-12 19:27         ` Paul E. McKenney
2024-11-13  3:20           ` Neeraj Upadhyay
2024-10-15 16:11     ` [PATCH rcu 12/15] rcutorture: Add srcu_read_lock_lite() support to rcutorture.reader_flavor Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 13/15] rcutorture: Add light-weight SRCU scenario Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 14/15] refscale: Add srcu_read_lock_lite() support using "srcu-lite" Paul E. McKenney
2024-10-29  0:25       ` [PATCH rcu v4 " Paul E. McKenney
2024-10-15 16:11     ` [PATCH rcu 15/15] srcu: Improve srcu_read_lock_lite() kernel-doc comment Paul E. McKenney
2024-11-12  4:37     ` [PATCH v3 rcu 0/13] SRCU-lite changes for v6.13 Neeraj Upadhyay

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=c15d4a80-2f27-4588-af87-9cf7cf3ad79e@amd.com \
    --to=neeraj.upadhyay@amd.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=frederic@kernel.org \
    --cc=kent.overstreet@linux.dev \
    --cc=kernel-team@meta.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oliver.sang@intel.com \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rcu@vger.kernel.org \
    --cc=rostedt@goodmis.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.