From: Qingfang Deng Date: Thu, 12 Mar 2026 09:37:31 +0000 (+0800) Subject: ppp: remove pch->chan NULL checks from tx path X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=febe8012458fd9057d3fb70f6b37ef67a07ff8a1;p=thirdparty%2Flinux.git ppp: remove pch->chan NULL checks from tx path Now that ppp_disconnect_channel() is called before pch->chan is set to NULL, a channel from ppp->channels list on the transmit path is guaranteed to have non-NULL pch->chan. Remove the pch->chan NULL checks from ppp_push(), ppp_mp_explode(), and ppp_fill_forward_path(), where a channel is obtained from the list. Remove the corresponding WRITE/READ_ONCE annotations as they no longer race. Signed-off-by: Qingfang Deng Link: https://patch.msgid.link/20260312093732.277254-2-dqfext@gmail.com Signed-off-by: Paolo Abeni --- diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index ad480b584e25e..a036ddfe327b9 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -1602,10 +1602,7 @@ static int ppp_fill_forward_path(struct net_device_path_ctx *ctx, if (!pch) return -ENODEV; - chan = READ_ONCE(pch->chan); - if (!chan) - return -ENODEV; - + chan = pch->chan; if (!chan->ops->fill_forward_path) return -EOPNOTSUPP; @@ -1928,9 +1925,9 @@ ppp_push(struct ppp *ppp, struct sk_buff *skb) spin_lock(&pch->downl); chan = pch->chan; - if (unlikely(!chan || (!chan->direct_xmit && skb_linearize(skb)))) { - /* channel got unregistered, or it requires a linear - * skb but linearization failed + if (unlikely(!chan->direct_xmit && skb_linearize(skb))) { + /* channel requires a linear skb but linearization + * failed */ kfree_skb(skb); ret = 1; @@ -1991,28 +1988,23 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; i = 0; list_for_each_entry(pch, &ppp->channels, clist) { - if (pch->chan) { - pch->avail = 1; - navail++; - pch->speed = pch->chan->speed; - } else { - pch->avail = 0; - } - if (pch->avail) { - if (skb_queue_empty(&pch->file.xq) || - !pch->had_frag) { - if (pch->speed == 0) - nzero++; - else - totspeed += pch->speed; - - pch->avail = 2; - ++nfree; - ++totfree; - } - if (!pch->had_frag && i < ppp->nxchan) - ppp->nxchan = i; + pch->avail = 1; + navail++; + pch->speed = pch->chan->speed; + + if (skb_queue_empty(&pch->file.xq) || !pch->had_frag) { + if (pch->speed == 0) + nzero++; + else + totspeed += pch->speed; + + pch->avail = 2; + ++nfree; + ++totfree; } + if (!pch->had_frag && i < ppp->nxchan) + ppp->nxchan = i; + ++i; } /* @@ -2071,25 +2063,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) pch->avail = 1; } - /* check the channel's mtu and whether it is still attached. */ spin_lock(&pch->downl); - if (pch->chan == NULL) { - /* can't use this channel, it's being deregistered */ - if (pch->speed == 0) - nzero--; - else - totspeed -= pch->speed; - - spin_unlock(&pch->downl); - pch->avail = 0; - totlen = len; - totfree--; - nfree--; - if (--navail == 0) - break; - continue; - } - /* *if the channel speed is not set divide *the packet evenly among the free channels; @@ -3035,7 +3009,7 @@ ppp_unregister_channel(struct ppp_channel *chan) ppp_disconnect_channel(pch); down_write(&pch->chan_sem); spin_lock_bh(&pch->downl); - WRITE_ONCE(pch->chan, NULL); + pch->chan = NULL; spin_unlock_bh(&pch->downl); up_write(&pch->chan_sem);