Netpoll will explicitly pass the polling call with a budget of 0 to indicate it's clearing the Tx path only. For the gve_rx_poll and gve_xdp_poll, they were mistakenly taking the 0 budget as the indication to do all the work. Add check to avoid the rx path and xdp path being called when budget is 0. And also avoid napi_complete_done being called when budget is 0 for netpoll.
The original fix was merged here: https://lore.kernel.org/r/20231114004144.2022268-1-ziweixiao@google.com Resend it since the original one was not cleanly applied to 6.1 kernel.
Fixes: f5cedc84a30d ("gve: Add transmit and receive support") Signed-off-by: Ziwei Xiao ziweixiao@google.com Reviewed-by: Praveen Kaligineedi pkaligineedi@google.com Signed-off-by: Praveen Kaligineedi pkaligineedi@google.com --- drivers/net/ethernet/google/gve/gve_main.c | 7 +++++++ drivers/net/ethernet/google/gve/gve_rx.c | 4 ---- drivers/net/ethernet/google/gve/gve_tx.c | 4 ---- 3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index d3f6ad586ba1..8771ccfc69b4 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -202,6 +202,10 @@ static int gve_napi_poll(struct napi_struct *napi, int budget)
if (block->tx) reschedule |= gve_tx_poll(block, budget); + + if (!budget) + return 0; + if (block->rx) { work_done = gve_rx_poll(block, budget); reschedule |= work_done == budget; @@ -242,6 +246,9 @@ static int gve_napi_poll_dqo(struct napi_struct *napi, int budget) if (block->tx) reschedule |= gve_tx_poll_dqo(block, /*do_clean=*/true);
+ if (!budget) + return 0; + if (block->rx) { work_done = gve_rx_poll_dqo(block, budget); reschedule |= work_done == budget; diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c index 021bbf308d68..639eb6848c7d 100644 --- a/drivers/net/ethernet/google/gve/gve_rx.c +++ b/drivers/net/ethernet/google/gve/gve_rx.c @@ -778,10 +778,6 @@ int gve_rx_poll(struct gve_notify_block *block, int budget)
feat = block->napi.dev->features;
- /* If budget is 0, do all the work */ - if (budget == 0) - budget = INT_MAX; - if (budget > 0) work_done = gve_clean_rx_done(rx, budget, feat);
diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c index 5e11b8236754..bf1ac0d1dc6f 100644 --- a/drivers/net/ethernet/google/gve/gve_tx.c +++ b/drivers/net/ethernet/google/gve/gve_tx.c @@ -725,10 +725,6 @@ bool gve_tx_poll(struct gve_notify_block *block, int budget) u32 nic_done; u32 to_do;
- /* If budget is 0, do all the work */ - if (budget == 0) - budget = INT_MAX; - /* In TX path, it may try to clean completed pkts in order to xmit, * to avoid cleaning conflict, use spin_lock(), it yields better * concurrency between xmit/clean than netif's lock.
[ Sasha's backport helper bot ]
Hi,
Found matching upstream commit: 278a370c1766060d2144d6cf0b06c101e1043b6d
Status in newer kernel trees: 6.12.y | Present (exact SHA1) 6.11.y | Present (exact SHA1) 6.6.y | Present (different SHA1: ff33be9cecee) 6.1.y | Not found
Note: The patch differs from the upstream commit: --- --- - 2024-11-26 14:46:00.728480326 -0500 +++ /tmp/tmp.OFZu4s6rk5 2024-11-26 14:46:00.726235127 -0500 @@ -1,40 +1,33 @@ -Netpoll will explicilty pass the polling call with a budget of 0 to -indicate it's clearing the Tx path only. For the gve_rx_poll and -gve_xdp_poll, they were mistakenly taking the 0 budget as the indication -to do all the work. Add check to avoid the rx path and xdp path being -called when budget is 0. And also avoid napi_complete_done being called -when budget is 0 for netpoll. +The original fix was merged here: +https://lore.kernel.org/r/20231114004144.2022268-1-ziweixiao@google.com +Resend it since the original one was not cleanly applied to 6.1 kernel.
Fixes: f5cedc84a30d ("gve: Add transmit and receive support") Signed-off-by: Ziwei Xiao ziweixiao@google.com -Link: https://lore.kernel.org/r/20231114004144.2022268-1-ziweixiao@google.com -Signed-off-by: Jakub Kicinski kuba@kernel.org +Reviewed-by: Praveen Kaligineedi pkaligineedi@google.com +Signed-off-by: Praveen Kaligineedi pkaligineedi@google.com --- - drivers/net/ethernet/google/gve/gve_main.c | 8 +++++++- + drivers/net/ethernet/google/gve/gve_main.c | 7 +++++++ drivers/net/ethernet/google/gve/gve_rx.c | 4 ---- drivers/net/ethernet/google/gve/gve_tx.c | 4 ---- - 3 files changed, 7 insertions(+), 9 deletions(-) + 3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c -index 276f996f95dcc..2d42e733837b0 100644 +index d3f6ad586ba1..8771ccfc69b4 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c -@@ -254,10 +254,13 @@ static int gve_napi_poll(struct napi_struct *napi, int budget) - if (block->tx) { - if (block->tx->q_num < priv->tx_cfg.num_queues) - reschedule |= gve_tx_poll(block, budget); -- else -+ else if (budget) - reschedule |= gve_xdp_poll(block, budget); - } +@@ -202,6 +202,10 @@ static int gve_napi_poll(struct napi_struct *napi, int budget)
+ if (block->tx) + reschedule |= gve_tx_poll(block, budget); ++ + if (!budget) + return 0; + if (block->rx) { work_done = gve_rx_poll(block, budget); reschedule |= work_done == budget; -@@ -298,6 +301,9 @@ static int gve_napi_poll_dqo(struct napi_struct *napi, int budget) +@@ -242,6 +246,9 @@ static int gve_napi_poll_dqo(struct napi_struct *napi, int budget) if (block->tx) reschedule |= gve_tx_poll_dqo(block, /*do_clean=*/true);
@@ -45,10 +38,10 @@ work_done = gve_rx_poll_dqo(block, budget); reschedule |= work_done == budget; diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c -index e84a066aa1a40..73655347902d2 100644 +index 021bbf308d68..639eb6848c7d 100644 --- a/drivers/net/ethernet/google/gve/gve_rx.c +++ b/drivers/net/ethernet/google/gve/gve_rx.c -@@ -1007,10 +1007,6 @@ int gve_rx_poll(struct gve_notify_block *block, int budget) +@@ -778,10 +778,6 @@ int gve_rx_poll(struct gve_notify_block *block, int budget)
feat = block->napi.dev->features;
@@ -60,17 +53,20 @@ work_done = gve_clean_rx_done(rx, budget, feat);
diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c -index 6957a865cff37..9f6ffc4a54f0b 100644 +index 5e11b8236754..bf1ac0d1dc6f 100644 --- a/drivers/net/ethernet/google/gve/gve_tx.c +++ b/drivers/net/ethernet/google/gve/gve_tx.c -@@ -925,10 +925,6 @@ bool gve_xdp_poll(struct gve_notify_block *block, int budget) - bool repoll; +@@ -725,10 +725,6 @@ bool gve_tx_poll(struct gve_notify_block *block, int budget) + u32 nic_done; u32 to_do;
- /* If budget is 0, do all the work */ - if (budget == 0) - budget = INT_MAX; - - /* Find out how much work there is to be done */ - nic_done = gve_tx_load_event_counter(priv, tx); - to_do = min_t(u32, (nic_done - tx->done), budget); + /* In TX path, it may try to clean completed pkts in order to xmit, + * to avoid cleaning conflict, use spin_lock(), it yields better + * concurrency between xmit/clean than netif's lock. +-- +2.47.0.338.g60cca15819-goog + ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.1.y | Success | Success |
On Tue, Nov 26, 2024 at 06:47:31PM +0000, Ziwei Xiao wrote:
Netpoll will explicitly pass the polling call with a budget of 0 to indicate it's clearing the Tx path only. For the gve_rx_poll and gve_xdp_poll, they were mistakenly taking the 0 budget as the indication to do all the work. Add check to avoid the rx path and xdp path being called when budget is 0. And also avoid napi_complete_done being called when budget is 0 for netpoll.
The original fix was merged here: https://lore.kernel.org/r/20231114004144.2022268-1-ziweixiao@google.com Resend it since the original one was not cleanly applied to 6.1 kernel.
Fixes: f5cedc84a30d ("gve: Add transmit and receive support") Signed-off-by: Ziwei Xiao ziweixiao@google.com Reviewed-by: Praveen Kaligineedi pkaligineedi@google.com Signed-off-by: Praveen Kaligineedi pkaligineedi@google.com
drivers/net/ethernet/google/gve/gve_main.c | 7 +++++++ drivers/net/ethernet/google/gve/gve_rx.c | 4 ---- drivers/net/ethernet/google/gve/gve_tx.c | 4 ---- 3 files changed, 7 insertions(+), 8 deletions(-)
No git id? :(
linux-stable-mirror@lists.linaro.org