Skip to content

Commit d7af80b

Browse files
isilenceaxboe
authored andcommitted
io_uring/zcrx: export zcrx via a file
Add an option to wrap a zcrx instance into a file and expose it to the user space. Currently, users can't do anything meaningful with the file, but it'll be used in a next patch to import it into another io_uring instance. It's implemented as a new op called ZCRX_CTRL_EXPORT for the IORING_REGISTER_ZCRX_CTRL registration opcode. Signed-off-by: David Wei <dw@davidwei.uk> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 742cb2e commit d7af80b

2 files changed

Lines changed: 72 additions & 7 deletions

File tree

include/uapi/linux/io_uring.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,7 @@ struct io_uring_zcrx_ifq_reg {
10831083

10841084
enum zcrx_ctrl_op {
10851085
ZCRX_CTRL_FLUSH_RQ,
1086+
ZCRX_CTRL_EXPORT,
10861087

10871088
__ZCRX_CTRL_LAST,
10881089
};
@@ -1091,12 +1092,20 @@ struct zcrx_ctrl_flush_rq {
10911092
__u64 __resv[6];
10921093
};
10931094

1095+
struct zcrx_ctrl_export {
1096+
__u32 zcrx_fd;
1097+
__u32 __resv1[11];
1098+
};
1099+
10941100
struct zcrx_ctrl {
10951101
__u32 zcrx_id;
10961102
__u32 op; /* see enum zcrx_ctrl_op */
10971103
__u64 __resv[2];
10981104

1099-
struct zcrx_ctrl_flush_rq zc_flush;
1105+
union {
1106+
struct zcrx_ctrl_export zc_export;
1107+
struct zcrx_ctrl_flush_rq zc_flush;
1108+
};
11001109
};
11011110

11021111
#ifdef __cplusplus

io_uring/zcrx.c

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/netdevice.h>
99
#include <linux/rtnetlink.h>
1010
#include <linux/skbuff_ref.h>
11+
#include <linux/anon_inodes.h>
1112

1213
#include <net/page_pool/helpers.h>
1314
#include <net/page_pool/memory_provider.h>
@@ -586,6 +587,15 @@ static void io_zcrx_scrub(struct io_zcrx_ifq *ifq)
586587
}
587588
}
588589

590+
static void zcrx_unregister(struct io_zcrx_ifq *ifq)
591+
{
592+
if (refcount_dec_and_test(&ifq->user_refs)) {
593+
io_close_queue(ifq);
594+
io_zcrx_scrub(ifq);
595+
}
596+
io_put_zcrx_ifq(ifq);
597+
}
598+
589599
struct io_mapped_region *io_zcrx_get_region(struct io_ring_ctx *ctx,
590600
unsigned int id)
591601
{
@@ -596,6 +606,55 @@ struct io_mapped_region *io_zcrx_get_region(struct io_ring_ctx *ctx,
596606
return ifq ? &ifq->region : NULL;
597607
}
598608

609+
static int zcrx_box_release(struct inode *inode, struct file *file)
610+
{
611+
struct io_zcrx_ifq *ifq = file->private_data;
612+
613+
if (WARN_ON_ONCE(!ifq))
614+
return -EFAULT;
615+
zcrx_unregister(ifq);
616+
return 0;
617+
}
618+
619+
static const struct file_operations zcrx_box_fops = {
620+
.owner = THIS_MODULE,
621+
.release = zcrx_box_release,
622+
};
623+
624+
static int zcrx_export(struct io_ring_ctx *ctx, struct io_zcrx_ifq *ifq,
625+
struct zcrx_ctrl *ctrl, void __user *arg)
626+
{
627+
struct zcrx_ctrl_export *ce = &ctrl->zc_export;
628+
struct file *file;
629+
int fd = -1;
630+
631+
if (!mem_is_zero(ce, sizeof(*ce)))
632+
return -EINVAL;
633+
fd = get_unused_fd_flags(O_CLOEXEC);
634+
if (fd < 0)
635+
return fd;
636+
637+
ce->zcrx_fd = fd;
638+
if (copy_to_user(arg, ctrl, sizeof(*ctrl))) {
639+
put_unused_fd(fd);
640+
return -EFAULT;
641+
}
642+
643+
refcount_inc(&ifq->refs);
644+
refcount_inc(&ifq->user_refs);
645+
646+
file = anon_inode_create_getfile("[zcrx]", &zcrx_box_fops,
647+
ifq, O_CLOEXEC, NULL);
648+
if (IS_ERR(file)) {
649+
put_unused_fd(fd);
650+
zcrx_unregister(ifq);
651+
return PTR_ERR(file);
652+
}
653+
654+
fd_install(fd, file);
655+
return 0;
656+
}
657+
599658
int io_register_zcrx_ifq(struct io_ring_ctx *ctx,
600659
struct io_uring_zcrx_ifq_reg __user *arg)
601660
{
@@ -742,12 +801,7 @@ void io_unregister_zcrx_ifqs(struct io_ring_ctx *ctx)
742801
}
743802
if (!ifq)
744803
break;
745-
746-
if (refcount_dec_and_test(&ifq->user_refs)) {
747-
io_close_queue(ifq);
748-
io_zcrx_scrub(ifq);
749-
}
750-
io_put_zcrx_ifq(ifq);
804+
zcrx_unregister(ifq);
751805
}
752806

753807
xa_destroy(&ctx->zcrx_ctxs);
@@ -1028,6 +1082,8 @@ int io_zcrx_ctrl(struct io_ring_ctx *ctx, void __user *arg, unsigned nr_args)
10281082
switch (ctrl.op) {
10291083
case ZCRX_CTRL_FLUSH_RQ:
10301084
return zcrx_flush_rq(ctx, zcrx, &ctrl);
1085+
case ZCRX_CTRL_EXPORT:
1086+
return zcrx_export(ctx, zcrx, &ctrl, arg);
10311087
}
10321088

10331089
return -EOPNOTSUPP;

0 commit comments

Comments
 (0)