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:
parent
d55bf60a89
commit
7fcbd0220e
@ -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
|
||||||
|
@ -1246,45 +1246,46 @@ 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;
|
||||||
if (vq->vring.desc == NULL) {
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
task_cnt = vq->vring.size;
|
vq = &vsession->virtqueue[qid];
|
||||||
if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
|
if (vq->vring.desc == NULL) {
|
||||||
/* sanity check */
|
return 0;
|
||||||
SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
|
}
|
||||||
vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
|
|
||||||
free_task_pool(bvsession);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_user_blk_task) * task_cnt,
|
|
||||||
SPDK_CACHE_LINE_SIZE, NULL,
|
|
||||||
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
|
|
||||||
if (vq->tasks == NULL) {
|
|
||||||
SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
|
|
||||||
vsession->name, task_cnt, i);
|
|
||||||
free_task_pool(bvsession);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < task_cnt; j++) {
|
task_cnt = vq->vring.size;
|
||||||
task = &((struct spdk_vhost_user_blk_task *)vq->tasks)[j];
|
if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
|
||||||
task->bvsession = bvsession;
|
/* sanity check */
|
||||||
task->req_idx = j;
|
SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
|
||||||
task->vq = vq;
|
vsession->name, qid, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
|
||||||
}
|
free_task_pool(bvsession);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_user_blk_task) * task_cnt,
|
||||||
|
SPDK_CACHE_LINE_SIZE, NULL,
|
||||||
|
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
|
||||||
|
if (vq->tasks == NULL) {
|
||||||
|
SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
|
||||||
|
vsession->name, task_cnt, qid);
|
||||||
|
free_task_pool(bvsession);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < task_cnt; j++) {
|
||||||
|
task = &((struct spdk_vhost_user_blk_task *)vq->tasks)[j];
|
||||||
|
task->bvsession = bvsession;
|
||||||
|
task->req_idx = j;
|
||||||
|
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 = {
|
||||||
|
@ -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 {
|
||||||
|
@ -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,45 +1309,46 @@ 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;
|
||||||
if (vq->vring.desc == NULL) {
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
task_cnt = vq->vring.size;
|
vq = &vsession->virtqueue[qid];
|
||||||
if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
|
if (vq->vring.desc == NULL) {
|
||||||
/* sanity check */
|
return 0;
|
||||||
SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
|
}
|
||||||
vsession->name, i, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
|
|
||||||
free_task_pool(svsession);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_scsi_task) * task_cnt,
|
|
||||||
SPDK_CACHE_LINE_SIZE, NULL,
|
|
||||||
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
|
|
||||||
if (vq->tasks == NULL) {
|
|
||||||
SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
|
|
||||||
vsession->name, task_cnt, i);
|
|
||||||
free_task_pool(svsession);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < task_cnt; j++) {
|
task_cnt = vq->vring.size;
|
||||||
task = &((struct spdk_vhost_scsi_task *)vq->tasks)[j];
|
if (task_cnt > SPDK_VHOST_MAX_VQ_SIZE) {
|
||||||
task->svsession = svsession;
|
/* sanity check */
|
||||||
task->vq = vq;
|
SPDK_ERRLOG("%s: virtqueue %"PRIu16" is too big. (size = %"PRIu32", max = %"PRIu32")\n",
|
||||||
task->req_idx = j;
|
vsession->name, qid, task_cnt, SPDK_VHOST_MAX_VQ_SIZE);
|
||||||
}
|
free_task_pool(svsession);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_scsi_task) * task_cnt,
|
||||||
|
SPDK_CACHE_LINE_SIZE, NULL,
|
||||||
|
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
|
||||||
|
if (vq->tasks == NULL) {
|
||||||
|
SPDK_ERRLOG("%s: failed to allocate %"PRIu32" tasks for virtqueue %"PRIu16"\n",
|
||||||
|
vsession->name, task_cnt, qid);
|
||||||
|
free_task_pool(svsession);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < task_cnt; j++) {
|
||||||
|
task = &((struct spdk_vhost_scsi_task *)vq->tasks)[j];
|
||||||
|
task->svsession = svsession;
|
||||||
|
task->vq = vq;
|
||||||
|
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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user