From 6e77b0b68d29e4e5f23805bb0f66fab78b686c77 Mon Sep 17 00:00:00 2001 From: Darek Stojaczyk Date: Tue, 30 Jul 2019 11:23:06 +0200 Subject: [PATCH] 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: Darek Stojaczyk Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/466733 Tested-by: SPDK CI Jenkins Reviewed-by: Vitaliy Mysak Reviewed-by: Jim Harris Reviewed-by: Changpeng Liu --- lib/vhost/vhost.c | 18 +++++++++--------- lib/vhost/vhost_blk.c | 11 ++--------- lib/vhost/vhost_nvme.c | 11 ++--------- lib/vhost/vhost_scsi.c | 2 -- 4 files changed, 13 insertions(+), 29 deletions(-) diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index acde6c8a5..415d532fe 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -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--; } diff --git a/lib/vhost/vhost_blk.c b/lib/vhost/vhost_blk.c index 13a51e1ab..7e5b377af 100644 --- a/lib/vhost/vhost_blk.c +++ b/lib/vhost/vhost_blk.c @@ -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, - 3, "start session"); - - if (rc != 0) { - vhost_put_poll_group(pg); - } - - return rc; + return vhost_session_send_event(pg, vsession, vhost_blk_start_cb, + 3, "start session"); } static int diff --git a/lib/vhost/vhost_nvme.c b/lib/vhost/vhost_nvme.c index 0da4079a1..de07ad5f6 100644 --- a/lib/vhost/vhost_nvme.c +++ b/lib/vhost/vhost_nvme.c @@ -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, - 3, "start session"); - - if (rc != 0) { - vhost_put_poll_group(pg); - } - - return rc; + return vhost_session_send_event(pg, vsession, spdk_vhost_nvme_start_cb, + 3, "start session"); } static void diff --git a/lib/vhost/vhost_scsi.c b/lib/vhost/vhost_scsi.c index 08caaa530..3a0c043ba 100644 --- a/lib/vhost/vhost_scsi.c +++ b/lib/vhost/vhost_scsi.c @@ -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;