Commit 492b7e93 authored by Sagi Grimberg's avatar Sagi Grimberg Committed by Greg Kroah-Hartman

nvmet-tcp: set MSG_MORE only if we actually have more to send

commit 98fd5c72 upstream.

When we send PDU data, we want to optimize the tcp stack
operation if we have more data to send. So when we set MSG_MORE
- We have more fragments coming in the batch, or
- We have a more data to send in this PDU
- We don't have a data digest trailer
- We optimize with the SUCCESS flag and omit the NVMe completion
  (used if sq_head pointer update is disabled)

This addresses a regression in QD=1 with SUCCESS flag optimization
as we unconditionally set MSG_MORE when we didn't actually have
more data to send.

Fixes: 70583295 ("nvmet-tcp: implement C2HData SUCCESS optimization")
Reported-by: default avatarMark Wunderlich <[email protected]>
Tested-by: default avatarMark Wunderlich <[email protected]>
Signed-off-by: Sagi Grimberg's avatarSagi Grimberg <[email protected]>
Signed-off-by: default avatarKeith Busch <[email protected]>
Signed-off-by: default avatarGreg Kroah-Hartman <[email protected]>
parent 0ba16eaf
......@@ -515,7 +515,7 @@ static int nvmet_try_send_data_pdu(struct nvmet_tcp_cmd *cmd)
return 1;
static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd)
static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd, bool last_in_batch)
struct nvmet_tcp_queue *queue = cmd->queue;
int ret;
......@@ -523,9 +523,15 @@ static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd)
while (cmd->cur_sg) {
struct page *page = sg_page(cmd->cur_sg);
u32 left = cmd->cur_sg->length - cmd->offset;
int flags = MSG_DONTWAIT;
if ((!last_in_batch && cmd->queue->send_list_len) ||
cmd->wbytes_done + left < cmd->req.transfer_len ||
queue->data_digest || !queue->nvme_sq.sqhd_disabled)
flags |= MSG_MORE;
ret = kernel_sendpage(cmd->queue->sock, page, cmd->offset,
left, flags);
if (ret <= 0)
return ret;
......@@ -660,7 +666,7 @@ static int nvmet_tcp_try_send_one(struct nvmet_tcp_queue *queue,
if (cmd->state == NVMET_TCP_SEND_DATA) {
ret = nvmet_try_send_data(cmd);
ret = nvmet_try_send_data(cmd, last_in_batch);
if (ret <= 0)
goto done_send;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment