@@ -518,6 +518,10 @@ enum {
/* register a range of fixed file slots for automatic slot allocation */
IORING_REGISTER_FILE_ALLOC_RANGE = 25,
+ /* set/clear busy poll settings */
+ IORING_REGISTER_NAPI = 26,
+ IORING_UNREGISTER_NAPI = 27,
+
/* this goes last */
IORING_REGISTER_LAST
};
@@ -640,6 +644,13 @@ struct io_uring_buf_reg {
__u64 resv[3];
};
+/* argument for IORING_(UN)REGISTER_NAPI */
+struct io_uring_napi {
+ __u32 busy_poll_to;
+ __u32 pad;
+ __u64 resv;
+};
+
/*
* io_uring_restriction->opcode values
*/
@@ -4283,6 +4283,15 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
break;
ret = io_register_file_alloc_range(ctx, arg);
break;
+ case IORING_REGISTER_NAPI:
+ ret = -EINVAL;
+ if (!arg)
+ break;
+ ret = io_register_napi(ctx, arg);
+ break;
+ case IORING_UNREGISTER_NAPI:
+ ret = io_unregister_napi(ctx, arg);
+ break;
default:
ret = -EINVAL;
break;
@@ -199,6 +199,41 @@ void io_napi_free(struct io_ring_ctx *ctx)
spin_unlock(&ctx->napi_lock);
}
+int io_register_napi(struct io_ring_ctx *ctx, void __user *arg)
+{
+ const struct io_uring_napi curr = {
+ .busy_poll_to = ctx->napi_busy_poll_to,
+ };
+ struct io_uring_napi napi;
+
+ if (copy_from_user(&napi, arg, sizeof(napi)))
+ return -EFAULT;
+ if (napi.pad || napi.resv)
+ return -EINVAL;
+
+ WRITE_ONCE(ctx->napi_busy_poll_to, napi.busy_poll_to);
+
+ if (copy_to_user(arg, &curr, sizeof(curr)))
+ return -EFAULT;
+
+ return 0;
+}
+
+int io_unregister_napi(struct io_ring_ctx *ctx, void __user *arg)
+{
+ const struct io_uring_napi curr = {
+ .busy_poll_to = ctx->napi_busy_poll_to,
+ };
+
+ if (arg) {
+ if (copy_to_user(arg, &curr, sizeof(curr)))
+ return -EFAULT;
+ }
+
+ WRITE_ONCE(ctx->napi_busy_poll_to, 0);
+ return 0;
+}
+
/*
* io_napi_add() - Add napi id to the busy poll list
* @req: pointer to io_kiocb request
@@ -14,6 +14,9 @@
void io_napi_init(struct io_ring_ctx *ctx);
void io_napi_free(struct io_ring_ctx *ctx);
+int io_register_napi(struct io_ring_ctx *ctx, void __user *arg);
+int io_unregister_napi(struct io_ring_ctx *ctx, void __user *arg);
+
void io_napi_add(struct io_kiocb *req);
void io_napi_setup_busy_loop(struct io_ring_ctx *ctx, struct io_wait_queue *iowq,
@@ -37,6 +40,16 @@ static inline void io_napi_free(struct io_ring_ctx *ctx)
{
}
+static inline int io_register_napi(struct io_ring_ctx *ctx, void __user *arg)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int io_unregister_napi(struct io_ring_ctx *ctx, void __user *arg)
+{
+ return -EOPNOTSUPP;
+}
+
static inline void io_napi_add(struct io_kiocb *req)
{
}