From 6c131d0c583cd5ceb2b497ae2dbeeae180d3573d Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Thu, 6 Jun 2013 01:44:48 -0700 Subject: vhost/scsi: Drop unnecessary wait_for_tasks=true usage with transport_generic_free_cmd This patch changes vhost_scsi_free_cmd() to call transport_generic_free_cmd() with wait_for_tasks=false in order to avoid the extra se_cmd->t_state_lock access for the wait_for_tasks=true case. This is unnecessary because vhost_scsi_free_cmd() is only ever called by vhost_scsi_complete_cmd_work() after TCM completion handoff, and by vhost_scsi_handle_vq() exception code before TCM submission handoff, so there is never a case where se_cmd is still active from TCM's perspective when transport_generic_free_cmd() is called. Cc: Christoph Hellwig Cc: Roland Dreier Cc: Kent Overstreet Cc: Asias He Cc: Michael S. Tsirkin Cc: Or Gerlitz Cc: Moussa Ba Signed-off-by: Nicholas Bellinger --- drivers/vhost/scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/vhost/scsi.c') diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 701420297225..aacf71ea001e 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -557,7 +557,7 @@ static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd) struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; /* TODO locking against target/backend threads? */ - transport_generic_free_cmd(se_cmd, 1); + transport_generic_free_cmd(se_cmd, 0); if (tv_cmd->tvc_sgl_count) { u32 i; -- cgit v1.2.3 From 084ed45b3846ffb803a6cd6d631c1723e77689e0 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Thu, 6 Jun 2013 02:20:41 -0700 Subject: vhost/scsi: Convert to se_cmd->cmd_kref TARGET_SCF_ACK_KREF usage This patch coverts vhost/scsi to se_cmd->cmd_kref TARGET_SCF_ACK_KREF usage, instead of assuming that vhost_scsi_free_cmd() is always called before TCM processing is completed in the response fast path. This includes adding vhost_scsi_check_stop_free() -> target_put_sess_cmd() to perform the second se_cmd->cmd_kref put, and moving vhost_scsi_free_cmd() resource release into tcm_vhost_release_cmd() that is invoked once the last se_cmd->cmd_kref put occurs. Cc: Christoph Hellwig Cc: Roland Dreier Cc: Kent Overstreet Cc: Asias He Cc: Michael S. Tsirkin Cc: Or Gerlitz Cc: Moussa Ba Signed-off-by: Nicholas Bellinger --- drivers/vhost/scsi.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'drivers/vhost/scsi.c') diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index aacf71ea001e..1e5e82042f84 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -446,7 +446,19 @@ static u32 tcm_vhost_tpg_get_inst_index(struct se_portal_group *se_tpg) static void tcm_vhost_release_cmd(struct se_cmd *se_cmd) { - return; + struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, + struct tcm_vhost_cmd, tvc_se_cmd); + + if (tv_cmd->tvc_sgl_count) { + u32 i; + for (i = 0; i < tv_cmd->tvc_sgl_count; i++) + put_page(sg_page(&tv_cmd->tvc_sgl[i])); + + kfree(tv_cmd->tvc_sgl); + } + + tcm_vhost_put_inflight(tv_cmd->inflight); + kfree(tv_cmd); } static int tcm_vhost_shutdown_session(struct se_session *se_sess) @@ -559,17 +571,11 @@ static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd) /* TODO locking against target/backend threads? */ transport_generic_free_cmd(se_cmd, 0); - if (tv_cmd->tvc_sgl_count) { - u32 i; - for (i = 0; i < tv_cmd->tvc_sgl_count; i++) - put_page(sg_page(&tv_cmd->tvc_sgl[i])); - - kfree(tv_cmd->tvc_sgl); - } - - tcm_vhost_put_inflight(tv_cmd->inflight); +} - kfree(tv_cmd); +static int vhost_scsi_check_stop_free(struct se_cmd *se_cmd) +{ + return target_put_sess_cmd(se_cmd->se_sess, se_cmd); } static void tcm_vhost_do_evt_work(struct vhost_scsi *vs, @@ -847,7 +853,7 @@ static void tcm_vhost_submission_work(struct work_struct *work) tv_cmd->tvc_cdb, &tv_cmd->tvc_sense_buf[0], tv_cmd->tvc_lun, tv_cmd->tvc_exp_data_len, tv_cmd->tvc_task_attr, tv_cmd->tvc_data_direction, - 0, sg_ptr, tv_cmd->tvc_sgl_count, + TARGET_SCF_ACK_KREF, sg_ptr, tv_cmd->tvc_sgl_count, sg_bidi_ptr, sg_no_bidi); if (rc < 0) { transport_send_check_condition_and_sense(se_cmd, @@ -2008,6 +2014,7 @@ static struct target_core_fabric_ops tcm_vhost_ops = { .tpg_release_fabric_acl = tcm_vhost_release_fabric_acl, .tpg_get_inst_index = tcm_vhost_tpg_get_inst_index, .release_cmd = tcm_vhost_release_cmd, + .check_stop_free = vhost_scsi_check_stop_free, .shutdown_session = tcm_vhost_shutdown_session, .close_session = tcm_vhost_close_session, .sess_get_index = tcm_vhost_sess_get_index, -- cgit v1.2.3 From b79fafac70fc9bbe640b8193ed772eb850efdfe6 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Wed, 3 Jul 2013 11:22:17 -0400 Subject: target: make queue_tm_rsp() return void The return value wasn't checked by any of the callers. Assuming this is correct behaviour, we can simplify some code by not bothering to generate it. nab: Add srpt_queue_data_in() + srpt_queue_tm_rsp() nops around srpt_queue_response() void return Signed-off-by: Joern Engel Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/srpt/ib_srpt.c | 27 +++++++++++++++++---------- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 4 +--- drivers/target/iscsi/iscsi_target_configfs.c | 3 +-- drivers/target/loopback/tcm_loop.c | 3 +-- drivers/target/sbp/sbp_target.c | 3 +-- drivers/target/tcm_fc/tcm_fc.h | 2 +- drivers/target/tcm_fc/tfc_cmd.c | 5 ++--- drivers/usb/gadget/tcm_usb_gadget.c | 3 +-- drivers/vhost/scsi.c | 4 ++-- include/target/target_core_fabric.h | 2 +- 10 files changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers/vhost/scsi.c') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 3f3f0416fbdd..653ac6bfc57a 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3011,7 +3011,7 @@ static u8 tcm_to_srp_tsk_mgmt_status(const int tcm_mgmt_status) * Callback function called by the TCM core. Must not block since it can be * invoked on the context of the IB completion handler. */ -static int srpt_queue_response(struct se_cmd *cmd) +static void srpt_queue_response(struct se_cmd *cmd) { struct srpt_rdma_ch *ch; struct srpt_send_ioctx *ioctx; @@ -3022,8 +3022,6 @@ static int srpt_queue_response(struct se_cmd *cmd) int resp_len; u8 srp_tm_status; - ret = 0; - ioctx = container_of(cmd, struct srpt_send_ioctx, cmd); ch = ioctx->ch; BUG_ON(!ch); @@ -3049,7 +3047,7 @@ static int srpt_queue_response(struct se_cmd *cmd) || WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) { atomic_inc(&ch->req_lim_delta); srpt_abort_cmd(ioctx); - goto out; + return; } dir = ioctx->cmd.data_direction; @@ -3061,7 +3059,7 @@ static int srpt_queue_response(struct se_cmd *cmd) if (ret) { printk(KERN_ERR "xfer_data failed for tag %llu\n", ioctx->tag); - goto out; + return; } } @@ -3082,9 +3080,17 @@ static int srpt_queue_response(struct se_cmd *cmd) srpt_set_cmd_state(ioctx, SRPT_STATE_DONE); target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd); } +} -out: - return ret; +static int srpt_queue_data_in(struct se_cmd *cmd) +{ + srpt_queue_response(cmd); + return 0; +} + +static void srpt_queue_tm_rsp(struct se_cmd *cmd) +{ + srpt_queue_response(cmd); } static int srpt_queue_status(struct se_cmd *cmd) @@ -3097,7 +3103,8 @@ static int srpt_queue_status(struct se_cmd *cmd) (SCF_TRANSPORT_TASK_SENSE | SCF_EMULATED_TASK_SENSE)) WARN_ON(cmd->scsi_status != SAM_STAT_CHECK_CONDITION); ioctx->queue_status_only = true; - return srpt_queue_response(cmd); + srpt_queue_response(cmd); + return 0; } static void srpt_refresh_port_work(struct work_struct *work) @@ -3930,9 +3937,9 @@ static struct target_core_fabric_ops srpt_template = { .set_default_node_attributes = srpt_set_default_node_attrs, .get_task_tag = srpt_get_task_tag, .get_cmd_state = srpt_get_tcm_cmd_state, - .queue_data_in = srpt_queue_response, + .queue_data_in = srpt_queue_data_in, .queue_status = srpt_queue_status, - .queue_tm_rsp = srpt_queue_response, + .queue_tm_rsp = srpt_queue_tm_rsp, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index bb7eb909f0b1..75caa39b807d 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -699,7 +699,7 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) return qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status); } -static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) +static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) { struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd, @@ -731,8 +731,6 @@ static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) * CTIO response packet. */ qlt_xmit_tm_rsp(mcmd); - - return 0; } /* Local pointer to allocated TCM configfs fabric module */ diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 684d73fcbedf..7d4e19f39fe6 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1790,13 +1790,12 @@ static int lio_queue_status(struct se_cmd *se_cmd) return 0; } -static int lio_queue_tm_rsp(struct se_cmd *se_cmd) +static void lio_queue_tm_rsp(struct se_cmd *se_cmd) { struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); cmd->i_state = ISTATE_SEND_TASKMGTRSP; iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); - return 0; } static char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg) diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 7c908141cc8a..568ad25f25d3 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -786,7 +786,7 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd) return 0; } -static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) +static void tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) { struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; struct tcm_loop_tmr *tl_tmr = se_tmr->fabric_tmr_ptr; @@ -796,7 +796,6 @@ static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd) */ atomic_set(&tl_tmr->tmr_complete, 1); wake_up(&tl_tmr->tl_tmr_wait); - return 0; } static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba) diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index d3536f57444f..e51b09a04d52 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1842,9 +1842,8 @@ static int sbp_queue_status(struct se_cmd *se_cmd) return sbp_send_sense(req); } -static int sbp_queue_tm_rsp(struct se_cmd *se_cmd) +static void sbp_queue_tm_rsp(struct se_cmd *se_cmd) { - return 0; } static int sbp_check_stop_free(struct se_cmd *se_cmd) diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h index eea69358ced3..0dd54a44abcf 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h @@ -161,7 +161,7 @@ int ft_write_pending(struct se_cmd *); int ft_write_pending_status(struct se_cmd *); u32 ft_get_task_tag(struct se_cmd *); int ft_get_cmd_state(struct se_cmd *); -int ft_queue_tm_resp(struct se_cmd *); +void ft_queue_tm_resp(struct se_cmd *); /* * other internal functions. diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 7b6bb72fa475..0e5a1caed176 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -394,14 +394,14 @@ static void ft_send_tm(struct ft_cmd *cmd) /* * Send status from completed task management request. */ -int ft_queue_tm_resp(struct se_cmd *se_cmd) +void ft_queue_tm_resp(struct se_cmd *se_cmd) { struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd); struct se_tmr_req *tmr = se_cmd->se_tmr_req; enum fcp_resp_rsp_codes code; if (cmd->aborted) - return 0; + return; switch (tmr->response) { case TMR_FUNCTION_COMPLETE: code = FCP_TMF_CMPL; @@ -421,7 +421,6 @@ int ft_queue_tm_resp(struct se_cmd *se_cmd) pr_debug("tmr fn %d resp %d fcp code %d\n", tmr->function, tmr->response, code); ft_send_resp_code(cmd, code); - return 0; } static void ft_send_work(struct work_struct *work); diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 7cacd6ae818e..0ff33396eef3 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1467,9 +1467,8 @@ static int usbg_get_cmd_state(struct se_cmd *se_cmd) return 0; } -static int usbg_queue_tm_rsp(struct se_cmd *se_cmd) +static void usbg_queue_tm_rsp(struct se_cmd *se_cmd) { - return 0; } static const char *usbg_check_wwn(const char *name) diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 1e5e82042f84..b35193807f0b 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -528,9 +528,9 @@ static int tcm_vhost_queue_status(struct se_cmd *se_cmd) return 0; } -static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) +static void tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) { - return 0; + return; } static void tcm_vhost_free_evt(struct vhost_scsi *vs, struct tcm_vhost_evt *evt) diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 1dcce9cc99b9..7a16178424f9 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -61,7 +61,7 @@ struct target_core_fabric_ops { int (*get_cmd_state)(struct se_cmd *); int (*queue_data_in)(struct se_cmd *); int (*queue_status)(struct se_cmd *); - int (*queue_tm_rsp)(struct se_cmd *); + void (*queue_tm_rsp)(struct se_cmd *); /* * fabric module calls for target_core_fabric_configfs.c */ -- cgit v1.2.3