netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC net 0/2] Fix rcu_read_lock issues in netdev-genl
@ 2024-11-12 18:13 Joe Damato
  2024-11-12 18:13 ` [RFC net 1/2] netdev-genl: Hold rcu_read_lock in napi_get Joe Damato
  2024-11-12 18:13 ` [RFC net 2/2] netdev-genl: Hold rcu_read_lock in napi_set Joe Damato
  0 siblings, 2 replies; 7+ messages in thread
From: Joe Damato @ 2024-11-12 18:13 UTC (permalink / raw)
  To: netdev
  Cc: pabeni, edumazet, amritha.nambiar, sridhar.samudrala, kuba,
	mkarsten, Joe Damato, David S. Miller, open list, Mina Almasry,
	Simon Horman

Greetings:

Paolo reported a splat [1] when running the new selftest for busy poll.
I confirmed and reproduced this splat locally.

This series proposed 2 patches, which:
  - Patch 1:
    - Adds a helper function to reduce code duplication that sets the
      error, extack, napi, etc.
    - Fixes a similar issue in an older commit and CCs stable as this
      fix could be backported.
  - Patch 2:
    - Uses the helper added in 1 to fix the recently added commit that
      adds netdev_nl_napi_set_doit which is exercised by the selftest
      triggering the splat that Paolo reported.

I retested locally after applying this series and confirmed that the
splat is fixed.

Note: I only CC'd stable on patch 1 because that code goes back a few
releases. patch 2 is fixing code merged very recently that does not yet
appear in any RC and so I've omit the CC for stable there. I've sent
this as an RFC because I am not sure if that's the right thing to do.

Let me know and I'll be happy to re-send (after 24hr) an official
series.

Thanks,
Joe

[1]: https://lore.kernel.org/netdev/719083c2-e277-447b-b6ea-ca3acb293a03@redhat.com/

Joe Damato (2):
  netdev-genl: Hold rcu_read_lock in napi_get
  netdev-genl: Hold rcu_read_lock in napi_set

 net/core/netdev-genl.c | 37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)


base-commit: a58f00ed24b849d449f7134fd5d86f07090fe2f5
-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC net 1/2] netdev-genl: Hold rcu_read_lock in napi_get
  2024-11-12 18:13 [RFC net 0/2] Fix rcu_read_lock issues in netdev-genl Joe Damato
@ 2024-11-12 18:13 ` Joe Damato
  2024-11-13  1:28   ` Jakub Kicinski
  2024-11-12 18:13 ` [RFC net 2/2] netdev-genl: Hold rcu_read_lock in napi_set Joe Damato
  1 sibling, 1 reply; 7+ messages in thread
From: Joe Damato @ 2024-11-12 18:13 UTC (permalink / raw)
  To: netdev
  Cc: pabeni, edumazet, amritha.nambiar, sridhar.samudrala, kuba,
	mkarsten, Joe Damato, stable, David S. Miller, Simon Horman,
	Mina Almasry, open list

Hold rcu_read_lock in netdev_nl_napi_get_doit, which calls napi_by_id
and is required to be called under rcu_read_lock.

Cc: stable@vger.kernel.org
Fixes: 27f91aaf49b3 ("netdev-genl: Add netlink framework functions for napi")
Signed-off-by: Joe Damato <jdamato@fastly.com>
---
 net/core/netdev-genl.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index 765ce7c9d73b..934c63a93524 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -216,6 +216,23 @@ netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
 	return -EMSGSIZE;
 }
 
+/* must be called under rcu_read_lock(), because napi_by_id requires it */
+static struct napi_struct *__do_napi_by_id(unsigned int napi_id,
+					   struct genl_info *info, int *err)
+{
+	struct napi_struct *napi;
+
+	napi = napi_by_id(napi_id);
+	if (napi) {
+		*err = 0;
+	} else {
+		NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
+		*err = -ENOENT;
+	}
+
+	return napi;
+}
+
 int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct napi_struct *napi;
@@ -233,15 +250,13 @@ int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
 		return -ENOMEM;
 
 	rtnl_lock();
+	rcu_read_lock();
 
-	napi = napi_by_id(napi_id);
-	if (napi) {
+	napi = __do_napi_by_id(napi_id, info, &err);
+	if (!err)
 		err = netdev_nl_napi_fill_one(rsp, napi, info);
-	} else {
-		NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
-		err = -ENOENT;
-	}
 
+	rcu_read_unlock();
 	rtnl_unlock();
 
 	if (err)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC net 2/2] netdev-genl: Hold rcu_read_lock in napi_set
  2024-11-12 18:13 [RFC net 0/2] Fix rcu_read_lock issues in netdev-genl Joe Damato
  2024-11-12 18:13 ` [RFC net 1/2] netdev-genl: Hold rcu_read_lock in napi_get Joe Damato
