diff mbox series

srcu: Guarantee non-negative return value from srcu_read_lock()

Message ID 97594073-e296-4876-9d6a-1e4a4f33d857@paulmck-laptop (mailing list archive)
State New
Headers show
Series srcu: Guarantee non-negative return value from srcu_read_lock() | expand

Commit Message

Paul E. McKenney Oct. 21, 2024, 10:13 p.m. UTC
For almost 20 years, the int return value from srcu_read_lock() has
been always either zero or one.  This commit therefore documents the
fact that it will be non-negative.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andrii Nakryiko <andrii@kernel.org

Comments

Andrii Nakryiko Oct. 21, 2024, 11:50 p.m. UTC | #1
On Mon, Oct 21, 2024 at 3:13 PM Paul E. McKenney <paulmck@kernel.org> wrote:
>
> For almost 20 years, the int return value from srcu_read_lock() has
> been always either zero or one.  This commit therefore documents the
> fact that it will be non-negative.
>
> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Andrii Nakryiko <andrii@kernel.org
>
> diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> index bab1dae3f69e6..512a8c54ba5ba 100644
> --- a/include/linux/srcu.h
> +++ b/include/linux/srcu.h
> @@ -238,13 +238,14 @@ void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
>   * a mutex that is held elsewhere while calling synchronize_srcu() or
>   * synchronize_srcu_expedited().
>   *
> - * The return value from srcu_read_lock() must be passed unaltered
> - * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
> - * the matching srcu_read_unlock() must occur in the same context, for
> - * example, it is illegal to invoke srcu_read_unlock() in an irq handler
> - * if the matching srcu_read_lock() was invoked in process context.  Or,
> - * for that matter to invoke srcu_read_unlock() from one task and the
> - * matching srcu_read_lock() from another.
> + * The return value from srcu_read_lock() is guaranteed to be
> + * non-negative.  This value must be passed unaltered to the matching
> + * srcu_read_unlock().  Note that srcu_read_lock() and the matching
> + * srcu_read_unlock() must occur in the same context, for example, it is
> + * illegal to invoke srcu_read_unlock() in an irq handler if the matching
> + * srcu_read_lock() was invoked in process context.  Or, for that matter to
> + * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
> + * from another.

For uprobe work I'm using __srcu_read_lock() and __srcu_read_unlock().
Presumably the same non-negative index will be returned/consumed there
as well, right? Can we add a blurb to that effect for them as well?

Otherwise LGTM, thanks!

Acked-by: Andrii Nakryiko <andrii@kernel.org>

