Skip to content

Commit f85901f

Browse files
josh8551021jfvogel
authored andcommitted
gve: fix XDP allocation path in edge cases
commit de63ac4 upstream. This patch fixes a number of consistency issues in the queue allocation path related to XDP. As it stands, the number of allocated XDP queues changes in three different scenarios. 1) Adding an XDP program while the interface is up via gve_add_xdp_queues 2) Removing an XDP program while the interface is up via gve_remove_xdp_queues 3) After queues have been allocated and the old queue memory has been removed in gve_queues_start. However, the requirement for the interface to be up for gve_(add|remove)_xdp_queues to be called, in conjunction with the fact that the number of queues stored in priv isn't updated until _after_ XDP queues have been allocated in the normal queue allocation path means that if an XDP program is added while the interface is down, XDP queues won't be added until the _second_ if_up, not the first. Given the expectation that the number of XDP queues is equal to the number of RX queues, scenario (3) has another problematic implication. When changing the number of queues while an XDP program is loaded, the number of XDP queues must be updated as well, as there is logic in the driver (gve_xdp_tx_queue_id()) which relies on every RX queue having a corresponding XDP TX queue. However, the number of XDP queues stored in priv would not be updated until _after_ a close/open leading to a mismatch in the number of XDP queues reported vs the number of XDP queues which actually exist after the queue count update completes. This patch remedies these issues by doing the following: 1) The allocation config getter function is set up to retrieve the _expected_ number of XDP queues to allocate instead of relying on the value stored in `priv` which is only updated once the queues have been allocated. 2) When adjusting queues, XDP queues are adjusted to match the number of RX queues when XDP is enabled. This only works in the case when queues are live, so part (1) of the fix must still be available in the case that queues are adjusted when there is an XDP program and the interface is down. Fixes: 5f08cd3 ("gve: Alloc before freeing when adjusting queues") Cc: [email protected] Signed-off-by: Joshua Washington <[email protected]> Signed-off-by: Praveen Kaligineedi <[email protected]> Reviewed-by: Praveen Kaligineedi <[email protected]> Reviewed-by: Shailend Chand <[email protected]> Reviewed-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> (cherry picked from commit e2ff6dd63159456103ea050c4f26279416cdad63) Signed-off-by: Jack Vogel <[email protected]>
1 parent fcc533f commit f85901f

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

drivers/net/ethernet/google/gve/gve_main.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,11 +930,13 @@ static void gve_init_sync_stats(struct gve_priv *priv)
930930
static void gve_tx_get_curr_alloc_cfg(struct gve_priv *priv,
931931
struct gve_tx_alloc_rings_cfg *cfg)
932932
{
933+
int num_xdp_queues = priv->xdp_prog ? priv->rx_cfg.num_queues : 0;
934+
933935
cfg->qcfg = &priv->tx_cfg;
934936
cfg->raw_addressing = !gve_is_qpl(priv);
935937
cfg->ring_size = priv->tx_desc_cnt;
936938
cfg->start_idx = 0;
937-
cfg->num_rings = gve_num_tx_queues(priv);
939+
cfg->num_rings = priv->tx_cfg.num_queues + num_xdp_queues;
938940
cfg->tx = priv->tx;
939941
}
940942

@@ -1843,6 +1845,7 @@ int gve_adjust_queues(struct gve_priv *priv,
18431845
{
18441846
struct gve_tx_alloc_rings_cfg tx_alloc_cfg = {0};
18451847
struct gve_rx_alloc_rings_cfg rx_alloc_cfg = {0};
1848+
int num_xdp_queues;
18461849
int err;
18471850

18481851
gve_get_curr_alloc_cfgs(priv, &tx_alloc_cfg, &rx_alloc_cfg);
@@ -1853,6 +1856,10 @@ int gve_adjust_queues(struct gve_priv *priv,
18531856
rx_alloc_cfg.qcfg = &new_rx_config;
18541857
tx_alloc_cfg.num_rings = new_tx_config.num_queues;
18551858

1859+
/* Add dedicated XDP TX queues if enabled. */
1860+
num_xdp_queues = priv->xdp_prog ? new_rx_config.num_queues : 0;
1861+
tx_alloc_cfg.num_rings += num_xdp_queues;
1862+
18561863
if (netif_running(priv->dev)) {
18571864
err = gve_adjust_config(priv, &tx_alloc_cfg, &rx_alloc_cfg);
18581865
return err;

0 commit comments

Comments
 (0)