aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2024-08-19 09:06:52 +0000
committerAndrew Turner <andrew@FreeBSD.org>2024-09-02 08:49:38 +0000
commit80df53c7fb1cefffff419adbb0767f36a44c27d2 (patch)
treec4e9a36d2cba3ab70071d7e755847d2f58de3dd3
parent56e8c3ec5241ec4747b8fdd42e0172325c7fc378 (diff)
buf_ring: Use atomic operations with br_cons_tail
Use an atomic operation with a memory barrier loading br_cons_tail from the producer thread and storing to it in the consumer thread. On dequeue we need to read the pointer value from the buf_ring before moving the consumer tail as that indicates the entry is available to be used. The store release atomic operation guarantees this. In the enqueueing thread we then need to use a load acquire atomic operation to ensure writing to this entry can only happen after the tail has been read and checked. Reported by: Ali Saidi <alisaidi@amazon.com> Co-developed by: Ali Saidi <alisaidi@amazon.com> Reviewed by: markj Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D46152 (cherry picked from commit 44e1cfca417c5ef0db908f3836ec3ba704ef1de2)
-rw-r--r--sys/sys/buf_ring.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/sys/sys/buf_ring.h b/sys/sys/buf_ring.h
index dec0f971ae44..9aeb5aa19fa8 100644
--- a/sys/sys/buf_ring.h
+++ b/sys/sys/buf_ring.h
@@ -91,7 +91,7 @@ buf_ring_enqueue(struct buf_ring *br, void *buf)
do {
prod_head = br->br_prod_head;
prod_next = prod_head + 1;
- cons_tail = br->br_cons_tail;
+ cons_tail = atomic_load_acq_32(&br->br_cons_tail);
if ((int32_t)(cons_tail + br->br_prod_size - prod_next) < 1) {
rmb();
@@ -229,7 +229,7 @@ buf_ring_dequeue_sc(struct buf_ring *br)
panic("inconsistent list cons_tail=%d cons_head=%d",
br->br_cons_tail, cons_head);
#endif
- br->br_cons_tail = cons_next;
+ atomic_store_rel_32(&br->br_cons_tail, cons_next);
return (buf);
}
@@ -257,7 +257,7 @@ buf_ring_advance_sc(struct buf_ring *br)
#ifdef DEBUG_BUFRING
br->br_ring[cons_head & mask] = NULL;
#endif
- br->br_cons_tail = cons_next;
+ atomic_store_rel_32(&br->br_cons_tail, cons_next);
}
/*