Linux Audio

Check our new training course

Loading...
v6.2
 1#include <linux/kernel.h>
 2#include <linux/errno.h>
 3#include <linux/file.h>
 4#include <linux/slab.h>
 5#include <linux/net.h>
 6#include <linux/io_uring.h>
 7
 8#include "io_uring.h"
 9#include "notif.h"
10#include "rsrc.h"
11
12static void io_notif_complete_tw_ext(struct io_kiocb *notif, bool *locked)
 
 
13{
14	struct io_notif_data *nd = io_notif_to_data(notif);
15	struct io_ring_ctx *ctx = notif->ctx;
16
17	if (nd->zc_report && (nd->zc_copied || !nd->zc_used))
18		notif->cqe.res |= IORING_NOTIF_USAGE_ZC_COPIED;
19
20	if (nd->account_pages && ctx->user) {
21		__io_unaccount_mem(ctx->user, nd->account_pages);
22		nd->account_pages = 0;
23	}
24	io_req_task_complete(notif, locked);
25}
26
27static void io_tx_ubuf_callback(struct sk_buff *skb, struct ubuf_info *uarg,
28				bool success)
29{
30	struct io_notif_data *nd = container_of(uarg, struct io_notif_data, uarg);
31	struct io_kiocb *notif = cmd_to_io_kiocb(nd);
32
33	if (refcount_dec_and_test(&uarg->refcnt))
34		io_req_task_work_add(notif);
 
 
 
 
 
 
35}
36
37static void io_tx_ubuf_callback_ext(struct sk_buff *skb, struct ubuf_info *uarg,
38			     bool success)
39{
40	struct io_notif_data *nd = container_of(uarg, struct io_notif_data, uarg);
 
 
41
42	if (nd->zc_report) {
43		if (success && !nd->zc_used && skb)
44			WRITE_ONCE(nd->zc_used, true);
45		else if (!success && !nd->zc_copied)
46			WRITE_ONCE(nd->zc_copied, true);
47	}
48	io_tx_ubuf_callback(skb, uarg, success);
 
 
 
 
 
 
 
 
 
 
 
49}
50
51void io_notif_set_extended(struct io_kiocb *notif)
52{
53	struct io_notif_data *nd = io_notif_to_data(notif);
54
55	if (nd->uarg.callback != io_tx_ubuf_callback_ext) {
56		nd->account_pages = 0;
57		nd->zc_report = false;
58		nd->zc_used = false;
59		nd->zc_copied = false;
60		nd->uarg.callback = io_tx_ubuf_callback_ext;
61		notif->io_task_work.func = io_notif_complete_tw_ext;
 
 
62	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63}
64
 
 
 
 
 
65struct io_kiocb *io_alloc_notif(struct io_ring_ctx *ctx)
66	__must_hold(&ctx->uring_lock)
67{
68	struct io_kiocb *notif;
69	struct io_notif_data *nd;
70
71	if (unlikely(!io_alloc_req_refill(ctx)))
72		return NULL;
73	notif = io_alloc_req(ctx);
74	notif->opcode = IORING_OP_NOP;
75	notif->flags = 0;
76	notif->file = NULL;
77	notif->task = current;
78	io_get_task_refs(1);
79	notif->rsrc_node = NULL;
80	notif->io_task_work.func = io_req_task_complete;
81
82	nd = io_notif_to_data(notif);
83	nd->uarg.flags = SKBFL_ZEROCOPY_FRAG | SKBFL_DONT_ORPHAN;
84	nd->uarg.callback = io_tx_ubuf_callback;
 
 
 
 
 
85	refcount_set(&nd->uarg.refcnt, 1);
86	return notif;
87}
v6.13.7
  1#include <linux/kernel.h>
  2#include <linux/errno.h>
  3#include <linux/file.h>
  4#include <linux/slab.h>
  5#include <linux/net.h>
  6#include <linux/io_uring.h>
  7
  8#include "io_uring.h"
  9#include "notif.h"
 10#include "rsrc.h"
 11
 12static const struct ubuf_info_ops io_ubuf_ops;
 13
 14static void io_notif_tw_complete(struct io_kiocb *notif, struct io_tw_state *ts)
 15{
 16	struct io_notif_data *nd = io_notif_to_data(notif);
 
 17
 18	do {
 19		notif = cmd_to_io_kiocb(nd);
 20
 21		lockdep_assert(refcount_read(&nd->uarg.refcnt) == 0);
 
 
 
 
 
 22
 23		if (unlikely(nd->zc_report) && (nd->zc_copied || !nd->zc_used))
 24			notif->cqe.res |= IORING_NOTIF_USAGE_ZC_COPIED;
 
 
 
 25
 26		if (nd->account_pages && notif->ctx->user) {
 27			__io_unaccount_mem(notif->ctx->user, nd->account_pages);
 28			nd->account_pages = 0;
 29		}
 30
 31		nd = nd->next;
 32		io_req_task_complete(notif, ts);
 33	} while (nd);
 34}
 35
 36void io_tx_ubuf_complete(struct sk_buff *skb, struct ubuf_info *uarg,
 37			 bool success)
 38{
 39	struct io_notif_data *nd = container_of(uarg, struct io_notif_data, uarg);
 40	struct io_kiocb *notif = cmd_to_io_kiocb(nd);
 41	unsigned tw_flags;
 42
 43	if (nd->zc_report) {
 44		if (success && !nd->zc_used && skb)
 45			WRITE_ONCE(nd->zc_used, true);
 46		else if (!success && !nd->zc_copied)
 47			WRITE_ONCE(nd->zc_copied, true);
 48	}
 49
 50	if (!refcount_dec_and_test(&uarg->refcnt))
 51		return;
 52
 53	if (nd->head != nd) {
 54		io_tx_ubuf_complete(skb, &nd->head->uarg, success);
 55		return;
 56	}
 57
 58	tw_flags = nd->next ? 0 : IOU_F_TWQ_LAZY_WAKE;
 59	notif->io_task_work.func = io_notif_tw_complete;
 60	__io_req_task_work_add(notif, tw_flags);
 61}
 62
 63static int io_link_skb(struct sk_buff *skb, struct ubuf_info *uarg)
 64{
 65	struct io_notif_data *nd, *prev_nd;
 66	struct io_kiocb *prev_notif, *notif;
 67	struct ubuf_info *prev_uarg = skb_zcopy(skb);
 68
 69	nd = container_of(uarg, struct io_notif_data, uarg);
 70	notif = cmd_to_io_kiocb(nd);
 71
 72	if (!prev_uarg) {
 73		net_zcopy_get(&nd->uarg);
 74		skb_zcopy_init(skb, &nd->uarg);
 75		return 0;
 76	}
 77	/* handle it separately as we can't link a notif to itself */
 78	if (unlikely(prev_uarg == &nd->uarg))
 79		return 0;
 80	/* we can't join two links together, just request a fresh skb */
 81	if (unlikely(nd->head != nd || nd->next))
 82		return -EEXIST;
 83	/* don't mix zc providers */
 84	if (unlikely(prev_uarg->ops != &io_ubuf_ops))
 85		return -EEXIST;
 86
 87	prev_nd = container_of(prev_uarg, struct io_notif_data, uarg);
 88	prev_notif = cmd_to_io_kiocb(nd);
 89
 90	/* make sure all noifications can be finished in the same task_work */
 91	if (unlikely(notif->ctx != prev_notif->ctx ||
 92		     notif->tctx != prev_notif->tctx))
 93		return -EEXIST;
 94
 95	nd->head = prev_nd->head;
 96	nd->next = prev_nd->next;
 97	prev_nd->next = nd;
 98	net_zcopy_get(&nd->head->uarg);
 99	return 0;
100}
101
102static const struct ubuf_info_ops io_ubuf_ops = {
103	.complete = io_tx_ubuf_complete,
104	.link_skb = io_link_skb,
105};
106
107struct io_kiocb *io_alloc_notif(struct io_ring_ctx *ctx)
108	__must_hold(&ctx->uring_lock)
109{
110	struct io_kiocb *notif;
111	struct io_notif_data *nd;
112
113	if (unlikely(!io_alloc_req(ctx, &notif)))
114		return NULL;
 
115	notif->opcode = IORING_OP_NOP;
116	notif->flags = 0;
117	notif->file = NULL;
118	notif->tctx = current->io_uring;
119	io_get_task_refs(1);
120	notif->file_node = NULL;
121	notif->buf_node = NULL;
122
123	nd = io_notif_to_data(notif);
124	nd->zc_report = false;
125	nd->account_pages = 0;
126	nd->next = NULL;
127	nd->head = nd;
128
129	nd->uarg.flags = IO_NOTIF_UBUF_FLAGS;
130	nd->uarg.ops = &io_ubuf_ops;
131	refcount_set(&nd->uarg.refcnt, 1);
132	return notif;
133}