[PATCH bpf-next 1/7] rcu: add rcu_migrate_enable and rcu_migrate_disable

Menglong Dong posted 7 patches 1 month, 2 weeks ago
[PATCH bpf-next 1/7] rcu: add rcu_migrate_enable and rcu_migrate_disable
Posted by Menglong Dong 1 month, 2 weeks ago
migrate_disable() is called to disable migration in the kernel, and it is
used togather with rcu_read_lock() oftenly.

However, with PREEMPT_RCU disabled, it's unnecessary, as rcu_read_lock()
will disable preemption, which will also disable migration.

Introduce rcu_migrate_enable() and rcu_migrate_disable(), which will do
the migration enable and disable only when the rcu_read_lock() can't do
it.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
 include/linux/rcupdate.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 120536f4c6eb..0d9dbd90d025 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -72,6 +72,16 @@ static inline bool same_state_synchronize_rcu(unsigned long oldstate1, unsigned
 void __rcu_read_lock(void);
 void __rcu_read_unlock(void);
 
+static inline void rcu_migrate_enable(void)
+{
+	migrate_enable();
+}
+
+static inline void rcu_migrate_disable(void)
+{
+	migrate_disable();
+}
+
 /*
  * Defined as a macro as it is a very low level header included from
  * areas that don't even know about current.  This gives the rcu_read_lock()
@@ -105,6 +115,14 @@ static inline int rcu_preempt_depth(void)
 	return 0;
 }
 
+static inline void rcu_migrate_enable(void)
+{
+}
+
+static inline void rcu_migrate_disable(void)
+{
+}
+
 #endif /* #else #ifdef CONFIG_PREEMPT_RCU */
 
 #ifdef CONFIG_RCU_LAZY
-- 
2.50.1
Re: [PATCH bpf-next 1/7] rcu: add rcu_migrate_enable and rcu_migrate_disable
Posted by Alexei Starovoitov 1 month, 2 weeks ago
On Fri, Aug 15, 2025 at 9:18 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> migrate_disable() is called to disable migration in the kernel, and it is
> used togather with rcu_read_lock() oftenly.
>
> However, with PREEMPT_RCU disabled, it's unnecessary, as rcu_read_lock()
> will disable preemption, which will also disable migration.
>
> Introduce rcu_migrate_enable() and rcu_migrate_disable(), which will do
> the migration enable and disable only when the rcu_read_lock() can't do
> it.
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> ---
>  include/linux/rcupdate.h | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> index 120536f4c6eb..0d9dbd90d025 100644
> --- a/include/linux/rcupdate.h
> +++ b/include/linux/rcupdate.h
> @@ -72,6 +72,16 @@ static inline bool same_state_synchronize_rcu(unsigned long oldstate1, unsigned
>  void __rcu_read_lock(void);
>  void __rcu_read_unlock(void);
>
> +static inline void rcu_migrate_enable(void)
> +{
> +       migrate_enable();
> +}

Interesting idea.
I think it has to be combined with rcu_read_lock(), since this api
makes sense only when used together.

rcu_read_lock_dont_migrate() ?

It will do rcu_read_lock() + migrate_disalbe() in PREEMPT_RCU
and rcu_read_lock() + preempt_disable() otherwise?

Also I'm not sure we can rely on rcu_read_lock()
disabling preemption in all !PREEMPT_RCU cases.
iirc it's more nuanced than that.
Re: [PATCH bpf-next 1/7] rcu: add rcu_migrate_enable and rcu_migrate_disable
Posted by Menglong Dong 1 month, 2 weeks ago
On Fri, Aug 15, 2025 at 9:02 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Aug 15, 2025 at 9:18 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > migrate_disable() is called to disable migration in the kernel, and it is
> > used togather with rcu_read_lock() oftenly.
> >
> > However, with PREEMPT_RCU disabled, it's unnecessary, as rcu_read_lock()
> > will disable preemption, which will also disable migration.
> >
> > Introduce rcu_migrate_enable() and rcu_migrate_disable(), which will do
> > the migration enable and disable only when the rcu_read_lock() can't do
> > it.
> >
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> >  include/linux/rcupdate.h | 18 ++++++++++++++++++
> >  1 file changed, 18 insertions(+)
> >
> > diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> > index 120536f4c6eb..0d9dbd90d025 100644
> > --- a/include/linux/rcupdate.h
> > +++ b/include/linux/rcupdate.h
> > @@ -72,6 +72,16 @@ static inline bool same_state_synchronize_rcu(unsigned long oldstate1, unsigned
> >  void __rcu_read_lock(void);
> >  void __rcu_read_unlock(void);
> >
> > +static inline void rcu_migrate_enable(void)
> > +{
> > +       migrate_enable();
> > +}
>
> Interesting idea.
> I think it has to be combined with rcu_read_lock(), since this api
> makes sense only when used together.
>
> rcu_read_lock_dont_migrate() ?

Yeah, it looks much better. So we can introduce:

  rcu_read_lock_dont_migrate()
  rcu_read_unlock_do_ migrate()

>
> It will do rcu_read_lock() + migrate_disalbe() in PREEMPT_RCU
> and rcu_read_lock() + preempt_disable() otherwise?
>
> Also I'm not sure we can rely on rcu_read_lock()
> disabling preemption in all !PREEMPT_RCU cases.
> iirc it's more nuanced than that.
Re: [PATCH bpf-next 1/7] rcu: add rcu_migrate_enable and rcu_migrate_disable
Posted by Paul E. McKenney 1 month, 2 weeks ago
On Fri, Aug 15, 2025 at 04:02:14PM +0300, Alexei Starovoitov wrote:
> On Fri, Aug 15, 2025 at 9:18 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > migrate_disable() is called to disable migration in the kernel, and it is
> > used togather with rcu_read_lock() oftenly.
> >
> > However, with PREEMPT_RCU disabled, it's unnecessary, as rcu_read_lock()
> > will disable preemption, which will also disable migration.
> >
> > Introduce rcu_migrate_enable() and rcu_migrate_disable(), which will do
> > the migration enable and disable only when the rcu_read_lock() can't do
> > it.
> >
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> >  include/linux/rcupdate.h | 18 ++++++++++++++++++
> >  1 file changed, 18 insertions(+)
> >
> > diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> > index 120536f4c6eb..0d9dbd90d025 100644
> > --- a/include/linux/rcupdate.h
> > +++ b/include/linux/rcupdate.h
> > @@ -72,6 +72,16 @@ static inline bool same_state_synchronize_rcu(unsigned long oldstate1, unsigned
> >  void __rcu_read_lock(void);
> >  void __rcu_read_unlock(void);
> >
> > +static inline void rcu_migrate_enable(void)
> > +{
> > +       migrate_enable();
> > +}
> 
> Interesting idea.
> I think it has to be combined with rcu_read_lock(), since this api
> makes sense only when used together.
> 
> rcu_read_lock_dont_migrate() ?
> 
> It will do rcu_read_lock() + migrate_disalbe() in PREEMPT_RCU
> and rcu_read_lock() + preempt_disable() otherwise?

That could easily be provided.  Or just make one, and if it starts
having enough use cases, it could be pulled into RCU proper.

> Also I'm not sure we can rely on rcu_read_lock()
> disabling preemption in all !PREEMPT_RCU cases.
> iirc it's more nuanced than that.

For once, something about RCU is non-nuanced.  But don't worry, it won't
happen again.  ;-)

In all !PREEMPT_RCU, preemption must be disabled across all RCU read-side
critical sections in order for RCU to work correctly.

							Thanx, Paul
Re: [PATCH bpf-next 1/7] rcu: add rcu_migrate_enable and rcu_migrate_disable
Posted by Menglong Dong 1 month, 2 weeks ago
On Fri, Aug 15, 2025 at 11:31 PM Paul E. McKenney <paulmck@kernel.org> wrote:
>
> On Fri, Aug 15, 2025 at 04:02:14PM +0300, Alexei Starovoitov wrote:
> > On Fri, Aug 15, 2025 at 9:18 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> > >
> > > migrate_disable() is called to disable migration in the kernel, and it is
> > > used togather with rcu_read_lock() oftenly.
> > >
> > > However, with PREEMPT_RCU disabled, it's unnecessary, as rcu_read_lock()
> > > will disable preemption, which will also disable migration.
> > >
> > > Introduce rcu_migrate_enable() and rcu_migrate_disable(), which will do
> > > the migration enable and disable only when the rcu_read_lock() can't do
> > > it.
> > >
> > > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > > ---
> > >  include/linux/rcupdate.h | 18 ++++++++++++++++++
> > >  1 file changed, 18 insertions(+)
> > >
> > > diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> > > index 120536f4c6eb..0d9dbd90d025 100644
> > > --- a/include/linux/rcupdate.h
> > > +++ b/include/linux/rcupdate.h
> > > @@ -72,6 +72,16 @@ static inline bool same_state_synchronize_rcu(unsigned long oldstate1, unsigned
> > >  void __rcu_read_lock(void);
> > >  void __rcu_read_unlock(void);
> > >
> > > +static inline void rcu_migrate_enable(void)
> > > +{
> > > +       migrate_enable();
> > > +}
> >
> > Interesting idea.
> > I think it has to be combined with rcu_read_lock(), since this api
> > makes sense only when used together.
> >
> > rcu_read_lock_dont_migrate() ?
> >
> > It will do rcu_read_lock() + migrate_disalbe() in PREEMPT_RCU
> > and rcu_read_lock() + preempt_disable() otherwise?
>
> That could easily be provided.  Or just make one, and if it starts
> having enough use cases, it could be pulled into RCU proper.

Hi, do you mean that we should start with a single
use case? In this series, I started it with the BPF
subsystem. Most of the situations are similar, which will
call rcu_read_lock+migrate_disable and run bpf prog.

>
> > Also I'm not sure we can rely on rcu_read_lock()
> > disabling preemption in all !PREEMPT_RCU cases.
> > iirc it's more nuanced than that.
>
> For once, something about RCU is non-nuanced.  But don't worry, it won't
> happen again.  ;-)
>
> In all !PREEMPT_RCU, preemption must be disabled across all RCU read-side
> critical sections in order for RCU to work correctly.

Great! I worried about this part too.

Thanks!
Menglong Dong

>
>                                                         Thanx, Paul
Re: [PATCH bpf-next 1/7] rcu: add rcu_migrate_enable and rcu_migrate_disable
Posted by Paul E. McKenney 1 month, 2 weeks ago
On Sun, Aug 17, 2025 at 10:01:23AM +0800, Menglong Dong wrote:
> On Fri, Aug 15, 2025 at 11:31 PM Paul E. McKenney <paulmck@kernel.org> wrote:
> >
> > On Fri, Aug 15, 2025 at 04:02:14PM +0300, Alexei Starovoitov wrote:
> > > On Fri, Aug 15, 2025 at 9:18 AM Menglong Dong <menglong8.dong@gmail.com> wrote:
> > > >
> > > > migrate_disable() is called to disable migration in the kernel, and it is
> > > > used togather with rcu_read_lock() oftenly.
> > > >
> > > > However, with PREEMPT_RCU disabled, it's unnecessary, as rcu_read_lock()
> > > > will disable preemption, which will also disable migration.
> > > >
> > > > Introduce rcu_migrate_enable() and rcu_migrate_disable(), which will do
> > > > the migration enable and disable only when the rcu_read_lock() can't do
> > > > it.
> > > >
> > > > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > > > ---
> > > >  include/linux/rcupdate.h | 18 ++++++++++++++++++
> > > >  1 file changed, 18 insertions(+)
> > > >
> > > > diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
> > > > index 120536f4c6eb..0d9dbd90d025 100644
> > > > --- a/include/linux/rcupdate.h
> > > > +++ b/include/linux/rcupdate.h
> > > > @@ -72,6 +72,16 @@ static inline bool same_state_synchronize_rcu(unsigned long oldstate1, unsigned
> > > >  void __rcu_read_lock(void);
> > > >  void __rcu_read_unlock(void);
> > > >
> > > > +static inline void rcu_migrate_enable(void)
> > > > +{
> > > > +       migrate_enable();
> > > > +}
> > >
> > > Interesting idea.
> > > I think it has to be combined with rcu_read_lock(), since this api
> > > makes sense only when used together.
> > >
> > > rcu_read_lock_dont_migrate() ?
> > >
> > > It will do rcu_read_lock() + migrate_disalbe() in PREEMPT_RCU
> > > and rcu_read_lock() + preempt_disable() otherwise?
> >
> > That could easily be provided.  Or just make one, and if it starts
> > having enough use cases, it could be pulled into RCU proper.
> 
> Hi, do you mean that we should start with a single
> use case? In this series, I started it with the BPF
> subsystem. Most of the situations are similar, which will
> call rcu_read_lock+migrate_disable and run bpf prog.

Other than my wanting more compact code, what you did in your patch
series is fine.

							Thanx, Paul

> > > Also I'm not sure we can rely on rcu_read_lock()
> > > disabling preemption in all !PREEMPT_RCU cases.
> > > iirc it's more nuanced than that.
> >
> > For once, something about RCU is non-nuanced.  But don't worry, it won't
> > happen again.  ;-)
> >
> > In all !PREEMPT_RCU, preemption must be disabled across all RCU read-side
> > critical sections in order for RCU to work correctly.
> 
> Great! I worried about this part too.
> 
> Thanks!
> Menglong Dong
> 
> >
> >                                                         Thanx, Paul