aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/io_uring.c48
-rw-r--r--include/uapi/linux/io_uring.h2
2 files changed, 50 insertions, 0 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 468f9da472b2..2a46de56d05c 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -241,6 +241,7 @@ struct io_ring_ctx {
241 unsigned cq_mask; 241 unsigned cq_mask;
242 struct wait_queue_head cq_wait; 242 struct wait_queue_head cq_wait;
243 struct fasync_struct *cq_fasync; 243 struct fasync_struct *cq_fasync;
244 struct eventfd_ctx *cq_ev_fd;
244 } ____cacheline_aligned_in_smp; 245 } ____cacheline_aligned_in_smp;
245 246
246 /* 247 /*
@@ -516,6 +517,8 @@ static void io_cqring_ev_posted(struct io_ring_ctx *ctx)
516 wake_up(&ctx->wait); 517 wake_up(&ctx->wait);
517 if (waitqueue_active(&ctx->sqo_wait)) 518 if (waitqueue_active(&ctx->sqo_wait))
518 wake_up(&ctx->sqo_wait); 519 wake_up(&ctx->sqo_wait);
520 if (ctx->cq_ev_fd)
521 eventfd_signal(ctx->cq_ev_fd, 1);
519} 522}
520 523
521static void io_cqring_add_event(struct io_ring_ctx *ctx, u64 user_data, 524static void io_cqring_add_event(struct io_ring_ctx *ctx, u64 user_data,
@@ -2757,6 +2760,38 @@ err:
2757 return ret; 2760 return ret;
2758} 2761}
2759 2762
2763static int io_eventfd_register(struct io_ring_ctx *ctx, void __user *arg)
2764{
2765 __s32 __user *fds = arg;
2766 int fd;
2767
2768 if (ctx->cq_ev_fd)
2769 return -EBUSY;
2770
2771 if (copy_from_user(&fd, fds, sizeof(*fds)))
2772 return -EFAULT;
2773
2774 ctx->cq_ev_fd = eventfd_ctx_fdget(fd);
2775 if (IS_ERR(ctx->cq_ev_fd)) {
2776 int ret = PTR_ERR(ctx->cq_ev_fd);
2777 ctx->cq_ev_fd = NULL;
2778 return ret;
2779 }
2780
2781 return 0;
2782}
2783
2784static int io_eventfd_unregister(struct io_ring_ctx *ctx)
2785{
2786 if (ctx->cq_ev_fd) {
2787 eventfd_ctx_put(ctx->cq_ev_fd);
2788 ctx->cq_ev_fd = NULL;
2789 return 0;
2790 }
2791
2792 return -ENXIO;
2793}
2794
2760static void io_ring_ctx_free(struct io_ring_ctx *ctx) 2795static void io_ring_ctx_free(struct io_ring_ctx *ctx)
2761{ 2796{
2762 io_finish_async(ctx); 2797 io_finish_async(ctx);
@@ -2766,6 +2801,7 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
2766 io_iopoll_reap_events(ctx); 2801 io_iopoll_reap_events(ctx);
2767 io_sqe_buffer_unregister(ctx); 2802 io_sqe_buffer_unregister(ctx);
2768 io_sqe_files_unregister(ctx); 2803 io_sqe_files_unregister(ctx);
2804 io_eventfd_unregister(ctx);
2769 2805
2770#if defined(CONFIG_UNIX) 2806#if defined(CONFIG_UNIX)
2771 if (ctx->ring_sock) 2807 if (ctx->ring_sock)
@@ -3179,6 +3215,18 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
3179 break; 3215 break;
3180 ret = io_sqe_files_unregister(ctx); 3216 ret = io_sqe_files_unregister(ctx);
3181 break; 3217 break;
3218 case IORING_REGISTER_EVENTFD:
3219 ret = -EINVAL;
3220 if (nr_args != 1)
3221 break;
3222 ret = io_eventfd_register(ctx, arg);
3223 break;
3224 case IORING_UNREGISTER_EVENTFD:
3225 ret = -EINVAL;
3226 if (arg || nr_args)
3227 break;
3228 ret = io_eventfd_unregister(ctx);
3229 break;
3182 default: 3230 default:
3183 ret = -EINVAL; 3231 ret = -EINVAL;
3184 break; 3232 break;
diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index e707a17c6908..a0c460025036 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -136,5 +136,7 @@ struct io_uring_params {
136#define IORING_UNREGISTER_BUFFERS 1 136#define IORING_UNREGISTER_BUFFERS 1
137#define IORING_REGISTER_FILES 2 137#define IORING_REGISTER_FILES 2
138#define IORING_UNREGISTER_FILES 3 138#define IORING_UNREGISTER_FILES 3
139#define IORING_REGISTER_EVENTFD 4
140#define IORING_UNREGISTER_EVENTFD 5
139 141
140#endif 142#endif