io_uring: add notification slot registration
[linux-2.6-microblaze.git] / io_uring / notif.h
1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <linux/net.h>
4 #include <linux/uio.h>
5 #include <net/sock.h>
6 #include <linux/nospec.h>
7
8 #define IO_NOTIF_SPLICE_BATCH   32
9 #define IORING_MAX_NOTIF_SLOTS (1U << 10)
10
11 struct io_notif {
12         struct ubuf_info        uarg;
13         struct io_ring_ctx      *ctx;
14         struct io_rsrc_node     *rsrc_node;
15
16         /* complete via tw if ->task is non-NULL, fallback to wq otherwise */
17         struct task_struct      *task;
18
19         /* cqe->user_data, io_notif_slot::tag if not overridden */
20         u64                     tag;
21         /* see struct io_notif_slot::seq */
22         u32                     seq;
23         /* hook into ctx->notif_list and ctx->notif_list_locked */
24         struct list_head        cache_node;
25
26         union {
27                 struct callback_head    task_work;
28                 struct work_struct      commit_work;
29         };
30 };
31
32 struct io_notif_slot {
33         /*
34          * Current/active notifier. A slot holds only one active notifier at a
35          * time and keeps one reference to it. Flush releases the reference and
36          * lazily replaces it with a new notifier.
37          */
38         struct io_notif         *notif;
39
40         /*
41          * Default ->user_data for this slot notifiers CQEs
42          */
43         u64                     tag;
44         /*
45          * Notifiers of a slot live in generations, we create a new notifier
46          * only after flushing the previous one. Track the sequential number
47          * for all notifiers and copy it into notifiers's cqe->cflags
48          */
49         u32                     seq;
50 };
51
52 int io_notif_register(struct io_ring_ctx *ctx,
53                       void __user *arg, unsigned int size);
54 int io_notif_unregister(struct io_ring_ctx *ctx);
55 void io_notif_cache_purge(struct io_ring_ctx *ctx);
56
57 struct io_notif *io_alloc_notif(struct io_ring_ctx *ctx,
58                                 struct io_notif_slot *slot);
59
60 static inline struct io_notif *io_get_notif(struct io_ring_ctx *ctx,
61                                             struct io_notif_slot *slot)
62 {
63         if (!slot->notif)
64                 slot->notif = io_alloc_notif(ctx, slot);
65         return slot->notif;
66 }
67
68 static inline struct io_notif_slot *io_get_notif_slot(struct io_ring_ctx *ctx,
69                                                       int idx)
70         __must_hold(&ctx->uring_lock)
71 {
72         if (idx >= ctx->nr_notif_slots)
73                 return NULL;
74         idx = array_index_nospec(idx, ctx->nr_notif_slots);
75         return &ctx->notif_slots[idx];
76 }