@ 2024-11-12 18:13 ` Joe Damato
  1 sibling, 0 replies; 7+ messages in thread
From: Joe Damato @ 2024-11-12 18:13 UTC (permalink / raw)
  To: netdev
  Cc: pabeni, edumazet, amritha.nambiar, sridhar.samudrala, kuba,
	mkarsten, Joe Damato, David S. Miller, Simon Horman, Mina Almasry,
	open list

Hold rcu_read_lock during netdev_nl_napi_set_doit, which calls
napi_by_id and requires rcu_read_lock to be held.

Add a helper function which calls napi_by_id and sets the error code and
extack. It is used by this commit and the next commit to reduce code
duplication.

Closes: https://lore.kernel.org/netdev/719083c2-e277-447b-b6ea-ca3acb293a03@redhat.com/
Fixes: 1287c1ae0fc2 ("netdev-genl: Support setting per-NAPI config values")
Signed-off-by: Joe Damato <jdamato@fastly.com>
---
 net/core/netdev-genl.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index 934c63a93524..2a04270e9d2d 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -361,15 +361,13 @@ int netdev_nl_napi_set_doit(struct sk_buff *skb, struct genl_info *info)
 	napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_ID]);
 
 	rtnl_lock();
+	rcu_read_lock();
 
-	napi = napi_by_id(napi_id);
-	if (napi) {
+	napi = __do_napi_by_id(napi_id, info, &err);
+	if (!err)
 		err = netdev_nl_napi_set_config(napi, info);
-	} else {
-		NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
-		err = -ENOENT;
-	}
 
+	rcu_read_unlock();
 	rtnl_unlock();
 
 	return err;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [RFC net 1/2] netdev-genl: Hold rcu_read_lock in napi_get
  2024-11-12 18:13 ` [RFC net 1/2] netdev-genl: Hold rcu_read_lock in napi_get Joe Damato
@ 2024-11-13  1:28   ` Jakub Kicinski
  2024-11-13  1:48     ` Joe Damato
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Kicinski @ 2024-11-13  1:28 UTC (permalink / raw)
  To: Joe Damato
  Cc: netdev, pabeni, edumazet, amritha.nambiar, sridhar.samudrala,
	mkarsten, stable, David S. Miller, Simon Horman, Mina Almasry,
	open list

On Tue, 12 Nov 2024 18:13:58 +0000 Joe Damato wrote:
> +/* must be called under rcu_read_lock(), because napi_by_id requires it */
> +static struct napi_struct *__do_napi_by_id(unsigned int napi_id,
> +					   struct genl_info *info, int *err)
> +{
> +	struct napi_struct *napi;
> +
> +	napi = napi_by_id(napi_id);
> +	if (napi) {
> +		*err = 0;
> +	} else {
> +		NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
> +		*err = -ENOENT;
> +	}
> +
> +	return napi;
> +}

Thanks for the quick follow up! I vote we don't factor this out.
I don't see what it buys us, TBH, normally we factor out code
to avoid having to unlock before return, but this code doesn't
have extra returns...

Just slap an rcu_read_lock / unlock around and that's it?

