patch 'event/sw: fix unlinks in progress counter races' has been queued to stable release 24.11.9

luca.boccassi at gmail.com luca.boccassi at gmail.com
Tue Oct 27 12:50:36 CET 2026


Hi,

FYI, your patch has been queued to stable release 24.11.9

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 10/29/26. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/bluca/dpdk-stable

This queued commit can be viewed at:
https://github.com/bluca/dpdk-stable/commit/13df5511e44bca5aa716522837a056a611387f3b

Thanks.

Luca Boccassi

---
>From 13df5511e44bca5aa716522837a056a611387f3b Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen at networkplumber.org>
Date: Tue, 13 Oct 2026 15:22:30 -0700
Subject: [PATCH] event/sw: fix unlinks in progress counter races

[ upstream commit c2466a1fc158a56ceef3b00b6a87ea0668054ed0 ]

The counter is written by both the application thread (increment on
unlink) and the scheduler (clear on ack) as a plain uint8_t. An
increment is lost if it lands between the scheduler's test and clear,
making rte_event_port_unlinks_in_progress() report completion before
the scheduler has seen the unlink. On a weakly ordered CPU nothing
orders the scheduler's cq map reads against the counter test, nor the
application's reads against the counter reaching zero.

Make the counter atomic: release fetch-add on unlink, acquire load to
read, and an acquire-release exchange to clear. The exchange cannot
lose an increment that lands after the test, so the scheduler can
keep its relaxed load of the counter first and take the locked
read-modify-write only when there is an unlink to acknowledge.

Fixes: bd5ac24fea88 ("event/sw: implement unlinks in progress function")

Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
Acked-by: Bruce Richardson <bruce.richardson at intel.com>
---
 drivers/event/sw/sw_evdev.c           |  8 +++++---
 drivers/event/sw/sw_evdev.h           | 11 +++++------
 drivers/event/sw/sw_evdev_scheduler.c | 17 ++++++++++++++---
 3 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/event/sw/sw_evdev.c b/drivers/event/sw/sw_evdev.c
index 3ad82e94acc..fedf638c605 100644
--- a/drivers/event/sw/sw_evdev.c
+++ b/drivers/event/sw/sw_evdev.c
@@ -119,8 +119,9 @@ sw_port_unlink(struct rte_eventdev *dev, void *port, uint8_t queues[],
 		}
 	}
 
-	p->unlinks_in_progress += unlinked;
-	rte_smp_mb();
+	/* Pairs with the acquire exchange in the scheduler */
+	rte_atomic_fetch_add_explicit(&p->unlinks_in_progress, unlinked,
+				      rte_memory_order_release);
 
 	return unlinked;
 }
@@ -130,7 +131,8 @@ sw_port_unlinks_in_progress(struct rte_eventdev *dev, void *port)
 {
 	RTE_SET_USED(dev);
 	struct sw_port *p = port;
-	return p->unlinks_in_progress;
+	return rte_atomic_load_explicit(&p->unlinks_in_progress,
+					rte_memory_order_acquire);
 }
 
 static int
diff --git a/drivers/event/sw/sw_evdev.h b/drivers/event/sw/sw_evdev.h
index f617c7d9661..1ae7199092b 100644
--- a/drivers/event/sw/sw_evdev.h
+++ b/drivers/event/sw/sw_evdev.h
@@ -154,13 +154,12 @@ struct sw_port {
 	/* A numeric ID for the port */
 	uint8_t id;
 
-	/* An atomic counter for when the port has been unlinked, and the
-	 * scheduler has not yet acked this unlink - hence there may still be
-	 * events in the buffers going to the port. When the unlinks in
-	 * progress is read by the scheduler, no more events will be pushed to
-	 * the port - hence the scheduler core can just assign zero.
+	/* Count of unlinks the scheduler has not yet acked, so there may
+	 * still be events in the buffers going to the port. Incremented by
+	 * the unlinking thread, cleared by the scheduler with an exchange so
+	 * an increment racing with the ack is not lost.
 	 */
-	uint8_t unlinks_in_progress;
+	RTE_ATOMIC(uint8_t) unlinks_in_progress;
 
 	int16_t is_directed; /** Takes from a single directed QID */
 	/**
diff --git a/drivers/event/sw/sw_evdev_scheduler.c b/drivers/event/sw/sw_evdev_scheduler.c
index a5fdcf301b5..207dee58543 100644
--- a/drivers/event/sw/sw_evdev_scheduler.c
+++ b/drivers/event/sw/sw_evdev_scheduler.c
@@ -523,9 +523,20 @@ sw_event_schedule(struct rte_eventdev *dev)
 		do {
 			in_pkts = 0;
 			for (i = 0; i < sw->port_count; i++) {
-				/* ack the unlinks in progress as done */
-				if (sw->ports[i].unlinks_in_progress)
-					sw->ports[i].unlinks_in_progress = 0;
+				struct sw_port *p = &sw->ports[i];
+
+				/* Ack the unlinks in progress as done.
+				 * The exchange cannot lose an increment that
+				 * lands after the test, and its acquire orders
+				 * the cq map reads below after the unlinker's
+				 * map update. Nothing to synchronize with when
+				 * the counter reads zero, so test first and
+				 * keep the locked op off the common path.
+				 */
+				if (rte_atomic_load_explicit(&p->unlinks_in_progress,
+						rte_memory_order_relaxed) != 0)
+					rte_atomic_exchange_explicit(&p->unlinks_in_progress,
+						0, rte_memory_order_acq_rel);
 
 				if (sw->ports[i].is_directed)
 					in_pkts += sw_schedule_pull_port_dir(sw, i);
-- 
2.47.3

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2026-10-27 11:43:59.159331963 +0000
+++ 0142-event-sw-fix-unlinks-in-progress-counter-races.patch	2026-10-27 11:43:53.662064030 +0000
@@ -1 +1 @@
-From c2466a1fc158a56ceef3b00b6a87ea0668054ed0 Mon Sep 17 00:00:00 2001
+From 13df5511e44bca5aa716522837a056a611387f3b Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit c2466a1fc158a56ceef3b00b6a87ea0668054ed0 ]
+
@@ -21 +22,0 @@
-Cc: stable at dpdk.org
@@ -32 +33 @@
-index a2f760a98d..87a8996f9d 100644
+index 3ad82e94acc..fedf638c605 100644
@@ -58 +59 @@
-index 5e49b08030..2c11d02911 100644
+index f617c7d9661..1ae7199092b 100644
@@ -81 +82 @@
-index a5fdcf301b..207dee5854 100644
+index a5fdcf301b5..207dee58543 100644


More information about the stable mailing list