]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.54/net-aquantia-tx-clean-budget-logic-error.patch
Linux 4.19.54
[thirdparty/kernel/stable-queue.git] / releases / 4.19.54 / net-aquantia-tx-clean-budget-logic-error.patch
CommitLineData
a15a8890
SL
1From 5122b5d03f515f5cec1429414a7a3b66c8f83027 Mon Sep 17 00:00:00 2001
2From: Igor Russkikh <Igor.Russkikh@aquantia.com>
3Date: Sat, 25 May 2019 09:57:59 +0000
4Subject: net: aquantia: tx clean budget logic error
5
6[ Upstream commit 31bafc49a7736989e4c2d9f7280002c66536e590 ]
7
8In case no other traffic happening on the ring, full tx cleanup
9may not be completed. That may cause socket buffer to overflow
10and tx traffic to stuck until next activity on the ring happens.
11
12This is due to logic error in budget variable decrementor.
13Variable is compared with zero, and then post decremented,
14causing it to become MAX_INT. Solution is remove decrementor
15from the `for` statement and rewrite it in a clear way.
16
17Fixes: b647d3980948e ("net: aquantia: Add tx clean budget and valid budget handling logic")
18Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
19Signed-off-by: David S. Miller <davem@davemloft.net>
20Signed-off-by: Sasha Levin <sashal@kernel.org>
21---
22 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 7 ++++---
23 1 file changed, 4 insertions(+), 3 deletions(-)
24
25diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
26index 6f3312350cac..b3c7994d73eb 100644
27--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
28+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
29@@ -139,10 +139,10 @@ void aq_ring_queue_stop(struct aq_ring_s *ring)
30 bool aq_ring_tx_clean(struct aq_ring_s *self)
31 {
32 struct device *dev = aq_nic_get_dev(self->aq_nic);
33- unsigned int budget = AQ_CFG_TX_CLEAN_BUDGET;
34+ unsigned int budget;
35
36- for (; self->sw_head != self->hw_head && budget--;
37- self->sw_head = aq_ring_next_dx(self, self->sw_head)) {
38+ for (budget = AQ_CFG_TX_CLEAN_BUDGET;
39+ budget && self->sw_head != self->hw_head; budget--) {
40 struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head];
41
42 if (likely(buff->is_mapped)) {
43@@ -167,6 +167,7 @@ bool aq_ring_tx_clean(struct aq_ring_s *self)
44
45 buff->pa = 0U;
46 buff->eop_index = 0xffffU;
47+ self->sw_head = aq_ring_next_dx(self, self->sw_head);
48 }
49
50 return !!budget;
51--
522.20.1
53