diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index d52d34fe1..943c2b6b3 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -591,7 +591,7 @@ spdk_vhost_session_mem_unregister(struct spdk_vhost_session *vsession) } -static void +void spdk_vhost_free_reactor(uint32_t lcore) { g_num_ctrlrs[lcore]--; @@ -821,7 +821,7 @@ spdk_vhost_dev_get_cpumask(struct spdk_vhost_dev *vdev) return vdev->cpumask; } -static uint32_t +uint32_t spdk_vhost_allocate_reactor(struct spdk_cpuset *cpumask) { uint32_t i, selected_core; @@ -1025,7 +1025,6 @@ stop_device(int vid) spdk_vhost_session_mem_unregister(vsession); free(vsession->mem); - spdk_vhost_free_reactor(vsession->lcore); vsession->lcore = -1; assert(vdev->active_session_num > 0); vdev->active_session_num--; @@ -1101,14 +1100,11 @@ start_device(int vid) } spdk_vhost_session_set_coalescing(vdev, vsession, NULL); - vsession->lcore = spdk_vhost_allocate_reactor(vdev->cpumask); spdk_vhost_session_mem_register(vsession); rc = vdev->backend->start_session(vsession); if (rc != 0) { spdk_vhost_session_mem_unregister(vsession); free(vsession->mem); - spdk_vhost_free_reactor(vsession->lcore); - vsession->lcore = -1; goto out; } diff --git a/lib/vhost/vhost_blk.c b/lib/vhost/vhost_blk.c index 5507afa71..f615564e2 100644 --- a/lib/vhost/vhost_blk.c +++ b/lib/vhost/vhost_blk.c @@ -719,8 +719,18 @@ out: static int spdk_vhost_blk_start(struct spdk_vhost_session *vsession) { - return spdk_vhost_session_send_event(vsession, spdk_vhost_blk_start_cb, - 3, "start session"); + int rc; + + vsession->lcore = spdk_vhost_allocate_reactor(vsession->vdev->cpumask); + rc = spdk_vhost_session_send_event(vsession, spdk_vhost_blk_start_cb, + 3, "start session"); + + if (rc != 0) { + spdk_vhost_free_reactor(vsession->lcore); + vsession->lcore = -1; + } + + return rc; } static int @@ -779,8 +789,17 @@ err: static int spdk_vhost_blk_stop(struct spdk_vhost_session *vsession) { - return spdk_vhost_session_send_event(vsession, spdk_vhost_blk_stop_cb, - 3, "stop session"); + int rc; + + rc = spdk_vhost_session_send_event(vsession, spdk_vhost_blk_stop_cb, + 3, "stop session"); + if (rc != 0) { + return rc; + } + + spdk_vhost_free_reactor(vsession->lcore); + vsession->lcore = -1; + return 0; } static void diff --git a/lib/vhost/vhost_internal.h b/lib/vhost/vhost_internal.h index 6ef7acbfb..38adf850d 100644 --- a/lib/vhost/vhost_internal.h +++ b/lib/vhost/vhost_internal.h @@ -343,6 +343,9 @@ int spdk_vhost_session_send_event(struct spdk_vhost_session *vsession, */ void spdk_vhost_session_event_done(void *event_ctx, int response); +void spdk_vhost_free_reactor(uint32_t lcore); +uint32_t spdk_vhost_allocate_reactor(struct spdk_cpuset *cpumask); + void spdk_vhost_lock(void); void spdk_vhost_unlock(void); int spdk_remove_vhost_controller(struct spdk_vhost_dev *vdev); diff --git a/lib/vhost/vhost_nvme.c b/lib/vhost/vhost_nvme.c index 4ee377773..44c407e27 100644 --- a/lib/vhost/vhost_nvme.c +++ b/lib/vhost/vhost_nvme.c @@ -1106,14 +1106,24 @@ spdk_vhost_nvme_start_cb(struct spdk_vhost_dev *vdev, static int spdk_vhost_nvme_start(struct spdk_vhost_session *vsession) { + int rc; + if (vsession->vdev->active_session_num > 0) { /* We're trying to start a second session */ SPDK_ERRLOG("Vhost-NVMe devices can support only one simultaneous connection.\n"); return -1; } - return spdk_vhost_session_send_event(vsession, spdk_vhost_nvme_start_cb, - 3, "start session"); + vsession->lcore = spdk_vhost_allocate_reactor(vsession->vdev->cpumask); + rc = spdk_vhost_session_send_event(vsession, spdk_vhost_nvme_start_cb, + 3, "start session"); + + if (rc != 0) { + spdk_vhost_free_reactor(vsession->lcore); + vsession->lcore = -1; + } + + return rc; } static void @@ -1196,8 +1206,17 @@ spdk_vhost_nvme_stop_cb(struct spdk_vhost_dev *vdev, static int spdk_vhost_nvme_stop(struct spdk_vhost_session *vsession) { - return spdk_vhost_session_send_event(vsession, spdk_vhost_nvme_stop_cb, - 3, "start session"); + int rc; + + rc = spdk_vhost_session_send_event(vsession, spdk_vhost_nvme_stop_cb, + 3, "start session"); + if (rc != 0) { + return rc; + } + + spdk_vhost_free_reactor(vsession->lcore); + vsession->lcore = -1; + return 0; } static void diff --git a/lib/vhost/vhost_scsi.c b/lib/vhost/vhost_scsi.c index e3ca65db5..c4756cf0a 100644 --- a/lib/vhost/vhost_scsi.c +++ b/lib/vhost/vhost_scsi.c @@ -77,6 +77,9 @@ struct spdk_scsi_dev_vhost_state { struct spdk_vhost_scsi_dev { struct spdk_vhost_dev vdev; struct spdk_scsi_dev_vhost_state scsi_dev_state[SPDK_VHOST_SCSI_CTRLR_MAX_DEVS]; + + /* The CPU chosen to poll I/O of all active vhost sessions */ + int32_t lcore; } __rte_cache_aligned; struct spdk_vhost_scsi_session { @@ -1217,14 +1220,7 @@ spdk_vhost_scsi_start_cb(struct spdk_vhost_dev *vdev, int rc; svsession = to_scsi_session(vsession); - if (svsession == NULL) { - SPDK_ERRLOG("Trying to start non-scsi controller as a scsi one.\n"); - rc = -1; - goto out; - } - - svdev = to_scsi_dev(vdev); - svsession->svdev = svdev; + svdev = svsession->svdev; /* validate all I/O queues are in a contiguous index range */ for (i = VIRTIO_SCSI_REQUESTQ; i < vsession->max_queues; i++) { @@ -1266,14 +1262,36 @@ out: static int spdk_vhost_scsi_start(struct spdk_vhost_session *vsession) { - if (vsession->vdev->active_session_num > 0) { - /* We're trying to start a second session */ - SPDK_ERRLOG("Vhost-SCSI devices can support only one simultaneous connection.\n"); + struct spdk_vhost_scsi_session *svsession; + struct spdk_vhost_scsi_dev *svdev; + int rc; + + svsession = to_scsi_session(vsession); + if (svsession == NULL) { + SPDK_ERRLOG("Trying to start non-scsi session as a scsi one.\n"); return -1; } - return spdk_vhost_session_send_event(vsession, spdk_vhost_scsi_start_cb, - 3, "start session"); + svdev = to_scsi_dev(vsession->vdev); + svsession->svdev = svdev; + + if (svdev->vdev.active_session_num == 0) { + svdev->lcore = spdk_vhost_allocate_reactor(svdev->vdev.cpumask); + } + + vsession->lcore = svdev->lcore; + rc = spdk_vhost_session_send_event(vsession, spdk_vhost_scsi_start_cb, + 3, "start session"); + if (rc != 0) { + vsession->lcore = -1; + + if (svdev->vdev.active_session_num == 0) { + spdk_vhost_free_reactor(svdev->lcore); + svdev->lcore = -1; + } + } + + return rc; } static int @@ -1339,8 +1357,22 @@ err: static int spdk_vhost_scsi_stop(struct spdk_vhost_session *vsession) { - return spdk_vhost_session_send_event(vsession, spdk_vhost_scsi_stop_cb, - 3, "stop session"); + struct spdk_vhost_scsi_session *svsession; + int rc; + + svsession = to_scsi_session(vsession); + rc = spdk_vhost_session_send_event(vsession, spdk_vhost_scsi_stop_cb, + 3, "stop session"); + if (rc != 0) { + return rc; + } + + vsession->lcore = -1; + if (vsession->vdev->active_session_num == 1) { + spdk_vhost_free_reactor(svsession->svdev->lcore); + svsession->svdev->lcore = -1; + } + return 0; } static void