Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 2 Sep 2024 09:12:46 GMT
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 3c15d02bb8a1 - stable/13 - buf_ring: Use atomic operations with br_cons_tail
Message-ID:  <202409020912.4829CkXS049930@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=3c15d02bb8a193d7c38cb9689454e4f26d12bb21

commit 3c15d02bb8a193d7c38cb9689454e4f26d12bb21
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-08-19 09:06:52 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-09-02 09:11:57 +0000

    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)
---
 sys/sys/buf_ring.h | 6 +++---
 1 file 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);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202409020912.4829CkXS049930>