Skip to content

Commit 97bbdc0

Browse files
isilenceaxboe
authored andcommitted
io_uring: add IORING_SETUP_SINGLE_ISSUER
Add a new IORING_SETUP_SINGLE_ISSUER flag and the userspace visible part of it, i.e. put limitations of submitters. Also, don't allow it together with IOPOLL as we're not going to put it to good use. Signed-off-by: Pavel Begunkov <[email protected]> Link: https://lore.kernel.org/r/4bcc41ee467fdf04c8aab8baf6ce3ba21858c3d4.1655371007.git.asml.silence@gmail.com Reviewed-by: Hao Xu <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 0ec6dca commit 97bbdc0

File tree

5 files changed

+36
-8
lines changed

5 files changed

+36
-8
lines changed

include/uapi/linux/io_uring.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,12 @@ enum {
140140
* IORING_SQ_TASKRUN in the sq ring flags. Not valid with COOP_TASKRUN.
141141
*/
142142
#define IORING_SETUP_TASKRUN_FLAG (1U << 9)
143-
144143
#define IORING_SETUP_SQE128 (1U << 10) /* SQEs are 128 byte */
145144
#define IORING_SETUP_CQE32 (1U << 11) /* CQEs are 32 byte */
145+
/*
146+
* Only one task is allowed to submit requests
147+
*/
148+
#define IORING_SETUP_SINGLE_ISSUER (1U << 12)
146149

147150
enum io_uring_op {
148151
IORING_OP_NOP,

io_uring/io_uring.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,6 +2457,8 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
24572457
io_destroy_buffers(ctx);
24582458
if (ctx->sq_creds)
24592459
put_cred(ctx->sq_creds);
2460+
if (ctx->submitter_task)
2461+
put_task_struct(ctx->submitter_task);
24602462

24612463
/* there are no registered resources left, nobody uses it */
24622464
if (ctx->rsrc_node)
@@ -3189,7 +3191,7 @@ static int io_uring_install_fd(struct io_ring_ctx *ctx, struct file *file)
31893191
if (fd < 0)
31903192
return fd;
31913193

3192-
ret = io_uring_add_tctx_node(ctx);
3194+
ret = __io_uring_add_tctx_node(ctx, false);
31933195
if (ret) {
31943196
put_unused_fd(fd);
31953197
return ret;
@@ -3409,7 +3411,8 @@ static long io_uring_setup(u32 entries, struct io_uring_params __user *params)
34093411
IORING_SETUP_CLAMP | IORING_SETUP_ATTACH_WQ |
34103412
IORING_SETUP_R_DISABLED | IORING_SETUP_SUBMIT_ALL |
34113413
IORING_SETUP_COOP_TASKRUN | IORING_SETUP_TASKRUN_FLAG |
3412-
IORING_SETUP_SQE128 | IORING_SETUP_CQE32))
3414+
IORING_SETUP_SQE128 | IORING_SETUP_CQE32 |
3415+
IORING_SETUP_SINGLE_ISSUER))
34133416
return -EINVAL;
34143417

34153418
return io_uring_create(entries, &p, params);

io_uring/io_uring_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ struct io_ring_ctx {
243243
/* Keep this last, we don't need it for the fast path */
244244

245245
struct io_restriction restrictions;
246+
struct task_struct *submitter_task;
246247

247248
/* slow path rsrc auxilary data, used by update/register */
248249
struct io_rsrc_node *rsrc_backup_node;

io_uring/tctx.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,32 @@ __cold int io_uring_alloc_task_context(struct task_struct *task,
9494
return 0;
9595
}
9696

97-
int __io_uring_add_tctx_node(struct io_ring_ctx *ctx)
97+
static int io_register_submitter(struct io_ring_ctx *ctx)
98+
{
99+
int ret = 0;
100+
101+
mutex_lock(&ctx->uring_lock);
102+
if (!ctx->submitter_task)
103+
ctx->submitter_task = get_task_struct(current);
104+
else if (ctx->submitter_task != current)
105+
ret = -EEXIST;
106+
mutex_unlock(&ctx->uring_lock);
107+
108+
return ret;
109+
}
110+
111+
int __io_uring_add_tctx_node(struct io_ring_ctx *ctx, bool submitter)
98112
{
99113
struct io_uring_task *tctx = current->io_uring;
100114
struct io_tctx_node *node;
101115
int ret;
102116

117+
if ((ctx->flags & IORING_SETUP_SINGLE_ISSUER) && submitter) {
118+
ret = io_register_submitter(ctx);
119+
if (ret)
120+
return ret;
121+
}
122+
103123
if (unlikely(!tctx)) {
104124
ret = io_uring_alloc_task_context(current, ctx);
105125
if (unlikely(ret))
@@ -133,7 +153,8 @@ int __io_uring_add_tctx_node(struct io_ring_ctx *ctx)
133153
list_add(&node->ctx_node, &ctx->tctx_list);
134154
mutex_unlock(&ctx->uring_lock);
135155
}
136-
tctx->last = ctx;
156+
if (submitter)
157+
tctx->last = ctx;
137158
return 0;
138159
}
139160

@@ -241,7 +262,7 @@ int io_ringfd_register(struct io_ring_ctx *ctx, void __user *__arg,
241262
return -EINVAL;
242263

243264
mutex_unlock(&ctx->uring_lock);
244-
ret = io_uring_add_tctx_node(ctx);
265+
ret = __io_uring_add_tctx_node(ctx, false);
245266
mutex_lock(&ctx->uring_lock);
246267
if (ret)
247268
return ret;

io_uring/tctx.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct io_tctx_node {
3434
int io_uring_alloc_task_context(struct task_struct *task,
3535
struct io_ring_ctx *ctx);
3636
void io_uring_del_tctx_node(unsigned long index);
37-
int __io_uring_add_tctx_node(struct io_ring_ctx *ctx);
37+
int __io_uring_add_tctx_node(struct io_ring_ctx *ctx, bool submitter);
3838
void io_uring_clean_tctx(struct io_uring_task *tctx);
3939

4040
void io_uring_unreg_ringfd(void);
@@ -52,5 +52,5 @@ static inline int io_uring_add_tctx_node(struct io_ring_ctx *ctx)
5252

5353
if (likely(tctx && tctx->last == ctx))
5454
return 0;
55-
return __io_uring_add_tctx_node(ctx);
55+
return __io_uring_add_tctx_node(ctx, true);
5656
}

0 commit comments

Comments
 (0)