nvme-tcp: fix io_work priority inversion
authorKeith Busch <kbusch@kernel.org>
Thu, 9 Sep 2021 15:54:52 +0000 (08:54 -0700)
committerChristoph Hellwig <hch@lst.de>
Tue, 14 Sep 2021 08:32:05 +0000 (10:32 +0200)
commit70f437fb4395ad4d1d16fab9a1ad9fbc9fc0579b
tree08033cf92886114b9b9cbffc632c2cc0a2d6fddd
parent9817d763dbe15327b9b3ff4404fa6f27f927e744
nvme-tcp: fix io_work priority inversion

Dispatching requests inline with the .queue_rq() call may block while
holding the send_mutex. If the tcp io_work also happens to schedule, it
may see the req_list is non-empty, leaving "pending" true and remaining
in TASK_RUNNING. Since io_work is of higher scheduling priority, the
.queue_rq task may not get a chance to run, blocking forward progress
and leading to io timeouts.

Instead of checking for pending requests within io_work, let the queueing
restart io_work outside the send_mutex lock if there is more work to be
done.

Fixes: a0fdd1418007f ("nvme-tcp: rerun io_work if req_list is not empty")
Reported-by: Samuel Jones <sjones@kalrayinc.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/host/tcp.c