Commit 88655eb2 authored by Changpeng Liu's avatar Changpeng Liu Committed by Konrad Sztyber
Browse files

lib/ublk: wait and retry before starting USER RECOVERY



When there are lots of inflight IOs during user recovery, the kernel
`ublk_drv` driver needs some time to set the device state to
UBLK_S_DEV_QUIESCED, if we start the new spdk_tgt quickly and send
UBLK_CMD_START_USER_RECOVERY command to kernel `ublk_drv` driver during
the transition period, kernel `ublk_drv` driver will return -EBUSY to user,
so add a delay retry here to read device state again.

Change-Id: I07cb92501e07b785a92df20dd6a4622da67372e9
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/23484


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent a1a770d0
Loading
Loading
Loading
Loading
+34 −5
Original line number Diff line number Diff line
@@ -319,6 +319,26 @@ ublk_ctrl_cmd_error(struct spdk_ublk_dev *ublk, int32_t res)
	}
}

static int
_ublk_get_device_state_retry(void *arg)
{
	struct spdk_ublk_dev *ublk = arg;
	int rc;

	spdk_poller_unregister(&ublk->retry_poller);

	rc = ublk_ctrl_cmd_submit(ublk, UBLK_CMD_GET_DEV_INFO);
	if (rc < 0) {
		ublk_delete_dev(ublk);
		if (ublk->ctrl_cb) {
			ublk->ctrl_cb(ublk->cb_arg, rc);
			ublk->ctrl_cb = NULL;
		}
	}

	return SPDK_POLLER_BUSY;
}

static void
ublk_ctrl_process_cqe(struct io_uring_cqe *cqe)
{
@@ -362,6 +382,20 @@ ublk_ctrl_process_cqe(struct io_uring_cqe *cqe)
		ublk_free_dev(ublk);
		break;
	case UBLK_CMD_GET_DEV_INFO:
		if (ublk->ublk_id != ublk->dev_info.dev_id) {
			SPDK_ERRLOG("Invalid ublk ID\n");
			rc = -EINVAL;
			goto cb_done;
		}

		UBLK_DEBUGLOG(ublk, "Ublk %u device state %u\n", ublk->ublk_id, ublk->dev_info.state);
		/* kernel ublk_drv driver returns -EBUSY if device state isn't UBLK_S_DEV_QUIESCED */
		if ((ublk->dev_info.state != UBLK_S_DEV_QUIESCED) && (ublk->retry_count < 3)) {
			ublk->retry_count++;
			ublk->retry_poller = SPDK_POLLER_REGISTER(_ublk_get_device_state_retry, ublk, 1000000);
			return;
		}

		rc = ublk_ctrl_start_recovery(ublk);
		if (rc < 0) {
			ublk_delete_dev(ublk);
@@ -1994,11 +2028,6 @@ ublk_ctrl_start_recovery(struct spdk_ublk_dev *ublk)
	int                     rc;
	uint32_t                i;

	if (ublk->ublk_id != ublk->dev_info.dev_id) {
		SPDK_ERRLOG("Invalid ublk ID\n");
		return -EINVAL;
	}

	ublk->num_queues = ublk->dev_info.nr_hw_queues;
	ublk->queue_depth = ublk->dev_info.queue_depth;
	ublk->dev_info.ublksrv_pid = getpid();