diff options
author | Alexei Potashnik <alexei@purestorage.com> | 2015-07-14 16:00:49 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-07-24 17:19:42 -0400 |
commit | 7359df25a53386dd33c223672bbd12cb49d0ce4f (patch) | |
tree | 1fa5616771e5023696200032b3bb0b5fa5a8af68 | |
parent | e52a8b45b9c782937f74b701f8c656d4e5619eb5 (diff) |
qla2xxx: terminate exchange when command is aborted by LIO
The newly introduced aborted_task TFO callback has to terminate
exchange with QLogic driver, since command is being deleted and
no status will be queued to the driver at a later point.
This patch also moves the burden of releasing one cmd refcount to
the aborted_task handler.
Changed iSCSI aborted_task logic to satisfy the above requirement.
Cc: <stable@vger.kernel.org> # v3.18+
Signed-off-by: Alexei Potashnik <alexei@purestorage.com>
Acked-by: Quinn Tran <quinn.tran@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 35 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.h | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.c | 11 |
3 files changed, 20 insertions, 35 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index b60f9075e9f7..58651ecbd88c 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -1924,20 +1924,6 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd, | |||
1924 | struct qla_hw_data *ha = vha->hw; | 1924 | struct qla_hw_data *ha = vha->hw; |
1925 | struct se_cmd *se_cmd = &cmd->se_cmd; | 1925 | struct se_cmd *se_cmd = &cmd->se_cmd; |
1926 | 1926 | ||
1927 | if (unlikely(cmd->aborted)) { | ||
1928 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014, | ||
1929 | "qla_target(%d): terminating exchange for aborted cmd=%p (se_cmd=%p, tag=%lld)", | ||
1930 | vha->vp_idx, cmd, se_cmd, se_cmd->tag); | ||
1931 | |||
1932 | cmd->state = QLA_TGT_STATE_ABORTED; | ||
1933 | cmd->cmd_flags |= BIT_6; | ||
1934 | |||
1935 | qlt_send_term_exchange(vha, cmd, &cmd->atio, 0); | ||
1936 | |||
1937 | /* !! At this point cmd could be already freed !! */ | ||
1938 | return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED; | ||
1939 | } | ||
1940 | |||
1941 | prm->cmd = cmd; | 1927 | prm->cmd = cmd; |
1942 | prm->tgt = tgt; | 1928 | prm->tgt = tgt; |
1943 | prm->rq_result = scsi_status; | 1929 | prm->rq_result = scsi_status; |
@@ -2524,9 +2510,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
2524 | res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, | 2510 | res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, |
2525 | &full_req_cnt); | 2511 | &full_req_cnt); |
2526 | if (unlikely(res != 0)) { | 2512 | if (unlikely(res != 0)) { |
2527 | if (res == QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED) | ||
2528 | return 0; | ||
2529 | |||
2530 | return res; | 2513 | return res; |
2531 | } | 2514 | } |
2532 | 2515 | ||
@@ -3092,6 +3075,24 @@ static void qlt_chk_exch_leak_thresh_hold(struct scsi_qla_host *vha) | |||
3092 | 3075 | ||
3093 | } | 3076 | } |
3094 | 3077 | ||
3078 | void qlt_abort_cmd(struct qla_tgt_cmd *cmd) | ||
3079 | { | ||
3080 | struct qla_tgt *tgt = cmd->tgt; | ||
3081 | struct scsi_qla_host *vha = tgt->vha; | ||
3082 | struct se_cmd *se_cmd = &cmd->se_cmd; | ||
3083 | |||
3084 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014, | ||
3085 | "qla_target(%d): terminating exchange for aborted cmd=%p " | ||
3086 | "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd, | ||
3087 | se_cmd->tag); | ||
3088 | |||
3089 | cmd->state = QLA_TGT_STATE_ABORTED; | ||
3090 | cmd->cmd_flags |= BIT_6; | ||
3091 | |||
3092 | qlt_send_term_exchange(vha, cmd, &cmd->atio, 0); | ||
3093 | } | ||
3094 | EXPORT_SYMBOL(qlt_abort_cmd); | ||
3095 | |||
3095 | void qlt_free_cmd(struct qla_tgt_cmd *cmd) | 3096 | void qlt_free_cmd(struct qla_tgt_cmd *cmd) |
3096 | { | 3097 | { |
3097 | struct qla_tgt_sess *sess = cmd->sess; | 3098 | struct qla_tgt_sess *sess = cmd->sess; |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 2ceb60ffc5e9..bca584ae45b7 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -808,13 +808,6 @@ int qla2x00_wait_for_hba_online(struct scsi_qla_host *); | |||
808 | #define FC_TM_REJECT 4 | 808 | #define FC_TM_REJECT 4 |
809 | #define FC_TM_FAILED 5 | 809 | #define FC_TM_FAILED 5 |
810 | 810 | ||
811 | /* | ||
812 | * Error code of qlt_pre_xmit_response() meaning that cmd's exchange was | ||
813 | * terminated, so no more actions is needed and success should be returned | ||
814 | * to target. | ||
815 | */ | ||
816 | #define QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED 0x1717 | ||
817 | |||
818 | #if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G) | 811 | #if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G) |
819 | #define pci_dma_lo32(a) (a & 0xffffffff) | 812 | #define pci_dma_lo32(a) (a & 0xffffffff) |
820 | #define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff) | 813 | #define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff) |
@@ -950,7 +943,6 @@ struct qla_tgt_cmd { | |||
950 | unsigned int conf_compl_supported:1; | 943 | unsigned int conf_compl_supported:1; |
951 | unsigned int sg_mapped:1; | 944 | unsigned int sg_mapped:1; |
952 | unsigned int free_sg:1; | 945 | unsigned int free_sg:1; |
953 | unsigned int aborted:1; /* Needed in case of SRR */ | ||
954 | unsigned int write_data_transferred:1; | 946 | unsigned int write_data_transferred:1; |
955 | unsigned int ctx_dsd_alloced:1; | 947 | unsigned int ctx_dsd_alloced:1; |
956 | unsigned int q_full:1; | 948 | unsigned int q_full:1; |
@@ -1134,6 +1126,7 @@ static inline uint32_t sid_to_key(const uint8_t *s_id) | |||
1134 | extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *); | 1126 | extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *); |
1135 | extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); | 1127 | extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); |
1136 | extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); | 1128 | extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); |
1129 | extern void qlt_abort_cmd(struct qla_tgt_cmd *); | ||
1137 | extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); | 1130 | extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); |
1138 | extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); | 1131 | extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); |
1139 | extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); | 1132 | extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 4e242c757947..9224a06646e6 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -541,7 +541,6 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd) | |||
541 | cmd->cmd_flags |= BIT_4; | 541 | cmd->cmd_flags |= BIT_4; |
542 | cmd->bufflen = se_cmd->data_length; | 542 | cmd->bufflen = se_cmd->data_length; |
543 | cmd->dma_data_direction = target_reverse_dma_direction(se_cmd); | 543 | cmd->dma_data_direction = target_reverse_dma_direction(se_cmd); |
544 | cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED); | ||
545 | 544 | ||
546 | cmd->sg_cnt = se_cmd->t_data_nents; | 545 | cmd->sg_cnt = se_cmd->t_data_nents; |
547 | cmd->sg = se_cmd->t_data_sg; | 546 | cmd->sg = se_cmd->t_data_sg; |
@@ -570,7 +569,6 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) | |||
570 | cmd->sg_cnt = 0; | 569 | cmd->sg_cnt = 0; |
571 | cmd->offset = 0; | 570 | cmd->offset = 0; |
572 | cmd->dma_data_direction = target_reverse_dma_direction(se_cmd); | 571 | cmd->dma_data_direction = target_reverse_dma_direction(se_cmd); |
573 | cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED); | ||
574 | if (cmd->cmd_flags & BIT_5) { | 572 | if (cmd->cmd_flags & BIT_5) { |
575 | pr_crit("Bit_5 already set for cmd = %p.\n", cmd); | 573 | pr_crit("Bit_5 already set for cmd = %p.\n", cmd); |
576 | dump_stack(); | 574 | dump_stack(); |
@@ -635,14 +633,7 @@ static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd) | |||
635 | { | 633 | { |
636 | struct qla_tgt_cmd *cmd = container_of(se_cmd, | 634 | struct qla_tgt_cmd *cmd = container_of(se_cmd, |
637 | struct qla_tgt_cmd, se_cmd); | 635 | struct qla_tgt_cmd, se_cmd); |
638 | struct scsi_qla_host *vha = cmd->vha; | 636 | qlt_abort_cmd(cmd); |
639 | struct qla_hw_data *ha = vha->hw; | ||
640 | |||
641 | if (!cmd->sg_mapped) | ||
642 | return; | ||
643 | |||
644 | pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); | ||
645 | cmd->sg_mapped = 0; | ||
646 | } | 637 | } |
647 | 638 | ||
648 | static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, | 639 | static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, |