Skip to content

Commit ccd2589

Browse files
committed
io_uring/net: punt IORING_OP_BIND async if it needs file create
For two reasons: 1) An opcode cannot block inside io_uring_enter() doing submissions, as it'll stall the submission side pipeline. 2) Ending up in sb_start_write() -> __sb_start_write() -> percpu_down_read_freezable() introduces a new lockdep edge, which it correctly complains about. Check if the socket type is AF_UNIX and has a non-empty pathname. If it does, mark it REQ_F_FORCE_ASYNC to punt the submission to io-wq rather than attempt to do it inline. Fixes: 7481fd9 ("io_uring: Introduce IORING_OP_BIND") Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent f44d38a commit ccd2589

1 file changed

Lines changed: 25 additions & 1 deletion

File tree

io_uring/net.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <linux/file.h>
55
#include <linux/slab.h>
66
#include <linux/net.h>
7+
#include <linux/un.h>
78
#include <linux/compat.h>
89
#include <net/compat.h>
910
#include <linux/io_uring.h>
@@ -1799,11 +1800,29 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
17991800
return IOU_COMPLETE;
18001801
}
18011802

1803+
/*
1804+
* Check if bind request would potentially end up with filename_create(),
1805+
* which in turn end up in mnt_want_write() which will grab the fs
1806+
* percpu start write sem. This can trigger a lockdep warning.
1807+
*/
1808+
static int io_bind_file_create(const struct io_async_msghdr *io, int addr_len)
1809+
{
1810+
const struct sockaddr_un *sun;
1811+
1812+
if (io->addr.ss_family != AF_UNIX)
1813+
return 0;
1814+
if (addr_len <= offsetof(struct sockaddr_un, sun_path))
1815+
return 0;
1816+
sun = (const struct sockaddr_un *) &io->addr;
1817+
return sun->sun_path[0] != '\0';
1818+
}
1819+
18021820
int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
18031821
{
18041822
struct io_bind *bind = io_kiocb_to_cmd(req, struct io_bind);
18051823
struct sockaddr __user *uaddr;
18061824
struct io_async_msghdr *io;
1825+
int ret;
18071826

18081827
if (sqe->len || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in)
18091828
return -EINVAL;
@@ -1814,7 +1833,12 @@ int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
18141833
io = io_msg_alloc_async(req);
18151834
if (unlikely(!io))
18161835
return -ENOMEM;
1817-
return move_addr_to_kernel(uaddr, bind->addr_len, &io->addr);
1836+
ret = move_addr_to_kernel(uaddr, bind->addr_len, &io->addr);
1837+
if (unlikely(ret))
1838+
return ret;
1839+
if (io_bind_file_create(io, bind->addr_len))
1840+
req->flags |= REQ_F_FORCE_ASYNC;
1841+
return 0;
18181842
}
18191843

18201844
int io_bind(struct io_kiocb *req, unsigned int issue_flags)

0 commit comments

Comments
 (0)