Commit 9ad2046a authored by Alexey Marchuk's avatar Alexey Marchuk Committed by Tomasz Zawadzki
Browse files

nvme: Update spdk_nvme_wait_for_completion_timeout error handling



Update error handling of spdk_nvme_wait_for_completion_timeout to
differentiate cases when request is completed (possibly with error)
or polling was aborted by timeout or transport/device error
The function returns 0 on success, -ECANCELED if transport/device
error occurred or operation timed out and -EIO if the
request is completed with error

Change-Id: I314f40d1acaa6cfa9b88e5417b1ee2c9801bbbd6
Signed-off-by: default avatarAlexey Marchuk <alexeymar@mellanox.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/481528


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 39965ab0
Loading
Loading
Loading
Loading
+26 −5
Original line number Diff line number Diff line
/*-
 *   BSD LICENSE
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *   Copyright (c) Intel Corporation. All rights reserved.
 *   Copyright (c) 2020 Mellanox Technologies LTD. All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
@@ -143,12 +143,27 @@ spdk_nvme_wait_for_completion(struct spdk_nvme_qpair *qpair,
	return spdk_nvme_wait_for_completion_robust_lock(qpair, status, NULL);
}

/**
 * Poll qpair for completions until a command completes.
 *
 * \param qpair queue to poll
 * \param status completion status
 * \param timeout_in_secs optional timeout
 *
 * \return 0 if command completed without error,
 * -EIO if command completed with error,
 * -ECANCELED if command is not completed due to transport/device error or time expired
 *
 * The command to wait upon must be submitted with nvme_completion_poll_cb as the callback
 * and status as the callback argument.
 */
int
spdk_nvme_wait_for_completion_timeout(struct spdk_nvme_qpair *qpair,
				      struct nvme_completion_poll_status *status,
				      uint64_t timeout_in_secs)
{
	uint64_t timeout_tsc = 0;
	int rc = 0;

	memset(&status->cpl, 0, sizeof(status->cpl));
	status->done = false;
@@ -157,14 +172,20 @@ spdk_nvme_wait_for_completion_timeout(struct spdk_nvme_qpair *qpair,
	}

	while (status->done == false) {
		spdk_nvme_qpair_process_completions(qpair, 0);
		rc = spdk_nvme_qpair_process_completions(qpair, 0);

		if (rc < 0) {
			status->cpl.status.sct = SPDK_NVME_SCT_GENERIC;
			status->cpl.status.sc = SPDK_NVME_SC_ABORTED_SQ_DELETION;
			break;
		}
		if (timeout_tsc && spdk_get_ticks() > timeout_tsc) {
			break;
		}
	}

	if (status->done == false) {
		return -EIO;
	if (status->done == false || rc < 0) {
		return -ECANCELED;
	}

	return spdk_nvme_cpl_is_error(&status->cpl) ? -EIO : 0;
+19 −5
Original line number Diff line number Diff line
/*-
 *   BSD LICENSE
 *
 *   Copyright (c) Intel Corporation.
 *   All rights reserved.
 *   Copyright (c) Intel Corporation. All rights reserved.
 *   Copyright (c) 2020 Mellanox Technologies LTD. All rights reserved.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
@@ -1210,14 +1210,16 @@ test_nvme_request_check_timeout(void)

struct nvme_completion_poll_status g_status;
uint64_t completion_delay, timeout_in_secs;
int g_process_comp_result;

int
spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions)
{
	spdk_delay_us(completion_delay * spdk_get_ticks_hz());

	g_status.done = completion_delay < timeout_in_secs ? true : false;
	g_status.done = completion_delay < timeout_in_secs && g_process_comp_result == 0 ? true : false;

	return 0;
	return g_process_comp_result;
}

static void
@@ -1235,7 +1237,19 @@ test_nvme_wait_for_completion(void)
	g_status.done = true;
	rc = spdk_nvme_wait_for_completion_timeout(&qpair, &g_status, timeout_in_secs);
	CU_ASSERT(g_status.done == false);
	CU_ASSERT(rc == -EIO);
	CU_ASSERT(rc == -ECANCELED);

	/* spdk_nvme_qpair_process_completions returns error */
	g_process_comp_result = -1;
	completion_delay = 1;
	timeout_in_secs = 2;
	rc = spdk_nvme_wait_for_completion_timeout(&qpair, &g_status, timeout_in_secs);
	CU_ASSERT(rc == -ECANCELED);
	CU_ASSERT(g_status.done == false);
	CU_ASSERT(g_status.cpl.status.sct == SPDK_NVME_SCT_GENERIC);
	CU_ASSERT(g_status.cpl.status.sc == SPDK_NVME_SC_ABORTED_SQ_DELETION);

	g_process_comp_result = 0;

	/* complete in time */
	completion_delay = 1;