This change extends the xsk_tx_metadata struct with GSO type and size fields. A new offload XDP_TX_METADATA_GSO is defined, which offloads gso_type and gso_size in skb_shared_info to XDP. Signed-off-by: Muyang Tian <tianmuyang@xxxxxxxxxx> --- Documentation/netlink/specs/netdev.yaml | 4 ++++ include/net/xdp_sock.h | 8 ++++++++ include/net/xdp_sock_drv.h | 1 + include/uapi/linux/if_xdp.h | 11 +++++++++++ include/uapi/linux/netdev.h | 2 ++ net/xdp/xsk.c | 5 +++++ tools/include/uapi/linux/if_xdp.h | 11 +++++++++++ tools/include/uapi/linux/netdev.h | 2 ++ 8 files changed, 44 insertions(+) diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml index 5beee7c8e7cf..f4aa04eba54c 100644 --- a/Documentation/netlink/specs/netdev.yaml +++ b/Documentation/netlink/specs/netdev.yaml @@ -78,6 +78,10 @@ definitions: name: tx-checksum doc: L3 checksum HW offload is supported by the driver. + - + name: tx-gso + doc: + GSO type and size is supported by the driver. - name: queue-type type: enum diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h index bfe625b55d55..e5acb27c3e07 100644 --- a/include/net/xdp_sock.h +++ b/include/net/xdp_sock.h @@ -110,11 +110,14 @@ struct xdp_sock { * indicates position where checksumming should start. * csum_offset indicates position where checksum should be stored. * + * void (*tmo_request_gso)(u32 gso_type, u16 gso_size, void *priv) + * Called when AF_XDP frame requested GSO info. */ struct xsk_tx_metadata_ops { void (*tmo_request_timestamp)(void *priv); u64 (*tmo_fill_timestamp)(void *priv); void (*tmo_request_checksum)(u16 csum_start, u16 csum_offset, void *priv); + void (*tmo_request_gso)(u32 gso_type, u16 gso_size, void *priv); }; #ifdef CONFIG_XDP_SOCKETS @@ -170,6 +173,11 @@ static inline void xsk_tx_metadata_request(const struct xsk_tx_metadata *meta, if (meta->flags & XDP_TXMD_FLAGS_CHECKSUM) ops->tmo_request_checksum(meta->request.csum_start, meta->request.csum_offset, priv); + + if (ops->tmo_request_gso) + if (meta->flags & XDP_TXMD_FLAGS_GSO) + ops->tmo_request_gso(meta->request.gso_type, + meta->request.gso_size, priv); } /** diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h index 0a5dca2b2b3f..b192dab2b835 100644 --- a/include/net/xdp_sock_drv.h +++ b/include/net/xdp_sock_drv.h @@ -198,6 +198,7 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr) #define XDP_TXMD_FLAGS_VALID ( \ XDP_TXMD_FLAGS_TIMESTAMP | \ XDP_TXMD_FLAGS_CHECKSUM | \ + XDP_TXMD_FLAGS_GSO | \ 0) static inline bool xsk_buff_valid_tx_metadata(struct xsk_tx_metadata *meta) diff --git a/include/uapi/linux/if_xdp.h b/include/uapi/linux/if_xdp.h index 42ec5ddaab8d..c3ea368bf613 100644 --- a/include/uapi/linux/if_xdp.h +++ b/include/uapi/linux/if_xdp.h @@ -127,6 +127,11 @@ struct xdp_options { */ #define XDP_TXMD_FLAGS_CHECKSUM (1 << 1) +/* Request transmit GSO info. GSO type and size are communicated via + * csum_start and csum_offset fields of struct xsk_tx_metadata. + */ +#define XDP_TXMD_FLAGS_GSO (1 << 2) + /* AF_XDP offloads request. 'request' union member is consumed by the driver * when the packet is being transmitted. 'completion' union member is * filled by the driver when the transmit completion arrives. @@ -142,6 +147,12 @@ struct xsk_tx_metadata { __u16 csum_start; /* Offset from csum_start where checksum should be stored. */ __u16 csum_offset; + + /* XDP_TXMD_FLAGS_GSO */ + /* Identical to skb_shared_info.gso_type*/ + __u32 gso_type; + /* Identical to skb_shared_info.gso_size*/ + __u16 gso_size; } request; struct { diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h index 1e711d6a4c6b..bd175afb3c6b 100644 --- a/include/uapi/linux/netdev.h +++ b/include/uapi/linux/netdev.h @@ -65,10 +65,12 @@ enum netdev_xdp_rx_metadata { * by the driver. * @NETDEV_XSK_FLAGS_TX_CHECKSUM: L3 checksum HW offload is supported by the * driver. + * @NETDEV_XSK_FLAGS_TX_GSO: GSO type and size is supported by the driver. */ enum netdev_xsk_flags { NETDEV_XSK_FLAGS_TX_TIMESTAMP = 1, NETDEV_XSK_FLAGS_TX_CHECKSUM = 2, + NETDEV_XSK_FLAGS_TX_GSO = 4, }; enum netdev_queue_type { diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index 1140b2a120ca..5a19edfce16c 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -745,6 +745,11 @@ static struct sk_buff *xsk_build_skb(struct xdp_sock *xs, goto free_err; } } + + if (meta->flags & XDP_TXMD_FLAGS_GSO) { + skb_shinfo(skb)->gso_type = meta->request.gso_type; + skb_shinfo(skb)->gso_size = meta->request.gso_size; + } } } diff --git a/tools/include/uapi/linux/if_xdp.h b/tools/include/uapi/linux/if_xdp.h index 2f082b01ff22..5714d0be8c53 100644 --- a/tools/include/uapi/linux/if_xdp.h +++ b/tools/include/uapi/linux/if_xdp.h @@ -127,6 +127,11 @@ struct xdp_options { */ #define XDP_TXMD_FLAGS_CHECKSUM (1 << 1) +/* Request transmit GSO info. GSO type and size are communicated via + * csum_start and csum_offset fields of struct xsk_tx_metadata. + */ +#define XDP_TXMD_FLAGS_GSO (1 << 2) + /* AF_XDP offloads request. 'request' union member is consumed by the driver * when the packet is being transmitted. 'completion' union member is * filled by the driver when the transmit completion arrives. @@ -142,6 +147,12 @@ struct xsk_tx_metadata { __u16 csum_start; /* Offset from csum_start where checksum should be stored. */ __u16 csum_offset; + + /* XDP_TXMD_FLAGS_GSO */ + /* Identical to skb_shared_info.gso_type*/ + __u32 gso_type; + /* Identical to skb_shared_info.gso_size*/ + __u16 gso_size; } request; struct { diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h index 1e711d6a4c6b..bd175afb3c6b 100644 --- a/tools/include/uapi/linux/netdev.h +++ b/tools/include/uapi/linux/netdev.h @@ -65,10 +65,12 @@ enum netdev_xdp_rx_metadata { * by the driver. * @NETDEV_XSK_FLAGS_TX_CHECKSUM: L3 checksum HW offload is supported by the * driver. + * @NETDEV_XSK_FLAGS_TX_GSO: GSO type and size is supported by the driver. */ enum netdev_xsk_flags { NETDEV_XSK_FLAGS_TX_TIMESTAMP = 1, NETDEV_XSK_FLAGS_TX_CHECKSUM = 2, + NETDEV_XSK_FLAGS_TX_GSO = 4, }; enum netdev_queue_type { -- 2.41.0