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

xsk: add new netlink attribute dedicated for ZC max frags

Introduce new netlink attribute NETDEV_A_DEV_XDP_ZC_MAX_SEGS that will
carry maximum fragments that underlying ZC driver is able to handle on
TX side. It is going to be included in netlink response only when driver
supports ZC. Any value higher than 1 implies multi-buffer ZC support on
underlying device.

Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Link: https://lore.kernel.org/r/20230719132421.584801-11-maciej.fijalkowski@intel.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Maciej Fijalkowski and committed by
Alexei Starovoitov
13ce2daa 07428da9

+25 -1
+6
Documentation/netlink/specs/netdev.yaml
··· 62 62 type: u64 63 63 enum: xdp-act 64 64 enum-as-flags: true 65 + - 66 + name: xdp_zc_max_segs 67 + doc: max fragment count supported by ZC driver 68 + type: u32 69 + checks: 70 + min: 1 65 71 66 72 operations: 67 73 list:
+1
include/linux/netdevice.h
··· 2250 2250 #define GRO_MAX_SIZE (8 * 65535u) 2251 2251 unsigned int gro_max_size; 2252 2252 unsigned int gro_ipv4_max_size; 2253 + unsigned int xdp_zc_max_segs; 2253 2254 rx_handler_func_t __rcu *rx_handler; 2254 2255 void __rcu *rx_handler_data; 2255 2256
+1
include/uapi/linux/netdev.h
··· 41 41 NETDEV_A_DEV_IFINDEX = 1, 42 42 NETDEV_A_DEV_PAD, 43 43 NETDEV_A_DEV_XDP_FEATURES, 44 + NETDEV_A_DEV_XDP_ZC_MAX_SEGS, 44 45 45 46 __NETDEV_A_DEV_MAX, 46 47 NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
+1
net/core/dev.c
··· 10613 10613 dev_net_set(dev, &init_net); 10614 10614 10615 10615 dev->gso_max_size = GSO_LEGACY_MAX_SIZE; 10616 + dev->xdp_zc_max_segs = 1; 10616 10617 dev->gso_max_segs = GSO_MAX_SEGS; 10617 10618 dev->gro_max_size = GRO_LEGACY_MAX_SIZE; 10618 10619 dev->gso_ipv4_max_size = GSO_LEGACY_MAX_SIZE;
+8
net/core/netdev-genl.c
··· 25 25 return -EINVAL; 26 26 } 27 27 28 + if (netdev->xdp_features & NETDEV_XDP_ACT_XSK_ZEROCOPY) { 29 + if (nla_put_u32(rsp, NETDEV_A_DEV_XDP_ZC_MAX_SEGS, 30 + netdev->xdp_zc_max_segs)) { 31 + genlmsg_cancel(rsp, hdr); 32 + return -EINVAL; 33 + } 34 + } 35 + 28 36 genlmsg_end(rsp, hdr); 29 37 30 38 return 0;
+1
tools/include/uapi/linux/netdev.h
··· 41 41 NETDEV_A_DEV_IFINDEX = 1, 42 42 NETDEV_A_DEV_PAD, 43 43 NETDEV_A_DEV_XDP_FEATURES, 44 + NETDEV_A_DEV_XDP_ZC_MAX_SEGS, 44 45 45 46 __NETDEV_A_DEV_MAX, 46 47 NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
+2 -1
tools/lib/bpf/libbpf.h
··· 1105 1105 __u32 skb_prog_id; /* output */ 1106 1106 __u8 attach_mode; /* output */ 1107 1107 __u64 feature_flags; /* output */ 1108 + __u32 xdp_zc_max_segs; /* output */ 1108 1109 size_t :0; 1109 1110 }; 1110 - #define bpf_xdp_query_opts__last_field feature_flags 1111 + #define bpf_xdp_query_opts__last_field xdp_zc_max_segs 1111 1112 1112 1113 LIBBPF_API int bpf_xdp_attach(int ifindex, int prog_fd, __u32 flags, 1113 1114 const struct bpf_xdp_attach_opts *opts);
+5
tools/lib/bpf/netlink.c
··· 45 45 46 46 struct xdp_features_md { 47 47 int ifindex; 48 + __u32 xdp_zc_max_segs; 48 49 __u64 flags; 49 50 }; 50 51 ··· 422 421 return NL_CONT; 423 422 424 423 md->flags = libbpf_nla_getattr_u64(tb[NETDEV_A_DEV_XDP_FEATURES]); 424 + if (tb[NETDEV_A_DEV_XDP_ZC_MAX_SEGS]) 425 + md->xdp_zc_max_segs = 426 + libbpf_nla_getattr_u32(tb[NETDEV_A_DEV_XDP_ZC_MAX_SEGS]); 425 427 return NL_DONE; 426 428 } 427 429 ··· 497 493 return libbpf_err(err); 498 494 499 495 opts->feature_flags = md.flags; 496 + opts->xdp_zc_max_segs = md.xdp_zc_max_segs; 500 497 501 498 skip_feature_flags: 502 499 return 0;