]>
Commit | Line | Data |
---|---|---|
fb43722c SL |
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 |