Back to home page

OSCL-LXR

 
 

    


0001 #include <linux/kernel.h>
0002 #include <linux/errno.h>
0003 #include <linux/file.h>
0004 #include <linux/slab.h>
0005 #include <linux/net.h>
0006 #include <linux/io_uring.h>
0007 
0008 #include "io_uring.h"
0009 #include "notif.h"
0010 #include "rsrc.h"
0011 
0012 static void __io_notif_complete_tw(struct io_kiocb *notif, bool *locked)
0013 {
0014     struct io_notif_data *nd = io_notif_to_data(notif);
0015     struct io_ring_ctx *ctx = notif->ctx;
0016 
0017     if (nd->account_pages && ctx->user) {
0018         __io_unaccount_mem(ctx->user, nd->account_pages);
0019         nd->account_pages = 0;
0020     }
0021     io_req_task_complete(notif, locked);
0022 }
0023 
0024 static void io_uring_tx_zerocopy_callback(struct sk_buff *skb,
0025                       struct ubuf_info *uarg,
0026                       bool success)
0027 {
0028     struct io_notif_data *nd = container_of(uarg, struct io_notif_data, uarg);
0029     struct io_kiocb *notif = cmd_to_io_kiocb(nd);
0030 
0031     if (refcount_dec_and_test(&uarg->refcnt)) {
0032         notif->io_task_work.func = __io_notif_complete_tw;
0033         io_req_task_work_add(notif);
0034     }
0035 }
0036 
0037 struct io_kiocb *io_alloc_notif(struct io_ring_ctx *ctx)
0038     __must_hold(&ctx->uring_lock)
0039 {
0040     struct io_kiocb *notif;
0041     struct io_notif_data *nd;
0042 
0043     if (unlikely(!io_alloc_req_refill(ctx)))
0044         return NULL;
0045     notif = io_alloc_req(ctx);
0046     notif->opcode = IORING_OP_NOP;
0047     notif->flags = 0;
0048     notif->file = NULL;
0049     notif->task = current;
0050     io_get_task_refs(1);
0051     notif->rsrc_node = NULL;
0052     io_req_set_rsrc_node(notif, ctx, 0);
0053 
0054     nd = io_notif_to_data(notif);
0055     nd->account_pages = 0;
0056     nd->uarg.flags = SKBFL_ZEROCOPY_FRAG | SKBFL_DONT_ORPHAN;
0057     nd->uarg.callback = io_uring_tx_zerocopy_callback;
0058     refcount_set(&nd->uarg.refcnt, 1);
0059     return notif;
0060 }
0061 
0062 void io_notif_flush(struct io_kiocb *notif)
0063     __must_hold(&slot->notif->ctx->uring_lock)
0064 {
0065     struct io_notif_data *nd = io_notif_to_data(notif);
0066 
0067     /* drop slot's master ref */
0068     if (refcount_dec_and_test(&nd->uarg.refcnt)) {
0069         notif->io_task_work.func = __io_notif_complete_tw;
0070         io_req_task_work_add(notif);
0071     }
0072 }