io_uring: add zc notification infrastructure
[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 struct io_notif {
9         struct ubuf_info        uarg;
10         struct io_ring_ctx      *ctx;
11
12         /* cqe->user_data, io_notif_slot::tag if not overridden */
13         u64                     tag;
14         /* see struct io_notif_slot::seq */
15         u32                     seq;
16
17         union {
18                 struct callback_head    task_work;
19                 struct work_struct      commit_work;
20         };
21 };
22
23 struct io_notif_slot {
24         /*
25          * Current/active notifier. A slot holds only one active notifier at a
26          * time and keeps one reference to it. Flush releases the reference and
27          * lazily replaces it with a new notifier.
28          */
29         struct io_notif         *notif;
30
31         /*
32          * Default ->user_data for this slot notifiers CQEs
33          */
34         u64                     tag;
35         /*
36          * Notifiers of a slot live in generations, we create a new notifier
37          * only after flushing the previous one. Track the sequential number
38          * for all notifiers and copy it into notifiers's cqe->cflags
39          */
40         u32                     seq;
41 };
42
43 int io_notif_unregister(struct io_ring_ctx *ctx);
44
45 struct io_notif *io_alloc_notif(struct io_ring_ctx *ctx,
46                                 struct io_notif_slot *slot);
47
48 static inline struct io_notif *io_get_notif(struct io_ring_ctx *ctx,
49                                             struct io_notif_slot *slot)
50 {
51         if (!slot->notif)
52                 slot->notif = io_alloc_notif(ctx, slot);
53         return slot->notif;
54 }
55
56 static inline struct io_notif_slot *io_get_notif_slot(struct io_ring_ctx *ctx,
57                                                       int idx)
58         __must_hold(&ctx->uring_lock)
59 {
60         if (idx >= ctx->nr_notif_slots)
61                 return NULL;
62         idx = array_index_nospec(idx, ctx->nr_notif_slots);
63         return &ctx->notif_slots[idx];
64 }