Skip to content

Commit d293b1a

Browse files
committed
io_uring/kbuf: add method for returning provided buffer ring head
The tail of the provided ring buffer is shared between the kernel and the application, but the head is private to the kernel as the application doesn't need to see it. However, this also prevents the application from knowing how many buffers the kernel has consumed. Usually this is fine, as the information is inherently racy in that the kernel could be consuming buffers continually, but for cleanup purposes it may be relevant to know how many buffers are still left in the ring. Add IORING_REGISTER_PBUF_STATUS which will return status for a given provided buffer ring. Right now it just returns the head, but space is reserved for more information later in, if needed. Link: axboe/liburing#1020 Signed-off-by: Jens Axboe <[email protected]>
1 parent 0a535ed commit d293b1a

File tree

4 files changed

+43
-0
lines changed

4 files changed

+43
-0
lines changed

include/uapi/linux/io_uring.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,9 @@ enum {
567567
/* register a range of fixed file slots for automatic slot allocation */
568568
IORING_REGISTER_FILE_ALLOC_RANGE = 25,
569569

570+
/* return status information for a buffer group */
571+
IORING_REGISTER_PBUF_STATUS = 26,
572+
570573
/* this goes last */
571574
IORING_REGISTER_LAST,
572575

@@ -693,6 +696,13 @@ struct io_uring_buf_reg {
693696
__u64 resv[3];
694697
};
695698

699+
/* argument for IORING_REGISTER_PBUF_STATUS */
700+
struct io_uring_buf_status {
701+
__u32 buf_group; /* input */
702+
__u32 head; /* output */
703+
__u32 resv[8];
704+
};
705+
696706
/*
697707
* io_uring_restriction->opcode values
698708
*/

io_uring/kbuf.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,32 @@ int io_unregister_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
750750
return 0;
751751
}
752752

753+
int io_register_pbuf_status(struct io_ring_ctx *ctx, void __user *arg)
754+
{
755+
struct io_uring_buf_status buf_status;
756+
struct io_buffer_list *bl;
757+
int i;
758+
759+
if (copy_from_user(&buf_status, arg, sizeof(buf_status)))
760+
return -EFAULT;
761+
762+
for (i = 0; i < ARRAY_SIZE(buf_status.resv); i++)
763+
if (buf_status.resv[i])
764+
return -EINVAL;
765+
766+
bl = io_buffer_get_list(ctx, buf_status.buf_group);
767+
if (!bl)
768+
return -ENOENT;
769+
if (!bl->is_mapped)
770+
return -EINVAL;
771+
772+
buf_status.head = bl->head;
773+
if (copy_to_user(arg, &buf_status, sizeof(buf_status)))
774+
return -EFAULT;
775+
776+
return 0;
777+
}
778+
753779
void *io_pbuf_get_address(struct io_ring_ctx *ctx, unsigned long bgid)
754780
{
755781
struct io_buffer_list *bl;

io_uring/kbuf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ int io_provide_buffers(struct io_kiocb *req, unsigned int issue_flags);
5353

5454
int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg);
5555
int io_unregister_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg);
56+
int io_register_pbuf_status(struct io_ring_ctx *ctx, void __user *arg);
5657

5758
void io_kbuf_mmap_list_free(struct io_ring_ctx *ctx);
5859

io_uring/register.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,12 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
542542
break;
543543
ret = io_register_file_alloc_range(ctx, arg);
544544
break;
545+
case IORING_REGISTER_PBUF_STATUS:
546+
ret = -EINVAL;
547+
if (!arg || nr_args != 1)
548+
break;
549+
ret = io_register_pbuf_status(ctx, arg);
550+
break;
545551
default:
546552
ret = -EINVAL;
547553
break;

0 commit comments

Comments
 (0)