public inbox for [email protected]
 help / color / mirror / Atom feed
* [PATCHSET RFC 0/6] Add io_uring support for futex wait/wake
@ 2023-06-09 18:31 Jens Axboe
  2023-06-09 18:31 ` [PATCH 1/6] futex: abstract out futex_op_to_flags() helper Jens Axboe
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Jens Axboe @ 2023-06-09 18:31 UTC (permalink / raw)
  To: io-uring; +Cc: andres

Hi,

Sending this just to the io_uring list for now so we can iron out
details, questions, concerns, etc before going a bit broader to get
the futex parts reviewed. Those are pretty straight forward though,
and try not to get too entangled into futex internals.

Anyway, this adds support for IORING_OP_FUTEX_{WAIT,WAKE}. The
WAKE part is pretty trivial, as we can just call into the wake side
of things. For wait, obviously we cannot, as we don't want to block
on waiting on a futex. When futex currently does a wait, it queues up
the futex_q in question and then does a sync wait/schedule on that.
The futex handler futex_wake_mark() is responsible for waking the
task that is synchronousely sleeping on that futex_q. This default
handler is hardwired, and we simply add a wake handler in futex_q
for this intead and change the hardwired futex_q->task to be a
generic data piece for the handler.

With that, we can queue up a futex_q and get a callback when it
would have woken. With that, we can sanely implement async WAIT
support without blocking.

Notable omissions in this code so far:

- We don't support timeouts with futex wait. We could definitely
  add this support. Outside of some complications with racing with
  wake (and cancelation), it is certainly doable. The main question
  here is we need it? And if we do, can we get by with just using
  linked timeouts for this? That's the io_uring idiomatic way of
  achieving this goal. That said, I may just go ahead and add it
  if I can solve the races in a clean fashion. Because at that point,
  seems the right thing to do.

- No PI support. This can certainly get added later.

Code can also be found here:

git://git.kernel.dk/linux io_uring-futex

or on cgit:

https://git.kernel.dk/cgit/linux/log/?h=io_uring-futex

Very simple sample code below showing how to do a wait and wake,
Obviously not that exciting, just a brief demo.


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <linux/futex.h>
#include <liburing.h>

#define	IORING_OP_FUTEX_WAIT (IORING_OP_SENDMSG_ZC + 1)
#define IORING_OP_FUTEX_WAKE (IORING_OP_FUTEX_WAIT + 1)

static void io_uring_prep_futex_wait(struct io_uring_sqe *sqe, void *futex,
				     int val)
{
	memset(sqe, 0, sizeof(*sqe));
	sqe->opcode = IORING_OP_FUTEX_WAIT;
	sqe->fd = FUTEX_WAIT;
	sqe->addr = (unsigned long) futex;
	sqe->len = val;
	sqe->file_index = FUTEX_BITSET_MATCH_ANY;
}

static void io_uring_prep_futex_wake(struct io_uring_sqe *sqe, void *futex,
				     int val)
{
	memset(sqe, 0, sizeof(*sqe));
	sqe->opcode = IORING_OP_FUTEX_WAKE;
	sqe->fd = FUTEX_WAIT;
	sqe->addr = (unsigned long) futex;
	sqe->len = val;
	sqe->file_index = FUTEX_BITSET_MATCH_ANY;
}

int main(int argc, char *argv[])
{
	struct io_uring_sqe *sqe;
	struct io_uring_cqe *cqe;
	struct io_uring ring;
	unsigned int *futex;
	int ret, i;

	futex = malloc(sizeof(*futex));
	*futex = 0;

	io_uring_queue_init(8, &ring, 0);

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

	*futex = 1;
	sqe = io_uring_get_sqe(&ring);
	io_uring_prep_futex_wake(sqe, futex, 1);
	sqe->user_data = 2;

	io_uring_submit(&ring);

	for (i = 0; i < 2; i++) {
		ret = io_uring_wait_cqe(&ring, &cqe);
		if (ret)
			return 1;

		io_uring_cqe_seen(&ring, cqe);
	}

	return 0;
}

-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-06-23 19:47 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-09 18:31 [PATCHSET RFC 0/6] Add io_uring support for futex wait/wake Jens Axboe
2023-06-09 18:31 ` [PATCH 1/6] futex: abstract out futex_op_to_flags() helper Jens Axboe
2023-06-09 18:31 ` [PATCH 2/6] futex: factor out the futex wake handling Jens Axboe
2023-06-09 18:31 ` [PATCH 3/6] futex: assign default futex_q->wait_data at insertion time Jens Axboe
2023-06-09 18:31 ` [PATCH 4/6] futex: add futex wait variant that takes a futex_q directly Jens Axboe
2023-06-09 18:31 ` [PATCH 5/6] io_uring: add support for futex wake and wait Jens Axboe
2023-06-12 16:06   ` Gabriel Krisman Bertazi
2023-06-12 20:37     ` Jens Axboe
2023-06-12 23:00       ` Gabriel Krisman Bertazi
2023-06-13  1:09         ` Jens Axboe
2023-06-13  2:55           ` io_uring link semantics (was [PATCH 5/6] io_uring: add support for futex wake and wait) Gabriel Krisman Bertazi
2023-06-23 19:04   ` [PATCH 5/6] io_uring: add support for futex wake and wait Andres Freund
2023-06-23 19:07     ` Jens Axboe
2023-06-23 19:34       ` Andres Freund
2023-06-23 19:46         ` Jens Axboe
2023-06-09 18:31 ` [PATCH 6/6] io_uring/futex: enable use of the allocation caches for futex_q Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox