Re: [PATCH net-next v2] ppp: enable TX scatter-gather
Paolo Abeni <[email protected]> Thu, 6 Nov 2025 15:18:54 +0100
| Newsgroups | gmane.linux.network,gmane.linux.ppp,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
On 11/3/25 4:15 AM, Qingfang Deng wrote: > When chan->direct_xmit is true, and no compressors are in use, PPP > prepends its header to a skb, and calls dev_queue_xmit directly. In this > mode the skb does not need to be linearized. > Enable NETIF_F_SG and NETIF_F_FRAGLIST, and add > ppp_update_dev_features() to conditionally disable them if a linear skb > is required. This is required to support PPPoE GSO. It's unclear to me why IFF_NO_QUEUE is necessary to avoid the linearization. > Signed-off-by: Qingfang Deng <[email protected]> > --- > v1 -> v2: > Changes dev->features under the TX spinlock to avoid races. > - https://lore.kernel.org/netdev/[email protected]/ > > drivers/net/ppp/ppp_generic.c | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c > index 854e1a95d29a..389542f0af5f 100644 > --- a/drivers/net/ppp/ppp_generic.c > +++ b/drivers/net/ppp/ppp_generic.c > @@ -498,6 +498,17 @@ static ssize_t ppp_read(struct file *file, char __user *buf, > return ret; > } > > +static void ppp_update_dev_features(struct ppp *ppp) > +{ > + struct net_device *dev = ppp->dev; > + > + if (!(dev->priv_flags & IFF_NO_QUEUE) || ppp->xc_state || > + ppp->flags & (SC_COMP_TCP | SC_CCP_UP)) > + dev->features &= ~(NETIF_F_SG | NETIF_F_FRAGLIST); > + else > + dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST; > +} > + > static bool ppp_check_packet(struct sk_buff *skb, size_t count) > { > /* LCP packets must include LCP header which 4 bytes long: > @@ -824,6 +835,7 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) > case PPPIOCSFLAGS: > if (get_user(val, p)) > break; > + rtnl_lock(); > ppp_lock(ppp); > cflags = ppp->flags & ~val; > #ifdef CONFIG_PPP_MULTILINK > @@ -834,6 +846,12 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) > ppp_unlock(ppp); > if (cflags & SC_CCP_OPEN) > ppp_ccp_closed(ppp); > + > + ppp_xmit_lock(ppp); > + ppp_update_dev_features(ppp); > + ppp_xmit_unlock(ppp); > + netdev_update_features(ppp->dev); > + rtnl_unlock(); > err = 0; > break; > > @@ -1650,6 +1668,8 @@ static void ppp_setup(struct net_device *dev) > dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; > dev->priv_destructor = ppp_dev_priv_destructor; > dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS; > + dev->features = NETIF_F_SG | NETIF_F_FRAGLIST; > + dev->hw_features = dev->features; > netif_keep_dst(dev); > } > > @@ -3112,13 +3132,17 @@ ppp_set_compress(struct ppp *ppp, struct ppp_option_data *data) > if (data->transmit) { > state = cp->comp_alloc(ccp_option, data->length); > if (state) { > + rtnl_lock(); > ppp_xmit_lock(ppp); > ppp->xstate &= ~SC_COMP_RUN; > ocomp = ppp->xcomp; > ostate = ppp->xc_state; > ppp->xcomp = cp; > ppp->xc_state = state; > + ppp_update_dev_features(ppp); > ppp_xmit_unlock(ppp); > + netdev_update_features(ppp->dev); > + rtnl_unlock(); Instead of dynamically changing the features, what about always exposing SG and FRAGLIST and linearize the skb as need for compression's sake? /P