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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'gve-optimize-and-enable-hw-gro-for-dqo'

Ankit Garg says:

====================
gve: optimize and enable HW GRO for DQO

The DQO device has always performed HW GRO, not LRO. This series updates
the feature bit and modifies the RX path to enhance support. It sets
gso_segs correctly so the software stack can continue coalescing, and
pulls network headers into the skb linear space to avoid multiple small
memory copies when header-split is disabled.

We also enable HW GRO by default on supported devices.
====================

Link: https://patch.msgid.link/20260303195549.2679070-1-joshwash@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+48 -14
+6 -4
drivers/net/ethernet/google/gve/gve_adminq.c
··· 791 791 cmd->create_rx_queue.rx_buff_ring_size = 792 792 cpu_to_be16(priv->rx_desc_cnt); 793 793 cmd->create_rx_queue.enable_rsc = 794 - !!(priv->dev->features & NETIF_F_LRO); 794 + !!(priv->dev->features & NETIF_F_GRO_HW); 795 795 if (priv->header_split_enabled) 796 796 cmd->create_rx_queue.header_buffer_size = 797 797 cpu_to_be16(priv->header_buf_size); ··· 1117 1117 1118 1118 gve_set_default_rss_sizes(priv); 1119 1119 1120 - /* DQO supports LRO. */ 1121 - if (!gve_is_gqi(priv)) 1122 - priv->dev->hw_features |= NETIF_F_LRO; 1120 + /* DQO supports HW-GRO. */ 1121 + if (gve_is_dqo(priv)) { 1122 + priv->dev->hw_features |= NETIF_F_GRO_HW; 1123 + priv->dev->features |= NETIF_F_GRO_HW; 1124 + } 1123 1125 1124 1126 priv->max_registered_pages = 1125 1127 be64_to_cpu(descriptor->max_registered_pages);
+8 -7
drivers/net/ethernet/google/gve/gve_main.c
··· 1758 1758 struct gve_priv *priv = netdev_priv(dev); 1759 1759 u16 max_xdp_mtu; 1760 1760 1761 - if (dev->features & NETIF_F_LRO) { 1761 + if (dev->features & NETIF_F_GRO_HW) { 1762 1762 NL_SET_ERR_MSG_MOD(extack, 1763 - "XDP is not supported when LRO is on."); 1763 + "XDP is not supported when HW-GRO is on."); 1764 1764 return -EOPNOTSUPP; 1765 1765 } 1766 1766 ··· 2177 2177 2178 2178 gve_get_curr_alloc_cfgs(priv, &tx_alloc_cfg, &rx_alloc_cfg); 2179 2179 2180 - if ((netdev->features & NETIF_F_LRO) != (features & NETIF_F_LRO)) { 2181 - netdev->features ^= NETIF_F_LRO; 2182 - if (priv->xdp_prog && (netdev->features & NETIF_F_LRO)) { 2180 + if ((netdev->features & NETIF_F_GRO_HW) != 2181 + (features & NETIF_F_GRO_HW)) { 2182 + netdev->features ^= NETIF_F_GRO_HW; 2183 + if (priv->xdp_prog && (netdev->features & NETIF_F_GRO_HW)) { 2183 2184 netdev_warn(netdev, 2184 - "XDP is not supported when LRO is on.\n"); 2185 - err = -EOPNOTSUPP; 2185 + "HW-GRO is not supported when XDP is on."); 2186 + err = -EOPNOTSUPP; 2186 2187 goto revert_features; 2187 2188 } 2188 2189 if (netif_running(netdev)) {
+34 -3
drivers/net/ethernet/google/gve/gve_rx_dqo.c
··· 942 942 struct gve_ptype ptype) 943 943 { 944 944 struct skb_shared_info *shinfo = skb_shinfo(skb); 945 + int rsc_segments, rsc_seg_len, hdr_len; 946 + skb_frag_t *frag; 947 + void *va; 945 948 946 - /* Only TCP is supported right now. */ 949 + /* HW-GRO only coalesces TCP. */ 947 950 if (ptype.l4_type != GVE_L4_TYPE_TCP) 948 951 return -EINVAL; 952 + 953 + rsc_seg_len = le16_to_cpu(desc->rsc_seg_len); 954 + if (!rsc_seg_len) 955 + return 0; 949 956 950 957 switch (ptype.l3_type) { 951 958 case GVE_L3_TYPE_IPV4: ··· 965 958 return -EINVAL; 966 959 } 967 960 968 - shinfo->gso_size = le16_to_cpu(desc->rsc_seg_len); 961 + if (skb_headlen(skb)) { 962 + /* With header-split, payload is in the non-linear part */ 963 + rsc_segments = DIV_ROUND_UP(skb->data_len, rsc_seg_len); 964 + } else { 965 + /* HW-GRO packets are guaranteed to have complete TCP/IP 966 + * headers in frag[0] when header-split is not enabled. 967 + */ 968 + frag = &skb_shinfo(skb)->frags[0]; 969 + va = skb_frag_address(frag); 970 + hdr_len = 971 + eth_get_headlen(skb->dev, va, skb_frag_size(frag)); 972 + rsc_segments = DIV_ROUND_UP(skb->len - hdr_len, rsc_seg_len); 973 + skb_copy_to_linear_data(skb, va, hdr_len); 974 + skb_frag_size_sub(frag, hdr_len); 975 + /* Verify we didn't empty the fragment completely as that could 976 + * otherwise lead to page leaks. 977 + */ 978 + DEBUG_NET_WARN_ON_ONCE(!skb_frag_size(frag)); 979 + skb_frag_off_add(frag, hdr_len); 980 + skb->data_len -= hdr_len; 981 + skb->tail += hdr_len; 982 + } 983 + shinfo->gso_size = rsc_seg_len; 984 + shinfo->gso_segs = rsc_segments; 985 + 969 986 return 0; 970 987 } 971 988 ··· 1022 991 return err; 1023 992 } 1024 993 1025 - if (skb_headlen(rx->ctx.skb_head) == 0) 994 + if (rx->ctx.skb_head == napi->skb) 1026 995 napi_gro_frags(napi); 1027 996 else 1028 997 napi_gro_receive(napi, rx->ctx.skb_head);