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.

gve: Consolidate and persist ethtool ring changes

Refactor the ethtool ring parameter configuration logic to address two
issues: unnecessary queue resets and lost configuration changes when
the interface is down.

Previously, `gve_set_ringparam` could trigger multiple queue
destructions and recreations for a single command, as different settings
(e.g., header split, ring sizes) were applied one by one. Furthermore,
if the interface was down, any changes made via ethtool were discarded
instead of being saved for the next time the interface was brought up.

This patch centralizes the configuration logic. Individual functions
like `gve_set_hsplit_config` are modified to only validate and stage
changes in a temporary config struct.

The main `gve_set_ringparam` function now gathers all staged changes
and applies them as a single, combined configuration:
1. If the interface is up, it calls `gve_adjust_config` once.
2. If the interface is down, it saves the settings directly to the
driver's private struct, ensuring they persist and are used when
the interface is brought back up.

Signed-off-by: Ankit Garg <nktgrg@google.com>
Reviewed-by: Harshitha Ramamurthy <hramamurthy@google.com>
Reviewed-by: Jordan Rhee <jordanrhee@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Joshua Washington <joshwash@google.com>
Link: https://patch.msgid.link/20251017012614.3631351-1-joshwash@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Ankit Garg and committed by
Jakub Kicinski
c30fd916 a5cd3a60

