diff --git a/lib/scsi/dev.c b/lib/scsi/dev.c index 424902f57..c7bbbfae0 100644 --- a/lib/scsi/dev.c +++ b/lib/scsi/dev.c @@ -262,7 +262,8 @@ spdk_scsi_dev_queue_task(struct spdk_scsi_dev *dev, { assert(task != NULL); - spdk_scsi_lun_execute_task(task->lun, task); + spdk_scsi_lun_append_task(task->lun, task); + spdk_scsi_lun_execute_tasks(task->lun); } static struct spdk_scsi_port * diff --git a/lib/scsi/lun.c b/lib/scsi/lun.c index d88409baf..fbd36b202 100644 --- a/lib/scsi/lun.c +++ b/lib/scsi/lun.c @@ -38,6 +38,7 @@ #include "spdk/thread.h" #include "spdk/event.h" #include "spdk/util.h" +#include "spdk/likely.h" void spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) @@ -131,7 +132,9 @@ spdk_scsi_lun_execute_mgmt_task(struct spdk_scsi_lun *lun) } task = TAILQ_FIRST(&lun->pending_mgmt_tasks); - if (task == NULL) { + if (spdk_likely(task == NULL)) { + /* Try to execute all pending tasks */ + spdk_scsi_lun_execute_tasks(lun); return; } TAILQ_REMOVE(&lun->pending_mgmt_tasks, task, scsi_link); @@ -176,8 +179,8 @@ spdk_scsi_task_process_null_lun(struct spdk_scsi_task *task) } } -void -spdk_scsi_lun_execute_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) +static void +_spdk_scsi_lun_execute_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) { int rc; @@ -207,6 +210,29 @@ spdk_scsi_lun_execute_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *tas } } +void +spdk_scsi_lun_append_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) +{ + TAILQ_INSERT_TAIL(&lun->pending_tasks, task, scsi_link); +} + +void +spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun) +{ + struct spdk_scsi_task *task, *task_tmp; + + if (spdk_scsi_lun_has_pending_mgmt_tasks(lun)) { + /* Pending IO tasks will wait for completion of existing mgmt tasks. + */ + return; + } + + TAILQ_FOREACH_SAFE(task, &lun->pending_tasks, scsi_link, task_tmp) { + TAILQ_REMOVE(&lun->pending_tasks, task, scsi_link); + _spdk_scsi_lun_execute_task(lun, task); + } +} + static void spdk_scsi_lun_remove(struct spdk_scsi_lun *lun) { @@ -344,6 +370,7 @@ spdk_scsi_lun_construct(struct spdk_bdev *bdev, } TAILQ_INIT(&lun->tasks); + TAILQ_INIT(&lun->pending_tasks); TAILQ_INIT(&lun->mgmt_tasks); TAILQ_INIT(&lun->pending_mgmt_tasks); @@ -476,10 +503,12 @@ spdk_scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun) !TAILQ_EMPTY(&lun->mgmt_tasks); } +/* This check includes both pending and submitted (outstanding) tasks. */ bool spdk_scsi_lun_has_pending_tasks(const struct spdk_scsi_lun *lun) { - return !TAILQ_EMPTY(&lun->tasks); + return !TAILQ_EMPTY(&lun->pending_tasks) || + !TAILQ_EMPTY(&lun->tasks); } bool diff --git a/lib/scsi/scsi_internal.h b/lib/scsi/scsi_internal.h index eecd7db65..4beb705b7 100644 --- a/lib/scsi/scsi_internal.h +++ b/lib/scsi/scsi_internal.h @@ -115,9 +115,12 @@ struct spdk_scsi_lun { /** List of open descriptors for this LUN. */ TAILQ_HEAD(, spdk_scsi_desc) open_descs; - /** pending tasks */ + /** submitted tasks */ TAILQ_HEAD(tasks, spdk_scsi_task) tasks; + /** pending tasks */ + TAILQ_HEAD(pending_tasks, spdk_scsi_task) pending_tasks; + /** submitted management tasks */ TAILQ_HEAD(mgmt_tasks, spdk_scsi_task) mgmt_tasks; @@ -143,7 +146,8 @@ _spdk_scsi_lun *spdk_scsi_lun_construct(struct spdk_bdev *bdev, void *hotremove_ctx); void spdk_scsi_lun_destruct(struct spdk_scsi_lun *lun); -void spdk_scsi_lun_execute_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); +void spdk_scsi_lun_append_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); +void spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun); void spdk_scsi_lun_append_mgmt_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task); void spdk_scsi_lun_execute_mgmt_task(struct spdk_scsi_lun *lun); bool spdk_scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun); diff --git a/test/unit/lib/scsi/dev.c/dev_ut.c b/test/unit/lib/scsi/dev.c/dev_ut.c index 21fb50533..859667d28 100644 --- a/test/unit/lib/scsi/dev.c/dev_ut.c +++ b/test/unit/lib/scsi/dev.c/dev_ut.c @@ -128,7 +128,12 @@ spdk_scsi_lun_has_pending_mgmt_tasks(const struct spdk_scsi_lun *lun) } void -spdk_scsi_lun_execute_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) +spdk_scsi_lun_append_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task) +{ +} + +void +spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun) { } diff --git a/test/unit/lib/scsi/lun.c/lun_ut.c b/test/unit/lib/scsi/lun.c/lun_ut.c index c2698975f..b0e5bb907 100644 --- a/test/unit/lib/scsi/lun.c/lun_ut.c +++ b/test/unit/lib/scsi/lun.c/lun_ut.c @@ -245,7 +245,8 @@ lun_task_mgmt_execute_abort_task_not_supported(void) task.lun = lun; task.cdb = cdb; - spdk_scsi_lun_execute_task(lun, &task); + spdk_scsi_lun_append_task(lun, &task); + spdk_scsi_lun_execute_tasks(lun); /* task should now be on the tasks list */ CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); @@ -289,7 +290,8 @@ lun_task_mgmt_execute_abort_task_all_not_supported(void) task.lun = lun; task.cdb = cdb; - spdk_scsi_lun_execute_task(lun, &task); + spdk_scsi_lun_append_task(lun, &task); + spdk_scsi_lun_execute_tasks(lun); /* task should now be on the tasks list */ CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); @@ -453,7 +455,8 @@ lun_execute_scsi_task_pending(void) */ CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); - spdk_scsi_lun_execute_task(lun, &task); + spdk_scsi_lun_append_task(lun, &task); + spdk_scsi_lun_execute_tasks(lun); /* Assert the task has been successfully added to the tasks queue */ CU_ASSERT(!TAILQ_EMPTY(&lun->tasks)); @@ -490,7 +493,8 @@ lun_execute_scsi_task_complete(void) */ CU_ASSERT(TAILQ_EMPTY(&lun->tasks)); - spdk_scsi_lun_execute_task(lun, &task); + spdk_scsi_lun_append_task(lun, &task); + spdk_scsi_lun_execute_tasks(lun); /* Assert the task has not been added to the tasks queue */ CU_ASSERT(TAILQ_EMPTY(&lun->tasks));