Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xdp: add xdp_set_features_flag utility routine

Introduce xdp_set_features_flag utility routine in order to update
dynamically xdp_features according to the dynamic hw configuration via
ethtool (e.g. changing number of hw rx/tx queues).
Add xdp_clear_features_flag() in order to clear all xdp_feature flag.

Reviewed-by: Shay Agroskin <shayagr@amazon.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Lorenzo Bianconi and committed by
Jakub Kicinski
f85949f9 bf51d277

+35 -7
+1
Documentation/netlink/specs/netdev.yaml
··· 9 9 - 10 10 type: flags 11 11 name: xdp-act 12 + render-max: true 12 13 entries: 13 14 - 14 15 name: basic
+11
include/net/xdp.h
··· 428 428 #ifdef CONFIG_NET 429 429 u32 bpf_xdp_metadata_kfunc_id(int id); 430 430 bool bpf_dev_bound_kfunc_id(u32 btf_id); 431 + void xdp_set_features_flag(struct net_device *dev, xdp_features_t val); 431 432 void xdp_features_set_redirect_target(struct net_device *dev, bool support_sg); 432 433 void xdp_features_clear_redirect_target(struct net_device *dev); 433 434 #else 434 435 static inline u32 bpf_xdp_metadata_kfunc_id(int id) { return 0; } 435 436 static inline bool bpf_dev_bound_kfunc_id(u32 btf_id) { return false; } 437 + 438 + static inline void 439 + xdp_set_features_flag(struct net_device *dev, xdp_features_t val) 440 + { 441 + } 436 442 437 443 static inline void 438 444 xdp_features_set_redirect_target(struct net_device *dev, bool support_sg) ··· 450 444 { 451 445 } 452 446 #endif 447 + 448 + static inline void xdp_clear_features_flag(struct net_device *dev) 449 + { 450 + xdp_set_features_flag(dev, 0); 451 + } 453 452 454 453 #endif /* __LINUX_NET_XDP_H__ */
+2
include/uapi/linux/netdev.h
··· 33 33 NETDEV_XDP_ACT_HW_OFFLOAD = 16, 34 34 NETDEV_XDP_ACT_RX_SG = 32, 35 35 NETDEV_XDP_ACT_NDO_XMIT_SG = 64, 36 + 37 + NETDEV_XDP_ACT_MASK = 127, 36 38 }; 37 39 38 40 enum {
+19 -7
net/core/xdp.c
··· 774 774 } 775 775 late_initcall(xdp_metadata_init); 776 776 777 + void xdp_set_features_flag(struct net_device *dev, xdp_features_t val) 778 + { 779 + val &= NETDEV_XDP_ACT_MASK; 780 + if (dev->xdp_features == val) 781 + return; 782 + 783 + dev->xdp_features = val; 784 + call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev); 785 + } 786 + EXPORT_SYMBOL_GPL(xdp_set_features_flag); 787 + 777 788 void xdp_features_set_redirect_target(struct net_device *dev, bool support_sg) 778 789 { 779 - dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT; 780 - if (support_sg) 781 - dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG; 790 + xdp_features_t val = (dev->xdp_features | NETDEV_XDP_ACT_NDO_XMIT); 782 791 783 - call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev); 792 + if (support_sg) 793 + val |= NETDEV_XDP_ACT_NDO_XMIT_SG; 794 + xdp_set_features_flag(dev, val); 784 795 } 785 796 EXPORT_SYMBOL_GPL(xdp_features_set_redirect_target); 786 797 787 798 void xdp_features_clear_redirect_target(struct net_device *dev) 788 799 { 789 - dev->xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT | 790 - NETDEV_XDP_ACT_NDO_XMIT_SG); 791 - call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev); 800 + xdp_features_t val = dev->xdp_features; 801 + 802 + val &= ~(NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_NDO_XMIT_SG); 803 + xdp_set_features_flag(dev, val); 792 804 } 793 805 EXPORT_SYMBOL_GPL(xdp_features_clear_redirect_target);
+2
tools/include/uapi/linux/netdev.h
··· 33 33 NETDEV_XDP_ACT_HW_OFFLOAD = 16, 34 34 NETDEV_XDP_ACT_RX_SG = 32, 35 35 NETDEV_XDP_ACT_NDO_XMIT_SG = 64, 36 + 37 + NETDEV_XDP_ACT_MASK = 127, 36 38 }; 37 39 38 40 enum {