lib/vhost: alloc VQ tasks in VQ setting function

Currently we will allocate all VQ's tasks when starting
the device, it will not allow us to add new VQ after
starting the device, so here, we move it to VQ setting
function.

Change-Id: I59cfc393d66779ab8a0eb704bc73bcede3f0a2a0
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14926
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Changpeng Liu 2022-10-11 17:16:28 +08:00 committed by Tomasz Zawadzki
parent d55bf60a89
commit 7fcbd0220e
4 changed files with 76 additions and 74 deletions

View File

@ -1018,6 +1018,8 @@ enable_device_vq(struct spdk_vhost_session *vsession, uint16_t qid)
{ {
struct spdk_vhost_virtqueue *q; struct spdk_vhost_virtqueue *q;
bool packed_ring; bool packed_ring;
const struct spdk_vhost_user_dev_backend *backend;
int rc;
if (qid >= SPDK_VHOST_MAX_VQUEUES) { if (qid >= SPDK_VHOST_MAX_VQUEUES) {
return -EINVAL; return -EINVAL;
@ -1047,6 +1049,12 @@ enable_device_vq(struct spdk_vhost_session *vsession, uint16_t qid)
return 0; return 0;
} }
backend = to_user_dev(vsession->vdev)->user_backend;
rc = backend->alloc_vq_tasks(vsession, qid);
if (rc) {
return rc;
}
/* /*
* Not sure right now but this look like some kind of QEMU bug and guest IO * Not sure right now but this look like some kind of QEMU bug and guest IO
* might be frozed without kicking all queues after live-migration. This look like * might be frozed without kicking all queues after live-migration. This look like

View File

@ -1246,26 +1246,28 @@ free_task_pool(struct spdk_vhost_blk_session *bvsession)
} }
static int static int
alloc_task_pool(struct spdk_vhost_blk_session *bvsession) alloc_vq_task_pool(struct spdk_vhost_session *vsession, uint16_t qid)
{ {
struct spdk_vhost_session *vsession = &bvsession->vsession; struct spdk_vhost_blk_session *bvsession = to_blk_session(vsession);
struct spdk_vhost_virtqueue *vq; struct spdk_vhost_virtqueue *vq;
struct spdk_vhost_user_blk_task *task; struct spdk_vhost_user_blk_task *task;
uint32_t task_cnt; uint32_t task_cnt;
uint16_t i;
uint32_t j; uint32_t j;
for (i = 0; i < vsession->max_queues; i++) { if (qid >= SPDK_VHOST_MAX_VQUEUES) {
vq = &vsession->virtqueue[i]; return -EINVAL;
}
vq = &vsession->virtqueue[qid];
if (vq->vring.desc == NULL) { if (vq->vring.desc == NULL) {
continue; return 0;
} }
task_cnt = vq->vring.size; task_cnt = vq->vring.size;
if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) { if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
/* sanity check */ /* sanity check */
SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n", SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE); vsession->name, qid, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
free_task_pool(bvsession); free_task_pool(bvsession);
return -1; return -1;
} }
@ -1274,7 +1276,7 @@ alloc_task_pool(struct spdk_vhost_blk_session *bvsession)
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA); SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
if (vq->tasks == NULL) { if (vq->tasks == NULL) {
SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n", SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
vsession->name, task_cnt, i); vsession->name, task_cnt, qid);
free_task_pool(bvsession); free_task_pool(bvsession);
return -1; return -1;
} }
@ -1285,7 +1287,6 @@ alloc_task_pool(struct spdk_vhost_blk_session *bvsession)
task->req_idx = j; task->req_idx = j;
task->vq = vq; task->vq = vq;
} }
}
return 0; return 0;
} }
@ -1313,12 +1314,6 @@ vhost_blk_start(struct spdk_vhost_dev *vdev,
} }
} }
rc = alloc_task_pool(bvsession);
if (rc != 0) {
SPDK_ERRLOG("%s: failed to alloc task pool.\n", vsession->name);
return rc;
}
if (bvdev->bdev) { if (bvdev->bdev) {
bvsession->io_channel = vhost_blk_get_io_channel(vdev); bvsession->io_channel = vhost_blk_get_io_channel(vdev);
if (!bvsession->io_channel) { if (!bvsession->io_channel) {
@ -1544,6 +1539,7 @@ static const struct spdk_vhost_user_dev_backend vhost_blk_user_device_backend =
.session_ctx_size = sizeof(struct spdk_vhost_blk_session) - sizeof(struct spdk_vhost_session), .session_ctx_size = sizeof(struct spdk_vhost_blk_session) - sizeof(struct spdk_vhost_session),
.start_session = vhost_blk_start, .start_session = vhost_blk_start,
.stop_session = vhost_blk_stop, .stop_session = vhost_blk_stop,
.alloc_vq_tasks = alloc_vq_task_pool,
}; };
static const struct spdk_vhost_dev_backend vhost_blk_device_backend = { static const struct spdk_vhost_dev_backend vhost_blk_device_backend = {

View File

@ -219,6 +219,7 @@ struct spdk_vhost_user_dev_backend {
spdk_vhost_session_fn start_session; spdk_vhost_session_fn start_session;
int (*stop_session)(struct spdk_vhost_session *vsession); int (*stop_session)(struct spdk_vhost_session *vsession);
int (*alloc_vq_tasks)(struct spdk_vhost_session *vsession, uint16_t qid);
}; };
enum vhost_backend_type { enum vhost_backend_type {

View File

@ -122,11 +122,13 @@ static void vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev,
static int vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev); static int vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev);
static int vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev, static int vhost_scsi_dev_param_changed(struct spdk_vhost_dev *vdev,
unsigned scsi_tgt_num); unsigned scsi_tgt_num);
static int alloc_vq_task_pool(struct spdk_vhost_session *vsession, uint16_t qid);
static const struct spdk_vhost_user_dev_backend spdk_vhost_scsi_user_device_backend = { static const struct spdk_vhost_user_dev_backend spdk_vhost_scsi_user_device_backend = {
.session_ctx_size = sizeof(struct spdk_vhost_scsi_session) - sizeof(struct spdk_vhost_session), .session_ctx_size = sizeof(struct spdk_vhost_scsi_session) - sizeof(struct spdk_vhost_session),
.start_session = vhost_scsi_start, .start_session = vhost_scsi_start,
.stop_session = vhost_scsi_stop, .stop_session = vhost_scsi_stop,
.alloc_vq_tasks = alloc_vq_task_pool,
}; };
static const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = { static const struct spdk_vhost_dev_backend spdk_vhost_scsi_device_backend = {
@ -1307,26 +1309,28 @@ free_task_pool(struct spdk_vhost_scsi_session *svsession)
} }
static int static int
alloc_task_pool(struct spdk_vhost_scsi_session *svsession) alloc_vq_task_pool(struct spdk_vhost_session *vsession, uint16_t qid)
{ {
struct spdk_vhost_session *vsession = &svsession->vsession; struct spdk_vhost_scsi_session *svsession = to_scsi_session(vsession);
struct spdk_vhost_virtqueue *vq; struct spdk_vhost_virtqueue *vq;
struct spdk_vhost_scsi_task *task; struct spdk_vhost_scsi_task *task;
uint32_t task_cnt; uint32_t task_cnt;
uint16_t i;
uint32_t j; uint32_t j;
for (i = 0; i < vsession->max_queues; i++) { if (qid >= SPDK_VHOST_MAX_VQUEUES) {
vq = &vsession->virtqueue[i]; return -EINVAL;
}
vq = &vsession->virtqueue[qid];
if (vq->vring.desc == NULL) { if (vq->vring.desc == NULL) {
continue; return 0;
} }
task_cnt = vq->vring.size; task_cnt = vq->vring.size;
if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) { if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
/* sanity check */ /* sanity check */
SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n", SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE); vsession->name, qid, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
free_task_pool(svsession); free_task_pool(svsession);
return -1; return -1;
} }
@ -1335,7 +1339,7 @@ alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA); SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
if (vq->tasks == NULL) { if (vq->tasks == NULL) {
SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n", SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
vsession->name, task_cnt, i); vsession->name, task_cnt, qid);
free_task_pool(svsession); free_task_pool(svsession);
return -1; return -1;
} }
@ -1346,7 +1350,6 @@ alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
task->vq = vq; task->vq = vq;
task->req_idx = j; task->req_idx = j;
} }
}
return 0; return 0;
} }
@ -1373,12 +1376,6 @@ vhost_scsi_start(struct spdk_vhost_dev *vdev,
} }
} }
rc = alloc_task_pool(svsession);
if (rc != 0) {
SPDK_ERRLOG("%s: failed to alloc task pool.\n", vsession->name);
return rc;
}
for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) { for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; i++) {
state = &svdev->scsi_dev_state[i]; state = &svdev->scsi_dev_state[i];
if (state->dev == NULL || state->status == VHOST_SCSI_DEV_REMOVING) { if (state->dev == NULL || state->status == VHOST_SCSI_DEV_REMOVING) {