From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> This patch pushes the main process context I/O execution into qla_target.c qla_tgt_do_work() and splits up interrupt context se_cmd initialization into tgt_ops->init_cmd() from I/O dispatch in tgt_ops->handle_cmd(). The latter will run in process context in qla_tgt_do_work() for qla_tgt->qla_tgt_wq without reacquire of qla_hw_data->hardware_lock Cc: Christoph Hellwig <hch@xxxxxx> Cc: Roland Dreier <roland@xxxxxxxxxxxxxxx> Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx> --- drivers/scsi/qla2xxx/qla_target.c | 38 +++++++++++++++++--- drivers/scsi/qla2xxx/qla_target.h | 3 +- drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c | 1 + drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c | 23 ++++--------- drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h | 3 +- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index c71cb8c..e2164bf 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -3017,7 +3017,7 @@ static inline int qla_tgt_get_fcp_task_attr(uint8_t task_codes) /* ha->hardware_lock supposed to be held on entry */ /* This functions sends the ISP 2xxx command to the tcm_qla2xxx target */ -static int qla_tgt_2xxx_send_cmd(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) +static int qla_tgt_2xxx_init_cmd(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) { atio_from_isp_t *atio = &cmd->atio; uint32_t data_length; @@ -3045,13 +3045,13 @@ static int qla_tgt_2xxx_send_cmd(struct scsi_qla_host *vha, struct qla_tgt_cmd * ql_dbg(ql_dbg_tgt_pkt, vha, 0xe207, "qla_target: START q2x command: %p" " lun: 0x%04x (tag %d)\n", cmd, lun, cmd->tag); - return vha->hw->tgt_ops->handle_cmd(vha, cmd, data_length, + return vha->hw->tgt_ops->init_cmd(vha, cmd, data_length, fcp_task_attr, data_dir, bidi); } /* ha->hardware_lock supposed to be held on entry */ /* This function sends the ISP 24xx command to the tcm_qla2xxx target */ -static int qla_tgt_24xx_send_cmd(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) +static int qla_tgt_24xx_init_cmd(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) { atio_from_isp_t *atio = &cmd->atio; uint32_t data_length; @@ -3078,24 +3078,50 @@ static int qla_tgt_24xx_send_cmd(struct scsi_qla_host *vha, struct qla_tgt_cmd * ql_dbg(ql_dbg_tgt_pkt, vha, 0xe208, "qla_target: START q24 Command %p" " unpacked_lun: 0x%08x (tag %d)\n", cmd, cmd->unpacked_lun, cmd->tag); - return vha->hw->tgt_ops->handle_cmd(vha, cmd, data_length, + return vha->hw->tgt_ops->init_cmd(vha, cmd, data_length, fcp_task_attr, data_dir, bidi); } +/* + * Process context for I/O path into tcm_qla2xxx code + */ +static void qla_tgt_do_work(struct work_struct *work) +{ + struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); + scsi_qla_host_t *vha = cmd->vha; + struct qla_hw_data *ha = vha->hw; + unsigned char *cdb; + atio_from_isp_t *atio = &cmd->atio; + + if (IS_FWI2_CAPABLE(ha)) + cdb = &atio->u.isp24.fcp_cmnd.cdb[0]; + else + cdb = &atio->u.isp2x.cdb[0]; + + vha->hw->tgt_ops->handle_cmd(cmd, cdb); +} + /* ha->hardware_lock supposed to be held on entry */ static int qla_tgt_send_cmd_to_target(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd, struct qla_tgt_sess *sess) { struct qla_hw_data *ha = vha->hw; + int ret = 0; cmd->sess = sess; cmd->loop_id = sess->loop_id; cmd->conf_compl_supported = sess->conf_compl_supported; if (IS_FWI2_CAPABLE(ha)) - return qla_tgt_24xx_send_cmd(vha, cmd); + ret = qla_tgt_24xx_init_cmd(vha, cmd); else - return qla_tgt_2xxx_send_cmd(vha, cmd); + ret = qla_tgt_2xxx_init_cmd(vha, cmd); + + if (!ret) { + INIT_WORK(&cmd->work, qla_tgt_do_work); + queue_work(cmd->tgt->qla_tgt_wq, &cmd->work); + } + return ret; } /* ha->hardware_lock supposed to be held on entry */ diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 92796bc..22d9bc0 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -720,8 +720,9 @@ struct qla_tgt_sess; */ struct qla_tgt_func_tmpl { - int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, + int (*init_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, uint32_t, int, int, int); + int (*handle_cmd)(struct qla_tgt_cmd *, unsigned char *); int (*handle_data)(struct qla_tgt_cmd *); int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t); void (*free_cmd)(struct qla_tgt_cmd *); diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c index f4ee520..5f9b5a5 100644 --- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c +++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_configfs.c @@ -851,6 +851,7 @@ static int tcm_qla2xxx_check_initiator_node_acl( * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. */ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { + .init_cmd = tcm_qla2xxx_init_cmd, .handle_cmd = tcm_qla2xxx_handle_cmd, .handle_data = tcm_qla2xxx_handle_data, .handle_tmr = tcm_qla2xxx_handle_tmr, diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c index cbe1320..b4fbc73 100644 --- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c +++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.c @@ -659,13 +659,12 @@ int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd) return 0; } -static void tcm_qla2xxx_do_work(struct work_struct *); - /* * Main entry point for incoming ATIO packets from qla_target.c - * and qla2xxx LLD code. Called with qla_hw_data->hardware_lock held + * and qla2xxx LLD code. Called with qla_hw_data->hardware_lock to + * setup qla_tgt_cmd->se_cmd */ -int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, +int tcm_qla2xxx_init_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, uint32_t data_length, int fcp_task_attr, int data_dir, int bidi) { @@ -703,25 +702,17 @@ int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, if (bidi) se_cmd->t_tasks_bidi = 1; - INIT_WORK(&cmd->work, tcm_qla2xxx_do_work); - queue_work(cmd->tgt->qla_tgt_wq, &cmd->work); return 0; } -void tcm_qla2xxx_do_work(struct work_struct *work) +/* + * Called from process context in qla_target.c:qla_tgt_do_work() code + */ +void tcm_qla2xxx_handle_cmd(struct qla_tgt_cmd *cmd, unsigned char *cdb) { - struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); struct se_cmd *se_cmd = &cmd->se_cmd; scsi_qla_host_t *vha = cmd->vha; - struct qla_hw_data *ha = vha->hw; - unsigned char *cdb; - atio_from_isp_t *atio = &cmd->atio; int rc; - - if (IS_FWI2_CAPABLE(ha)) - cdb = &atio->u.isp24.fcp_cmnd.cdb[0]; - else - cdb = &atio->u.isp2x.cdb[0]; /* * Locate se_lun pointer and attach it to struct se_cmd */ diff --git a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h index ea1f5fb..48e9b8b 100644 --- a/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h +++ b/drivers/target/tcm_qla2xxx/tcm_qla2xxx_fabric.h @@ -39,8 +39,9 @@ extern int tcm_qla2xxx_write_pending_status(struct se_cmd *); extern void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *); extern u32 tcm_qla2xxx_get_task_tag(struct se_cmd *); extern int tcm_qla2xxx_get_cmd_state(struct se_cmd *); -extern int tcm_qla2xxx_handle_cmd(struct scsi_qla_host *, struct qla_tgt_cmd *, +extern int tcm_qla2xxx_init_cmd(struct scsi_qla_host *, struct qla_tgt_cmd *, uint32_t, int, int, int); +extern void tcm_qla2xxx_handle_cmd(struct qla_tgt_cmd *, unsigned char *); extern int tcm_qla2xxx_new_cmd_map(struct se_cmd *); extern int tcm_qla2xxx_handle_data(struct qla_tgt_cmd *); extern int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t); -- 1.7.2.5 -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html