]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-5.1/scsi-lpfc-correct-rcu-unlock-issue-in-lpfc_nvme_info.patch
move all the pending queues back to their "real" places
[thirdparty/kernel/stable-queue.git] / queue-5.1 / scsi-lpfc-correct-rcu-unlock-issue-in-lpfc_nvme_info.patch
1 From 9450c00c32b3d1caf45e04ee6be409093cc1db06 Mon Sep 17 00:00:00 2001
2 From: James Smart <jsmart2021@gmail.com>
3 Date: Mon, 6 May 2019 17:26:48 -0700
4 Subject: scsi: lpfc: correct rcu unlock issue in lpfc_nvme_info_show
5
6 [ Upstream commit 79080d349f7f58a2e86c56043a3d04184d5f294a ]
7
8 Many of the exit cases were not releasing the rcu read lock. Corrected the
9 exit paths.
10
11 Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
12 Signed-off-by: James Smart <jsmart2021@gmail.com>
13 Tested-by: Bart Van Assche <bvanassche@acm.org>
14 Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
15 Signed-off-by: Sasha Levin <sashal@kernel.org>
16 ---
17 drivers/scsi/lpfc/lpfc_attr.c | 32 +++++++++++++++++++-------------
18 1 file changed, 19 insertions(+), 13 deletions(-)
19
20 diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
21 index f30cb0fb9a82..26a22e41204e 100644
22 --- a/drivers/scsi/lpfc/lpfc_attr.c
23 +++ b/drivers/scsi/lpfc/lpfc_attr.c
24 @@ -338,7 +338,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
25 phba->sli4_hba.io_xri_max,
26 lpfc_sli4_get_els_iocb_cnt(phba));
27 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
28 - goto buffer_done;
29 + goto rcu_unlock_buf_done;
30
31 /* Port state is only one of two values for now. */
32 if (localport->port_id)
33 @@ -354,7 +354,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
34 wwn_to_u64(vport->fc_nodename.u.wwn),
35 localport->port_id, statep);
36 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
37 - goto buffer_done;
38 + goto rcu_unlock_buf_done;
39
40 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
41 nrport = NULL;
42 @@ -381,39 +381,39 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
43
44 /* Tab in to show lport ownership. */
45 if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE)
46 - goto buffer_done;
47 + goto rcu_unlock_buf_done;
48 if (phba->brd_no >= 10) {
49 if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
50 - goto buffer_done;
51 + goto rcu_unlock_buf_done;
52 }
53
54 scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
55 nrport->port_name);
56 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
57 - goto buffer_done;
58 + goto rcu_unlock_buf_done;
59
60 scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
61 nrport->node_name);
62 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
63 - goto buffer_done;
64 + goto rcu_unlock_buf_done;
65
66 scnprintf(tmp, sizeof(tmp), "DID x%06x ",
67 nrport->port_id);
68 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
69 - goto buffer_done;
70 + goto rcu_unlock_buf_done;
71
72 /* An NVME rport can have multiple roles. */
73 if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
74 if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
75 - goto buffer_done;
76 + goto rcu_unlock_buf_done;
77 }
78 if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
79 if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
80 - goto buffer_done;
81 + goto rcu_unlock_buf_done;
82 }
83 if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) {
84 if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE)
85 - goto buffer_done;
86 + goto rcu_unlock_buf_done;
87 }
88 if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
89 FC_PORT_ROLE_NVME_TARGET |
90 @@ -421,12 +421,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
91 scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
92 nrport->port_role);
93 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
94 - goto buffer_done;
95 + goto rcu_unlock_buf_done;
96 }
97
98 scnprintf(tmp, sizeof(tmp), "%s\n", statep);
99 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
100 - goto buffer_done;
101 + goto rcu_unlock_buf_done;
102 }
103 rcu_read_unlock();
104
105 @@ -488,7 +488,13 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
106 atomic_read(&lport->cmpl_fcp_err));
107 strlcat(buf, tmp, PAGE_SIZE);
108
109 -buffer_done:
110 + /* RCU is already unlocked. */
111 + goto buffer_done;
112 +
113 + rcu_unlock_buf_done:
114 + rcu_read_unlock();
115 +
116 + buffer_done:
117 len = strnlen(buf, PAGE_SIZE);
118
119 if (unlikely(len >= (PAGE_SIZE - 1))) {
120 --
121 2.20.1
122