mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
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: 7481fd93fa ("io_uring: Introduce IORING_OP_BIND")
Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
f44d38a31f
commit
ccd25890f7
|
|
@ -4,6 +4,7 @@
|
|||
#include <linux/file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/un.h>
|
||||
#include <linux/compat.h>
|
||||
#include <net/compat.h>
|
||||
#include <linux/io_uring.h>
|
||||
|
|
@ -1799,11 +1800,29 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
|
|||
return IOU_COMPLETE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if bind request would potentially end up with filename_create(),
|
||||
* which in turn end up in mnt_want_write() which will grab the fs
|
||||
* percpu start write sem. This can trigger a lockdep warning.
|
||||
*/
|
||||
static int io_bind_file_create(const struct io_async_msghdr *io, int addr_len)
|
||||
{
|
||||
const struct sockaddr_un *sun;
|
||||
|
||||
if (io->addr.ss_family != AF_UNIX)
|
||||
return 0;
|
||||
if (addr_len <= offsetof(struct sockaddr_un, sun_path))
|
||||
return 0;
|
||||
sun = (const struct sockaddr_un *) &io->addr;
|
||||
return sun->sun_path[0] != '\0';
|
||||
}
|
||||
|
||||
int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
{
|
||||
struct io_bind *bind = io_kiocb_to_cmd(req, struct io_bind);
|
||||
struct sockaddr __user *uaddr;
|
||||
struct io_async_msghdr *io;
|
||||
int ret;
|
||||
|
||||
if (sqe->len || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in)
|
||||
return -EINVAL;
|
||||
|
|
@ -1814,7 +1833,12 @@ int io_bind_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
|||
io = io_msg_alloc_async(req);
|
||||
if (unlikely(!io))
|
||||
return -ENOMEM;
|
||||
return move_addr_to_kernel(uaddr, bind->addr_len, &io->addr);
|
||||
ret = move_addr_to_kernel(uaddr, bind->addr_len, &io->addr);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
if (io_bind_file_create(io, bind->addr_len))
|
||||
req->flags |= REQ_F_FORCE_ASYNC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int io_bind(struct io_kiocb *req, unsigned int issue_flags)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user