Skip to content

Commit c820657

Browse files
steffen-maiermartinkpetersen
authored andcommitted
scsi: zfcp: reduce flood of fcrscn1 trace records on multi-element RSCN
If an incoming ELS of type RSCN contains more than one element, zfcp suboptimally causes repeated erp trigger NOP trace records for each previously failed port. These could be ports that went away. It loops over each RSCN element, and for each of those in an inner loop over all zfcp_ports. The trigger to recover failed ports should be just the reception of some RSCN, no matter how many elements it has. So we can loop over failed ports separately, and only then loop over each RSCN element to handle the non-failed ports. The call chain was: zfcp_fc_incoming_rscn for (i = 1; i < no_entries; i++) _zfcp_fc_incoming_rscn list_for_each_entry(port, &adapter->port_list, list) if (masked port->d_id match) zfcp_fc_test_link if (!port->d_id) zfcp_erp_port_reopen "fcrscn1" <=== In order the reduce the "flooding" of the REC trace area in such cases, we factor out handling the failed ports to be outside of the entries loop: zfcp_fc_incoming_rscn if (no_entries > 1) <=== list_for_each_entry(port, &adapter->port_list, list) <=== if (!port->d_id) zfcp_erp_port_reopen "fcrscn1" <=== for (i = 1; i < no_entries; i++) _zfcp_fc_incoming_rscn list_for_each_entry(port, &adapter->port_list, list) if (masked port->d_id match) zfcp_fc_test_link Abbreviated example trace records before this code change: Tag : fcrscn1 WWPN : 0x500507630310d327 ERP want : 0x02 ERP need : 0x02 Tag : fcrscn1 WWPN : 0x500507630310d327 ERP want : 0x02 ERP need : 0x00 NOP => superfluous trace record The last trace entry repeats if there are more than 2 RSCN elements. Signed-off-by: Steffen Maier <maier@linux.ibm.com> Reviewed-by: Benjamin Block <bblock@linux.ibm.com> Reviewed-by: Jens Remus <jremus@linux.ibm.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 242ec14 commit c820657

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

drivers/s390/scsi/zfcp_fc.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,14 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
239239
list_for_each_entry(port, &adapter->port_list, list) {
240240
if ((port->d_id & range) == (ntoh24(page->rscn_fid) & range))
241241
zfcp_fc_test_link(port);
242-
if (!port->d_id)
243-
zfcp_erp_port_reopen(port,
244-
ZFCP_STATUS_COMMON_ERP_FAILED,
245-
"fcrscn1");
246242
}
247243
read_unlock_irqrestore(&adapter->port_list_lock, flags);
248244
}
249245

250246
static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
251247
{
252248
struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data;
249+
struct zfcp_adapter *adapter = fsf_req->adapter;
253250
struct fc_els_rscn *head;
254251
struct fc_els_rscn_page *page;
255252
u16 i;
@@ -263,6 +260,22 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
263260
no_entries = be16_to_cpu(head->rscn_plen) /
264261
sizeof(struct fc_els_rscn_page);
265262

263+
if (no_entries > 1) {
264+
/* handle failed ports */
265+
unsigned long flags;
266+
struct zfcp_port *port;
267+
268+
read_lock_irqsave(&adapter->port_list_lock, flags);
269+
list_for_each_entry(port, &adapter->port_list, list) {
270+
if (port->d_id)
271+
continue;
272+
zfcp_erp_port_reopen(port,
273+
ZFCP_STATUS_COMMON_ERP_FAILED,
274+
"fcrscn1");
275+
}
276+
read_unlock_irqrestore(&adapter->port_list_lock, flags);
277+
}
278+
266279
for (i = 1; i < no_entries; i++) {
267280
/* skip head and start with 1st element */
268281
page++;

0 commit comments

Comments
 (0)