scsi: LUN reset waits for completion of all prior tasks

IO submissions to backends have to complete first in LUN reset.
Previous patch makes the waiting time limited.

LUN reset don't use timeout for now because even if LUN reset reports
timeout, error handling of the initiator will be escalated and the
initiator will issue stronger command and will wait eventually
until all outstanding tasks completed.

Besides, not using timeout in LUN reset will make implementation simple.

If timeout becomes necessary, I'll do it in the separate patch later.

Change-Id: Ie9e4502068c19b1727ea65dc773ddf08cedec7c4
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/434766
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Shuhei Matsumoto 2018-11-29 10:23:07 +09:00 committed by Ben Walker
parent b409bf4080
commit d0e3f624f0
3 changed files with 39 additions and 9 deletions

View File

@ -61,19 +61,37 @@ spdk_scsi_lun_complete_mgmt_task(struct spdk_scsi_lun *lun, struct spdk_scsi_tas
spdk_scsi_lun_execute_mgmt_task(lun);
}
/* This will be called in the callback to the bdev reset function. */
static bool
spdk_scsi_lun_has_outstanding_tasks(struct spdk_scsi_lun *lun)
{
return !TAILQ_EMPTY(&lun->tasks);
}
/* Reset task have to wait until all prior outstanding tasks complete. */
static int
spdk_scsi_lun_reset_check_outstanding_tasks(void *arg)
{
struct spdk_scsi_task *task = (struct spdk_scsi_task *)arg;
struct spdk_scsi_lun *lun = task->lun;
if (spdk_scsi_lun_has_outstanding_tasks(lun)) {
return 0;
}
spdk_poller_unregister(&lun->reset_poller);
spdk_scsi_lun_complete_mgmt_task(lun, task);
return 1;
}
void
spdk_scsi_lun_complete_reset_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)
{
if (task->status == SPDK_SCSI_STATUS_GOOD) {
/*
* The backend LUN device was just reset. If there are active tasks
* in the backend, it means that LUN reset fails, and we set failure
* status to LUN reset task.
*/
if (spdk_scsi_lun_has_pending_tasks(lun)) {
SPDK_ERRLOG("lun->tasks should be empty after reset\n");
task->response = SPDK_SCSI_TASK_MGMT_RESP_TARGET_FAILURE;
if (spdk_scsi_lun_has_outstanding_tasks(lun)) {
lun->reset_poller =
spdk_poller_register(spdk_scsi_lun_reset_check_outstanding_tasks,
task, 10);
return;
}
}

View File

@ -127,6 +127,8 @@ struct spdk_scsi_lun {
/** pending management tasks */
TAILQ_HEAD(pending_mgmt_tasks, spdk_scsi_task) pending_mgmt_tasks;
/** poller to check completion of tasks prior to reset */
struct spdk_poller *reset_poller;
};
struct spdk_lun_db_entry {

View File

@ -77,6 +77,16 @@ void _spdk_trace_record(uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id,
{
}
uint64_t spdk_get_ticks(void)
{
return 0;
}
uint64_t spdk_get_ticks_hz(void)
{
return 0;
}
static void
spdk_lun_ut_cpl_task(struct spdk_scsi_task *task)
{