Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/uapi/linux/io_uring.h
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,8 @@ struct io_uring_buf_reg {
__u32 ring_entries;
__u16 bgid;
__u16 flags;
__u64 resv[3];
__u32 min_left;
__u32 resv[5];
};

/* argument for IORING_REGISTER_PBUF_STATUS */
Expand Down
9 changes: 7 additions & 2 deletions io_uring/kbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static bool io_kbuf_inc_commit(struct io_buffer_list *bl, int len)
this_len = min_t(u32, len, buf_len);
buf_len -= this_len;
/* Stop looping for invalid buffer length of 0 */
if (buf_len || !this_len) {
if (buf_len > bl->min_left_sub_one || !this_len) {
WRITE_ONCE(buf->addr, READ_ONCE(buf->addr) + this_len);
WRITE_ONCE(buf->len, buf_len);
return false;
Expand Down Expand Up @@ -637,6 +637,10 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
if (reg.ring_entries >= 65536)
return -EINVAL;

/* minimum left byte count is a property of incremental buffers */
if (!(reg.flags & IOU_PBUF_RING_INC) && reg.min_left)
return -EINVAL;

bl = io_buffer_get_list(ctx, reg.bgid);
if (bl) {
/* if mapped buffer ring OR classic exists, don't allow */
Expand Down Expand Up @@ -680,10 +684,11 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
}
#endif

bl->nr_entries = reg.ring_entries;
bl->mask = reg.ring_entries - 1;
bl->flags |= IOBL_BUF_RING;
bl->buf_ring = br;
if (reg.min_left)
bl->min_left_sub_one = reg.min_left - 1;
if (reg.flags & IOU_PBUF_RING_INC)
bl->flags |= IOBL_INC;
ret = io_buffer_add_list(ctx, bl, reg.bgid);
Expand Down
8 changes: 7 additions & 1 deletion io_uring/kbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,18 @@ struct io_buffer_list {
__u16 bgid;

/* below is for ring provided buffers */
__u16 nr_entries;
__u16 head;
__u16 mask;

__u16 flags;

/*
* minimum required amount to be left to reuse an incrementally
* consumed buffer. If less than this is left at consumption time,
* buffer is done and head is incremented to the next buffer.
*/
__u32 min_left_sub_one;

struct io_mapped_region region;
};

Expand Down
2 changes: 2 additions & 0 deletions io_uring/napi.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ static int io_napi_register_napi(struct io_ring_ctx *ctx,
/* clean the napi list for new settings */
io_napi_free(ctx);
WRITE_ONCE(ctx->napi_track_mode, napi->op_param);
/* cap NAPI at 10 msec of spin time */
napi->busy_poll_to = min(10000, napi->busy_poll_to);
WRITE_ONCE(ctx->napi_busy_poll_dt, napi->busy_poll_to * NSEC_PER_USEC);
WRITE_ONCE(ctx->napi_prefer_busy_poll, !!napi->prefer_busy_poll);
return 0;
Expand Down