Commit ba32ee2b authored by Liu Xiaodong's avatar Liu Xiaodong Committed by Jim Harris
Browse files

vhost: set timeout for session's stop_poller



If there is still some inflight IO which prevents
vhost_session_stop_done(), stop_poller can try
within 4 seconds, and then call vhost_session_stop_done
with -ETIMEDOUT.

This can avoid endless blocking in ctrl pthread if there
is no response from vhost session or its backend bdev.
Then spdk vhost target can still serve all other vhost
devices and operations besides the error one.

Change-Id: I2fc78b4da926c936a2e42dc0e66ce1c60001330d
Signed-off-by: default avatarLiu Xiaodong <xiaodong.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10393


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent d39038e1
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -1564,6 +1564,10 @@ vhost_destroy_connection_cb(int vid)

	if (vsession->started) {
		rc = _stop_session(vsession);
		if (rc != 0) {
			pthread_mutex_unlock(&g_vhost_mutex);
			return rc;
		}
	}

	TAILQ_REMOVE(&vsession->vdev->vsessions, vsession, tailq);
@@ -1571,7 +1575,7 @@ vhost_destroy_connection_cb(int vid)
	free(vsession);
	pthread_mutex_unlock(&g_vhost_mutex);

	return rc;
	return 0;
}

void
+11 −4
Original line number Diff line number Diff line
@@ -1346,11 +1346,16 @@ destroy_session_poller_cb(void *arg)
	struct spdk_vhost_session *vsession = &bvsession->vsession;
	int i;

	if (vsession->task_cnt > 0) {
		return SPDK_POLLER_BUSY;
	if (vsession->task_cnt > 0 || spdk_vhost_trylock() != 0) {
		assert(vsession->stop_retry_count > 0);
		vsession->stop_retry_count--;
		if (vsession->stop_retry_count == 0) {
			SPDK_ERRLOG("%s: Timedout when destroy session (task_cnt %d)\n", vsession->name,
				    vsession->task_cnt);
			spdk_poller_unregister(&bvsession->stop_poller);
			vhost_session_stop_done(vsession, -ETIMEDOUT);
		}

	if (spdk_vhost_trylock() != 0) {
		return SPDK_POLLER_BUSY;
	}

@@ -1387,6 +1392,8 @@ vhost_blk_stop_cb(struct spdk_vhost_dev *vdev,
		vhost_blk_session_unregister_interrupts(bvsession);
	}

	/* vhost_session_send_event timeout is 3 seconds, here set retry within 4 seconds */
	bvsession->vsession.stop_retry_count = 4000;
	bvsession->stop_poller = SPDK_POLLER_REGISTER(destroy_session_poller_cb,
				 bvsession, 1000);
	return 0;
+3 −0
Original line number Diff line number Diff line
@@ -166,6 +166,9 @@ struct spdk_vhost_session {
	/* Interval used for event coalescing checking. */
	uint64_t stats_check_interval;

	/* Session's stop poller will only try limited times to destroy the session. */
	uint32_t stop_retry_count;

	struct spdk_vhost_virtqueue virtqueue[SPDK_VHOST_MAX_VQUEUES];

	TAILQ_ENTRY(spdk_vhost_session) tailq;
+12 −4
Original line number Diff line number Diff line
@@ -1443,11 +1443,16 @@ destroy_session_poller_cb(void *arg)
	struct spdk_scsi_dev_session_state *state;
	uint32_t i;

	if (vsession->task_cnt > 0) {
		return SPDK_POLLER_BUSY;
	if (vsession->task_cnt > 0 || spdk_vhost_trylock() != 0) {
		assert(vsession->stop_retry_count > 0);
		vsession->stop_retry_count--;
		if (vsession->stop_retry_count == 0) {
			SPDK_ERRLOG("%s: Timedout when destroy session (task_cnt %d)\n", vsession->name,
				    vsession->task_cnt);
			spdk_poller_unregister(&svsession->stop_poller);
			vhost_session_stop_done(vsession, -ETIMEDOUT);
		}

	if (spdk_vhost_trylock() != 0) {
		return SPDK_POLLER_BUSY;
	}

@@ -1506,6 +1511,9 @@ vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev,
	 */
	spdk_poller_unregister(&svsession->mgmt_poller);

	/* vhost_session_send_event timeout is 3 seconds, here set retry within 4 seconds */
	svsession->vsession.stop_retry_count = 4000;

	/* Wait for all pending I/Os to complete, then process all the
	 * remaining hotremove events one last time.
	 */