vhost_scsi: removed deferred tasks
Removed deferred tasks and dynamic memory management in task processing in vhost_scsi. Each vhost task will now have it's own iovec array Change-Id: Ie51a2404e9cd3c4e03bcea5a8d5b16498dd4d093 Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com> Reviewed-on: https://review.gerrithub.io/363342 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
aff7e226f7
commit
bfd1361714
@ -47,18 +47,11 @@
|
||||
typeof(((type *)0)->member) *__mptr = (ptr); \
|
||||
(type *)((char *)__mptr - offsetof(type, member)); })
|
||||
|
||||
typedef TAILQ_HEAD(, spdk_vhost_task) need_iovecs_tailq_t;
|
||||
|
||||
static struct rte_mempool *g_task_pool;
|
||||
static struct rte_mempool *g_iov_buffer_pool;
|
||||
|
||||
static need_iovecs_tailq_t g_need_iovecs[RTE_MAX_LCORE];
|
||||
|
||||
void
|
||||
spdk_vhost_task_put(struct spdk_vhost_task *task)
|
||||
{
|
||||
assert(&task->scsi.iov == task->scsi.iovs);
|
||||
assert(task->scsi.iovcnt == 1);
|
||||
spdk_scsi_task_put(&task->scsi);
|
||||
}
|
||||
|
||||
@ -91,44 +84,6 @@ spdk_vhost_task_get(struct spdk_vhost_scsi_dev *vdev)
|
||||
return task;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_vhost_enqueue_task(struct spdk_vhost_task *task)
|
||||
{
|
||||
need_iovecs_tailq_t *tailq = &g_need_iovecs[rte_lcore_id()];
|
||||
|
||||
TAILQ_INSERT_TAIL(tailq, task, iovecs_link);
|
||||
}
|
||||
|
||||
struct spdk_vhost_task *
|
||||
spdk_vhost_dequeue_task(void)
|
||||
{
|
||||
need_iovecs_tailq_t *tailq = &g_need_iovecs[rte_lcore_id()];
|
||||
struct spdk_vhost_task *task;
|
||||
|
||||
if (TAILQ_EMPTY(tailq))
|
||||
return NULL;
|
||||
|
||||
task = TAILQ_FIRST(tailq);
|
||||
TAILQ_REMOVE(tailq, task, iovecs_link);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
struct iovec *
|
||||
spdk_vhost_iovec_alloc(void)
|
||||
{
|
||||
struct iovec *iov = NULL;
|
||||
|
||||
rte_mempool_get(g_iov_buffer_pool, (void **)&iov);
|
||||
return iov;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_vhost_iovec_free(struct iovec *iov)
|
||||
{
|
||||
rte_mempool_put(g_iov_buffer_pool, iov);
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_vhost_subsystem_init(void)
|
||||
{
|
||||
@ -139,23 +94,8 @@ spdk_vhost_subsystem_init(void)
|
||||
if (!g_task_pool) {
|
||||
SPDK_ERRLOG("create task pool failed\n");
|
||||
rc = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
g_iov_buffer_pool = rte_mempool_create("vhost iov buffer pool", 2048,
|
||||
VHOST_SCSI_IOVS_LEN * sizeof(struct iovec),
|
||||
128, 0, NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
|
||||
if (!g_iov_buffer_pool) {
|
||||
SPDK_ERRLOG("create iov buffer pool failed\n");
|
||||
rc = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (int i = 0; i < RTE_MAX_LCORE; i++) {
|
||||
TAILQ_INIT(&g_need_iovecs[i]);
|
||||
}
|
||||
|
||||
end:
|
||||
spdk_subsystem_init_next(rc);
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ struct spdk_vhost_dev;
|
||||
|
||||
struct spdk_vhost_task {
|
||||
struct spdk_scsi_task scsi;
|
||||
struct iovec iovs[VHOST_SCSI_IOVS_LEN];
|
||||
|
||||
union {
|
||||
struct virtio_scsi_cmd_resp *resp;
|
||||
@ -55,20 +56,12 @@ struct spdk_vhost_task {
|
||||
int req_idx;
|
||||
|
||||
struct rte_vhost_vring *vq;
|
||||
|
||||
TAILQ_ENTRY(spdk_vhost_task) iovecs_link;
|
||||
};
|
||||
|
||||
void spdk_vhost_enqueue_task(struct spdk_vhost_task *task);
|
||||
struct spdk_vhost_task *spdk_vhost_dequeue_task(void);
|
||||
|
||||
void spdk_vhost_task_put(struct spdk_vhost_task *task);
|
||||
struct spdk_vhost_task *spdk_vhost_task_get(struct spdk_vhost_scsi_dev *vdev);
|
||||
|
||||
void spdk_vhost_dev_task_ref(struct spdk_vhost_dev *vdev);
|
||||
void spdk_vhost_dev_task_unref(struct spdk_vhost_dev *vdev);
|
||||
|
||||
void spdk_vhost_iovec_free(struct iovec *iov);
|
||||
struct iovec *spdk_vhost_iovec_alloc(void);
|
||||
|
||||
#endif /* SPDK_VHOST_TASK_H */
|
||||
|
@ -99,46 +99,11 @@ static void invalid_request(struct spdk_vhost_task *task);
|
||||
static void
|
||||
submit_completion(struct spdk_vhost_task *task)
|
||||
{
|
||||
struct iovec *iovs = NULL;
|
||||
int result;
|
||||
|
||||
spdk_vhost_vq_used_ring_enqueue(&task->svdev->vdev, task->vq, task->req_idx,
|
||||
task->scsi.data_transferred);
|
||||
SPDK_TRACELOG(SPDK_TRACE_VHOST, "Finished task (%p) req_idx=%d\n", task, task->req_idx);
|
||||
|
||||
if (task->scsi.iovs != &task->scsi.iov) {
|
||||
iovs = task->scsi.iovs;
|
||||
task->scsi.iovs = &task->scsi.iov;
|
||||
task->scsi.iovcnt = 1;
|
||||
}
|
||||
|
||||
spdk_vhost_task_put(task);
|
||||
|
||||
if (!iovs) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
task = spdk_vhost_dequeue_task();
|
||||
if (!task) {
|
||||
spdk_vhost_iovec_free(iovs);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set iovs so underlying functions will not try to alloc IOV */
|
||||
task->scsi.iovs = iovs;
|
||||
task->scsi.iovcnt = VHOST_SCSI_IOVS_LEN;
|
||||
|
||||
result = process_request(task);
|
||||
if (result == 0) {
|
||||
task_submit(task);
|
||||
break;
|
||||
} else {
|
||||
task->scsi.iovs = &task->scsi.iov;
|
||||
task->scsi.iovcnt = 1;
|
||||
invalid_request(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -308,12 +273,10 @@ task_data_setup(struct spdk_vhost_task *task,
|
||||
struct rte_vhost_vring *vq = task->vq;
|
||||
struct spdk_vhost_dev *vdev = &task->svdev->vdev;
|
||||
struct vring_desc *desc = spdk_vhost_vq_get_desc(task->vq, task->req_idx);
|
||||
struct iovec *iovs = task->scsi.iovs;
|
||||
uint16_t iovcnt = 0, iovcnt_max = task->scsi.iovcnt;
|
||||
struct iovec *iovs = task->iovs;
|
||||
uint16_t iovcnt = 0, iovcnt_max = VHOST_SCSI_IOVS_LEN;
|
||||
uint32_t len = 0;
|
||||
|
||||
assert(iovcnt_max == 1 || iovcnt_max == VHOST_SCSI_IOVS_LEN);
|
||||
|
||||
/* Sanity check. First descriptor must be readable and must have next one. */
|
||||
if (unlikely(spdk_vhost_vring_desc_is_wr(desc) || !spdk_vhost_vring_desc_has_next(desc))) {
|
||||
SPDK_WARNLOG("Invalid first (request) descriptor.\n");
|
||||
@ -326,6 +289,7 @@ task_data_setup(struct spdk_vhost_task *task,
|
||||
desc = spdk_vhost_vring_desc_get_next(vq->desc, desc);
|
||||
task->scsi.dxfer_dir = spdk_vhost_vring_desc_is_wr(desc) ? SPDK_SCSI_DIR_FROM_DEV :
|
||||
SPDK_SCSI_DIR_TO_DEV;
|
||||
task->scsi.iovs = iovs;
|
||||
|
||||
if (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV) {
|
||||
/*
|
||||
@ -347,14 +311,6 @@ task_data_setup(struct spdk_vhost_task *task,
|
||||
}
|
||||
|
||||
desc = spdk_vhost_vring_desc_get_next(vq->desc, desc);
|
||||
if (iovcnt_max != VHOST_SCSI_IOVS_LEN && spdk_vhost_vring_desc_has_next(desc)) {
|
||||
iovs = spdk_vhost_iovec_alloc();
|
||||
if (iovs == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
iovcnt_max = VHOST_SCSI_IOVS_LEN;
|
||||
}
|
||||
|
||||
/* All remaining descriptors are data. */
|
||||
while (iovcnt < iovcnt_max) {
|
||||
@ -379,19 +335,6 @@ task_data_setup(struct spdk_vhost_task *task,
|
||||
* No need to check descriptor WR flag as this is done while setting scsi.dxfer_dir.
|
||||
*/
|
||||
|
||||
if (iovcnt_max != VHOST_SCSI_IOVS_LEN && spdk_vhost_vring_desc_has_next(desc)) {
|
||||
/* If next descriptor is not for response, allocate iovs. */
|
||||
if (!spdk_vhost_vring_desc_is_wr(spdk_vhost_vring_desc_get_next(vq->desc, desc))) {
|
||||
iovs = spdk_vhost_iovec_alloc();
|
||||
|
||||
if (iovs == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
iovcnt_max = VHOST_SCSI_IOVS_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process descriptors up to response. */
|
||||
while (!spdk_vhost_vring_desc_is_wr(desc) && iovcnt < iovcnt_max) {
|
||||
spdk_vhost_vring_desc_to_iov(vdev, &iovs[iovcnt], desc);
|
||||
@ -413,22 +356,17 @@ task_data_setup(struct spdk_vhost_task *task,
|
||||
}
|
||||
}
|
||||
|
||||
if (iovcnt_max > 1 && iovcnt == iovcnt_max) {
|
||||
if (iovcnt == iovcnt_max) {
|
||||
SPDK_WARNLOG("Too many IO vectors in chain!\n");
|
||||
goto abort_task;
|
||||
}
|
||||
|
||||
task->scsi.iovs = iovs;
|
||||
task->scsi.iovcnt = iovcnt;
|
||||
task->scsi.length = len;
|
||||
task->scsi.transfer_len = len;
|
||||
return 0;
|
||||
|
||||
abort_task:
|
||||
if (iovs != task->scsi.iovs) {
|
||||
spdk_vhost_iovec_free(iovs);
|
||||
}
|
||||
|
||||
if (task->resp) {
|
||||
task->resp->response = VIRTIO_SCSI_S_ABORTED;
|
||||
}
|
||||
@ -496,9 +434,6 @@ process_requestq(struct spdk_vhost_scsi_dev *svdev, struct rte_vhost_vring *vq)
|
||||
task_submit(task);
|
||||
SPDK_TRACELOG(SPDK_TRACE_VHOST, "====== Task %p req_idx %d submitted ======\n", task,
|
||||
task->req_idx);
|
||||
} else if (result > 0) {
|
||||
spdk_vhost_enqueue_task(task);
|
||||
SPDK_TRACELOG(SPDK_TRACE_VHOST, "====== Task %p req_idx %d deferred ======\n", task, task->req_idx);
|
||||
} else {
|
||||
invalid_request(task);
|
||||
SPDK_TRACELOG(SPDK_TRACE_VHOST, "====== Task %p req_idx %d failed ======\n", task, task->req_idx);
|
||||
|
Loading…
Reference in New Issue
Block a user