]>
Commit | Line | Data |
---|---|---|
b991a285 GKH |
1 | From 7867b98dceb7741065c9c1b645136facad5c2e93 Mon Sep 17 00:00:00 2001 |
2 | From: "himanshu.madhani@cavium.com" <himanshu.madhani@cavium.com> | |
3 | Date: Mon, 4 Dec 2017 14:45:16 -0800 | |
4 | Subject: scsi: qla2xxx: Fix memory leak in dual/target mode | |
5 | ||
6 | From: himanshu.madhani@cavium.com <himanshu.madhani@cavium.com> | |
7 | ||
8 | commit 7867b98dceb7741065c9c1b645136facad5c2e93 upstream. | |
9 | ||
10 | When driver is loaded in Target/Dual mode, it creates QPair to support | |
11 | MQ and allocates resources for each QPair. This Qpair initialization is | |
12 | delayed until the FW personality is changed to Dual/Target mode by | |
13 | issuing chip reset. At the time of chip reset firmware is re-initilized | |
14 | in correct personality all the QPairs are initialized by sending | |
15 | MBC_INITIALIZE_MULTIQ (001Fh). | |
16 | ||
17 | This patch fixes memory leak by adding check to issue | |
18 | MBC_INITIALIZE_MULTIQ command only while deleting rsp/req queue when the | |
19 | flag is set for initiator mode, and clean up QPair resources correctly | |
20 | during the driver unload. This MBX does not need to be issued for | |
21 | Target/Dual mode because chip reset will reset ISP. | |
22 | ||
23 | Fixes: d65237c7f0860 ("scsi: qla2xxx: Fix mailbox failure while deleting Queue pairs") | |
24 | Cc: <stable@vger.kernel.org> # 4.10+ | |
25 | Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> | |
26 | Reviewed-by: Hannes Reinecke <hare@suse.com> | |
27 | Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> | |
28 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
29 | ||
30 | --- | |
31 | drivers/scsi/qla2xxx/qla_init.c | 4 +--- | |
32 | drivers/scsi/qla2xxx/qla_mid.c | 18 ++++++++++-------- | |
33 | 2 files changed, 11 insertions(+), 11 deletions(-) | |
34 | ||
35 | --- a/drivers/scsi/qla2xxx/qla_init.c | |
36 | +++ b/drivers/scsi/qla2xxx/qla_init.c | |
37 | @@ -8221,9 +8221,6 @@ int qla2xxx_delete_qpair(struct scsi_qla | |
38 | int ret = QLA_FUNCTION_FAILED; | |
39 | struct qla_hw_data *ha = qpair->hw; | |
40 | ||
41 | - if (!vha->flags.qpairs_req_created && !vha->flags.qpairs_rsp_created) | |
42 | - goto fail; | |
43 | - | |
44 | qpair->delete_in_progress = 1; | |
45 | while (atomic_read(&qpair->ref_count)) | |
46 | msleep(500); | |
47 | @@ -8231,6 +8228,7 @@ int qla2xxx_delete_qpair(struct scsi_qla | |
48 | ret = qla25xx_delete_req_que(vha, qpair->req); | |
49 | if (ret != QLA_SUCCESS) | |
50 | goto fail; | |
51 | + | |
52 | ret = qla25xx_delete_rsp_que(vha, qpair->rsp); | |
53 | if (ret != QLA_SUCCESS) | |
54 | goto fail; | |
55 | --- a/drivers/scsi/qla2xxx/qla_mid.c | |
56 | +++ b/drivers/scsi/qla2xxx/qla_mid.c | |
57 | @@ -575,14 +575,15 @@ qla25xx_free_rsp_que(struct scsi_qla_hos | |
58 | int | |
59 | qla25xx_delete_req_que(struct scsi_qla_host *vha, struct req_que *req) | |
60 | { | |
61 | - int ret = -1; | |
62 | + int ret = QLA_SUCCESS; | |
63 | ||
64 | - if (req) { | |
65 | + if (req && vha->flags.qpairs_req_created) { | |
66 | req->options |= BIT_0; | |
67 | ret = qla25xx_init_req_que(vha, req); | |
68 | + if (ret != QLA_SUCCESS) | |
69 | + return QLA_FUNCTION_FAILED; | |
70 | } | |
71 | - if (ret == QLA_SUCCESS) | |
72 | - qla25xx_free_req_que(vha, req); | |
73 | + qla25xx_free_req_que(vha, req); | |
74 | ||
75 | return ret; | |
76 | } | |
77 | @@ -590,14 +591,15 @@ qla25xx_delete_req_que(struct scsi_qla_h | |
78 | int | |
79 | qla25xx_delete_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | |
80 | { | |
81 | - int ret = -1; | |
82 | + int ret = QLA_SUCCESS; | |
83 | ||
84 | - if (rsp) { | |
85 | + if (rsp && vha->flags.qpairs_rsp_created) { | |
86 | rsp->options |= BIT_0; | |
87 | ret = qla25xx_init_rsp_que(vha, rsp); | |
88 | + if (ret != QLA_SUCCESS) | |
89 | + return QLA_FUNCTION_FAILED; | |
90 | } | |
91 | - if (ret == QLA_SUCCESS) | |
92 | - qla25xx_free_rsp_que(vha, rsp); | |
93 | + qla25xx_free_rsp_que(vha, rsp); | |
94 | ||
95 | return ret; | |
96 | } |