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 <dariusz.stojaczyk@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/466733 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Vitaliy Mysak <vitaliy.mysak@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
1eba43239e
commit
6e77b0b68d
@ -890,23 +890,18 @@ vhost_get_poll_group(struct spdk_cpuset *cpumask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(selected_pg != NULL);
|
assert(selected_pg != NULL);
|
||||||
assert(selected_pg->ref < UINT_MAX);
|
|
||||||
selected_pg->ref++;
|
|
||||||
return selected_pg;
|
return selected_pg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
vhost_put_poll_group(struct vhost_poll_group *pg)
|
|
||||||
{
|
|
||||||
assert(pg->ref > 0);
|
|
||||||
pg->ref--;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
vhost_session_start_done(struct spdk_vhost_session *vsession, int response)
|
vhost_session_start_done(struct spdk_vhost_session *vsession, int response)
|
||||||
{
|
{
|
||||||
if (response == 0) {
|
if (response == 0) {
|
||||||
vsession->started = true;
|
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);
|
assert(vsession->vdev->active_session_num < UINT32_MAX);
|
||||||
vsession->vdev->active_session_num++;
|
vsession->vdev->active_session_num++;
|
||||||
}
|
}
|
||||||
@ -920,6 +915,11 @@ vhost_session_stop_done(struct spdk_vhost_session *vsession, int response)
|
|||||||
{
|
{
|
||||||
if (response == 0) {
|
if (response == 0) {
|
||||||
vsession->started = false;
|
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);
|
assert(vsession->vdev->active_session_num > 0);
|
||||||
vsession->vdev->active_session_num--;
|
vsession->vdev->active_session_num--;
|
||||||
}
|
}
|
||||||
|
@ -712,17 +712,10 @@ static int
|
|||||||
vhost_blk_start(struct spdk_vhost_session *vsession)
|
vhost_blk_start(struct spdk_vhost_session *vsession)
|
||||||
{
|
{
|
||||||
struct vhost_poll_group *pg;
|
struct vhost_poll_group *pg;
|
||||||
int rc;
|
|
||||||
|
|
||||||
pg = vhost_get_poll_group(vsession->vdev->cpumask);
|
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");
|
3, "start session");
|
||||||
|
|
||||||
if (rc != 0) {
|
|
||||||
vhost_put_poll_group(pg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1114,7 +1114,6 @@ static int
|
|||||||
spdk_vhost_nvme_start(struct spdk_vhost_session *vsession)
|
spdk_vhost_nvme_start(struct spdk_vhost_session *vsession)
|
||||||
{
|
{
|
||||||
struct vhost_poll_group *pg;
|
struct vhost_poll_group *pg;
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (vsession->vdev->active_session_num > 0) {
|
if (vsession->vdev->active_session_num > 0) {
|
||||||
/* We're trying to start a second session */
|
/* 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);
|
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");
|
3, "start session");
|
||||||
|
|
||||||
if (rc != 0) {
|
|
||||||
vhost_put_poll_group(pg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1358,7 +1358,6 @@ vhost_scsi_start(struct spdk_vhost_session *vsession)
|
|||||||
3, "start session");
|
3, "start session");
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
if (svdev->vdev.active_session_num == 0) {
|
if (svdev->vdev.active_session_num == 0) {
|
||||||
vhost_put_poll_group(svdev->poll_group);
|
|
||||||
svdev->poll_group = NULL;
|
svdev->poll_group = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1459,7 +1458,6 @@ vhost_scsi_stop(struct spdk_vhost_session *vsession)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vsession->vdev->active_session_num == 0) {
|
if (vsession->vdev->active_session_num == 0) {
|
||||||
vhost_put_poll_group(svsession->svdev->poll_group);
|
|
||||||
svsession->svdev->poll_group = NULL;
|
svsession->svdev->poll_group = NULL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user