src/queue: add comments on the read and write barriers

Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Jens Axboe
2019-02-10 08:19:54 -07:00
parent e9aa44135b
commit 520efcd606

View File

@@ -21,6 +21,13 @@ static int __io_uring_get_completion(struct io_uring *ring,
*cqe_ptr = NULL; *cqe_ptr = NULL;
head = *cq->khead; head = *cq->khead;
do { do {
/*
* It's necessary to use a read_barrier() before reading
* the CQ tail, since the kernel updates it locklessly. The
* kernel has the matching store barrier for the update. The
* kernel also ensures that previous stores to CQEs are ordered
* with the tail update.
*/
read_barrier(); read_barrier();
if (head != *cq->ktail) { if (head != *cq->ktail) {
*cqe_ptr = &cq->cqes[head & mask]; *cqe_ptr = &cq->cqes[head & mask];
@@ -36,6 +43,10 @@ static int __io_uring_get_completion(struct io_uring *ring,
if (*cqe_ptr) { if (*cqe_ptr) {
*cq->khead = head + 1; *cq->khead = head + 1;
/*
* Ensure that the kernel sees our new head, the kernel has
* the matching read barrier.
*/
write_barrier(); write_barrier();
} }
@@ -72,7 +83,9 @@ int io_uring_submit(struct io_uring *ring)
unsigned ktail, ktail_next, submitted; unsigned ktail, ktail_next, submitted;
/* /*
* If we have pending IO in the kring, submit it first * If we have pending IO in the kring, submit it first. We need a
* read barrier here to match the kernels store barrier when updating
* the SQ head.
*/ */
read_barrier(); read_barrier();
if (*sq->khead != *sq->ktail) { if (*sq->khead != *sq->ktail) {
@@ -105,8 +118,18 @@ int io_uring_submit(struct io_uring *ring)
return 0; return 0;
if (*sq->ktail != ktail) { if (*sq->ktail != ktail) {
/*
* First write barrier ensures that the SQE stores are updated
* with the tail update. This is needed so that the kernel
* will never see a tail update without the preceeding sQE
* stores being done.
*/
write_barrier(); write_barrier();
*sq->ktail = ktail; *sq->ktail = ktail;
/*
* The kernel has the matching read barrier for reading the
* SQ tail.
*/
write_barrier(); write_barrier();
} }