hv_netvsc: fix race that may miss tx queue wakeup
When the ring buffer is almost full due to RX completion messages, a TX packet may reach the "low watermark" and cause the queue stopped. If the TX completion arrives earlier than queue stopping, the wakeup may be missed. This patch moves the check for the last pending packet to cover both EAGAIN and success cases, so the queue will be reliably waked up when necessary. Reported-and-tested-by: Stephan Klein <stephan.klein@wegfinder.at> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
ea9866793d
Коммит
93aa4792c3
|
@ -875,12 +875,6 @@ static inline int netvsc_send_pkt(
|
|||
} else if (ret == -EAGAIN) {
|
||||
netif_tx_stop_queue(txq);
|
||||
ndev_ctx->eth_stats.stop_queue++;
|
||||
if (atomic_read(&nvchan->queue_sends) < 1 &&
|
||||
!net_device->tx_disable) {
|
||||
netif_tx_wake_queue(txq);
|
||||
ndev_ctx->eth_stats.wake_queue++;
|
||||
ret = -ENOSPC;
|
||||
}
|
||||
} else {
|
||||
netdev_err(ndev,
|
||||
"Unable to send packet pages %u len %u, ret %d\n",
|
||||
|
@ -888,6 +882,15 @@ static inline int netvsc_send_pkt(
|
|||
ret);
|
||||
}
|
||||
|
||||
if (netif_tx_queue_stopped(txq) &&
|
||||
atomic_read(&nvchan->queue_sends) < 1 &&
|
||||
!net_device->tx_disable) {
|
||||
netif_tx_wake_queue(txq);
|
||||
ndev_ctx->eth_stats.wake_queue++;
|
||||
if (ret == -EAGAIN)
|
||||
ret = -ENOSPC;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче