Skip to content

Commit b03f15c

Browse files
praveenkaligineedikuba-moo
authored andcommitted
gve: Fix stuck TX queue for DQ queue format
gve_tx_timeout was calculating missed completions in a way that is only relevant in the GQ queue format. Additionally, it was attempting to disable device interrupts, which is not needed in either GQ or DQ queue formats. As a result, TX timeouts with the DQ queue format likely would have triggered early resets without kicking the queue at all. This patch drops the check for pending work altogether and always kicks the queue after validating the queue has not seen a TX timeout too recently. Cc: [email protected] Fixes: 87a7f32 ("gve: Recover from queue stall due to missed IRQ") Co-developed-by: Tim Hostetler <[email protected]> Signed-off-by: Tim Hostetler <[email protected]> Signed-off-by: Praveen Kaligineedi <[email protected]> Signed-off-by: Harshitha Ramamurthy <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 6c4a92d commit b03f15c

File tree

1 file changed

+37
-30
lines changed

1 file changed

+37
-30
lines changed

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

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,49 +1917,56 @@ static void gve_turnup_and_check_status(struct gve_priv *priv)
19171917
gve_handle_link_status(priv, GVE_DEVICE_STATUS_LINK_STATUS_MASK & status);
19181918
}
19191919

1920-
static void gve_tx_timeout(struct net_device *dev, unsigned int txqueue)
1920+
static struct gve_notify_block *gve_get_tx_notify_block(struct gve_priv *priv,
1921+
unsigned int txqueue)
19211922
{
1922-
struct gve_notify_block *block;
1923-
struct gve_tx_ring *tx = NULL;
1924-
struct gve_priv *priv;
1925-
u32 last_nic_done;
1926-
u32 current_time;
19271923
u32 ntfy_idx;
19281924

1929-
netdev_info(dev, "Timeout on tx queue, %d", txqueue);
1930-
priv = netdev_priv(dev);
19311925
if (txqueue > priv->tx_cfg.num_queues)
1932-
goto reset;
1926+
return NULL;
19331927

19341928
ntfy_idx = gve_tx_idx_to_ntfy(priv, txqueue);
19351929
if (ntfy_idx >= priv->num_ntfy_blks)
1936-
goto reset;
1930+
return NULL;
1931+
1932+
return &priv->ntfy_blocks[ntfy_idx];
1933+
}
1934+
1935+
static bool gve_tx_timeout_try_q_kick(struct gve_priv *priv,
1936+
unsigned int txqueue)
1937+
{
1938+
struct gve_notify_block *block;
1939+
u32 current_time;
19371940

1938-
block = &priv->ntfy_blocks[ntfy_idx];
1939-
tx = block->tx;
1941+
block = gve_get_tx_notify_block(priv, txqueue);
1942+
1943+
if (!block)
1944+
return false;
19401945

19411946
current_time = jiffies_to_msecs(jiffies);
1942-
if (tx->last_kick_msec + MIN_TX_TIMEOUT_GAP > current_time)
1943-
goto reset;
1947+
if (block->tx->last_kick_msec + MIN_TX_TIMEOUT_GAP > current_time)
1948+
return false;
19441949

1945-
/* Check to see if there are missed completions, which will allow us to
1946-
* kick the queue.
1947-
*/
1948-
last_nic_done = gve_tx_load_event_counter(priv, tx);
1949-
if (last_nic_done - tx->done) {
1950-
netdev_info(dev, "Kicking queue %d", txqueue);
1951-
iowrite32be(GVE_IRQ_MASK, gve_irq_doorbell(priv, block));
1952-
napi_schedule(&block->napi);
1953-
tx->last_kick_msec = current_time;
1954-
goto out;
1955-
} // Else reset.
1950+
netdev_info(priv->dev, "Kicking queue %d", txqueue);
1951+
napi_schedule(&block->napi);
1952+
block->tx->last_kick_msec = current_time;
1953+
return true;
1954+
}
19561955

1957-
reset:
1958-
gve_schedule_reset(priv);
1956+
static void gve_tx_timeout(struct net_device *dev, unsigned int txqueue)
1957+
{
1958+
struct gve_notify_block *block;
1959+
struct gve_priv *priv;
19591960

1960-
out:
1961-
if (tx)
1962-
tx->queue_timeout++;
1961+
netdev_info(dev, "Timeout on tx queue, %d", txqueue);
1962+
priv = netdev_priv(dev);
1963+
1964+
if (!gve_tx_timeout_try_q_kick(priv, txqueue))
1965+
gve_schedule_reset(priv);
1966+
1967+
block = gve_get_tx_notify_block(priv, txqueue);
1968+
if (block)
1969+
block->tx->queue_timeout++;
19631970
priv->tx_timeo_cnt++;
19641971
}
19651972

0 commit comments

Comments
 (0)