Skip to content

Commit

Permalink
io_uring: add zc notification flush requests
Browse files Browse the repository at this point in the history
Overlay notification control onto IORING_OP_RSRC_UPDATE (former
IORING_OP_FILES_UPDATE). It allows to flush a range of zc notifications
from slots with indexes [sqe->off, sqe->off+sqe->len). If sqe->arg is
not zero, it also copies sqe->arg as a new tag for all flushed
notifications.

Note, it doesn't flush a notification of a slot if there was no requests
attached to it (since last flush or registration).

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/df13e2363400682a73dd9e71c3b990b8d1ff0333.1657643355.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Pavel Begunkov authored and Jens Axboe committed Jul 25, 2022
1 parent 4379d5f commit 492dddb
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/uapi/linux/io_uring.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ enum io_uring_op {
*/
enum {
IORING_RSRC_UPDATE_FILES,
IORING_RSRC_UPDATE_NOTIF,
};

/*
Expand Down
38 changes: 38 additions & 0 deletions io_uring/rsrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "io_uring.h"
#include "openclose.h"
#include "rsrc.h"
#include "notif.h"

struct io_rsrc_update {
struct file *file;
Expand Down Expand Up @@ -744,13 +745,50 @@ static int io_files_update(struct io_kiocb *req, unsigned int issue_flags)
return IOU_OK;
}

static int io_notif_update(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_rsrc_update *up = io_kiocb_to_cmd(req);
struct io_ring_ctx *ctx = req->ctx;
unsigned len = up->nr_args;
unsigned idx_end, idx = up->offset;
int ret = 0;

io_ring_submit_lock(ctx, issue_flags);
if (unlikely(check_add_overflow(idx, len, &idx_end))) {
ret = -EOVERFLOW;
goto out;
}
if (unlikely(idx_end > ctx->nr_notif_slots)) {
ret = -EINVAL;
goto out;
}

for (; idx < idx_end; idx++) {
struct io_notif_slot *slot = &ctx->notif_slots[idx];

if (!slot->notif)
continue;
if (up->arg)
slot->tag = up->arg;
io_notif_slot_flush_submit(slot, issue_flags);
}
out:
io_ring_submit_unlock(ctx, issue_flags);
if (ret < 0)
req_set_fail(req);
io_req_set_res(req, ret, 0);
return IOU_OK;
}

int io_rsrc_update(struct io_kiocb *req, unsigned int issue_flags)
{
struct io_rsrc_update *up = io_kiocb_to_cmd(req);

switch (up->type) {
case IORING_RSRC_UPDATE_FILES:
return io_files_update(req, issue_flags);
case IORING_RSRC_UPDATE_NOTIF:
return io_notif_update(req, issue_flags);
}
return -EINVAL;
}
Expand Down

0 comments on commit 492dddb

Please sign in to comment.