nvme/tcp: add max_completion exit condition to loop inside read_pdu

A loop inside 'nvme_tcp_qpair_process_completions' makes
'max_completions' actually behaving like a minimum:
	do {
		rc = nvme_tcp_read_pdu(tqpair, &reaped);
		[...]
	} while (reaped < max_completions);

Before this change 'max_completion' constraint, in its true sense,
was actually not respected and a loop inside 'nvme_tcp_read_pdu'
could be executed indefinitely as long as a recv state changed.

To prevent this behavior, max_completion must be passed to
'nvme_tcp_read_pdu' and used as an additional exit condition.

Signed-off-by: Szulik, Maciej <maciej.szulik@intel.com>
Change-Id: I28da962f4a62f08ddb51915b5d0dae9611a82dee
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15136
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
Szulik, Maciej 2022-10-25 11:02:03 +02:00 committed by Tomasz Zawadzki
parent 497132086b
commit 51ae6d4002

View File

@ -1593,7 +1593,7 @@ nvme_tcp_pdu_psh_handle(struct nvme_tcp_qpair *tqpair, uint32_t *reaped)
}
static int
nvme_tcp_read_pdu(struct nvme_tcp_qpair *tqpair, uint32_t *reaped)
nvme_tcp_read_pdu(struct nvme_tcp_qpair *tqpair, uint32_t *reaped, uint32_t max_completions)
{
int rc = 0;
struct nvme_tcp_pdu *pdu;
@ -1687,7 +1687,7 @@ nvme_tcp_read_pdu(struct nvme_tcp_qpair *tqpair, uint32_t *reaped)
assert(0);
break;
}
} while (prev_state != tqpair->recv_state);
} while (prev_state != tqpair->recv_state && *reaped + tqpair->async_complete < max_completions);
out:
*reaped += tqpair->async_complete;
@ -1763,7 +1763,7 @@ nvme_tcp_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_c
reaped = 0;
do {
rc = nvme_tcp_read_pdu(tqpair, &reaped);
rc = nvme_tcp_read_pdu(tqpair, &reaped, max_completions);
if (rc < 0) {
SPDK_DEBUGLOG(nvme, "Error polling CQ! (%d): %s\n",
errno, spdk_strerror(errno));