Revision 3770a42bb8ceb856877699257a43c0585a5d2996 authored by Sagi Grimberg on 05 September 2022, 15:07:06 UTC, committed by Christoph Hellwig on 06 September 2022, 04:40:44 UTC
When we queue requests, we strive to batch as much as possible and also
signal the network stack that more data is about to be sent over a socket
with MSG_SENDPAGE_NOTLAST. This flag looks at the pending requests queued
as well as queue->more_requests that is derived from the block layer
last-in-batch indication.

We set more_request=true when we flush the request directly from
.queue_rq submission context (in nvme_tcp_send_all), however this is
wrongly assuming that no other requests may be queued during the
execution of nvme_tcp_send_all.

Due to this, a race condition may happen where:

 1. request X is queued as !last-in-batch
 2. request X submission context calls nvme_tcp_send_all directly
 3. nvme_tcp_send_all is preempted and schedules to a different cpu
 4. request Y is queued as last-in-batch
 5. nvme_tcp_send_all context sends request X+Y, however signals for
    both MSG_SENDPAGE_NOTLAST because queue->more_requests=true.

==> none of the requests is pushed down to the wire as the network
stack is waiting for more data, both requests timeout.

To fix this, we eliminate queue->more_requests and only rely on
the queue req_list and send_list to be not-empty.

Fixes: 122e5b9f3d37 ("nvme-tcp: optimize network stack with setting msg flags according to batch size")
Reported-by: Jonathan Nicklin <jnicklin@blockbridge.com>
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Tested-by: Jonathan Nicklin <jnicklin@blockbridge.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent 160f354
History
File Mode Size
Makefile -rw-r--r-- 366 bytes
advise.c -rw-r--r-- 2.1 KB
advise.h -rw-r--r-- 316 bytes
alloc_cache.h -rw-r--r-- 1.1 KB
cancel.c -rw-r--r-- 7.1 KB
cancel.h -rw-r--r-- 579 bytes
epoll.c -rw-r--r-- 1.5 KB
epoll.h -rw-r--r-- 213 bytes
fdinfo.c -rw-r--r-- 6.1 KB
fdinfo.h -rw-r--r-- 100 bytes
filetable.c -rw-r--r-- 4.4 KB
filetable.h -rw-r--r-- 2.5 KB
fs.c -rw-r--r-- 6.4 KB
fs.h -rw-r--r-- 929 bytes
io-wq.c -rw-r--r-- 33.5 KB
io-wq.h -rw-r--r-- 2.0 KB
io_uring.c -rw-r--r-- 100.7 KB
io_uring.h -rw-r--r-- 8.3 KB
kbuf.c -rw-r--r-- 13.1 KB
kbuf.h -rw-r--r-- 3.8 KB
msg_ring.c -rw-r--r-- 4.0 KB
msg_ring.h -rw-r--r-- 178 bytes
net.c -rw-r--r-- 29.6 KB
net.h -rw-r--r-- 2.0 KB
nop.c -rw-r--r-- 498 bytes
nop.h -rw-r--r-- 168 bytes
notif.c -rw-r--r-- 3.9 KB
notif.h -rw-r--r-- 2.2 KB
opdef.c -rw-r--r-- 10.9 KB
opdef.h -rw-r--r-- 1.1 KB
openclose.c -rw-r--r-- 6.0 KB
openclose.h -rw-r--r-- 596 bytes
poll.c -rw-r--r-- 25.5 KB
poll.h -rw-r--r-- 1006 bytes
refs.h -rw-r--r-- 1.2 KB
rsrc.c -rw-r--r-- 32.5 KB
rsrc.h -rw-r--r-- 4.5 KB
rw.c -rw-r--r-- 26.6 KB
rw.h -rw-r--r-- 666 bytes
slist.h -rw-r--r-- 3.0 KB
splice.c -rw-r--r-- 2.8 KB
splice.h -rw-r--r-- 306 bytes
sqpoll.c -rw-r--r-- 9.6 KB
sqpoll.h -rw-r--r-- 753 bytes
statx.c -rw-r--r-- 1.5 KB
statx.h -rw-r--r-- 217 bytes
sync.c -rw-r--r-- 2.6 KB
sync.h -rw-r--r-- 460 bytes
tctx.c -rw-r--r-- 7.4 KB
tctx.h -rw-r--r-- 934 bytes
timeout.c -rw-r--r-- 16.5 KB
timeout.h -rw-r--r-- 1.2 KB
uring_cmd.c -rw-r--r-- 2.7 KB
uring_cmd.h -rw-r--r-- 494 bytes
xattr.c -rw-r--r-- 5.4 KB
xattr.h -rw-r--r-- 654 bytes

back to top