diff options
author | Bart Van Assche <bart.vanassche@sandisk.com> | 2017-05-24 02:48:42 +0300 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2017-07-07 09:11:25 +0300 |
commit | 4c1f0e65397f4e5768b955c32489d5b4b6b92a90 (patch) | |
tree | 3253af4701f701b736e5b784bc4eb91d8ee5127f /drivers/target/loopback | |
parent | 75f141aaf48e13812b4fee914a66f6fce28b543f (diff) | |
download | linux-4c1f0e65397f4e5768b955c32489d5b4b6b92a90.tar.xz |
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: Bart 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: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/loopback')
-rw-r--r-- | drivers/target/loopback/tcm_loop.c | 25 |
1 files changed, 9 insertions, 16 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 8cf556b4c5ca..b6a913e38b30 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -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) { - /* - * 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; + return transport_generic_free_cmd(se_cmd, 0); } 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, se_sess = tl_tpg->tl_nexus->se_sess; 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) goto release; wait_for_completion(&tl_cmd->tmr_done); ret = se_cmd->se_tmr_req->response; + target_put_sess_cmd(se_cmd); + +out: + return ret; release: if (se_cmd) - transport_generic_free_cmd(se_cmd, 1); + transport_generic_free_cmd(se_cmd, 0); else kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); - return ret; + goto out; } static int tcm_loop_abort_task(struct scsi_cmnd *sc) |