Skip to content

Commit ff140cc

Browse files
krismanaxboe
authored andcommitted
io_uring: Introduce IORING_OP_LISTEN
IORING_OP_LISTEN provides the semantic of listen(2) via io_uring. While this is an essentially synchronous system call, the main point is to enable a network path to execute fully with io_uring registered and descriptorless files. Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> Link: https://lore.kernel.org/r/20240614163047.31581-4-krisman@suse.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 7481fd9 commit ff140cc

File tree

4 files changed

+45
-0
lines changed

4 files changed

+45
-0
lines changed

include/uapi/linux/io_uring.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ enum io_uring_op {
258258
IORING_OP_FIXED_FD_INSTALL,
259259
IORING_OP_FTRUNCATE,
260260
IORING_OP_BIND,
261+
IORING_OP_LISTEN,
261262

262263
/* this goes last, obviously */
263264
IORING_OP_LAST,

io_uring/net.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ struct io_bind {
5656
int addr_len;
5757
};
5858

59+
struct io_listen {
60+
struct file *file;
61+
int backlog;
62+
};
63+
5964
struct io_sr_msg {
6065
struct file *file;
6166
union {
@@ -1751,6 +1756,29 @@ int io_bind(struct io_kiocb *req, unsigned int issue_flags)
17511756
return 0;
17521757
}
17531758

1759+
int io_listen_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
1760+
{
1761+
struct io_listen *listen = io_kiocb_to_cmd(req, struct io_listen);
1762+
1763+
if (sqe->addr || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in || sqe->addr2)
1764+
return -EINVAL;
1765+
1766+
listen->backlog = READ_ONCE(sqe->len);
1767+
return 0;
1768+
}
1769+
1770+
int io_listen(struct io_kiocb *req, unsigned int issue_flags)
1771+
{
1772+
struct io_listen *listen = io_kiocb_to_cmd(req, struct io_listen);
1773+
int ret;
1774+
1775+
ret = __sys_listen_socket(sock_from_file(req->file), listen->backlog);
1776+
if (ret < 0)
1777+
req_set_fail(req);
1778+
io_req_set_res(req, ret, 0);
1779+
return 0;
1780+
}
1781+
17541782
void io_netmsg_cache_free(const void *entry)
17551783
{
17561784
struct io_async_msghdr *kmsg = (struct io_async_msghdr *) entry;

io_uring/net.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ void io_send_zc_cleanup(struct io_kiocb *req);
5252
int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
5353
int io_bind(struct io_kiocb *req, unsigned int issue_flags);
5454

55+
int io_listen_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
56+
int io_listen(struct io_kiocb *req, unsigned int issue_flags);
57+
5558
void io_netmsg_cache_free(const void *entry);
5659
#else
5760
static inline void io_netmsg_cache_free(const void *entry)

io_uring/opdef.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,16 @@ const struct io_issue_def io_issue_defs[] = {
503503
.async_size = sizeof(struct io_async_msghdr),
504504
#else
505505
.prep = io_eopnotsupp_prep,
506+
#endif
507+
},
508+
[IORING_OP_LISTEN] = {
509+
#if defined(CONFIG_NET)
510+
.needs_file = 1,
511+
.prep = io_listen_prep,
512+
.issue = io_listen,
513+
.async_size = sizeof(struct io_async_msghdr),
514+
#else
515+
.prep = io_eopnotsupp_prep,
506516
#endif
507517
},
508518
};
@@ -729,6 +739,9 @@ const struct io_cold_def io_cold_defs[] = {
729739
[IORING_OP_BIND] = {
730740
.name = "BIND",
731741
},
742+
[IORING_OP_LISTEN] = {
743+
.name = "LISTEN",
744+
},
732745
};
733746

734747
const char *io_uring_get_opcode(u8 opcode)

0 commit comments

Comments
 (0)