Commit 6e77b0b6 authored by Darek Stojaczyk's avatar Darek Stojaczyk Committed by Jim Harris
Browse files

vhost: make poll group refcount per-session



Change the way we increase poll group reference counts
for round-robin scheduling.

So far we used to increase them whenever someone called
vhost_get_poll_group() and this worked fine for Vhost-Block
which picks a new poll group for each session. Vhost-SCSI,
however, picks only one poll group for all sessions on
a vhost device. This means that some threads will have
multiple Vhost-SCSI pollers but will still appear to the
vhost scheduler as if they had only one.

To fix it, increase poll group refcnt only when sessions
are really being started - in vhost_session_start_done().

Change-Id: I60f0d2101239e5a91138a5afd30c51dc1ccf7c2e
Signed-off-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/466733


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarVitaliy Mysak <vitaliy.mysak@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent 1eba4323
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -890,23 +890,18 @@ vhost_get_poll_group(struct spdk_cpuset *cpumask)
	}

	assert(selected_pg != NULL);
	assert(selected_pg->ref < UINT_MAX);
	selected_pg->ref++;
	return selected_pg;
}

void
vhost_put_poll_group(struct vhost_poll_group *pg)
{
	assert(pg->ref > 0);
	pg->ref--;
}

void
vhost_session_start_done(struct spdk_vhost_session *vsession, int response)
{
	if (response == 0) {
		vsession->started = true;
		assert(vsession->poll_group != NULL);
		assert(vsession->poll_group->ref < UINT_MAX);
		vsession->poll_group->ref++;

		assert(vsession->vdev->active_session_num < UINT32_MAX);
		vsession->vdev->active_session_num++;
	}
@@ -920,6 +915,11 @@ vhost_session_stop_done(struct spdk_vhost_session *vsession, int response)
{
	if (response == 0) {
		vsession->started = false;
		assert(vsession->poll_group != NULL);
		assert(vsession->poll_group->ref > 0);
		vsession->poll_group->ref--;
		vsession->poll_group = NULL;

		assert(vsession->vdev->active_session_num > 0);
		vsession->vdev->active_session_num--;
	}
+2 −9
Original line number Diff line number Diff line
@@ -712,17 +712,10 @@ static int
vhost_blk_start(struct spdk_vhost_session *vsession)
{
	struct vhost_poll_group *pg;
	int rc;

	pg = vhost_get_poll_group(vsession->vdev->cpumask);
	rc = vhost_session_send_event(pg, vsession, vhost_blk_start_cb,
	return vhost_session_send_event(pg, vsession, vhost_blk_start_cb,
					3, "start session");

	if (rc != 0) {
		vhost_put_poll_group(pg);
	}

	return rc;
}

static int
+2 −9
Original line number Diff line number Diff line
@@ -1114,7 +1114,6 @@ static int
spdk_vhost_nvme_start(struct spdk_vhost_session *vsession)
{
	struct vhost_poll_group *pg;
	int rc;

	if (vsession->vdev->active_session_num > 0) {
		/* We're trying to start a second session */
@@ -1123,14 +1122,8 @@ spdk_vhost_nvme_start(struct spdk_vhost_session *vsession)
	}

	pg = vhost_get_poll_group(vsession->vdev->cpumask);
	rc = vhost_session_send_event(pg, vsession, spdk_vhost_nvme_start_cb,
	return vhost_session_send_event(pg, vsession, spdk_vhost_nvme_start_cb,
					3, "start session");

	if (rc != 0) {
		vhost_put_poll_group(pg);
	}

	return rc;
}

static void
+0 −2
Original line number Diff line number Diff line
@@ -1358,7 +1358,6 @@ vhost_scsi_start(struct spdk_vhost_session *vsession)
				      3, "start session");
	if (rc != 0) {
		if (svdev->vdev.active_session_num == 0) {
			vhost_put_poll_group(svdev->poll_group);
			svdev->poll_group = NULL;
		}
	}
@@ -1459,7 +1458,6 @@ vhost_scsi_stop(struct spdk_vhost_session *vsession)
	}

	if (vsession->vdev->active_session_num == 0) {
		vhost_put_poll_group(svsession->svdev->poll_group);
		svsession->svdev->poll_group = NULL;
	}
	return 0;