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-improve-rx-buffer-length-management'

Ankit Garg says:

====================
gve: Improve RX buffer length management

This patch series improves the management of the RX buffer length for
the DQO queue format in the gve driver. The goal is to make RX buffer
length config more explicit, easy to change, and performant by default.

We accomplish that in four patches:

1. Currently, the buffer length is implicitly coupled with the header
split setting, which is an unintuitive and restrictive design. The
first patch decouples the RX buffer length from the header split
configuration.

2. The second patch is a preparatory step for third. It converts the XDP
config verification method to use extack for better error reporting.

3. The third patch exposes the `rx_buf_len` parameter to userspace via
ethtool, allowing user to directly view or modify the RX buffer length
if supported by the device.

4. The final patch improves the out-of-the-box RX single stream throughput
by >10% by changing the driver's default behavior to select the
maximum supported RX buffer length advertised by the device during
initialization.
====================

Link: https://patch.msgid.link/20251106192746.243525-1-joshwash@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+78 -24
+9 -3
drivers/net/ethernet/google/gve/gve.h
··· 59 59 60 60 #define GVE_DEFAULT_RX_BUFFER_SIZE 2048 61 61 62 - #define GVE_MAX_RX_BUFFER_SIZE 4096 63 - 64 62 #define GVE_XDP_RX_BUFFER_SIZE_DQO 4096 65 63 66 64 #define GVE_DEFAULT_RX_BUFFER_OFFSET 2048 ··· 1167 1169 priv->queue_format == GVE_GQI_QPL_FORMAT; 1168 1170 } 1169 1171 1172 + static inline bool gve_is_dqo(struct gve_priv *priv) 1173 + { 1174 + return priv->queue_format == GVE_DQO_RDA_FORMAT || 1175 + priv->queue_format == GVE_DQO_QPL_FORMAT; 1176 + } 1177 + 1170 1178 static inline u32 gve_num_tx_queues(struct gve_priv *priv) 1171 1179 { 1172 1180 return priv->tx_cfg.num_queues + priv->tx_cfg.num_xdp_queues; ··· 1253 1249 struct gve_rx_alloc_rings_cfg *cfg); 1254 1250 void gve_rx_start_ring_gqi(struct gve_priv *priv, int idx); 1255 1251 void gve_rx_stop_ring_gqi(struct gve_priv *priv, int idx); 1256 - u16 gve_get_pkt_buf_size(const struct gve_priv *priv, bool enable_hplit); 1257 1252 bool gve_header_split_supported(const struct gve_priv *priv); 1253 + int gve_set_rx_buf_len_config(struct gve_priv *priv, u32 rx_buf_len, 1254 + struct netlink_ext_ack *extack, 1255 + struct gve_rx_alloc_rings_cfg *rx_alloc_cfg); 1258 1256 int gve_set_hsplit_config(struct gve_priv *priv, u8 tcp_data_split, 1259 1257 struct gve_rx_alloc_rings_cfg *rx_alloc_cfg); 1260 1258 /* rx buffer handling */
+4
drivers/net/ethernet/google/gve/gve_adminq.c
··· 987 987 dev_info(&priv->pdev->dev, 988 988 "BUFFER SIZES device option enabled with max_rx_buffer_size of %u, header_buf_size of %u.\n", 989 989 priv->max_rx_buffer_size, priv->header_buf_size); 990 + if (gve_is_dqo(priv) && 991 + priv->max_rx_buffer_size > GVE_DEFAULT_RX_BUFFER_SIZE) 992 + priv->rx_cfg.packet_buffer_size = 993 + priv->max_rx_buffer_size; 990 994 } 991 995 992 996 /* Read and store ring size ranges given by device */
+11 -2
drivers/net/ethernet/google/gve/gve_ethtool.c
··· 529 529 cmd->rx_pending = priv->rx_desc_cnt; 530 530 cmd->tx_pending = priv->tx_desc_cnt; 531 531 532 + kernel_cmd->rx_buf_len = priv->rx_cfg.packet_buffer_size; 533 + 532 534 if (!gve_header_split_supported(priv)) 533 535 kernel_cmd->tcp_data_split = ETHTOOL_TCP_DATA_SPLIT_UNKNOWN; 534 536 else if (priv->header_split_enabled) ··· 591 589 int err; 592 590 593 591 gve_get_curr_alloc_cfgs(priv, &tx_alloc_cfg, &rx_alloc_cfg); 592 + 593 + err = gve_set_rx_buf_len_config(priv, kernel_cmd->rx_buf_len, extack, 594 + &rx_alloc_cfg); 595 + if (err) 596 + return err; 597 + 594 598 err = gve_set_hsplit_config(priv, kernel_cmd->tcp_data_split, 595 599 &rx_alloc_cfg); 596 600 if (err) ··· 613 605 return err; 614 606 } else { 615 607 /* Set ring params for the next up */ 616 - priv->header_split_enabled = rx_alloc_cfg.enable_header_split; 617 608 priv->rx_cfg.packet_buffer_size = 618 609 rx_alloc_cfg.packet_buffer_size; 610 + priv->header_split_enabled = rx_alloc_cfg.enable_header_split; 619 611 priv->tx_desc_cnt = tx_alloc_cfg.ring_size; 620 612 priv->rx_desc_cnt = rx_alloc_cfg.ring_size; 621 613 } ··· 954 946 955 947 const struct ethtool_ops gve_ethtool_ops = { 956 948 .supported_coalesce_params = ETHTOOL_COALESCE_USECS, 957 - .supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT, 949 + .supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT | 950 + ETHTOOL_RING_USE_RX_BUF_LEN, 958 951 .get_drvinfo = gve_get_drvinfo, 959 952 .get_strings = gve_get_strings, 960 953 .get_sset_count = gve_get_sset_count,
+54 -19
drivers/net/ethernet/google/gve/gve_main.c
··· 1707 1707 return 0; 1708 1708 } 1709 1709 1710 - static int verify_xdp_configuration(struct net_device *dev) 1710 + static int gve_verify_xdp_configuration(struct net_device *dev, 1711 + struct netlink_ext_ack *extack) 1711 1712 { 1712 1713 struct gve_priv *priv = netdev_priv(dev); 1713 1714 u16 max_xdp_mtu; 1714 1715 1715 1716 if (dev->features & NETIF_F_LRO) { 1716 - netdev_warn(dev, "XDP is not supported when LRO is on.\n"); 1717 + NL_SET_ERR_MSG_MOD(extack, 1718 + "XDP is not supported when LRO is on."); 1717 1719 return -EOPNOTSUPP; 1718 1720 } 1719 1721 1720 1722 if (priv->header_split_enabled) { 1721 - netdev_warn(dev, "XDP is not supported when header-data split is enabled.\n"); 1723 + NL_SET_ERR_MSG_MOD(extack, 1724 + "XDP is not supported when header-data split is enabled."); 1725 + return -EOPNOTSUPP; 1726 + } 1727 + 1728 + if (priv->rx_cfg.packet_buffer_size != SZ_2K) { 1729 + NL_SET_ERR_MSG_FMT_MOD(extack, 1730 + "XDP is not supported for Rx buf len %d, only %d supported.", 1731 + priv->rx_cfg.packet_buffer_size, SZ_2K); 1722 1732 return -EOPNOTSUPP; 1723 1733 } 1724 1734 ··· 1737 1727 max_xdp_mtu -= GVE_RX_PAD; 1738 1728 1739 1729 if (dev->mtu > max_xdp_mtu) { 1740 - netdev_warn(dev, "XDP is not supported for mtu %d.\n", 1741 - dev->mtu); 1730 + NL_SET_ERR_MSG_FMT_MOD(extack, 1731 + "XDP is not supported for mtu %d.", 1732 + dev->mtu); 1742 1733 return -EOPNOTSUPP; 1743 1734 } 1744 1735 1745 1736 if (priv->rx_cfg.num_queues != priv->tx_cfg.num_queues || 1746 1737 (2 * priv->tx_cfg.num_queues > priv->tx_cfg.max_queues)) { 1747 - netdev_warn(dev, "XDP load failed: The number of configured RX queues %d should be equal to the number of configured TX queues %d and the number of configured RX/TX queues should be less than or equal to half the maximum number of RX/TX queues %d", 1748 - priv->rx_cfg.num_queues, 1749 - priv->tx_cfg.num_queues, 1738 + netdev_warn(dev, 1739 + "XDP load failed: The number of configured RX queues %d should be equal to the number of configured TX queues %d and the number of configured RX/TX queues should be less than or equal to half the maximum number of RX/TX queues %d.", 1740 + priv->rx_cfg.num_queues, priv->tx_cfg.num_queues, 1750 1741 priv->tx_cfg.max_queues); 1742 + NL_SET_ERR_MSG_MOD(extack, 1743 + "XDP load failed: The number of configured RX queues should be equal to the number of configured TX queues and the number of configured RX/TX queues should be less than or equal to half the maximum number of RX/TX queues"); 1751 1744 return -EINVAL; 1752 1745 } 1753 1746 return 0; ··· 1761 1748 struct gve_priv *priv = netdev_priv(dev); 1762 1749 int err; 1763 1750 1764 - err = verify_xdp_configuration(dev); 1751 + err = gve_verify_xdp_configuration(dev, xdp->extack); 1765 1752 if (err) 1766 1753 return err; 1767 1754 switch (xdp->command) { ··· 2054 2041 priv->tx_timeo_cnt++; 2055 2042 } 2056 2043 2057 - u16 gve_get_pkt_buf_size(const struct gve_priv *priv, bool enable_hsplit) 2058 - { 2059 - if (enable_hsplit && priv->max_rx_buffer_size >= GVE_MAX_RX_BUFFER_SIZE) 2060 - return GVE_MAX_RX_BUFFER_SIZE; 2061 - else 2062 - return GVE_DEFAULT_RX_BUFFER_SIZE; 2063 - } 2064 - 2065 2044 /* Header split is only supported on DQ RDA queue format. If XDP is enabled, 2066 2045 * header split is not allowed. 2067 2046 */ ··· 2061 2056 { 2062 2057 return priv->header_buf_size && 2063 2058 priv->queue_format == GVE_DQO_RDA_FORMAT && !priv->xdp_prog; 2059 + } 2060 + 2061 + int gve_set_rx_buf_len_config(struct gve_priv *priv, u32 rx_buf_len, 2062 + struct netlink_ext_ack *extack, 2063 + struct gve_rx_alloc_rings_cfg *rx_alloc_cfg) 2064 + { 2065 + u32 old_rx_buf_len = rx_alloc_cfg->packet_buffer_size; 2066 + 2067 + if (rx_buf_len == old_rx_buf_len) 2068 + return 0; 2069 + 2070 + /* device options may not always contain support for 4K buffers */ 2071 + if (!gve_is_dqo(priv) || priv->max_rx_buffer_size < SZ_4K) { 2072 + NL_SET_ERR_MSG_MOD(extack, 2073 + "Modifying Rx buf len is not supported"); 2074 + return -EOPNOTSUPP; 2075 + } 2076 + 2077 + if (priv->xdp_prog && rx_buf_len != SZ_2K) { 2078 + NL_SET_ERR_MSG_MOD(extack, 2079 + "Rx buf len can only be 2048 when XDP is on"); 2080 + return -EINVAL; 2081 + } 2082 + 2083 + if (rx_buf_len != SZ_2K && rx_buf_len != SZ_4K) { 2084 + NL_SET_ERR_MSG_MOD(extack, 2085 + "Rx buf len can only be 2048 or 4096"); 2086 + return -EINVAL; 2087 + } 2088 + rx_alloc_cfg->packet_buffer_size = rx_buf_len; 2089 + 2090 + return 0; 2064 2091 } 2065 2092 2066 2093 int gve_set_hsplit_config(struct gve_priv *priv, u8 tcp_data_split, ··· 2117 2080 return 0; 2118 2081 2119 2082 rx_alloc_cfg->enable_header_split = enable_hdr_split; 2120 - rx_alloc_cfg->packet_buffer_size = 2121 - gve_get_pkt_buf_size(priv, enable_hdr_split); 2122 2083 2123 2084 return 0; 2124 2085 }