>   */
>  static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
>  {
Paul E. McKenney Oct. 22, 2024, 12:21 a.m. UTC | #2
On Mon, Oct 21, 2024 at 04:50:44PM -0700, Andrii Nakryiko wrote:
> On Mon, Oct 21, 2024 at 3:13 PM Paul E. McKenney <paulmck@kernel.org> wrote:
> >
> > For almost 20 years, the int return value from srcu_read_lock() has
> > been always either zero or one.  This commit therefore documents the
> > fact that it will be non-negative.
> >
> > Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Cc: Andrii Nakryiko <andrii@kernel.org
> >
> > diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> > index bab1dae3f69e6..512a8c54ba5ba 100644
> > --- a/include/linux/srcu.h
> > +++ b/include/linux/srcu.h
> > @@ -238,13 +238,14 @@ void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
> >   * a mutex that is held elsewhere while calling synchronize_srcu() or
> >   * synchronize_srcu_expedited().
> >   *
> > - * The return value from srcu_read_lock() must be passed unaltered
> > - * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
> > - * the matching srcu_read_unlock() must occur in the same context, for
> > - * example, it is illegal to invoke srcu_read_unlock() in an irq handler
> > - * if the matching srcu_read_lock() was invoked in process context.  Or,
> > - * for that matter to invoke srcu_read_unlock() from one task and the
> > - * matching srcu_read_lock() from another.
> > + * The return value from srcu_read_lock() is guaranteed to be
> > + * non-negative.  This value must be passed unaltered to the matching
> > + * srcu_read_unlock().  Note that srcu_read_lock() and the matching
> > + * srcu_read_unlock() must occur in the same context, for example, it is
> > + * illegal to invoke srcu_read_unlock() in an irq handler if the matching
> > + * srcu_read_lock() was invoked in process context.  Or, for that matter to
> > + * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
> > + * from another.
> 
> For uprobe work I'm using __srcu_read_lock() and __srcu_read_unlock().
> Presumably the same non-negative index will be returned/consumed there
> as well, right? Can we add a blurb to that effect for them as well?

Does the change shown below cover it?

> Otherwise LGTM, thanks!
> 
> Acked-by: Andrii Nakryiko <andrii@kernel.org>

Thank you -- I will apply on my next rebase.

						Thanx, Paul

> >   */
> >  static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
> >  {

------------------------------------------------------------------------

diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index 07147efcb64d3..3d587bf2b2c12 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -738,7 +738,8 @@ EXPORT_SYMBOL_GPL(srcu_check_read_flavor);
 /*
  * Counts the new reader in the appropriate per-CPU element of the
  * srcu_struct.
- * Returns an index that must be passed to the matching srcu_read_unlock().
+ * Returns a guaranteed non-negative index that must be passed to the
+ * matching srcu_read_unlock().
  */
 int __srcu_read_lock(struct srcu_struct *ssp)
 {
Andrii Nakryiko Oct. 22, 2024, 2:01 a.m. UTC | #3
On Mon, Oct 21, 2024 at 5:21 PM Paul E. McKenney <paulmck@kernel.org> wrote:
>
> On Mon, Oct 21, 2024 at 04:50:44PM -0700, Andrii Nakryiko wrote:
> > On Mon, Oct 21, 2024 at 3:13 PM Paul E. McKenney <paulmck@kernel.org> wrote:
> > >
> > > For almost 20 years, the int return value from srcu_read_lock() has
> > > been always either zero or one.  This commit therefore documents the
> > > fact that it will be non-negative.
> > >
> > > Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> > > Cc: Peter Zijlstra <peterz@infradead.org>
> > > Cc: Andrii Nakryiko <andrii@kernel.org
> > >
> > > diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> > > index bab1dae3f69e6..512a8c54ba5ba 100644
> > > --- a/include/linux/srcu.h
> > > +++ b/include/linux/srcu.h
> > > @@ -238,13 +238,14 @@ void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
> > >   * a mutex that is held elsewhere while calling synchronize_srcu() or
> > >   * synchronize_srcu_expedited().
> > >   *
> > > - * The return value from srcu_read_lock() must be passed unaltered
> > > - * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
> > > - * the matching srcu_read_unlock() must occur in the same context, for
> > > - * example, it is illegal to invoke srcu_read_unlock() in an irq handler
> > > - * if the matching srcu_read_lock() was invoked in process context.  Or,
> > > - * for that matter to invoke srcu_read_unlock() from one task and the
> > > - * matching srcu_read_lock() from another.
> > > + * The return value from srcu_read_lock() is guaranteed to be
> > > + * non-negative.  This value must be passed unaltered to the matching
> > > + * srcu_read_unlock().  Note that srcu_read_lock() and the matching
> > > + * srcu_read_unlock() must occur in the same context, for example, it is
> > > + * illegal to invoke srcu_read_unlock() in an irq handler if the matching
> > > + * srcu_read_lock() was invoked in process context.  Or, for that matter to
> > > + * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
> > > + * from another.
> >
> > For uprobe work I'm using __srcu_read_lock() and __srcu_read_unlock().
> > Presumably the same non-negative index will be returned/consumed there
> > as well, right? Can we add a blurb to that effect for them as well?
>
> Does the change shown below cover it?

Yep, looks good, thank you! You might want to fix
s/srcu_read_unlock/__srcu_read_unlock/, while at it, but that's
orthogonal.

>
> > Otherwise LGTM, thanks!
> >
> > Acked-by: Andrii Nakryiko <andrii@kernel.org>
>
> Thank you -- I will apply on my next rebase.
>
>                                                 Thanx, Paul
>
> > >   */
> > >  static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
> > >  {
>
> ------------------------------------------------------------------------
>
> diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
> index 07147efcb64d3..3d587bf2b2c12 100644
> --- a/kernel/rcu/srcutree.c
> +++ b/kernel/rcu/srcutree.c
> @@ -738,7 +738,8 @@ EXPORT_SYMBOL_GPL(srcu_check_read_flavor);
>  /*
>   * Counts the new reader in the appropriate per-CPU element of the
>   * srcu_struct.
> - * Returns an index that must be passed to the matching srcu_read_unlock().
> + * Returns a guaranteed non-negative index that must be passed to the
> + * matching srcu_read_unlock().
>   */
>  int __srcu_read_lock(struct srcu_struct *ssp)
>  {
Paul E. McKenney Oct. 22, 2024, 3:30 a.m. UTC | #4
On Mon, Oct 21, 2024 at 07:01:02PM -0700, Andrii Nakryiko wrote:
> On Mon, Oct 21, 2024 at 5:21 PM Paul E. McKenney <paulmck@kernel.org> wrote:
> >
> > On Mon, Oct 21, 2024 at 04:50:44PM -0700, Andrii Nakryiko wrote:
> > > On Mon, Oct 21, 2024 at 3:13 PM Paul E. McKenney <paulmck@kernel.org> wrote:
> > > >
> > > > For almost 20 years, the int return value from srcu_read_lock() has
> > > > been always either zero or one.  This commit therefore documents the
> > > > fact that it will be non-negative.
> > > >
> > > > Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> > > > Cc: Peter Zijlstra <peterz@infradead.org>
> > > > Cc: Andrii Nakryiko <andrii@kernel.org
> > > >
> > > > diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> > > > index bab1dae3f69e6..512a8c54ba5ba 100644
> > > > --- a/include/linux/srcu.h
> > > > +++ b/include/linux/srcu.h
> > > > @@ -238,13 +238,14 @@ void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
> > > >   * a mutex that is held elsewhere while calling synchronize_srcu() or
> > > >   * synchronize_srcu_expedited().
> > > >   *
> > > > - * The return value from srcu_read_lock() must be passed unaltered
> > > > - * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
> > > > - * the matching srcu_read_unlock() must occur in the same context, for
> > > > - * example, it is illegal to invoke srcu_read_unlock() in an irq handler
> > > > - * if the matching srcu_read_lock() was invoked in process context.  Or,
> > > > - * for that matter to invoke srcu_read_unlock() from one task and the
> > > > - * matching srcu_read_lock() from another.
> > > > + * The return value from srcu_read_lock() is guaranteed to be
> > > > + * non-negative.  This value must be passed unaltered to the matching
> > > > + * srcu_read_unlock().  Note that srcu_read_lock() and the matching
> > > > + * srcu_read_unlock() must occur in the same context, for example, it is
> > > > + * illegal to invoke srcu_read_unlock() in an irq handler if the matching
> > > > + * srcu_read_lock() was invoked in process context.  Or, for that matter to
> > > > + * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
> > > > + * from another.
> > >
> > > For uprobe work I'm using __srcu_read_lock() and __srcu_read_unlock().
> > > Presumably the same non-negative index will be returned/consumed there
> > > as well, right? Can we add a blurb to that effect for them as well?
> >
> > Does the change shown below cover it?
> 
> Yep, looks good, thank you! You might want to fix
> s/srcu_read_unlock/__srcu_read_unlock/, while at it, but that's
> orthogonal.

As long as we are in the area...  Please see below for the update.

Thoughts?

							Thanx, Paul

------------------------------------------------------------------------

commit 4433b7d3785d8d2a700f5ed5ca234c64bc63180e
Author: Paul E. McKenney <paulmck@kernel.org>
Date:   Mon Oct 21 15:09:39 2024 -0700

    srcu: Guarantee non-negative return value from srcu_read_lock()
    
    For almost 20 years, the int return value from srcu_read_lock() has
    been always either zero or one.  This commit therefore documents the
    fact that it will be non-negative, and does the same for the underlying
    __srcu_read_lock().
    
    [ paulmck: Apply Andrii Nakryiko feedback. ]
    
    Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Acked-by: Andrii Nakryiko <andrii@kernel.org>

diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index bab1dae3f69e6..512a8c54ba5ba 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -238,13 +238,14 @@ void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
  * a mutex that is held elsewhere while calling synchronize_srcu() or
  * synchronize_srcu_expedited().
  *
- * The return value from srcu_read_lock() must be passed unaltered
- * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
- * the matching srcu_read_unlock() must occur in the same context, for
- * example, it is illegal to invoke srcu_read_unlock() in an irq handler
- * if the matching srcu_read_lock() was invoked in process context.  Or,
- * for that matter to invoke srcu_read_unlock() from one task and the
- * matching srcu_read_lock() from another.
+ * The return value from srcu_read_lock() is guaranteed to be
+ * non-negative.  This value must be passed unaltered to the matching
+ * srcu_read_unlock().  Note that srcu_read_lock() and the matching
+ * srcu_read_unlock() must occur in the same context, for example, it is
+ * illegal to invoke srcu_read_unlock() in an irq handler if the matching
+ * srcu_read_lock() was invoked in process context.  Or, for that matter to
+ * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
+ * from another.
  */
 static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
 {
diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index 07147efcb64d3..ae17c214e0de5 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -738,7 +738,8 @@ EXPORT_SYMBOL_GPL(srcu_check_read_flavor);
 /*
  * Counts the new reader in the appropriate per-CPU element of the
  * srcu_struct.
- * Returns an index that must be passed to the matching srcu_read_unlock().
+ * Returns a guaranteed non-negative index that must be passed to the
+ * matching __srcu_read_unlock().
  */
 int __srcu_read_lock(struct srcu_struct *ssp)
 {
Andrii Nakryiko Oct. 22, 2024, 3:40 a.m. UTC | #5
On Mon, Oct 21, 2024 at 8:30 PM Paul E. McKenney <paulmck@kernel.org> wrote:
>
> On Mon, Oct 21, 2024 at 07:01:02PM -0700, Andrii Nakryiko wrote:
> > On Mon, Oct 21, 2024 at 5:21 PM Paul E. McKenney <paulmck@kernel.org> wrote:
> > >
> > > On Mon, Oct 21, 2024 at 04:50:44PM -0700, Andrii Nakryiko wrote:
> > > > On Mon, Oct 21, 2024 at 3:13 PM Paul E. McKenney <paulmck@kernel.org> wrote:
> > > > >
> > > > > For almost 20 years, the int return value from srcu_read_lock() has
> > > > > been always either zero or one.  This commit therefore documents the
> > > > > fact that it will be non-negative.
> > > > >
> > > > > Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> > > > > Cc: Peter Zijlstra <peterz@infradead.org>
> > > > > Cc: Andrii Nakryiko <andrii@kernel.org
> > > > >
> > > > > diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> > > > > index bab1dae3f69e6..512a8c54ba5ba 100644
> > > > > --- a/include/linux/srcu.h
> > > > > +++ b/include/linux/srcu.h
> > > > > @@ -238,13 +238,14 @@ void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
> > > > >   * a mutex that is held elsewhere while calling synchronize_srcu() or
> > > > >   * synchronize_srcu_expedited().
> > > > >   *
> > > > > - * The return value from srcu_read_lock() must be passed unaltered
> > > > > - * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
> > > > > - * the matching srcu_read_unlock() must occur in the same context, for
> > > > > - * example, it is illegal to invoke srcu_read_unlock() in an irq handler
> > > > > - * if the matching srcu_read_lock() was invoked in process context.  Or,
> > > > > - * for that matter to invoke srcu_read_unlock() from one task and the
> > > > > - * matching srcu_read_lock() from another.
> > > > > + * The return value from srcu_read_lock() is guaranteed to be
> > > > > + * non-negative.  This value must be passed unaltered to the matching
> > > > > + * srcu_read_unlock().  Note that srcu_read_lock() and the matching
> > > > > + * srcu_read_unlock() must occur in the same context, for example, it is
> > > > > + * illegal to invoke srcu_read_unlock() in an irq handler if the matching
> > > > > + * srcu_read_lock() was invoked in process context.  Or, for that matter to
> > > > > + * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
> > > > > + * from another.
> > > >
> > > > For uprobe work I'm using __srcu_read_lock() and __srcu_read_unlock().
> > > > Presumably the same non-negative index will be returned/consumed there
> > > > as well, right? Can we add a blurb to that effect for them as well?
> > >
> > > Does the change shown below cover it?
> >
> > Yep, looks good, thank you! You might want to fix
> > s/srcu_read_unlock/__srcu_read_unlock/, while at it, but that's
> > orthogonal.
>
> As long as we are in the area...  Please see below for the update.
>
> Thoughts?
>

LGTM

Acked-by: Andrii Nakryiko <andrii@kernel.org>

>                                                         Thanx, Paul
>
> ------------------------------------------------------------------------
>
> commit 4433b7d3785d8d2a700f5ed5ca234c64bc63180e
> Author: Paul E. McKenney <paulmck@kernel.org>
> Date:   Mon Oct 21 15:09:39 2024 -0700
>
>     srcu: Guarantee non-negative return value from srcu_read_lock()
>
>     For almost 20 years, the int return value from srcu_read_lock() has
>     been always either zero or one.  This commit therefore documents the
>     fact that it will be non-negative, and does the same for the underlying
>     __srcu_read_lock().
>
>     [ paulmck: Apply Andrii Nakryiko feedback. ]
>
>     Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
>     Cc: Peter Zijlstra <peterz@infradead.org>
>     Acked-by: Andrii Nakryiko <andrii@kernel.org>
>
> diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> index bab1dae3f69e6..512a8c54ba5ba 100644
> --- a/include/linux/srcu.h
> +++ b/include/linux/srcu.h
> @@ -238,13 +238,14 @@ void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
>   * a mutex that is held elsewhere while calling synchronize_srcu() or
>   * synchronize_srcu_expedited().
>   *
> - * The return value from srcu_read_lock() must be passed unaltered
> - * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
> - * the matching srcu_read_unlock() must occur in the same context, for
> - * example, it is illegal to invoke srcu_read_unlock() in an irq handler
> - * if the matching srcu_read_lock() was invoked in process context.  Or,
> - * for that matter to invoke srcu_read_unlock() from one task and the
> - * matching srcu_read_lock() from another.
> + * The return value from srcu_read_lock() is guaranteed to be
> + * non-negative.  This value must be passed unaltered to the matching
> + * srcu_read_unlock().  Note that srcu_read_lock() and the matching
> + * srcu_read_unlock() must occur in the same context, for example, it is
> + * illegal to invoke srcu_read_unlock() in an irq handler if the matching
> + * srcu_read_lock() was invoked in process context.  Or, for that matter to
> + * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
> + * from another.
>   */
>  static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
>  {
> diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
> index 07147efcb64d3..ae17c214e0de5 100644
> --- a/kernel/rcu/srcutree.c
> +++ b/kernel/rcu/srcutree.c
> @@ -738,7 +738,8 @@ EXPORT_SYMBOL_GPL(srcu_check_read_flavor);
>  /*
>   * Counts the new reader in the appropriate per-CPU element of the
>   * srcu_struct.
> - * Returns an index that must be passed to the matching srcu_read_unlock().
> + * Returns a guaranteed non-negative index that must be passed to the
> + * matching __srcu_read_unlock().
>   */
>  int __srcu_read_lock(struct srcu_struct *ssp)
>  {
Christoph Hellwig Oct. 22, 2024, 6:51 a.m. UTC | #6
On Mon, Oct 21, 2024 at 03:13:05PM -0700, Paul E. McKenney wrote:
> For almost 20 years, the int return value from srcu_read_lock() has
> been always either zero or one.  This commit therefore documents the
> fact that it will be non-negative.

If it is always zero or one, wouldn't bool the better return value
type?
Peter Zijlstra Oct. 22, 2024, 7:06 a.m. UTC | #7
On Mon, Oct 21, 2024 at 11:51:40PM -0700, Christoph Hellwig wrote:
> On Mon, Oct 21, 2024 at 03:13:05PM -0700, Paul E. McKenney wrote:
> > For almost 20 years, the int return value from srcu_read_lock() has
> > been always either zero or one.  This commit therefore documents the
> > fact that it will be non-negative.
> 
> If it is always zero or one, wouldn't bool the better return value
> type?

What is returned is an array index -- and SRCU is currently built using
an array of size 2. Using larger arrays is conceivable (IIRC some
versions of preemptible RCU used up to 4 or something).

So while the values 0,1 are possible inside bool, that does not reflect
the nature of the numbers, which is an array index. Mapping that onto
bool would be slightly confusing (and limit possible future extention of
using larger arrays for SRCU).
Peter Zijlstra Oct. 22, 2024, 7:07 a.m. UTC | #8
On Mon, Oct 21, 2024 at 08:30:43PM -0700, Paul E. McKenney wrote:
> Thoughts?

Thanks Paul!

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>

> ------------------------------------------------------------------------
> 
> commit 4433b7d3785d8d2a700f5ed5ca234c64bc63180e
> Author: Paul E. McKenney <paulmck@kernel.org>
> Date:   Mon Oct 21 15:09:39 2024 -0700
> 
>     srcu: Guarantee non-negative return value from srcu_read_lock()
>     
>     For almost 20 years, the int return value from srcu_read_lock() has
>     been always either zero or one.  This commit therefore documents the
>     fact that it will be non-negative, and does the same for the underlying
>     __srcu_read_lock().
>     
>     [ paulmck: Apply Andrii Nakryiko feedback. ]
>     
>     Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
>     Cc: Peter Zijlstra <peterz@infradead.org>
>     Acked-by: Andrii Nakryiko <andrii@kernel.org>
> 
> diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> index bab1dae3f69e6..512a8c54ba5ba 100644
> --- a/include/linux/srcu.h
> +++ b/include/linux/srcu.h
> @@ -238,13 +238,14 @@ void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
>   * a mutex that is held elsewhere while calling synchronize_srcu() or
>   * synchronize_srcu_expedited().
>   *
> - * The return value from srcu_read_lock() must be passed unaltered
> - * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
> - * the matching srcu_read_unlock() must occur in the same context, for
> - * example, it is illegal to invoke srcu_read_unlock() in an irq handler
> - * if the matching srcu_read_lock() was invoked in process context.  Or,
> - * for that matter to invoke srcu_read_unlock() from one task and the
> - * matching srcu_read_lock() from another.
> + * The return value from srcu_read_lock() is guaranteed to be
> + * non-negative.  This value must be passed unaltered to the matching
> + * srcu_read_unlock().  Note that srcu_read_lock() and the matching
> + * srcu_read_unlock() must occur in the same context, for example, it is
> + * illegal to invoke srcu_read_unlock() in an irq handler if the matching
> + * srcu_read_lock() was invoked in process context.  Or, for that matter to
> + * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
> + * from another.
>   */
>  static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
>  {
> diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
> index 07147efcb64d3..ae17c214e0de5 100644
> --- a/kernel/rcu/srcutree.c
> +++ b/kernel/rcu/srcutree.c
> @@ -738,7 +738,8 @@ EXPORT_SYMBOL_GPL(srcu_check_read_flavor);
>  /*
>   * Counts the new reader in the appropriate per-CPU element of the
>   * srcu_struct.
> - * Returns an index that must be passed to the matching srcu_read_unlock().
> + * Returns a guaranteed non-negative index that must be passed to the
> + * matching __srcu_read_unlock().
>   */
>  int __srcu_read_lock(struct srcu_struct *ssp)
>  {
Christoph Hellwig Oct. 22, 2024, 7:07 a.m. UTC | #9
On Tue, Oct 22, 2024 at 09:06:35AM +0200, Peter Zijlstra wrote:
> What is returned is an array index -- and SRCU is currently built using
> an array of size 2. Using larger arrays is conceivable (IIRC some
> versions of preemptible RCU used up to 4 or something).
> 
> So while the values 0,1 are possible inside bool, that does not reflect
> the nature of the numbers, which is an array index. Mapping that onto
> bool would be slightly confusing (and limit possible future extention of
> using larger arrays for SRCU).

Ok, make sense.  Maybe add this to the comment if we're updating іt.
But using an unsigned return value might still be useful.
Peter Zijlstra Oct. 22, 2024, 7:10 a.m. UTC | #10
On Tue, Oct 22, 2024 at 12:07:35AM -0700, Christoph Hellwig wrote:
> On Tue, Oct 22, 2024 at 09:06:35AM +0200, Peter Zijlstra wrote:
> > What is returned is an array index -- and SRCU is currently built using
> > an array of size 2. Using larger arrays is conceivable (IIRC some
> > versions of preemptible RCU used up to 4 or something).
> > 
> > So while the values 0,1 are possible inside bool, that does not reflect
> > the nature of the numbers, which is an array index. Mapping that onto
> > bool would be slightly confusing (and limit possible future extention of
> > using larger arrays for SRCU).
> 
> Ok, make sense.  Maybe add this to the comment if we're updating іt.
> But using an unsigned return value might still be useful.

Ah, well, the thing that got us here is that we (Andrii and me) wanted
to use -1 as an 'invalid' value to indicate SRCU is not currently in
use.

So it all being int is really rather convenient :-)
Christoph Hellwig Oct. 22, 2024, 7:13 a.m. UTC | #11
On Tue, Oct 22, 2024 at 09:10:18AM +0200, Peter Zijlstra wrote:
> Ah, well, the thing that got us here is that we (Andrii and me) wanted
> to use -1 as an 'invalid' value to indicate SRCU is not currently in
> use.
> 
> So it all being int is really rather convenient :-)

Then please document that use.  Maybe even with a symolic name for
-1 that clearly describes these uses.
Paul E. McKenney Oct. 22, 2024, 2:26 p.m. UTC | #12
On Tue, Oct 22, 2024 at 12:13:12AM -0700, Christoph Hellwig wrote:
> On Tue, Oct 22, 2024 at 09:10:18AM +0200, Peter Zijlstra wrote:
> > Ah, well, the thing that got us here is that we (Andrii and me) wanted
> > to use -1 as an 'invalid' value to indicate SRCU is not currently in
> > use.
> > 
> > So it all being int is really rather convenient :-)
> 
> Then please document that use.  Maybe even with a symolic name for
> -1 that clearly describes these uses.

Would this work?

#define SRCU_INVALID_INDEX -1

Whatever the name, maybe Peter and Andrii define this under #ifndef
right now, and we get it into include/linux/srcu.h over time.

Or is there a better way?  Or name, for that matter.

							Thanx, Paul
Paul E. McKenney Oct. 22, 2024, 2:27 p.m. UTC | #13
On Tue, Oct 22, 2024 at 09:07:17AM +0200, Peter Zijlstra wrote:
> On Mon, Oct 21, 2024 at 08:30:43PM -0700, Paul E. McKenney wrote:
> > Thoughts?
> 
> Thanks Paul!
> 
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Thank you, Peter!  I will apply this on my next rebase.

							Thanx, Paul

> > ------------------------------------------------------------------------
> > 
> > commit 4433b7d3785d8d2a700f5ed5ca234c64bc63180e
> > Author: Paul E. McKenney <paulmck@kernel.org>
> > Date:   Mon Oct 21 15:09:39 2024 -0700
> > 
> >     srcu: Guarantee non-negative return value from srcu_read_lock()
> >     
> >     For almost 20 years, the int return value from srcu_read_lock() has
> >     been always either zero or one.  This commit therefore documents the
> >     fact that it will be non-negative, and does the same for the underlying
> >     __srcu_read_lock().
> >     
> >     [ paulmck: Apply Andrii Nakryiko feedback. ]
> >     
> >     Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> >     Cc: Peter Zijlstra <peterz@infradead.org>
> >     Acked-by: Andrii Nakryiko <andrii@kernel.org>
> > 
> > diff --git a/include/linux/srcu.h b/include/linux/srcu.h
> > index bab1dae3f69e6..512a8c54ba5ba 100644
> > --- a/include/linux/srcu.h
> > +++ b/include/linux/srcu.h
> > @@ -238,13 +238,14 @@ void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
> >   * a mutex that is held elsewhere while calling synchronize_srcu() or
> >   * synchronize_srcu_expedited().
> >   *
> > - * The return value from srcu_read_lock() must be passed unaltered
> > - * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
> > - * the matching srcu_read_unlock() must occur in the same context, for
> > - * example, it is illegal to invoke srcu_read_unlock() in an irq handler
> > - * if the matching srcu_read_lock() was invoked in process context.  Or,
> > - * for that matter to invoke srcu_read_unlock() from one task and the
> > - * matching srcu_read_lock() from another.
> > + * The return value from srcu_read_lock() is guaranteed to be
> > + * non-negative.  This value must be passed unaltered to the matching
> > + * srcu_read_unlock().  Note that srcu_read_lock() and the matching
> > + * srcu_read_unlock() must occur in the same context, for example, it is
> > + * illegal to invoke srcu_read_unlock() in an irq handler if the matching
> > + * srcu_read_lock() was invoked in process context.  Or, for that matter to
> > + * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
> > + * from another.
> >   */
> >  static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
> >  {
> > diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
> > index 07147efcb64d3..ae17c214e0de5 100644
> > --- a/kernel/rcu/srcutree.c
> > +++ b/kernel/rcu/srcutree.c
> > @@ -738,7 +738,8 @@ EXPORT_SYMBOL_GPL(srcu_check_read_flavor);
> >  /*
> >   * Counts the new reader in the appropriate per-CPU element of the
> >   * srcu_struct.
> > - * Returns an index that must be passed to the matching srcu_read_unlock().
> > + * Returns a guaranteed non-negative index that must be passed to the
> > + * matching __srcu_read_unlock().
> >   */
> >  int __srcu_read_lock(struct srcu_struct *ssp)
> >  {
Andrii Nakryiko Oct. 22, 2024, 5:29 p.m. UTC | #14
On Tue, Oct 22, 2024 at 7:26 AM Paul E. McKenney <paulmck@kernel.org> wrote:
>
> On Tue, Oct 22, 2024 at 12:13:12AM -0700, Christoph Hellwig wrote:
> > On Tue, Oct 22, 2024 at 09:10:18AM +0200, Peter Zijlstra wrote:
> > > Ah, well, the thing that got us here is that we (Andrii and me) wanted
> > > to use -1 as an 'invalid' value to indicate SRCU is not currently in
> > > use.
> > >
> > > So it all being int is really rather convenient :-)
> >
> > Then please document that use.  Maybe even with a symolic name for
> > -1 that clearly describes these uses.
>
> Would this work?
>
> #define SRCU_INVALID_INDEX -1
>

But why? It's a nice property to have an int-returning API where valid
values are only >= 0, so callers are free to use the entire negative
range (not just -1) for whatever they need to store in case there is
no srcu_idx value.

Why are we complicating something that's simple and straightforward?
It's similar with any fd- and id- returning API.

Marking it as u16 would be fine, but unusual (and probably suboptimal
due to common u16 to int conversion).

Marking it as unsigned int would be bad, because it implies that all
32 bits can be used for valid value, making it impossible to use <0
for something else.

Just documenting that valid int values are always >= is good and
convenient, why not sticking to just that?

> Whatever the name, maybe Peter and Andrii define this under #ifndef
> right now, and we get it into include/linux/srcu.h over time.
>
> Or is there a better way?  Or name, for that matter.
>
>                                                         Thanx, Paul
Christoph Hellwig Oct. 23, 2024, 6:40 a.m. UTC | #15
On Tue, Oct 22, 2024 at 10:29:13AM -0700, Andrii Nakryiko wrote:
> >
> > Would this work?
> >
> > #define SRCU_INVALID_INDEX -1
> >
> 
> But why?

Becaue it very clearly documents what is going on.

>It's a nice property to have an int-returning API where valid
> values are only >= 0, so callers are free to use the entire negative
> range (not just -1) for whatever they need to store in case there is
> no srcu_idx value.

Well, if you have a concrete use case for that we can probably live
with it, but I'd rather have that use case extremely well documented,
as it will be very puzzling to the reader.
Alan Huang Oct. 23, 2024, 6:58 a.m. UTC | #16
On Oct 22, 2024, at 22:26, Paul E. McKenney <paulmck@kernel.org> wrote:
> 
> On Tue, Oct 22, 2024 at 12:13:12AM -0700, Christoph Hellwig wrote:
>> On Tue, Oct 22, 2024 at 09:10:18AM +0200, Peter Zijlstra wrote:
>>> Ah, well, the thing that got us here is that we (Andrii and me) wanted
>>> to use -1 as an 'invalid' value to indicate SRCU is not currently in
>>> use.
>>> 
>>> So it all being int is really rather convenient :-)
>> 
>> Then please document that use.  Maybe even with a symolic name for
>> -1 that clearly describes these uses.
> 
> Would this work?
> 
> #define SRCU_INVALID_INDEX -1

Is there any similar guarantee of the return value of get_state_synchronize_rcu
or start_poll_synchronize_rcu, like invalid value?

> 
> Whatever the name, maybe Peter and Andrii define this under #ifndef
> right now, and we get it into include/linux/srcu.h over time.
> 
> Or is there a better way?  Or name, for that matter.
> 
> Thanx, Paul
>
Andrii Nakryiko Oct. 23, 2024, 4:34 p.m. UTC | #17
On Tue, Oct 22, 2024 at 11:40 PM Christoph Hellwig <hch@infradead.org> wrote:
>
> On Tue, Oct 22, 2024 at 10:29:13AM -0700, Andrii Nakryiko wrote:
> > >
> > > Would this work?
> > >
> > > #define SRCU_INVALID_INDEX -1
> > >
> >
> > But why?
>
> Becaue it very clearly documents what is going on.

So does saying "returned value is going to be non-negative, always".
It's not some weird and unusual thing in C by any means.

>
> >It's a nice property to have an int-returning API where valid
> > values are only >= 0, so callers are free to use the entire negative
> > range (not just -1) for whatever they need to store in case there is
> > no srcu_idx value.
>
> Well, if you have a concrete use case for that we can probably live
> with it, but I'd rather have that use case extremely well documented,
> as it will be very puzzling to the reader.
>

See [0] for what Peter is proposing. Note hprobe_init() and its use of
`srcu_idx < 0` as a mark that there is no SRCU "session" associated
with the uprobe. Now, if we say that SRCU_INVALID_INDEX is the only
invalid value, it leaves a question: what to do with other negative
srcu_idx values? Are they valid? Should I now WARN() on "unknown
invalid" values? Why all these complications? I'd rather just not have
a unified hprobe_init() at that point, TBH.

But anyways, taking a step back. Take idr_alloc()/idr_alloc_cyclic()
APIs as an example. They return int, but valid IDs are documented to
be positive. This leaves users of this API free to use int to store ID
in their data structures, knowing that <= 0 is "no ID", and if
necessary, they can have multiple possible "no ID" situations.

Same principle here. Why prescribing a randomly picked -1 as the only
"valid" invalid value, if anything negative is clearly impossible.


  [0] https://lore.kernel.org/linux-trace-kernel/20241018101647.GA36494@noisy.programming.kicks-ass.net/
Paul E. McKenney Oct. 23, 2024, 4:40 p.m. UTC | #18
On Wed, Oct 23, 2024 at 02:58:07PM +0800, Alan Huang wrote:
> On Oct 22, 2024, at 22:26, Paul E. McKenney <paulmck@kernel.org> wrote:
> > 
> > On Tue, Oct 22, 2024 at 12:13:12AM -0700, Christoph Hellwig wrote:
> >> On Tue, Oct 22, 2024 at 09:10:18AM +0200, Peter Zijlstra wrote:
> >>> Ah, well, the thing that got us here is that we (Andrii and me) wanted
> >>> to use -1 as an 'invalid' value to indicate SRCU is not currently in
> >>> use.
> >>> 
> >>> So it all being int is really rather convenient :-)
> >> 
> >> Then please document that use.  Maybe even with a symolic name for
> >> -1 that clearly describes these uses.
> > 
> > Would this work?
> > 
> > #define SRCU_INVALID_INDEX -1
> 
> Is there any similar guarantee of the return value of get_state_synchronize_rcu
> or start_poll_synchronize_rcu, like invalid value?

Yes, there is a get_completed_synchronize_rcu() function that returns a
value that causes poll_state_synchronize_rcu() to always return true.
There is also a get_completed_synchronize_rcu_full() function that
returns a value that causes poll_state_synchronize_rcu_full() to always
return true.

There has been some discussion of another set of values that cause
poll_state_synchronize_rcu() and poll_state_synchronize_rcu_full() to
always return false, but there is not yet a use case for this.  Easy to
provide if required, but why further explode the RCU API unless it really
is required?

							Thanx, Paul

> > Whatever the name, maybe Peter and Andrii define this under #ifndef
> > right now, and we get it into include/linux/srcu.h over time.
> > 
> > Or is there a better way?  Or name, for that matter.
> > 
> > Thanx, Paul
> > 
>
Alan Huang Oct. 23, 2024, 4:46 p.m. UTC | #19
On Oct 24, 2024, at 00:34, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote:
> 
> On Tue, Oct 22, 2024 at 11:40 PM Christoph Hellwig <hch@infradead.org> wrote:
>> 
>> On Tue, Oct 22, 2024 at 10:29:13AM -0700, Andrii Nakryiko wrote:
>>>> 
>>>> Would this work?
>>>> 
>>>> #define SRCU_INVALID_INDEX -1
>>>> 
>>> 
>>> But why?
>> 
>> Becaue it very clearly documents what is going on.
> 
> So does saying "returned value is going to be non-negative, always".
> It's not some weird and unusual thing in C by any means.
> 
>> 
>>> It's a nice property to have an int-returning API where valid
>>> values are only >= 0, so callers are free to use the entire negative
>>> range (not just -1) for whatever they need to store in case there is
>>> no srcu_idx value.
>> 
>> Well, if you have a concrete use case for that we can probably live
>> with it, but I'd rather have that use case extremely well documented,
>> as it will be very puzzling to the reader.
>> 
> 
> See [0] for what Peter is proposing. Note hprobe_init() and its use of
> `srcu_idx < 0` as a mark that there is no SRCU "session" associated
> with the uprobe. Now, if we say that SRCU_INVALID_INDEX is the only
> invalid value, it leaves a question: what to do with other negative
> srcu_idx values? Are they valid? Should I now WARN() on "unknown
> invalid" values? Why all these complications? I'd rather just not have
> a unified hprobe_init() at that point, TBH.
> 
> But anyways, taking a step back. Take idr_alloc()/idr_alloc_cyclic()
> APIs as an example. They return int, but valid IDs are documented to
> be positive. This leaves users of this API free to use int to store ID
> in their data structures, knowing that <= 0 is "no ID", and if
> necessary, they can have multiple possible "no ID" situations.
> 
> Same principle here. Why prescribing a randomly picked -1 as the only
> "valid" invalid value, if anything negative is clearly impossible.
> 

A IS_INVALID_SRCU_INDEX macro would suffice, you need the condition anyway.

> 
>  [0] https://lore.kernel.org/linux-trace-kernel/20241018101647.GA36494@noisy.programming.kicks-ass.net/
Alan Huang Oct. 23, 2024, 4:56 p.m. UTC | #20
On Oct 24, 2024, at 00:40, Paul E. McKenney <paulmck@kernel.org> wrote:
> 
> On Wed, Oct 23, 2024 at 02:58:07PM +0800, Alan Huang wrote:
>> On Oct 22, 2024, at 22:26, Paul E. McKenney <paulmck@kernel.org> wrote:
>>> 
>>> On Tue, Oct 22, 2024 at 12:13:12AM -0700, Christoph Hellwig wrote:
>>>> On Tue, Oct 22, 2024 at 09:10:18AM +0200, Peter Zijlstra wrote:
>>>>> Ah, well, the thing that got us here is that we (Andrii and me) wanted
>>>>> to use -1 as an 'invalid' value to indicate SRCU is not currently in
>>>>> use.
>>>>> 
>>>>> So it all being int is really rather convenient :-)
>>>> 
>>>> Then please document that use.  Maybe even with a symolic name for
>>>> -1 that clearly describes these uses.
>>> 
>>> Would this work?
>>> 
>>> #define SRCU_INVALID_INDEX -1
>> 
>> Is there any similar guarantee of the return value of get_state_synchronize_rcu
>> or start_poll_synchronize_rcu, like invalid value?
> 
> Yes, there is a get_completed_synchronize_rcu() function that returns a
> value that causes poll_state_synchronize_rcu() to always return true.
> There is also a get_completed_synchronize_rcu_full() function that
> returns a value that causes poll_state_synchronize_rcu_full() to always
> return true.

This is exactly the API I was searching for, didn’t read the doc thoroughly : )

Thanks!

> 
> There has been some discussion of another set of values that cause
> poll_state_synchronize_rcu() and poll_state_synchronize_rcu_full() to
> always return false, but there is not yet a use case for this.  Easy to
> provide if required, but why further explode the RCU API unless it really
> is required?
> 
> Thanx, Paul
> 
>>> Whatever the name, maybe Peter and Andrii define this under #ifndef
>>> right now, and we get it into include/linux/srcu.h over time.
>>> 
>>> Or is there a better way?  Or name, for that matter.
>>> 
>>> Thanx, Paul
>>> 
>>
Andrii Nakryiko Oct. 23, 2024, 4:59 p.m. UTC | #21
On Wed, Oct 23, 2024 at 9:46 AM Alan Huang <mmpgouride@gmail.com> wrote:
>
> On Oct 24, 2024, at 00:34, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote:
> >
> > On Tue, Oct 22, 2024 at 11:40 PM Christoph Hellwig <hch@infradead.org> wrote:
> >>
> >> On Tue, Oct 22, 2024 at 10:29:13AM -0700, Andrii Nakryiko wrote:
> >>>>
> >>>> Would this work?
> >>>>
> >>>> #define SRCU_INVALID_INDEX -1
> >>>>
> >>>
> >>> But why?
> >>
> >> Becaue it very clearly documents what is going on.
> >
> > So does saying "returned value is going to be non-negative, always".
> > It's not some weird and unusual thing in C by any means.
> >
> >>
> >>> It's a nice property to have an int-returning API where valid
> >>> values are only >= 0, so callers are free to use the entire negative
> >>> range (not just -1) for whatever they need to store in case there is
> >>> no srcu_idx value.
> >>
> >> Well, if you have a concrete use case for that we can probably live
> >> with it, but I'd rather have that use case extremely well documented,
> >> as it will be very puzzling to the reader.
> >>
> >
> > See [0] for what Peter is proposing. Note hprobe_init() and its use of
> > `srcu_idx < 0` as a mark that there is no SRCU "session" associated
> > with the uprobe. Now, if we say that SRCU_INVALID_INDEX is the only
> > invalid value, it leaves a question: what to do with other negative
> > srcu_idx values? Are they valid? Should I now WARN() on "unknown
> > invalid" values? Why all these complications? I'd rather just not have
> > a unified hprobe_init() at that point, TBH.
> >
> > But anyways, taking a step back. Take idr_alloc()/idr_alloc_cyclic()
> > APIs as an example. They return int, but valid IDs are documented to
> > be positive. This leaves users of this API free to use int to store ID
> > in their data structures, knowing that <= 0 is "no ID", and if
> > necessary, they can have multiple possible "no ID" situations.
> >
> > Same principle here. Why prescribing a randomly picked -1 as the only
> > "valid" invalid value, if anything negative is clearly impossible.
> >
>
> A IS_INVALID_SRCU_INDEX macro would suffice, you need the condition anyway.

That condition is `if (srcu_idx < 0)`, no need for ugly macros that
obscure things unnecessarily.

>
> >
> >  [0] https://lore.kernel.org/linux-trace-kernel/20241018101647.GA36494@noisy.programming.kicks-ass.net/
>
>
diff mbox series

Patch

diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index bab1dae3f69e6..512a8c54ba5ba 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -238,13 +238,14 @@  void srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);
  * a mutex that is held elsewhere while calling synchronize_srcu() or
  * synchronize_srcu_expedited().
  *
- * The return value from srcu_read_lock() must be passed unaltered
- * to the matching srcu_read_unlock().  Note that srcu_read_lock() and
- * the matching srcu_read_unlock() must occur in the same context, for
- * example, it is illegal to invoke srcu_read_unlock() in an irq handler
- * if the matching srcu_read_lock() was invoked in process context.  Or,
- * for that matter to invoke srcu_read_unlock() from one task and the
- * matching srcu_read_lock() from another.
+ * The return value from srcu_read_lock() is guaranteed to be
+ * non-negative.  This value must be passed unaltered to the matching
+ * srcu_read_unlock().  Note that srcu_read_lock() and the matching
+ * srcu_read_unlock() must occur in the same context, for example, it is
+ * illegal to invoke srcu_read_unlock() in an irq handler if the matching
+ * srcu_read_lock() was invoked in process context.  Or, for that matter to
+ * invoke srcu_read_unlock() from one task and the matching srcu_read_lock()
+ * from another.
  */
 static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
 {