The write barrier plus plain store publish patterns (cq map count,
port initialized, device started) become release stores; the barrier
after clearing started in sw_stop() becomes a release fence. All are
control path.

Scheduler reads of cq_num_mapped_cqs stay plain loads: acquire loads
would land in the inner scheduling loops on weakly ordered CPUs. The
transient window where a new count is visible before the map entry
on such CPUs predates this change and is unchanged by it; unlink is
covered by the counter handshake.

Signed-off-by: Stephen Hemminger <[email protected]>
---
 drivers/event/sw/sw_evdev.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/event/sw/sw_evdev.c b/drivers/event/sw/sw_evdev.c
index bb6f50e03b..bdb3dff997 100644
--- a/drivers/event/sw/sw_evdev.c
+++ b/drivers/event/sw/sw_evdev.c
@@ -84,8 +84,10 @@ sw_port_link(struct rte_eventdev *dev, void *port, const 
uint8_t queues[],
                }
 
                q->cq_map[q->cq_num_mapped_cqs] = p->id;
-               rte_smp_wmb();
-               q->cq_num_mapped_cqs++;
+               /* Release publishes the map entry before the new count */
+               rte_atomic_store_explicit(
+                       (uint32_t __rte_atomic *)&q->cq_num_mapped_cqs,
+                       q->cq_num_mapped_cqs + 1, rte_memory_order_release);
        }
        return i;
 }
@@ -105,8 +107,14 @@ sw_port_unlink(struct rte_eventdev *dev, void *port, 
uint8_t queues[],
                        if (q->cq_map[j] == p->id) {
                                q->cq_map[j] =
                                        q->cq_map[q->cq_num_mapped_cqs - 1];
-                               rte_smp_wmb();
-                               q->cq_num_mapped_cqs--;
+                               /* Release publishes the map update
+                                * before the new count
+                                */
+                               rte_atomic_store_explicit(
+                                       (uint32_t __rte_atomic *)
+                                               &q->cq_num_mapped_cqs,
+                                       q->cq_num_mapped_cqs - 1,
+                                       rte_memory_order_release);
                                unlinked++;
 
                                p->num_qids_mapped--;
@@ -208,8 +216,9 @@ sw_port_setup(struct rte_eventdev *dev, uint8_t port_id,
        }
        dev->data->ports[port_id] = p;
 
-       rte_smp_wmb();
-       p->initialized = 1;
+       /* Release publishes the port setup before initialized flag */
+       rte_atomic_store_explicit((uint8_t __rte_atomic *)&p->initialized, 1,
+                                 rte_memory_order_release);
        return 0;
 }
 
@@ -815,8 +824,9 @@ sw_start(struct rte_eventdev *dev)
        if (sw_xstats_init(sw) < 0)
                return -EINVAL;
 
-       rte_smp_wmb();
-       sw->started = 1;
+       /* Release publishes device state before the started flag */
+       rte_atomic_store_explicit((uint8_t __rte_atomic *)&sw->started, 1,
+                                 rte_memory_order_release);
 
        return 0;
 }
@@ -845,7 +855,8 @@ sw_stop(struct rte_eventdev *dev)
        sw_clean_qid_iqs(dev);
        sw_xstats_uninit(sw);
        sw->started = 0;
-       rte_smp_wmb();
+       /* Order the started store before re-enabling the service */
+       rte_atomic_thread_fence(rte_memory_order_release);
 
        if (runstate == 1)
                rte_service_runstate_set(sw->service_id, 1);
-- 
2.53.0

Reply via email to