Feel free to repost soon.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC net 1/2] netdev-genl: Hold rcu_read_lock in napi_get
  2024-11-13  1:28   ` Jakub Kicinski
@ 2024-11-13  1:48     ` Joe Damato
  2024-11-13  2:01       ` Jakub Kicinski
  0 siblings, 1 reply; 7+ messages in thread
From: Joe Damato @ 2024-11-13  1:48 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, pabeni, edumazet, amritha.nambiar, sridhar.samudrala,
	mkarsten, stable, David S. Miller, Simon Horman, Mina Almasry,
	open list

On Tue, Nov 12, 2024 at 05:28:40PM -0800, Jakub Kicinski wrote:
> On Tue, 12 Nov 2024 18:13:58 +0000 Joe Damato wrote:
> > +/* must be called under rcu_read_lock(), because napi_by_id requires it */
> > +static struct napi_struct *__do_napi_by_id(unsigned int napi_id,
> > +					   struct genl_info *info, int *err)
> > +{
> > +	struct napi_struct *napi;
> > +
> > +	napi = napi_by_id(napi_id);
> > +	if (napi) {
> > +		*err = 0;
> > +	} else {
> > +		NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
> > +		*err = -ENOENT;
> > +	}
> > +
> > +	return napi;
> > +}
> 
> Thanks for the quick follow up! I vote we don't factor this out.
> I don't see what it buys us, TBH, normally we factor out code
> to avoid having to unlock before return, but this code doesn't
> have extra returns...
> 
> Just slap an rcu_read_lock / unlock around and that's it?

Sure sounds good.

Sorry for the noob question: should I break it up into two patches
with one CCing stable and the other not like I did for this RFC?

Patch 1 definitely "feels" like a fixes + CC stable
Patch 2 could be either net-next or a net + "fixes" without stable?

> Feel free to repost soon.

Will do, just lmk on the above so I can submit it the correct way.

Thanks for the quick feedback.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC net 1/2] netdev-genl: Hold rcu_read_lock in napi_get
  2024-11-13  1:48     ` Joe Damato
@ 2024-11-13  2:01       ` Jakub Kicinski
  2024-11-13  2:05         ` Joe Damato
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Kicinski @ 2024-11-13  2:01 UTC (permalink / raw)
  To: Joe Damato
  Cc: netdev, pabeni, edumazet, amritha.nambiar, sridhar.samudrala,
	mkarsten, stable, David S. Miller, Simon Horman, Mina Almasry,
	open list

On Tue, 12 Nov 2024 17:48:42 -0800 Joe Damato wrote:
> Sorry for the noob question: should I break it up into two patches
> with one CCing stable and the other not like I did for this RFC?
> 
> Patch 1 definitely "feels" like a fixes + CC stable
> Patch 2 could be either net-next or a net + "fixes" without stable?

Oh, sorry, I didn't comment on that because that part is correct.
The split is great, will make backporting easier.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC net 1/2] netdev-genl: Hold rcu_read_lock in napi_get
  2024-11-13  2:01       ` Jakub Kicinski
@ 2024-11-13  2:05         ` Joe Damato
  0 siblings, 0 replies; 7+ messages in thread
From: Joe Damato @ 2024-11-13  2:05 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, pabeni, edumazet, amritha.nambiar, sridhar.samudrala,
	mkarsten, stable, David S. Miller, Simon Horman, Mina Almasry,
	open list

On Tue, Nov 12, 2024 at 06:01:02PM -0800, Jakub Kicinski wrote:
> On Tue, 12 Nov 2024 17:48:42 -0800 Joe Damato wrote:
> > Sorry for the noob question: should I break it up into two patches
> > with one CCing stable and the other not like I did for this RFC?
> > 
> > Patch 1 definitely "feels" like a fixes + CC stable
> > Patch 2 could be either net-next or a net + "fixes" without stable?
> 
> Oh, sorry, I didn't comment on that because that part is correct.
> The split is great, will make backporting easier.

OK, cool, that's what I figured. Thanks for the guidance; will
repost shortly.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-11-13  2:05 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-12 18:13 [RFC net 0/2] Fix rcu_read_lock issues in netdev-genl Joe Damato
2024-11-12 18:13 ` [RFC net 1/2] netdev-genl: Hold rcu_read_lock in napi_get Joe Damato
2024-11-13  1:28   ` Jakub Kicinski
2024-11-13  1:48     ` Joe Damato
2024-11-13  2:01       ` Jakub Kicinski
2024-11-13  2:05         ` Joe Damato
2024-11-12 18:13 ` [RFC net 2/2] netdev-genl: Hold rcu_read_lock in napi_set Joe Damato

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).