]>
Commit | Line | Data |
---|---|---|
dcd32332 SL |
1 | From e925cd8562c1fbe85603d18b49cd08e76a7f95bc Mon Sep 17 00:00:00 2001 |
2 | From: Steffen Maier <maier@linux.ibm.com> | |
3 | Date: Tue, 26 Mar 2019 14:37:00 +0100 | |
4 | Subject: scsi: zfcp: reduce flood of fcrscn1 trace records on multi-element | |
5 | RSCN | |
6 | ||
7 | [ Upstream commit c8206579175c34a2546de8a74262456278a7795a ] | |
8 | ||
9 | If an incoming ELS of type RSCN contains more than one element, zfcp | |
10 | suboptimally causes repeated erp trigger NOP trace records for each | |
11 | previously failed port. These could be ports that went away. It loops over | |
12 | each RSCN element, and for each of those in an inner loop over all | |
13 | zfcp_ports. | |
14 | ||
15 | The trigger to recover failed ports should be just the reception of some | |
16 | RSCN, no matter how many elements it has. So we can loop over failed ports | |
17 | separately, and only then loop over each RSCN element to handle the | |
18 | non-failed ports. | |
19 | ||
20 | The call chain was: | |
21 | ||
22 | zfcp_fc_incoming_rscn | |
23 | for (i = 1; i < no_entries; i++) | |
24 | _zfcp_fc_incoming_rscn | |
25 | list_for_each_entry(port, &adapter->port_list, list) | |
26 | if (masked port->d_id match) zfcp_fc_test_link | |
27 | if (!port->d_id) zfcp_erp_port_reopen "fcrscn1" <=== | |
28 | ||
29 | In order the reduce the "flooding" of the REC trace area in such cases, we | |
30 | factor out handling the failed ports to be outside of the entries loop: | |
31 | ||
32 | zfcp_fc_incoming_rscn | |
33 | if (no_entries > 1) <=== | |
34 | list_for_each_entry(port, &adapter->port_list, list) <=== | |
35 | if (!port->d_id) zfcp_erp_port_reopen "fcrscn1" <=== | |
36 | for (i = 1; i < no_entries; i++) | |
37 | _zfcp_fc_incoming_rscn | |
38 | list_for_each_entry(port, &adapter->port_list, list) | |
39 | if (masked port->d_id match) zfcp_fc_test_link | |
40 | ||
41 | Abbreviated example trace records before this code change: | |
42 | ||
43 | Tag : fcrscn1 | |
44 | WWPN : 0x500507630310d327 | |
45 | ERP want : 0x02 | |
46 | ERP need : 0x02 | |
47 | ||
48 | Tag : fcrscn1 | |
49 | WWPN : 0x500507630310d327 | |
50 | ERP want : 0x02 | |
51 | ERP need : 0x00 NOP => superfluous trace record | |
52 | ||
53 | The last trace entry repeats if there are more than 2 RSCN elements. | |
54 | ||
55 | Signed-off-by: Steffen Maier <maier@linux.ibm.com> | |
56 | Reviewed-by: Benjamin Block <bblock@linux.ibm.com> | |
57 | Reviewed-by: Jens Remus <jremus@linux.ibm.com> | |
58 | Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> | |
59 | Signed-off-by: Sasha Levin (Microsoft) <sashal@kernel.org> | |
60 | --- | |
61 | drivers/s390/scsi/zfcp_fc.c | 21 +++++++++++++++++---- | |
62 | 1 file changed, 17 insertions(+), 4 deletions(-) | |
63 | ||
64 | diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c | |
65 | index 237688af179b..f7630cf581cd 100644 | |
66 | --- a/drivers/s390/scsi/zfcp_fc.c | |
67 | +++ b/drivers/s390/scsi/zfcp_fc.c | |
68 | @@ -238,10 +238,6 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | |
69 | list_for_each_entry(port, &adapter->port_list, list) { | |
70 | if ((port->d_id & range) == (ntoh24(page->rscn_fid) & range)) | |
71 | zfcp_fc_test_link(port); | |
72 | - if (!port->d_id) | |
73 | - zfcp_erp_port_reopen(port, | |
74 | - ZFCP_STATUS_COMMON_ERP_FAILED, | |
75 | - "fcrscn1"); | |
76 | } | |
77 | read_unlock_irqrestore(&adapter->port_list_lock, flags); | |
78 | } | |
79 | @@ -249,6 +245,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | |
80 | static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) | |
81 | { | |
82 | struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data; | |
83 | + struct zfcp_adapter *adapter = fsf_req->adapter; | |
84 | struct fc_els_rscn *head; | |
85 | struct fc_els_rscn_page *page; | |
86 | u16 i; | |
87 | @@ -261,6 +258,22 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) | |
88 | /* see FC-FS */ | |
89 | no_entries = head->rscn_plen / sizeof(struct fc_els_rscn_page); | |
90 | ||
91 | + if (no_entries > 1) { | |
92 | + /* handle failed ports */ | |
93 | + unsigned long flags; | |
94 | + struct zfcp_port *port; | |
95 | + | |
96 | + read_lock_irqsave(&adapter->port_list_lock, flags); | |
97 | + list_for_each_entry(port, &adapter->port_list, list) { | |
98 | + if (port->d_id) | |
99 | + continue; | |
100 | + zfcp_erp_port_reopen(port, | |
101 | + ZFCP_STATUS_COMMON_ERP_FAILED, | |
102 | + "fcrscn1"); | |
103 | + } | |
104 | + read_unlock_irqrestore(&adapter->port_list_lock, flags); | |
105 | + } | |
106 | + | |
107 | for (i = 1; i < no_entries; i++) { | |
108 | /* skip head and start with 1st element */ | |
109 | page++; | |
110 | -- | |
111 | 2.19.1 | |
112 |