diff options
| author | Paolo Abeni <pabeni@redhat.com> | 2026-07-20 09:18:11 +0200 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2026-07-20 09:18:11 +0200 |
| commit | 298bb2b8903323f6ef2eab4819a2e477765f0ff1 (patch) | |
| tree | f1cf02687ba2434059d95d4ef3f2cc810acf50ca /drivers/net/ppp | |
| parent | 285fd588859f42b14f6f455faaa336b4077c3a87 (diff) | |
| parent | e13caf1c26587434f0b768193100440939c0fb91 (diff) | |
| download | linux-next-298bb2b8903323f6ef2eab4819a2e477765f0ff1.tar.gz linux-next-298bb2b8903323f6ef2eab4819a2e477765f0ff1.zip | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR (net-7.2-rc4).
No conflicts.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'drivers/net/ppp')
| -rw-r--r-- | drivers/net/ppp/ppp_generic.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 57c68efa5ff8..717c1d3aa953 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -184,6 +184,7 @@ struct channel { struct list_head clist; /* link in list of channels per unit */ spinlock_t upl; /* protects `ppp' and 'bridge' */ struct channel __rcu *bridge; /* "bridged" ppp channel */ + struct rcu_head rcu; /* for RCU-deferred free of the channel */ #ifdef CONFIG_PPP_MULTILINK u8 avail; /* flag used in multilink stuff */ u8 had_frag; /* >= 1 fragments have been sent */ @@ -3562,6 +3563,18 @@ ppp_disconnect_channel(struct channel *pch) return err; } +/* Purge after the grace period: a late ppp_input() may still queue an + * skb on pch->file.rq before the last RCU reader drains. + */ +static void ppp_release_channel_free(struct rcu_head *rcu) +{ + struct channel *pch = container_of(rcu, struct channel, rcu); + + skb_queue_purge(&pch->file.xq); + skb_queue_purge(&pch->file.rq); + kfree(pch); +} + /* * Drop a reference to a ppp channel and free its memory if the refcount reaches * zero. @@ -3581,9 +3594,7 @@ static void ppp_release_channel(struct channel *pch) pr_err("ppp: destroying undead channel %p !\n", pch); return; } - skb_queue_purge(&pch->file.xq); - skb_queue_purge(&pch->file.rq); - kfree(pch); + call_rcu(&pch->rcu, ppp_release_channel_free); } static void __exit ppp_cleanup(void) @@ -3596,6 +3607,7 @@ static void __exit ppp_cleanup(void) device_destroy(&ppp_class, MKDEV(PPP_MAJOR, 0)); class_unregister(&ppp_class); unregister_pernet_device(&ppp_net_ops); + rcu_barrier(); /* wait for RCU callbacks before module unload */ } /* |
