* [PATCH RESEND net v1 0/2] avoid compiler and IQ/OQ reordering
@ 2026-02-12 12:16 Vimlesh Kumar
2026-02-12 12:16 ` [PATCH RESEND net v1 1/2] octeon_ep: " Vimlesh Kumar
2026-02-12 12:16 ` [PATCH RESEND net v1 2/2] octeon_ep_vf: " Vimlesh Kumar
0 siblings, 2 replies; 5+ messages in thread
From: Vimlesh Kumar @ 2026-02-12 12:16 UTC (permalink / raw)
To: netdev, linux-kernel; +Cc: sedara, srasheed, hgani, Vimlesh Kumar
Utilize READ_ONCE and WRITE_ONCE APIs to prevent compiler
optimization and reordering. Ensure IO queue OUT/IN_CNT
registers are flushed. Relocate IQ/OQ IN/OUT_CNTS updates
to occur before NAPI completion, and replace napi_complete
with napi_complete_done.
Resending based on discussion with reviewer.
https://lore.kernel.org/all/MN6PR18MB54667119674AC692ED7EF978D39FA@MN6PR18MB5466.namprd18.prod.outlook.com/
Vimlesh Kumar (2):
octeon_ep: avoid compiler and IQ/OQ reordering
octeon_ep_vf: avoid compiler and IQ/OQ reordering
.../ethernet/marvell/octeon_ep/octep_main.c | 40 +++++++++++++------
.../net/ethernet/marvell/octeon_ep/octep_rx.c | 27 +++++++++----
.../marvell/octeon_ep_vf/octep_vf_main.c | 38 +++++++++++++-----
.../marvell/octeon_ep_vf/octep_vf_rx.c | 28 +++++++++----
4 files changed, 95 insertions(+), 38 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH RESEND net v1 1/2] octeon_ep: avoid compiler and IQ/OQ reordering
2026-02-12 12:16 [PATCH RESEND net v1 0/2] avoid compiler and IQ/OQ reordering Vimlesh Kumar
@ 2026-02-12 12:16 ` Vimlesh Kumar
2026-02-17 9:56 ` Paolo Abeni
2026-02-12 12:16 ` [PATCH RESEND net v1 2/2] octeon_ep_vf: " Vimlesh Kumar
1 sibling, 1 reply; 5+ messages in thread
From: Vimlesh Kumar @ 2026-02-12 12:16 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sedara, srasheed, hgani, Vimlesh Kumar, Veerasenareddy Burru,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Satananda Burla, Abhijit Ayarekar
Utilize READ_ONCE and WRITE_ONCE APIs for IO queue Tx/Rx
variable access to prevent compiler optimization and reordering.
Additionally, ensure IO queue OUT/IN_CNT registers are flushed
by performing a read-back after writing.
Relocate IQ/OQ IN/OUT_CNTS updates to occur before NAPI completion,
and replace napi_complete with napi_complete_done.
Fixes: 37d79d0596062 ("octeon_ep: add Tx/Rx processing and interrupt support")
Signed-off-by: Sathesh Edara <sedara@marvell.com>
Signed-off-by: Shinas Rasheed <srasheed@marvell.com>
Signed-off-by: Vimlesh Kumar <vimleshk@marvell.com>
---
.../ethernet/marvell/octeon_ep/octep_main.c | 40 +++++++++++++------
.../net/ethernet/marvell/octeon_ep/octep_rx.c | 27 +++++++++----
2 files changed, 47 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
index bcea3fc26a8c..ccfb248d0914 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
@@ -555,28 +555,43 @@ static void octep_clean_irqs(struct octep_device *oct)
}
/**
- * octep_enable_ioq_irq() - Enable MSI-x interrupt of a Tx/Rx queue.
+ * octep_update_pkt() - Update IQ/OQ IN/OUT_CNT registers.
*
* @iq: Octeon Tx queue data structure.
* @oq: Octeon Rx queue data structure.
*/
-static void octep_enable_ioq_irq(struct octep_iq *iq, struct octep_oq *oq)
+static void octep_update_pkt(struct octep_iq *iq, struct octep_oq *oq)
{
- u32 pkts_pend = oq->pkts_pending;
+ u32 pkts_pend = READ_ONCE(oq->pkts_pending);
+ u32 last_pkt_count = READ_ONCE(oq->last_pkt_count);
+ u32 pkts_processed = READ_ONCE(iq->pkts_processed);
+ u32 pkt_in_done = READ_ONCE(iq->pkt_in_done);
netdev_dbg(iq->netdev, "enabling intr for Q-%u\n", iq->q_no);
- if (iq->pkts_processed) {
- writel(iq->pkts_processed, iq->inst_cnt_reg);
- iq->pkt_in_done -= iq->pkts_processed;
- iq->pkts_processed = 0;
+ if (pkts_processed) {
+ writel(pkts_processed, iq->inst_cnt_reg);
+ readl(iq->inst_cnt_reg);
+ WRITE_ONCE(iq->pkt_in_done, (pkt_in_done - pkts_processed));
+ WRITE_ONCE(iq->pkts_processed, 0);
}
- if (oq->last_pkt_count - pkts_pend) {
- writel(oq->last_pkt_count - pkts_pend, oq->pkts_sent_reg);
- oq->last_pkt_count = pkts_pend;
+ if (last_pkt_count - pkts_pend) {
+ writel(last_pkt_count - pkts_pend, oq->pkts_sent_reg);
+ readl(oq->pkts_sent_reg);
+ WRITE_ONCE(oq->last_pkt_count, pkts_pend);
}
/* Flush the previous wrties before writing to RESEND bit */
- wmb();
+ smp_wmb();
+}
+
+/**
+ * octep_enable_ioq_irq() - Enable MSI-x interrupt of a Tx/Rx queue.
+ *
+ * @iq: Octeon Tx queue data structure.
+ * @oq: Octeon Rx queue data structure.
+ */
+static void octep_enable_ioq_irq(struct octep_iq *iq, struct octep_oq *oq)
+{
writeq(1UL << OCTEP_OQ_INTR_RESEND_BIT, oq->pkts_sent_reg);
writeq(1UL << OCTEP_IQ_INTR_RESEND_BIT, iq->inst_cnt_reg);
}
@@ -602,7 +617,8 @@ static int octep_napi_poll(struct napi_struct *napi, int budget)
if (tx_pending || rx_done >= budget)
return budget;
- napi_complete(napi);
+ octep_update_pkt(ioq_vector->iq, ioq_vector->oq);
+ napi_complete_done(napi, rx_done);
octep_enable_ioq_irq(ioq_vector->iq, ioq_vector->oq);
return rx_done;
}
diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c b/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c
index 82b6b19e76b4..11f1b45d0f92 100644
--- a/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c
+++ b/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c
@@ -318,10 +318,16 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct,
struct octep_oq *oq)
{
u32 pkt_count, new_pkts;
+ u32 last_pkt_count, pkts_pending;
pkt_count = readl(oq->pkts_sent_reg);
- new_pkts = pkt_count - oq->last_pkt_count;
+ last_pkt_count = READ_ONCE(oq->last_pkt_count);
+ new_pkts = pkt_count - last_pkt_count;
+ if (pkt_count < last_pkt_count) {
+ dev_err(oq->dev, "OQ-%u pkt_count(%u) < oq->last_pkt_count(%u)\n",
+ oq->q_no, pkt_count, last_pkt_count);
+ }
/* Clear the hardware packets counter register if the rx queue is
* being processed continuously with-in a single interrupt and
* reached half its max value.
@@ -332,8 +338,9 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct,
pkt_count = readl(oq->pkts_sent_reg);
new_pkts += pkt_count;
}
- oq->last_pkt_count = pkt_count;
- oq->pkts_pending += new_pkts;
+ WRITE_ONCE(oq->last_pkt_count, pkt_count);
+ pkts_pending = READ_ONCE(oq->pkts_pending);
+ WRITE_ONCE(oq->pkts_pending, (pkts_pending + new_pkts));
return new_pkts;
}
@@ -408,7 +415,7 @@ static int __octep_oq_process_rx(struct octep_device *oct,
u16 rx_ol_flags;
u32 read_idx;
- read_idx = oq->host_read_idx;
+ read_idx = READ_ONCE(oq->host_read_idx);
rx_bytes = 0;
desc_used = 0;
for (pkt = 0; pkt < pkts_to_process; pkt++) {
@@ -493,7 +500,7 @@ static int __octep_oq_process_rx(struct octep_device *oct,
napi_gro_receive(oq->napi, skb);
}
- oq->host_read_idx = read_idx;
+ WRITE_ONCE(oq->host_read_idx, read_idx);
oq->refill_count += desc_used;
oq->stats->packets += pkt;
oq->stats->bytes += rx_bytes;
@@ -516,22 +523,26 @@ int octep_oq_process_rx(struct octep_oq *oq, int budget)
{
u32 pkts_available, pkts_processed, total_pkts_processed;
struct octep_device *oct = oq->octep_dev;
+ u32 pkts_pending;
pkts_available = 0;
pkts_processed = 0;
total_pkts_processed = 0;
while (total_pkts_processed < budget) {
/* update pending count only when current one exhausted */
- if (oq->pkts_pending == 0)
+ pkts_pending = READ_ONCE(oq->pkts_pending);
+ if (pkts_pending == 0)
octep_oq_check_hw_for_pkts(oct, oq);
+ pkts_pending = READ_ONCE(oq->pkts_pending);
pkts_available = min(budget - total_pkts_processed,
- oq->pkts_pending);
+ pkts_pending);
if (!pkts_available)
break;
pkts_processed = __octep_oq_process_rx(oct, oq,
pkts_available);
- oq->pkts_pending -= pkts_processed;
+ pkts_pending = READ_ONCE(oq->pkts_pending);
+ WRITE_ONCE(oq->pkts_pending, (pkts_pending - pkts_processed));
total_pkts_processed += pkts_processed;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH RESEND net v1 2/2] octeon_ep_vf: avoid compiler and IQ/OQ reordering
2026-02-12 12:16 [PATCH RESEND net v1 0/2] avoid compiler and IQ/OQ reordering Vimlesh Kumar
2026-02-12 12:16 ` [PATCH RESEND net v1 1/2] octeon_ep: " Vimlesh Kumar
@ 2026-02-12 12:16 ` Vimlesh Kumar
1 sibling, 0 replies; 5+ messages in thread
From: Vimlesh Kumar @ 2026-02-12 12:16 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: sedara, srasheed, hgani, Vimlesh Kumar, Veerasenareddy Burru,
Satananda Burla, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni
Utilize READ_ONCE and WRITE_ONCE APIs for IO queue Tx/Rx
variable access to prevent compiler optimization and reordering.
Additionally, ensure IO queue OUT/IN_CNT registers are flushed
by performing a read-back after writing.
Relocate IQ/OQ IN/OUT_CNTS updates to occur before NAPI completion,
and replace napi_complete with napi_complete_done.
Fixes: 1cd3b407977c3 ("octeon_ep_vf: add Tx/Rx processing and interrupt support")
Signed-off-by: Sathesh Edara <sedara@marvell.com>
Signed-off-by: Shinas Rasheed <srasheed@marvell.com>
Signed-off-by: Vimlesh Kumar <vimleshk@marvell.com>
---
.../marvell/octeon_ep_vf/octep_vf_main.c | 38 ++++++++++++++-----
.../marvell/octeon_ep_vf/octep_vf_rx.c | 28 ++++++++++----
2 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c
index 420c3f4cf741..27a5fc38bccb 100644
--- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c
+++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c
@@ -286,28 +286,45 @@ static void octep_vf_clean_irqs(struct octep_vf_device *oct)
}
/**
- * octep_vf_enable_ioq_irq() - Enable MSI-x interrupt of a Tx/Rx queue.
+ * octep_vf_update_pkt() - Update IQ/OQ IN/OUT_CNT registers.
*
* @iq: Octeon Tx queue data structure.
* @oq: Octeon Rx queue data structure.
*/
-static void octep_vf_enable_ioq_irq(struct octep_vf_iq *iq, struct octep_vf_oq *oq)
+
+static void octep_vf_update_pkt(struct octep_vf_iq *iq, struct octep_vf_oq *oq)
{
- u32 pkts_pend = oq->pkts_pending;
+ u32 pkts_pend = READ_ONCE(oq->pkts_pending);
+ u32 last_pkt_count = READ_ONCE(oq->last_pkt_count);
+ u32 pkts_processed = READ_ONCE(iq->pkts_processed);
+ u32 pkt_in_done = READ_ONCE(iq->pkt_in_done);
netdev_dbg(iq->netdev, "enabling intr for Q-%u\n", iq->q_no);
- if (iq->pkts_processed) {
- writel(iq->pkts_processed, iq->inst_cnt_reg);
- iq->pkt_in_done -= iq->pkts_processed;
- iq->pkts_processed = 0;
+ if (pkts_processed) {
+ writel(pkts_processed, iq->inst_cnt_reg);
+ readl(iq->inst_cnt_reg);
+ WRITE_ONCE(iq->pkt_in_done, (pkt_in_done - pkts_processed));
+ WRITE_ONCE(iq->pkts_processed, 0);
}
- if (oq->last_pkt_count - pkts_pend) {
- writel(oq->last_pkt_count - pkts_pend, oq->pkts_sent_reg);
- oq->last_pkt_count = pkts_pend;
+ if (last_pkt_count - pkts_pend) {
+ writel(last_pkt_count - pkts_pend, oq->pkts_sent_reg);
+ readl(oq->pkts_sent_reg);
+ WRITE_ONCE(oq->last_pkt_count, pkts_pend);
}
/* Flush the previous wrties before writing to RESEND bit */
smp_wmb();
+}
+
+/**
+ * octep_vf_enable_ioq_irq() - Enable MSI-x interrupt of a Tx/Rx queue.
+ *
+ * @iq: Octeon Tx queue data structure.
+ * @oq: Octeon Rx queue data structure.
+ */
+static void octep_vf_enable_ioq_irq(struct octep_vf_iq *iq,
+ struct octep_vf_oq *oq)
+{
writeq(1UL << OCTEP_VF_OQ_INTR_RESEND_BIT, oq->pkts_sent_reg);
writeq(1UL << OCTEP_VF_IQ_INTR_RESEND_BIT, iq->inst_cnt_reg);
}
@@ -333,6 +350,7 @@ static int octep_vf_napi_poll(struct napi_struct *napi, int budget)
if (tx_pending || rx_done >= budget)
return budget;
+ octep_vf_update_pkt(ioq_vector->iq, ioq_vector->oq);
if (likely(napi_complete_done(napi, rx_done)))
octep_vf_enable_ioq_irq(ioq_vector->iq, ioq_vector->oq);
diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c
index d70c8be3cfc4..31380962c212 100644
--- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c
+++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c
@@ -319,9 +319,16 @@ static int octep_vf_oq_check_hw_for_pkts(struct octep_vf_device *oct,
struct octep_vf_oq *oq)
{
u32 pkt_count, new_pkts;
+ u32 last_pkt_count, pkts_pending;
pkt_count = readl(oq->pkts_sent_reg);
- new_pkts = pkt_count - oq->last_pkt_count;
+ last_pkt_count = READ_ONCE(oq->last_pkt_count);
+ new_pkts = pkt_count - last_pkt_count;
+
+ if (pkt_count < last_pkt_count) {
+ dev_err(oq->dev, "OQ-%u pkt_count(%u) < oq->last_pkt_count(%u)\n",
+ oq->q_no, pkt_count, last_pkt_count);
+ }
/* Clear the hardware packets counter register if the rx queue is
* being processed continuously with-in a single interrupt and
@@ -333,8 +340,9 @@ static int octep_vf_oq_check_hw_for_pkts(struct octep_vf_device *oct,
pkt_count = readl(oq->pkts_sent_reg);
new_pkts += pkt_count;
}
- oq->last_pkt_count = pkt_count;
- oq->pkts_pending += new_pkts;
+ WRITE_ONCE(oq->last_pkt_count, pkt_count);
+ pkts_pending = READ_ONCE(oq->pkts_pending);
+ WRITE_ONCE(oq->pkts_pending, (pkts_pending + new_pkts));
return new_pkts;
}
@@ -363,7 +371,7 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct,
struct sk_buff *skb;
u32 read_idx;
- read_idx = oq->host_read_idx;
+ read_idx = READ_ONCE(oq->host_read_idx);
rx_bytes = 0;
desc_used = 0;
for (pkt = 0; pkt < pkts_to_process; pkt++) {
@@ -457,7 +465,7 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct,
napi_gro_receive(oq->napi, skb);
}
- oq->host_read_idx = read_idx;
+ WRITE_ONCE(oq->host_read_idx, read_idx);
oq->refill_count += desc_used;
oq->stats->packets += pkt;
oq->stats->bytes += rx_bytes;
@@ -480,22 +488,26 @@ int octep_vf_oq_process_rx(struct octep_vf_oq *oq, int budget)
{
u32 pkts_available, pkts_processed, total_pkts_processed;
struct octep_vf_device *oct = oq->octep_vf_dev;
+ u32 pkts_pending;
pkts_available = 0;
pkts_processed = 0;
total_pkts_processed = 0;
while (total_pkts_processed < budget) {
/* update pending count only when current one exhausted */
- if (oq->pkts_pending == 0)
+ pkts_pending = READ_ONCE(oq->pkts_pending);
+ if (pkts_pending == 0)
octep_vf_oq_check_hw_for_pkts(oct, oq);
+ pkts_pending = READ_ONCE(oq->pkts_pending);
pkts_available = min(budget - total_pkts_processed,
- oq->pkts_pending);
+ pkts_pending);
if (!pkts_available)
break;
pkts_processed = __octep_vf_oq_process_rx(oct, oq,
pkts_available);
- oq->pkts_pending -= pkts_processed;
+ pkts_pending = READ_ONCE(oq->pkts_pending);
+ WRITE_ONCE(oq->pkts_pending, (pkts_pending - pkts_processed));
total_pkts_processed += pkts_processed;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH RESEND net v1 1/2] octeon_ep: avoid compiler and IQ/OQ reordering
2026-02-12 12:16 ` [PATCH RESEND net v1 1/2] octeon_ep: " Vimlesh Kumar
@ 2026-02-17 9:56 ` Paolo Abeni
2026-02-20 9:05 ` [EXTERNAL] " Vimlesh Kumar
0 siblings, 1 reply; 5+ messages in thread
From: Paolo Abeni @ 2026-02-17 9:56 UTC (permalink / raw)
To: Vimlesh Kumar, netdev, linux-kernel
Cc: sedara, srasheed, hgani, Veerasenareddy Burru, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Satananda Burla,
Abhijit Ayarekar
On 2/12/26 1:16 PM, Vimlesh Kumar wrote:
> Utilize READ_ONCE and WRITE_ONCE APIs for IO queue Tx/Rx
> variable access to prevent compiler optimization and reordering.
You must include into the commit message a more detalied description of
what could possibly go wrong and way. Also why wmb/rmb are not enough?
AFAICS this is the only driver requiring such annotations to cooperate
with the H/W and/or the firmware.
> Additionally, ensure IO queue OUT/IN_CNT registers are flushed
> by performing a read-back after writing.
>
> Relocate IQ/OQ IN/OUT_CNTS updates to occur before NAPI completion,
> and replace napi_complete with napi_complete_done.
This looks like a separate change, and again requires a more complete
explaination of what could possibly go wrong and why.
/P
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [EXTERNAL] Re: [PATCH RESEND net v1 1/2] octeon_ep: avoid compiler and IQ/OQ reordering
2026-02-17 9:56 ` Paolo Abeni
@ 2026-02-20 9:05 ` Vimlesh Kumar
0 siblings, 0 replies; 5+ messages in thread
From: Vimlesh Kumar @ 2026-02-20 9:05 UTC (permalink / raw)
To: Paolo Abeni, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Sathesh B Edara, Shinas Rasheed, Haseeb Gani,
Veerasenareddy Burru, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Satananda Burla, Abhijit Ayarekar
> -----Original Message-----
> From: Paolo Abeni <pabeni@redhat.com>
> Sent: Tuesday, February 17, 2026 3:27 PM
> To: Vimlesh Kumar <vimleshk@marvell.com>; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Cc: Sathesh B Edara <sedara@marvell.com>; Shinas Rasheed
> <srasheed@marvell.com>; Haseeb Gani <hgani@marvell.com>;
> Veerasenareddy Burru <vburru@marvell.com>; Andrew Lunn
> <andrew+netdev@lunn.ch>; David S. Miller <davem@davemloft.net>; Eric
> Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>;
> Satananda Burla <sburla@marvell.com>; Abhijit Ayarekar
> <aayarekar@marvell.com>
> Subject: [EXTERNAL] Re: [PATCH RESEND net v1 1/2] octeon_ep: avoid
> compiler and IQ/OQ reordering
>
> On 2/12/26 1: 16 PM, Vimlesh Kumar wrote: > Utilize READ_ONCE and
> WRITE_ONCE APIs for IO queue Tx/Rx > variable access to prevent compiler
> optimization and reordering. You must include into the commit message a
> more detalied description ZjQcmQRYFpfptBannerStart Prioritize security for
> external emails:
> Confirm sender and content safety before clicking links or opening
> attachments <https://us-phishalarm-
> ewt.proofpoint.com/EWT/v1/CRVmXkqW!tg3ZH19USLUQtQwcGZ0azRxgxLTZz
> 2cNkGvS--_KO-IogsuxixXwwaeWTH8X4mQk8IOqO4OBanncc-
> aHiWiEa1ficdO6m6Pmo0k$>
> Report Suspicious
>
> ZjQcmQRYFpfptBannerEnd
> On 2/12/26 1:16 PM, Vimlesh Kumar wrote:
> > Utilize READ_ONCE and WRITE_ONCE APIs for IO queue Tx/Rx variable
> > access to prevent compiler optimization and reordering.
>
> You must include into the commit message a more detalied description of
> what could possibly go wrong and way. Also why wmb/rmb are not enough?
>
> AFAICS this is the only driver requiring such annotations to cooperate with
> the H/W and/or the firmware.
Hi Paolo,
Thank you for the review and feedback, we will add more detailed description about using READ_ONCE/WRITE_ONCE API in commit message.
To add more to the explanation:
The compiler could reorder reads/writes to pkts_pending, last_pkt_count, etc., causing stale values to be used when calculating packets to process or register updates to send to hardware. The Octeon hardware requires a read-back after writing to OUT_CNT/IN_CNT registers to ensure the write has been flushed through any posted write buffers before the interrupt resend bit is set. Without this, we have observed cases where the hardware didn't properly update its internal state.
wmb/rmb only provides ordering guarantees but doesn't prevent the compiler from performing optimizations like caching in registers, load tearing etc.
>
> > Additionally, ensure IO queue OUT/IN_CNT registers are flushed by
> > performing a read-back after writing.
> >
> > Relocate IQ/OQ IN/OUT_CNTS updates to occur before NAPI completion,
> > and replace napi_complete with napi_complete_done.
>
> This looks like a separate change, and again requires a more complete
> explaination of what could possibly go wrong and why.
Yes, it looks like a separate fix in retrospect.
Moving the IQ/OQ counter updates before napi_complete_done ensures:
- Counter registers are updated before re-enabling interrupts.
- Prevents a race where new packets arrive but counters aren't properly synchronized.
- napi_complete_done (vs napi_complete) allows for better interrupt coalescing.
I'll split this into two separate patches and provide more detailed commit messages.
>
> /P
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-02-20 9:06 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-12 12:16 [PATCH RESEND net v1 0/2] avoid compiler and IQ/OQ reordering Vimlesh Kumar
2026-02-12 12:16 ` [PATCH RESEND net v1 1/2] octeon_ep: " Vimlesh Kumar
2026-02-17 9:56 ` Paolo Abeni
2026-02-20 9:05 ` [EXTERNAL] " Vimlesh Kumar
2026-02-12 12:16 ` [PATCH RESEND net v1 2/2] octeon_ep_vf: " Vimlesh Kumar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox