Re: [PATCH] scsi: target: Remove tcm_loop target reset handling

Hannes Reinecke <[email protected]> Mon, 1 Jun 2026 08:14:39 +0200
Newsgroups org.kernel.vger.target-devel,org.kernel.vger.linux-scsi
Message-ID <[email protected]>
On 5/30/26 07:23, Mike Christie wrote:
> 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: 1333eee56cdf ("scsi: target: tcm_loop: Drain commands in target_reset handler")
> Signed-off-by: Mike Christie <[email protected]>
> ---
>   drivers/target/loopback/tcm_loop.c | 64 ------------------------------
>   1 file changed, 64 deletions(-)
> 
> diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
> index 110297345751..d29830b951f7 100644
> --- a/drivers/target/loopback/tcm_loop.c
> +++ b/drivers/target/loopback/tcm_loop.c
> @@ -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,

Reviewed-by: Hannes Reinecke <[email protected]>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                  Kernel Storage Architect
[email protected]                               +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich