Commit 3421c7f6 authored by Ming Lei's avatar Ming Lei Committed by Jens Axboe

ublk: make sure io cmd handled in submitter task context

In well-done ublk server implementation, ublk io command won't be
linked into any link chain. Meantime they are always handled in no-wait
style, so basically io cmd is always handled in submitter task context.

However, the server may set IOSQE_ASYNC, or io command is linked to one
chain mistakenly, then we may still run into io-wq context and
ctx->uring_lock isn't held.

So in case of IO_URING_F_UNLOCKED, schedule this command by
io_uring_cmd_complete_in_task to force running it in submitter task. Then
ublk_ch_uring_cmd_local() is guaranteed to run with context uring_lock held,
and we needn't to worry about sync among submission code path any more.
Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20231009093324.957829-3-ming.lei@redhat.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 8ed90e37
...@@ -1811,7 +1811,8 @@ static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, ...@@ -1811,7 +1811,8 @@ static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub,
return NULL; return NULL;
} }
static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) static inline int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
unsigned int issue_flags)
{ {
/* /*
* Not necessary for async retry, but let's keep it simple and always * Not necessary for async retry, but let's keep it simple and always
...@@ -1825,9 +1826,28 @@ static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) ...@@ -1825,9 +1826,28 @@ static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
.addr = READ_ONCE(ub_src->addr) .addr = READ_ONCE(ub_src->addr)
}; };
WARN_ON_ONCE(issue_flags & IO_URING_F_UNLOCKED);
return __ublk_ch_uring_cmd(cmd, issue_flags, &ub_cmd); return __ublk_ch_uring_cmd(cmd, issue_flags, &ub_cmd);
} }
static void ublk_ch_uring_cmd_cb(struct io_uring_cmd *cmd,
unsigned int issue_flags)
{
ublk_ch_uring_cmd_local(cmd, issue_flags);
}
static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
{
/* well-implemented server won't run into unlocked */
if (unlikely(issue_flags & IO_URING_F_UNLOCKED)) {
io_uring_cmd_complete_in_task(cmd, ublk_ch_uring_cmd_cb);
return -EIOCBQUEUED;
}
return ublk_ch_uring_cmd_local(cmd, issue_flags);
}
static inline bool ublk_check_ubuf_dir(const struct request *req, static inline bool ublk_check_ubuf_dir(const struct request *req,
int ubuf_dir) int ubuf_dir)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment