Skip to content

Commit

Permalink
Update sqe layout and prep helpers
Browse files Browse the repository at this point in the history
Let's be smart about it and actually set aside sqe->futex_flags for
io_uring specific flags, and move the FUTEX2_* flags to sqe->fd instead.
This leaves us open to have tweaks internally for io_uring futex commands,
rather than need to add FUTEX2_ flags for that which may not at all make
any sense for the core futex2(2) syscalls.

This has bitten us in the bit previously and we've had to add a new
opcode rather than just add a flag, the most recent example of that is
the IORING_OP_READ_MULTISHOT which clearly could've just been a flag
for the READ/READV/READ_FIXED opcodes.

While doing so, make sure we have two sets of flags passed to the prep
helpers, so that we're future proof in that regard.

Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
axboe committed Sep 27, 2023
1 parent 54f0f9a commit 0b8fac7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 19 deletions.
17 changes: 10 additions & 7 deletions src/include/liburing.h
Original file line number Diff line number Diff line change
Expand Up @@ -1174,26 +1174,29 @@ IOURINGINLINE void io_uring_prep_waitid(struct io_uring_sqe *sqe,

IOURINGINLINE void io_uring_prep_futex_wake(struct io_uring_sqe *sqe,
uint32_t *futex, uint64_t val,
uint64_t mask, uint32_t flags)
uint64_t mask, uint32_t futex_flags,
unsigned int flags)
{
io_uring_prep_rw(IORING_OP_FUTEX_WAKE, sqe, 0, futex, 0, val);
sqe->futex_flags = flags | 2; /* FLAGS_SIZE_32 */
io_uring_prep_rw(IORING_OP_FUTEX_WAKE, sqe, futex_flags, futex, 0, val);
sqe->futex_flags = flags;
sqe->addr3 = mask;
}

IOURINGINLINE void io_uring_prep_futex_wait(struct io_uring_sqe *sqe,
uint32_t *futex, uint64_t val,
uint64_t mask, uint32_t flags)
uint64_t mask, uint32_t futex_flags,
unsigned int flags)
{
io_uring_prep_rw(IORING_OP_FUTEX_WAIT, sqe, 0, futex, 0, val);
sqe->futex_flags = flags | 2; /* FLAGS_SIZE_32 */
io_uring_prep_rw(IORING_OP_FUTEX_WAIT, sqe, futex_flags, futex, 0, val);
sqe->futex_flags = flags;
sqe->addr3 = mask;
}

struct futex_waitv;
IOURINGINLINE void io_uring_prep_futex_waitv(struct io_uring_sqe *sqe,
struct futex_waitv *futex,
uint32_t nr_futex, uint32_t flags)
uint32_t nr_futex,
unsigned int flags)
{
io_uring_prep_rw(IORING_OP_FUTEX_WAITV, sqe, 0, futex, nr_futex, 0);
sqe->futex_flags = flags;
Expand Down
36 changes: 24 additions & 12 deletions test/futex.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ static void *fwake(void *data)

*futex = 1;
sqe = io_uring_get_sqe(&ring);
io_uring_prep_futex_wake(sqe, futex, 1, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wake(sqe, futex, 1, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);
sqe->user_data = 3;

io_uring_submit(&ring);
Expand Down Expand Up @@ -91,7 +92,8 @@ static int __test(struct io_uring *ring, int vectored, int async,
if (vectored)
io_uring_prep_futex_waitv(sqe, fw, nfutex, 0);
else
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);
if (async)
sqe->flags |= IOSQE_ASYNC;
sqe->user_data = 1;
Expand Down Expand Up @@ -186,14 +188,16 @@ static int test_order(int vectored, int async)
*/
sqe = io_uring_get_sqe(&ring);
if (!vectored)
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);
else
io_uring_prep_futex_waitv(sqe, &fw, 1, 0);
sqe->user_data = 1;

sqe = io_uring_get_sqe(&ring);
if (!vectored)
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);
else
io_uring_prep_futex_waitv(sqe, &fw, 1, 0);
sqe->user_data = 2;
Expand All @@ -205,7 +209,8 @@ static int test_order(int vectored, int async)
*/
*futex = 1;
sqe = io_uring_get_sqe(&ring);
io_uring_prep_futex_wake(sqe, futex, 1, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wake(sqe, futex, 1, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);
sqe->user_data = 100;
if (async)
sqe->flags |= IOSQE_ASYNC;
Expand Down Expand Up @@ -266,14 +271,16 @@ static int test_multi_wake(int vectored)
*/
sqe = io_uring_get_sqe(&ring);
if (!vectored)
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);
else
io_uring_prep_futex_waitv(sqe, &fw, 1, 0);
sqe->user_data = 1;

sqe = io_uring_get_sqe(&ring);
if (!vectored)
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);
else
io_uring_prep_futex_waitv(sqe, &fw, 1, 0);
sqe->user_data = 2;
Expand All @@ -285,7 +292,8 @@ static int test_multi_wake(int vectored)
*/
*futex = 1;
sqe = io_uring_get_sqe(&ring);
io_uring_prep_futex_wake(sqe, futex, 2, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wake(sqe, futex, 2, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);
sqe->user_data = 100;

io_uring_submit(&ring);
Expand Down Expand Up @@ -337,13 +345,15 @@ static int test_wake_zero(void)

sqe = io_uring_get_sqe(&ring);
sqe->user_data = 1;
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);

io_uring_submit(&ring);

sqe = io_uring_get_sqe(&ring);
sqe->user_data = 2;
io_uring_prep_futex_wake(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0);
io_uring_prep_futex_wake(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY,
FUTEX2_SIZE_U32, 0);

io_uring_submit(&ring);

Expand Down Expand Up @@ -392,7 +402,8 @@ static int test_invalid(void)

sqe = io_uring_get_sqe(&ring);
sqe->user_data = 1;
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0x1000);
io_uring_prep_futex_wait(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0x1000,
0);

io_uring_submit(&ring);

Expand All @@ -409,7 +420,8 @@ static int test_invalid(void)

sqe = io_uring_get_sqe(&ring);
sqe->user_data = 1;
io_uring_prep_futex_wake(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0x1000);
io_uring_prep_futex_wake(sqe, futex, 0, FUTEX_BITSET_MATCH_ANY, 0x1000,
0);

io_uring_submit(&ring);

Expand Down

0 comments on commit 0b8fac7

Please sign in to comment.