Skip to content

Commit

Permalink
nvmet-tcp: set MSG_MORE only if we actually have more to send
Browse files Browse the repository at this point in the history
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
when:
- 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: 7058329 ("nvmet-tcp: implement C2HData SUCCESS optimization")
Reported-by: Mark Wunderlich <[email protected]>
Tested-by: Mark Wunderlich <[email protected]>
Signed-off-by: Sagi Grimberg <[email protected]>
Signed-off-by: Keith Busch <[email protected]>
  • Loading branch information
sagigrimberg authored and keithbusch committed Mar 20, 2020
1 parent 9134ae2 commit 98fd5c7
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions drivers/nvme/target/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,17 +515,23 @@ 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;

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, MSG_DONTWAIT | MSG_MORE);
left, flags);
if (ret <= 0)
return ret;

Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 98fd5c7

Please sign in to comment.