+54 -58
+2 -1
drivers/net/ethernet/google/gve/gve.h
··· 1251 1251 void gve_rx_stop_ring_gqi(struct gve_priv *priv, int idx); 1252 1252 u16 gve_get_pkt_buf_size(const struct gve_priv *priv, bool enable_hplit); 1253 1253 bool gve_header_split_supported(const struct gve_priv *priv); 1254 - int gve_set_hsplit_config(struct gve_priv *priv, u8 tcp_data_split); 1254 + int gve_set_hsplit_config(struct gve_priv *priv, u8 tcp_data_split, 1255 + struct gve_rx_alloc_rings_cfg *rx_alloc_cfg); 1255 1256 /* rx buffer handling */ 1256 1257 int gve_buf_ref_cnt(struct gve_rx_buf_state_dqo *bs); 1257 1258 void gve_free_page_dqo(struct gve_priv *priv, struct gve_rx_buf_state_dqo *bs,
+46 -46
drivers/net/ethernet/google/gve/gve_ethtool.c
··· 537 537 kernel_cmd->tcp_data_split = ETHTOOL_TCP_DATA_SPLIT_DISABLED; 538 538 } 539 539 540 - static int gve_adjust_ring_sizes(struct gve_priv *priv, 541 - u16 new_tx_desc_cnt, 542 - u16 new_rx_desc_cnt) 543 - { 544 - struct gve_tx_alloc_rings_cfg tx_alloc_cfg = {0}; 545 - struct gve_rx_alloc_rings_cfg rx_alloc_cfg = {0}; 546 - int err; 547 - 548 - /* get current queue configuration */ 549 - gve_get_curr_alloc_cfgs(priv, &tx_alloc_cfg, &rx_alloc_cfg); 550 - 551 - /* copy over the new ring_size from ethtool */ 552 - tx_alloc_cfg.ring_size = new_tx_desc_cnt; 553 - rx_alloc_cfg.ring_size = new_rx_desc_cnt; 554 - 555 - if (netif_running(priv->dev)) { 556 - err = gve_adjust_config(priv, &tx_alloc_cfg, &rx_alloc_cfg); 557 - if (err) 558 - return err; 559 - } 560 - 561 - /* Set new ring_size for the next up */ 562 - priv->tx_desc_cnt = new_tx_desc_cnt; 563 - priv->rx_desc_cnt = new_rx_desc_cnt; 564 - 565 - return 0; 566 - } 567 - 568 540 static int gve_validate_req_ring_size(struct gve_priv *priv, u16 new_tx_desc_cnt, 569 541 u16 new_rx_desc_cnt) 570 542 { ··· 556 584 return 0; 557 585 } 558 586 559 - static int gve_set_ringparam(struct net_device *netdev, 560 - struct ethtool_ringparam *cmd, 561 - struct kernel_ethtool_ringparam *kernel_cmd, 562 - struct netlink_ext_ack *extack) 587 + static int gve_set_ring_sizes_config(struct gve_priv *priv, u16 new_tx_desc_cnt, 588 + u16 new_rx_desc_cnt, 589 + struct gve_tx_alloc_rings_cfg *tx_alloc_cfg, 590 + struct gve_rx_alloc_rings_cfg *rx_alloc_cfg) 563 591 { 564 - struct gve_priv *priv = netdev_priv(netdev); 565 - u16 new_tx_cnt, new_rx_cnt; 566 - int err; 567 - 568 - err = gve_set_hsplit_config(priv, kernel_cmd->tcp_data_split); 569 - if (err) 570 - return err; 571 - 572 - if (cmd->tx_pending == priv->tx_desc_cnt && cmd->rx_pending == priv->rx_desc_cnt) 592 + if (new_tx_desc_cnt == priv->tx_desc_cnt && 593 + new_rx_desc_cnt == priv->rx_desc_cnt) 573 594 return 0; 574 595 575 596 if (!priv->modify_ring_size_enabled) { ··· 570 605 return -EOPNOTSUPP; 571 606 } 572 607 573 - new_tx_cnt = cmd->tx_pending; 574 - new_rx_cnt = cmd->rx_pending; 575 - 576 - if (gve_validate_req_ring_size(priv, new_tx_cnt, new_rx_cnt)) 608 + if (gve_validate_req_ring_size(priv, new_tx_desc_cnt, new_rx_desc_cnt)) 577 609 return -EINVAL; 578 610 579 - return gve_adjust_ring_sizes(priv, new_tx_cnt, new_rx_cnt); 611 + tx_alloc_cfg->ring_size = new_tx_desc_cnt; 612 + rx_alloc_cfg->ring_size = new_rx_desc_cnt; 613 + return 0; 614 + } 615 + 616 + static int gve_set_ringparam(struct net_device *netdev, 617 + struct ethtool_ringparam *cmd, 618 + struct kernel_ethtool_ringparam *kernel_cmd, 619 + struct netlink_ext_ack *extack) 620 + { 621 + struct gve_tx_alloc_rings_cfg tx_alloc_cfg = {0}; 622 + struct gve_rx_alloc_rings_cfg rx_alloc_cfg = {0}; 623 + struct gve_priv *priv = netdev_priv(netdev); 624 + int err; 625 + 626 + gve_get_curr_alloc_cfgs(priv, &tx_alloc_cfg, &rx_alloc_cfg); 627 + err = gve_set_hsplit_config(priv, kernel_cmd->tcp_data_split, 628 + &rx_alloc_cfg); 629 + if (err) 630 + return err; 631 + 632 + err = gve_set_ring_sizes_config(priv, cmd->tx_pending, cmd->rx_pending, 633 + &tx_alloc_cfg, &rx_alloc_cfg); 634 + if (err) 635 + return err; 636 + 637 + if (netif_running(priv->dev)) { 638 + err = gve_adjust_config(priv, &tx_alloc_cfg, &rx_alloc_cfg); 639 + if (err) 640 + return err; 641 + } else { 642 + /* Set ring params for the next up */ 643 + priv->header_split_enabled = rx_alloc_cfg.enable_header_split; 644 + priv->rx_cfg.packet_buffer_size = 645 + rx_alloc_cfg.packet_buffer_size; 646 + priv->tx_desc_cnt = tx_alloc_cfg.ring_size; 647 + priv->rx_desc_cnt = rx_alloc_cfg.ring_size; 648 + } 649 + return 0; 580 650 } 581 651 582 652 static int gve_user_reset(struct net_device *netdev, u32 *flags)
+6 -11
drivers/net/ethernet/google/gve/gve_main.c
··· 2058 2058 priv->queue_format == GVE_DQO_RDA_FORMAT && !priv->xdp_prog; 2059 2059 } 2060 2060 2061 - int gve_set_hsplit_config(struct gve_priv *priv, u8 tcp_data_split) 2061 + int gve_set_hsplit_config(struct gve_priv *priv, u8 tcp_data_split, 2062 + struct gve_rx_alloc_rings_cfg *rx_alloc_cfg) 2062 2063 { 2063 - struct gve_tx_alloc_rings_cfg tx_alloc_cfg = {0}; 2064 - struct gve_rx_alloc_rings_cfg rx_alloc_cfg = {0}; 2065 2064 bool enable_hdr_split; 2066 - int err = 0; 2067 2065 2068 2066 if (tcp_data_split == ETHTOOL_TCP_DATA_SPLIT_UNKNOWN) 2069 2067 return 0; ··· 2079 2081 if (enable_hdr_split == priv->header_split_enabled) 2080 2082 return 0; 2081 2083 2082 - gve_get_curr_alloc_cfgs(priv, &tx_alloc_cfg, &rx_alloc_cfg); 2084 + rx_alloc_cfg->enable_header_split = enable_hdr_split; 2085 + rx_alloc_cfg->packet_buffer_size = 2086 + gve_get_pkt_buf_size(priv, enable_hdr_split); 2083 2087 2084 - rx_alloc_cfg.enable_header_split = enable_hdr_split; 2085 - rx_alloc_cfg.packet_buffer_size = gve_get_pkt_buf_size(priv, enable_hdr_split); 2086 - 2087 - if (netif_running(priv->dev)) 2088 - err = gve_adjust_config(priv, &tx_alloc_cfg, &rx_alloc_cfg); 2089 - return err; 2088 + return 0; 2090 2089 } 2091 2090 2092 2091 static int gve_set_features(struct net_device *netdev,