Message ID | 20250308214045.1160445-9-almasrymina@google.com (mailing list archive) |
---|---|
State | New |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Device memory TCP TX | expand |
On 3/8/25 10:40 PM, Mina Almasry wrote: > We should not enable netmem TX for drivers that don't declare support. > > Check for driver netmem TX support during devmem TX binding and fail if > the driver does not have the functionality. > > Check for driver support in validate_xmit_skb as well. > > Signed-off-by: Mina Almasry <almasrymina@google.com> > Acked-by: Stanislav Fomichev <sdf@fomichev.me> > > --- > > v5: https://lore.kernel.org/netdev/20250227041209.2031104-8-almasrymina@google.com/ > - Check that the dmabuf mappings belongs to the specific device the TX > is being sent from (Jakub) > > v4: > - New patch > > --- > net/core/dev.c | 33 +++++++++++++++++++++++++++++++++ > net/core/devmem.h | 6 ++++++ > net/core/netdev-genl.c | 7 +++++++ > 3 files changed, 46 insertions(+) > > diff --git a/net/core/dev.c b/net/core/dev.c > index 1cb134ff7327..5553947123a0 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -3868,10 +3868,43 @@ int skb_csum_hwoffload_help(struct sk_buff *skb, > } > EXPORT_SYMBOL(skb_csum_hwoffload_help); > > +static struct sk_buff *validate_xmit_unreadable_skb(struct sk_buff *skb, > + struct net_device *dev) > +{ > + struct skb_shared_info *shinfo; > + struct net_iov *niov; > + > + if (likely(skb_frags_readable(skb))) > + goto out; > + > + if (likely(!dev->netmem_tx)) Minor nit: I think the above is actually unlikely. The skb is unreadable: is supposed to be transmitted on a device supporting netmem_tx, otherwise we are in exceptional/error path. No need to repost just for this. Thanks, Paolo
diff --git a/net/core/dev.c b/net/core/dev.c index 1cb134ff7327..5553947123a0 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3868,10 +3868,43 @@ int skb_csum_hwoffload_help(struct sk_buff *skb, } EXPORT_SYMBOL(skb_csum_hwoffload_help); +static struct sk_buff *validate_xmit_unreadable_skb(struct sk_buff *skb, + struct net_device *dev) +{ + struct skb_shared_info *shinfo; + struct net_iov *niov; + + if (likely(skb_frags_readable(skb))) + goto out; + + if (likely(!dev->netmem_tx)) + goto out_free; + + shinfo = skb_shinfo(skb); + + if (shinfo->nr_frags > 0) { + niov = netmem_to_net_iov(skb_frag_netmem(&shinfo->frags[0])); + if (net_is_devmem_iov(niov) && + net_devmem_iov_binding(niov)->dev != dev) + goto out_free; + } + +out: + return skb; + +out_free: + kfree_skb(skb); + return NULL; +} + static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device *dev, bool *again) { netdev_features_t features; + skb = validate_xmit_unreadable_skb(skb, dev); + if (unlikely(!skb)) + goto out_null; + features = netif_skb_features(skb); skb = validate_xmit_vlan(skb, features); if (unlikely(!skb)) diff --git a/net/core/devmem.h b/net/core/devmem.h index 67168aae5e5b..919e6ed28fdc 100644 --- a/net/core/devmem.h +++ b/net/core/devmem.h @@ -229,6 +229,12 @@ net_devmem_get_niov_at(struct net_devmem_dmabuf_binding *binding, size_t addr, { return NULL; } + +static inline struct net_devmem_dmabuf_binding * +net_devmem_iov_binding(const struct net_iov *niov) +{ + return NULL; +} #endif #endif /* _NET_DEVMEM_H */ diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c index 6e7cd6a5c177..6c5d62df0d65 100644 --- a/net/core/netdev-genl.c +++ b/net/core/netdev-genl.c @@ -972,6 +972,13 @@ int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info) goto err_unlock; } + if (!netdev->netmem_tx) { + err = -EOPNOTSUPP; + NL_SET_ERR_MSG(info->extack, + "Driver does not support netmem TX"); + goto err_unlock; + } + binding = net_devmem_bind_dmabuf(netdev, DMA_TO_DEVICE, dmabuf_fd, info->extack); if (IS_ERR(binding)) {