Skip to content

Commit 25e1f67

Browse files
sagigrimbergChristoph Hellwig
authored andcommitted
nvme-tcp: fix H2CData PDU send accounting (again)
We should not access request members after the last send, even to determine if indeed it was the last data payload send. The reason is that a completion could have arrived and trigger a new execution of the request which overridden these members. This was fixed by commit 825619b ("nvme-tcp: fix possible use-after-completion"). Commit e371af0 broke that assumption again to address cases where multiple r2t pdus are sent per request. To fix it, we need to record the request data_sent and data_len and after the payload network send we reference these counters to determine weather we should advance the request iterator. Fixes: e371af0 ("nvme-tcp: fix incorrect h2cdata pdu offset accounting") Reported-by: Keith Busch <[email protected]> Cc: [email protected] # 5.10+ Signed-off-by: Sagi Grimberg <[email protected]> Reviewed-by: Keith Busch <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 926245c commit 25e1f67

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

drivers/nvme/host/tcp.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,12 +926,14 @@ static void nvme_tcp_fail_request(struct nvme_tcp_request *req)
926926
static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
927927
{
928928
struct nvme_tcp_queue *queue = req->queue;
929+
int req_data_len = req->data_len;
929930

930931
while (true) {
931932
struct page *page = nvme_tcp_req_cur_page(req);
932933
size_t offset = nvme_tcp_req_cur_offset(req);
933934
size_t len = nvme_tcp_req_cur_length(req);
934935
bool last = nvme_tcp_pdu_last_send(req, len);
936+
int req_data_sent = req->data_sent;
935937
int ret, flags = MSG_DONTWAIT;
936938

937939
if (last && !queue->data_digest && !nvme_tcp_queue_more(queue))
@@ -958,7 +960,7 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
958960
* in the request where we don't want to modify it as we may
959961
* compete with the RX path completing the request.
960962
*/
961-
if (req->data_sent + ret < req->data_len)
963+
if (req_data_sent + ret < req_data_len)
962964
nvme_tcp_advance_req(req, ret);
963965

964966
/* fully successful last send in current PDU */

0 commit comments

Comments
 (0)