scsi: target: Remove tcm_loop target reset handling

tcm_loop_target_reset is supposed to handle all the LUNs on a target but
it's only doing a TMR_LUN_RESET so only that one LUN is handled.  This
will cause us to return early while IOs to other LUNs are still hung in
lower layers. This just removes the target reset handler for the driver
because LIO doesn't support target resets and for the common case where
this is run from the scsi-ml error hamdler we have already tried an
abort and lun reset so waiting again is most likely useless.

Fixes: 1333eee56c ("scsi: target: tcm_loop: Drain commands in target_reset handler")
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260530052349.5134-1-michael.christie@oracle.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Mike Christie 2026-05-30 00:23:47 -05:00 committed by Martin K. Petersen
parent fc6f9719e6
commit 7c08d43083

View File

@ -270,69 +270,6 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
}
static bool tcm_loop_flush_work_iter(struct request *rq, void *data)
{
struct scsi_cmnd *sc = blk_mq_rq_to_pdu(rq);
struct tcm_loop_cmd *tl_cmd = scsi_cmd_priv(sc);
struct se_cmd *se_cmd = &tl_cmd->tl_se_cmd;
flush_work(&se_cmd->work);
return true;
}
static int tcm_loop_target_reset(struct scsi_cmnd *sc)
{
struct tcm_loop_hba *tl_hba;
struct tcm_loop_tpg *tl_tpg;
struct Scsi_Host *sh = sc->device->host;
int ret;
/*
* Locate the tcm_loop_hba_t pointer
*/
tl_hba = *(struct tcm_loop_hba **)shost_priv(sh);
if (!tl_hba) {
pr_err("Unable to perform device reset without active I_T Nexus\n");
return FAILED;
}
/*
* Locate the tl_tpg pointer from TargetID in sc->device->id
*/
tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
if (!tl_tpg)
return FAILED;
/*
* Issue a LUN_RESET to drain all commands that the target core
* knows about. This handles commands not yet marked CMD_T_COMPLETE.
*/
ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, 0, TMR_LUN_RESET);
if (ret != TMR_FUNCTION_COMPLETE)
return FAILED;
/*
* Flush any deferred target core completion work that may still be
* queued. Commands that already had CMD_T_COMPLETE set before the TMR
* are skipped by the TMR drain, but their async completion work
* (transport_lun_remove_cmd percpu_ref_put, release_cmd scsi_done)
* may still be pending in target_completion_wq.
*
* The SCSI EH will reuse in-flight scsi_cmnd structures for recovery
* commands (e.g. TUR) immediately after this handler returns SUCCESS
* if deferred work is still pending, the memset in queuecommand would
* zero the se_cmd while the work accesses it, leaking the LUN
* percpu_ref and hanging configfs unlink forever.
*
* Use blk_mq_tagset_busy_iter() to find all started requests and
* flush_work() on each the same pattern used by mpi3mr, scsi_debug,
* and other SCSI drivers to drain outstanding commands during reset.
*/
blk_mq_tagset_busy_iter(&sh->tag_set, tcm_loop_flush_work_iter, NULL);
tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE;
return SUCCESS;
}
static const struct scsi_host_template tcm_loop_driver_template = {
.show_info = tcm_loop_show_info,
.proc_name = "tcm_loopback",
@ -341,7 +278,6 @@ static const struct scsi_host_template tcm_loop_driver_template = {
.change_queue_depth = scsi_change_queue_depth,
.eh_abort_handler = tcm_loop_abort_task,
.eh_device_reset_handler = tcm_loop_device_reset,
.eh_target_reset_handler = tcm_loop_target_reset,
.this_id = -1,
.sg_tablesize = 256,
.max_sectors = 0xFFFF,