* [PATCH net-next v03 0/4] net: hinic3: Bugfix for later patch-set.
@ 2026-11-12 7:06 Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 1/4] hinic3: Solve an stall issue in hinic3_rx_poll() Fan Gong
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Fan Gong @ 2026-11-12 7:06 UTC (permalink / raw)
To: Fan Gong, Wu Di, Teng Peisen, netdev, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Andrew Lunn, Ioana Ciornei, Maxime Chevallier, Mohsin Bashir,
Dimitri Daskalakis, Harshitha Ramamurthy, Larysa Zaremba,
Vadim Fedorenko
Cc: linux-kernel, linux-doc, Zhou Shuai, Wu Like
These issues were discovered by LLM Gemini-4-Argon and Claude-Opus-5-5.
At the same time, LLM recommended submitting an independent patch.
These issues were not actually triggered. Based on theoretical analysis
and consideration of actual risks, this patch is used to fix the issues.
Testing:
These patch-set have been tested on hinic3 hardware.
V03:
* Clenaup checkpatchs in file hinic3_netdev_ops.c.(AI Review)
* nic_svc_cap->max_sqs is already in the range [1, 256].(AI Review)
V02: https://lore.kernel.org/all/179437094656.2168702.7238120951030130700@kernel.org/
* Rewrite the commit message and provide an explanation for each
patch.(AI Review)
* Split checkpatchs in to a separate patch.(AI Review)
* Fix the failure of napi_alloc_skb() in recv_one_pkt().(AI Review)
* READ_ONCE()/WRITE_ONCE() only stop the compiler from tearing or caching
the access. They don't order anything against the work item, and they
can't stop it from running. So, remove READ_ONCE() and WRITE_ONCE() on
nic_dev->adaptive_rx_coal.(AI Review)
V01: https://lore.kernel.org/netdev/cover.1793946318.git.gongfan1@huawei.com/
Fan Gong (4):
hinic3: Solve an stall issue in hinic3_rx_poll()
hinic3: Avoid concurrent updates on 32-bit systems.
hinic3: fix some checkpatchs.
hinic3: Ensure that the value of max_qps is not changed
.../huawei/hinic3/hinic3_netdev_ops.c | 76 ++++++++-----------
.../net/ethernet/huawei/hinic3/hinic3_rss.c | 9 +--
.../net/ethernet/huawei/hinic3/hinic3_rx.c | 11 ++-
3 files changed, 44 insertions(+), 52 deletions(-)
base-commit: 73022f605c447f31610b94ed4a983d2b4bf2c721
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net-next v03 1/4] hinic3: Solve an stall issue in hinic3_rx_poll()
2026-11-12 7:06 [PATCH net-next v03 0/4] net: hinic3: Bugfix for later patch-set Fan Gong
@ 2026-11-12 7:06 ` Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 2/4] hinic3: Avoid concurrent updates on 32-bit systems Fan Gong
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Fan Gong @ 2026-11-12 7:06 UTC (permalink / raw)
To: Fan Gong, Wu Di, Teng Peisen, netdev, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Andrew Lunn, Ioana Ciornei, Maxime Chevallier, Mohsin Bashir,
Dimitri Daskalakis, Harshitha Ramamurthy, Larysa Zaremba,
Vadim Fedorenko
Cc: linux-kernel, linux-doc, Zhou Shuai, Wu Like
When Large Receive Offload (LRO) packets are large, such as 32KB, each
packet consumes 16 Work Queue Elements (WQEs). If multiple large LRO
packets occur at this time, it will cause rapid consumption of WQEs in
the RQ and WQEs cannot be replenished in time. The chip will drop
packets due to lack of WQEs, causing the RQ to be unable to receive
packets. Furthermore, the NAPI instance will not be polled again,
resulting in residual packets in the RQ.
When napi_alloc_skb() fails inside recv_one_pkt(), hinic3_rx_poll()
breaks out of the loop without advancing rxq->cons_idx or clearing
rx_cqe->status, and returns nr_pkts (< budget). hinic3_poll() then
calls napi_complete_done() and re-enables the edge-triggered MSI-X
interrupt while the unprocessed CQE remains at the head of the ring,
stalling the receive queue until a new packet arrives to trigger
another interrupt.
Fixes: 17fcb3dc12bb ("hinic3: module initialization and tx/rx logic")
Co-developed-by: Wu Di <wudi234@huawei.com>
Signed-off-by: Wu Di <wudi234@huawei.com>
Co-developed-by: Teng Peisen <tengpeisen@huawei.com>
Signed-off-by: Teng Peisen <tengpeisen@huawei.com>
Signed-off-by: Fan Gong <gongfan1@huawei.com>
---
drivers/net/ethernet/huawei/hinic3/hinic3_rx.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
index 309ab5901379..f2262cdd6628 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c
@@ -555,6 +555,7 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
struct hinic3_nic_dev *nic_dev = netdev_priv(rxq->netdev);
u32 sw_ci, status, pkt_len, vlan_len;
struct hinic3_rq_cqe *rx_cqe;
+ bool poll_again = false;
u32 num_wqe = 0;
int nr_pkts = 0;
u16 num_lro;
@@ -571,8 +572,10 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
vlan_len = le32_to_cpu(rx_cqe->vlan_len);
pkt_len = RQ_CQE_SGE_GET(vlan_len, LEN);
- if (recv_one_pkt(rxq, rx_cqe, pkt_len, vlan_len, status))
+ if (recv_one_pkt(rxq, rx_cqe, pkt_len, vlan_len, status)) {
+ poll_again = true;
break;
+ }
nr_pkts++;
num_lro = RQ_CQE_STATUS_GET(status, NUM_LRO);
@@ -581,12 +584,14 @@ int hinic3_rx_poll(struct hinic3_rxq *rxq, int budget)
rx_cqe->status = 0;
- if (num_wqe >= nic_dev->lro_replenish_thld)
+ if (num_wqe >= nic_dev->lro_replenish_thld) {
+ poll_again = true;
break;
+ }
}
if (rxq->delta >= HINIC3_RX_BUFFER_WRITE)
hinic3_rx_fill_buffers(rxq);
- return nr_pkts;
+ return poll_again ? budget : nr_pkts;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next v03 2/4] hinic3: Avoid concurrent updates on 32-bit systems.
2026-11-12 7:06 [PATCH net-next v03 0/4] net: hinic3: Bugfix for later patch-set Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 1/4] hinic3: Solve an stall issue in hinic3_rx_poll() Fan Gong
@ 2026-11-12 7:06 ` Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 3/4] hinic3: fix some checkpatchs Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 4/4] hinic3: Ensure that the value of max_qps is not changed Fan Gong
3 siblings, 0 replies; 5+ messages in thread
From: Fan Gong @ 2026-11-12 7:06 UTC (permalink / raw)
To: Fan Gong, Wu Di, Teng Peisen, netdev, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Andrew Lunn, Ioana Ciornei, Maxime Chevallier, Mohsin Bashir,
Dimitri Daskalakis, Harshitha Ramamurthy, Larysa Zaremba,
Vadim Fedorenko
Cc: linux-kernel, linux-doc, Zhou Shuai, Wu Like
Within the while loop of hinic3_get_stats64(), the counters between
u64_stats_fetch_retry and u64_stats_fetch_begin are incremented by +=.
This operation will cause repeated counting of the counters on a 32-bit
system. Therefore, change += to + and the counters are incremented
out side the wile loop.
csum_errors and other_errors are not the same things. csum_errors will
go to csum_bad in netdev netlink qstats.
Remove unnecessary checks for the nic_dev->txqs and nic_dev->rxqs.
Remove dead stores before the loop.
Fixes: f47872bed40f ("hinic3: Add .ndo_tx_timeout and .ndo_get_stats64")
Co-developed-by: Wu Di <wudi234@huawei.com>
Signed-off-by: Wu Di <wudi234@huawei.com>
Co-developed-by: Teng Peisen <tengpeisen@huawei.com>
Signed-off-by: Teng Peisen <tengpeisen@huawei.com>
Signed-off-by: Fan Gong <gongfan1@huawei.com>
---
.../huawei/hinic3/hinic3_netdev_ops.c | 42 +++++++------------
1 file changed, 14 insertions(+), 28 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index da73811641a9..d1fd91d97ccf 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -791,49 +791,35 @@ static void hinic3_get_stats64(struct net_device *netdev,
unsigned int start;
int i;
- bytes = 0;
- packets = 0;
- dropped = 0;
for (i = 0; i < nic_dev->max_qps; i++) {
- if (!nic_dev->txqs)
- break;
-
txq = &nic_dev->txqs[i];
txq_stats = &txq->txq_stats;
do {
start = u64_stats_fetch_begin(&txq_stats->syncp);
- bytes += txq_stats->bytes;
- packets += txq_stats->packets;
- dropped += txq_stats->dropped;
+ bytes = txq_stats->bytes;
+ packets = txq_stats->packets;
+ dropped = txq_stats->dropped;
} while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+ stats->tx_packets += packets;
+ stats->tx_bytes += bytes;
+ stats->tx_dropped += dropped;
}
- stats->tx_packets = packets;
- stats->tx_bytes = bytes;
- stats->tx_dropped = dropped;
- bytes = 0;
- packets = 0;
- errors = 0;
- dropped = 0;
for (i = 0; i < nic_dev->max_qps; i++) {
- if (!nic_dev->rxqs)
- break;
-
rxq = &nic_dev->rxqs[i];
rxq_stats = &rxq->rxq_stats;
do {
start = u64_stats_fetch_begin(&rxq_stats->syncp);
- bytes += rxq_stats->bytes;
- packets += rxq_stats->packets;
- errors += rxq_stats->csum_errors +
- rxq_stats->other_errors;
- dropped += rxq_stats->dropped;
+ bytes = rxq_stats->bytes;
+ packets = rxq_stats->packets;
+ errors = rxq_stats->other_errors;
+ dropped = rxq_stats->dropped;
} while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+ stats->rx_packets += packets;
+ stats->rx_bytes += bytes;
+ stats->rx_errors += errors;
+ stats->rx_dropped += dropped;
}
- stats->rx_packets = packets;
- stats->rx_bytes = bytes;
- stats->rx_errors = errors;
- stats->rx_dropped = dropped;
}
static void hinic3_nic_set_rx_mode(struct net_device *netdev)
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next v03 3/4] hinic3: fix some checkpatchs.
2026-11-12 7:06 [PATCH net-next v03 0/4] net: hinic3: Bugfix for later patch-set Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 1/4] hinic3: Solve an stall issue in hinic3_rx_poll() Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 2/4] hinic3: Avoid concurrent updates on 32-bit systems Fan Gong
@ 2026-11-12 7:06 ` Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 4/4] hinic3: Ensure that the value of max_qps is not changed Fan Gong
3 siblings, 0 replies; 5+ messages in thread
From: Fan Gong @ 2026-11-12 7:06 UTC (permalink / raw)
To: Fan Gong, Wu Di, Teng Peisen, netdev, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Andrew Lunn, Ioana Ciornei, Maxime Chevallier, Mohsin Bashir,
Dimitri Daskalakis, Harshitha Ramamurthy, Larysa Zaremba,
Vadim Fedorenko
Cc: linux-kernel, linux-doc, Zhou Shuai, Wu Like
Cleanup checkpatchs of lines exceeding 80 columns.
Co-developed-by: Wu Di <wudi234@huawei.com>
Signed-off-by: Wu Di <wudi234@huawei.com>
Co-developed-by: Teng Peisen <tengpeisen@huawei.com>
Signed-off-by: Teng Peisen <tengpeisen@huawei.com>
Signed-off-by: Fan Gong <gongfan1@huawei.com>
---
.../huawei/hinic3/hinic3_netdev_ops.c | 34 +++++++++++--------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
index d1fd91d97ccf..621d8b12e247 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c
@@ -121,8 +121,9 @@ static void hinic3_destroy_num_qps(struct net_device *netdev)
kfree(nic_dev->qps_msix_entries);
}
-static int hinic3_alloc_txrxq_resources(struct net_device *netdev,
- struct hinic3_dyna_txrxq_params *q_params)
+static int
+hinic3_alloc_txrxq_resources(struct net_device *netdev,
+ struct hinic3_dyna_txrxq_params *q_params)
{
int err;
@@ -176,8 +177,9 @@ static int hinic3_alloc_txrxq_resources(struct net_device *netdev,
return err;
}
-static void hinic3_free_txrxq_resources(struct net_device *netdev,
- struct hinic3_dyna_txrxq_params *q_params)
+static void
+hinic3_free_txrxq_resources(struct net_device *netdev,
+ struct hinic3_dyna_txrxq_params *q_params)
{
hinic3_free_rxqs_res(netdev, q_params->num_qps, q_params->rq_depth,
q_params->rxqs_res);
@@ -251,16 +253,17 @@ static void hinic3_remove_configure(struct net_device *netdev)
hinic3_rss_uninit(netdev);
}
-static int hinic3_alloc_channel_resources(struct net_device *netdev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+static int
+hinic3_alloc_channel_resources(struct net_device *netdev,
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *q_params)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
int err;
- qp_params->num_qps = trxq_params->num_qps;
- qp_params->sq_depth = trxq_params->sq_depth;
- qp_params->rq_depth = trxq_params->rq_depth;
+ qp_params->num_qps = q_params->num_qps;
+ qp_params->sq_depth = q_params->sq_depth;
+ qp_params->rq_depth = q_params->rq_depth;
err = hinic3_alloc_qps(nic_dev, qp_params);
if (err) {
@@ -268,7 +271,7 @@ static int hinic3_alloc_channel_resources(struct net_device *netdev,
return err;
}
- err = hinic3_alloc_txrxq_resources(netdev, trxq_params);
+ err = hinic3_alloc_txrxq_resources(netdev, q_params);
if (err) {
netdev_err(netdev, "Failed to alloc txrxq resources\n");
hinic3_free_qps(nic_dev, qp_params);
@@ -278,13 +281,14 @@ static int hinic3_alloc_channel_resources(struct net_device *netdev,
return 0;
}
-static void hinic3_free_channel_resources(struct net_device *netdev,
- struct hinic3_dyna_qp_params *qp_params,
- struct hinic3_dyna_txrxq_params *trxq_params)
+static void
+hinic3_free_channel_resources(struct net_device *netdev,
+ struct hinic3_dyna_qp_params *qp_params,
+ struct hinic3_dyna_txrxq_params *q_params)
{
struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
- hinic3_free_txrxq_resources(netdev, trxq_params);
+ hinic3_free_txrxq_resources(netdev, q_params);
hinic3_free_qps(nic_dev, qp_params);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next v03 4/4] hinic3: Ensure that the value of max_qps is not changed
2026-11-12 7:06 [PATCH net-next v03 0/4] net: hinic3: Bugfix for later patch-set Fan Gong
` (2 preceding siblings ...)
2026-11-12 7:06 ` [PATCH net-next v03 3/4] hinic3: fix some checkpatchs Fan Gong
@ 2026-11-12 7:06 ` Fan Gong
3 siblings, 0 replies; 5+ messages in thread
From: Fan Gong @ 2026-11-12 7:06 UTC (permalink / raw)
To: Fan Gong, Wu Di, Teng Peisen, netdev, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Andrew Lunn, Ioana Ciornei, Maxime Chevallier, Mohsin Bashir,
Dimitri Daskalakis, Harshitha Ramamurthy, Larysa Zaremba,
Vadim Fedorenko
Cc: linux-kernel, linux-doc, Zhou Shuai, Wu Like
nic_dev->max_qps is used to allocate hardware resources. Therefore,
it is assigned the value 1 only when its value is abnormal. In other
scenarios, the value cannot be changed. However, the value of
nic_dev->q_params.num_qps can be dynamically changed.
Fixes: 1f3838b84a63 ("hinic3: Add Rss function")
Co-developed-by: Wu Di <wudi234@huawei.com>
Signed-off-by: Wu Di <wudi234@huawei.com>
Co-developed-by: Teng Peisen <tengpeisen@huawei.com>
Signed-off-by: Teng Peisen <tengpeisen@huawei.com>
Signed-off-by: Fan Gong <gongfan1@huawei.com>
---
| 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
--git a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
index 25db74d8c7dd..75dc0c044071 100644
--- a/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
+++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rss.c
@@ -307,15 +307,13 @@ void hinic3_try_to_enable_rss(struct net_device *netdev)
int err;
nic_dev->max_qps = hinic3_func_max_qnum(hwdev);
- if (nic_dev->max_qps <= 1 ||
+ if (nic_dev->max_qps == 1 ||
!hinic3_test_support(nic_dev, HINIC3_NIC_F_RSS))
goto err_reset_q_params;
err = alloc_rss_resource(netdev);
- if (err) {
- nic_dev->max_qps = 1;
+ if (err)
goto err_reset_q_params;
- }
set_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
decide_num_qps(netdev);
@@ -324,7 +322,6 @@ void hinic3_try_to_enable_rss(struct net_device *netdev)
if (err) {
dev_err(hwdev->dev, "Failed to set hardware rss parameters\n");
hinic3_clear_rss_config(netdev);
- nic_dev->max_qps = 1;
goto err_reset_q_params;
}
@@ -332,5 +329,5 @@ void hinic3_try_to_enable_rss(struct net_device *netdev)
err_reset_q_params:
clear_bit(HINIC3_RSS_ENABLE, &nic_dev->flags);
- nic_dev->q_params.num_qps = nic_dev->max_qps;
+ nic_dev->q_params.num_qps = 1;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-12 7:06 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-12 7:06 [PATCH net-next v03 0/4] net: hinic3: Bugfix for later patch-set Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 1/4] hinic3: Solve an stall issue in hinic3_rx_poll() Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 2/4] hinic3: Avoid concurrent updates on 32-bit systems Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 3/4] hinic3: fix some checkpatchs Fan Gong
2026-11-12 7:06 ` [PATCH net-next v03 4/4] hinic3: Ensure that the value of max_qps is not changed Fan Gong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox