112 lines
4.2 KiB
Diff
112 lines
4.2 KiB
Diff
From d2324558512bc6ce618c81544a0c27b69ce2979f Mon Sep 17 00:00:00 2001
|
|
From: Yunsheng Lin <linyunsheng@huawei.com>
|
|
Date: Thu, 18 Nov 2021 20:44:38 +0800
|
|
Subject: [PATCH 140/283] net: hns3: fix for miscalculation of rx unused desc
|
|
|
|
mainline inclusion
|
|
from mainline-v5.15-rc7
|
|
commit 9f9f0f19994b42b3e5e8735d41b9c5136828a76c
|
|
category: bugfix
|
|
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EMYT
|
|
CVE: NA
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9f9f0f19994b42b3e5e8735d41b9c5136828a76c
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
rx unused desc is the desc that need attatching new buffer
|
|
before refilling to hw to receive new packet, the number of
|
|
desc need attatching new buffer is calculated using next_to_use
|
|
and next_to_clean. when next_to_use == next_to_clean, currently
|
|
hns3 driver assumes that all the desc has the buffer attatched,
|
|
but 'next_to_use == next_to_clean' also means all the desc need
|
|
attatching new buffer if hw has comsumed all the desc and the
|
|
driver has not attatched any buffer to the desc yet.
|
|
|
|
This patch adds 'refill' in desc_cb to indicate whether a new
|
|
buffer has been refilled to a desc.
|
|
|
|
Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
|
|
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
|
|
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Reviewed-by: Yongxin Li <liyongxin1@huawei.com>
|
|
Signed-off-by: Junxin Chen <chenjunxin1@huawei.com>
|
|
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
Signed-off-by: Xiaodong Li <lixiaodong67@huawei.com>
|
|
---
|
|
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 9 ++++++++-
|
|
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 1 +
|
|
2 files changed, 9 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
index b0699bffb22a..9acb48ff8c6f 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
@@ -2931,6 +2931,7 @@ static void hns3_buffer_detach(struct hns3_enet_ring *ring, int i)
|
|
{
|
|
hns3_unmap_buffer(ring, &ring->desc_cb[i]);
|
|
ring->desc[i].addr = 0;
|
|
+ ring->desc_cb[i].refill = 0;
|
|
}
|
|
|
|
static void hns3_free_buffer_detach(struct hns3_enet_ring *ring, int i,
|
|
@@ -3008,7 +3009,7 @@ static int hns3_alloc_and_attach_buffer(struct hns3_enet_ring *ring, int i)
|
|
return ret;
|
|
|
|
ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma);
|
|
-
|
|
+ ring->desc_cb[i].refill = 1;
|
|
return 0;
|
|
}
|
|
|
|
@@ -3037,6 +3038,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i,
|
|
{
|
|
hns3_unmap_buffer(ring, &ring->desc_cb[i]);
|
|
ring->desc_cb[i] = *res_cb;
|
|
+ ring->desc_cb[i].refill = 1;
|
|
ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma);
|
|
ring->desc[i].rx.bd_base_info = 0;
|
|
}
|
|
@@ -3044,6 +3046,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i,
|
|
static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i)
|
|
{
|
|
ring->desc_cb[i].reuse_flag = 0;
|
|
+ ring->desc_cb[i].refill = 1;
|
|
ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
|
|
ring->desc_cb[i].page_offset);
|
|
ring->desc[i].rx.bd_base_info = 0;
|
|
@@ -3149,6 +3152,9 @@ static int hns3_desc_unused(struct hns3_enet_ring *ring)
|
|
int ntc = ring->next_to_clean;
|
|
int ntu = ring->next_to_use;
|
|
|
|
+ if (unlikely(ntc == ntu && !ring->desc_cb[ntc].refill))
|
|
+ return ring->desc_num;
|
|
+
|
|
return ((ntc >= ntu) ? 0 : ring->desc_num) + ntc - ntu;
|
|
}
|
|
|
|
@@ -3464,6 +3470,7 @@ static void hns3_rx_ring_move_fw(struct hns3_enet_ring *ring)
|
|
{
|
|
ring->desc[ring->next_to_clean].rx.bd_base_info &=
|
|
cpu_to_le32(~BIT(HNS3_RXD_VLD_B));
|
|
+ ring->desc_cb[ring->next_to_clean].refill = 0;
|
|
ring->next_to_clean += 1;
|
|
|
|
if (unlikely(ring->next_to_clean == ring->desc_num))
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
index b082f0fa7064..433422fda7b8 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
@@ -321,6 +321,7 @@ struct hns3_desc_cb {
|
|
u32 length; /* length of the buffer */
|
|
|
|
u16 reuse_flag;
|
|
+ u16 refill;
|
|
|
|
/* desc type, used by the ring user to mark the type of the priv data */
|
|
u16 type;
|
|
--
|
|
2.34.1
|
|
|