Commit 4c1f0e65 authored by Bart Van Assche's avatar Bart Van Assche Committed by Nicholas Bellinger

target/tcm_loop: Make TMF processing slightly faster

Target drivers must guarantee that struct se_cmd and struct se_tmr_req
exist as long as target_tmr_work() is in progress. This is why the
tcm_loop driver today passes 1 as second argument to
transport_generic_free_cmd() from inside the TMF code. Instead of
making the TMF code wait, make the TMF code obtain two references
(SCF_ACK_KREF) and drop one reference from inside the .check_stop_free()
callback.
Signed-off-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: David Disseldorp <ddiss@suse.de>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 75f141aa
...@@ -51,19 +51,7 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd); ...@@ -51,19 +51,7 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd);
*/ */
static int tcm_loop_check_stop_free(struct se_cmd *se_cmd) static int tcm_loop_check_stop_free(struct se_cmd *se_cmd)
{ {
/* return transport_generic_free_cmd(se_cmd, 0);
* Do not release struct se_cmd's containing a valid TMR
* pointer. These will be released directly in tcm_loop_device_reset()
* with transport_generic_free_cmd().
*/
if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
return 0;
/*
* Release the struct se_cmd, which will make a callback to release
* struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd()
*/
transport_generic_free_cmd(se_cmd, 0);
return 1;
} }
static void tcm_loop_release_cmd(struct se_cmd *se_cmd) static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
...@@ -244,18 +232,23 @@ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg, ...@@ -244,18 +232,23 @@ static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
se_sess = tl_tpg->tl_nexus->se_sess; se_sess = tl_tpg->tl_nexus->se_sess;
rc = target_submit_tmr(se_cmd, se_sess, tl_cmd->tl_sense_buf, lun, rc = target_submit_tmr(se_cmd, se_sess, tl_cmd->tl_sense_buf, lun,
NULL, tmr, GFP_KERNEL, task, 0 /*flags*/); NULL, tmr, GFP_KERNEL, task,
TARGET_SCF_ACK_KREF);
if (rc < 0) if (rc < 0)
goto release; goto release;
wait_for_completion(&tl_cmd->tmr_done); wait_for_completion(&tl_cmd->tmr_done);
ret = se_cmd->se_tmr_req->response; ret = se_cmd->se_tmr_req->response;
target_put_sess_cmd(se_cmd);
out:
return ret;
release: release:
if (se_cmd) if (se_cmd)
transport_generic_free_cmd(se_cmd, 1); transport_generic_free_cmd(se_cmd, 0);
else else
kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
return ret; goto out;
} }
static int tcm_loop_abort_task(struct scsi_cmnd *sc) static int tcm_loop_abort_task(struct scsi_cmnd *sc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment