Skip to content

Commit

Permalink
[SCSI] zfcp: No automatic port_rescan on events
Browse files Browse the repository at this point in the history
In FC fabrics with large zones, the automatic port_rescan on incoming ELS
and any adapter recovery can cause quite some traffic at the very same
time, especially if lots of Linux images share an HBA, which is common on
s390. This can cause trouble and failures. Fix this by making such port
rescans dependent on a user configurable module parameter.

The following unconditional automatic port rescans remain as is:
On setting an adapter online and
on manual user-triggered writes to the sysfs attribute port_rescan.

Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Steffen Maier authored and James Bottomley committed Sep 24, 2012
1 parent d99b601 commit 43f60cb
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 4 deletions.
7 changes: 6 additions & 1 deletion drivers/s390/scsi/zfcp_ccw.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
tag);
zfcp_erp_wait(adapter);
flush_work(&adapter->scan_work);
flush_work(&adapter->scan_work); /* ok to call even if nothing queued */

zfcp_ccw_adapter_put(adapter);

Expand Down Expand Up @@ -171,6 +171,11 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev)
adapter->req_no = 0;

zfcp_ccw_activate(cdev, 0, "ccsonl1");
/* scan for remote ports
either at the end of any successful adapter recovery
or only after the adapter recovery for setting a device online */
zfcp_fc_inverse_conditional_port_scan(adapter);
flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
zfcp_ccw_adapter_put(adapter);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/s390/scsi/zfcp_erp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
if (result == ZFCP_ERP_SUCCEEDED) {
register_service_level(&adapter->service_level);
queue_work(adapter->work_queue, &adapter->scan_work);
zfcp_fc_conditional_port_scan(adapter);
queue_work(adapter->work_queue, &adapter->ns_up_work);
} else
unregister_service_level(&adapter->service_level);
Expand Down
2 changes: 2 additions & 0 deletions drivers/s390/scsi/zfcp_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
extern void zfcp_fc_sym_name_update(struct work_struct *);
extern void zfcp_fc_conditional_port_scan(struct zfcp_adapter *);
extern void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *);

/* zfcp_fsf.c */
extern struct kmem_cache *zfcp_fsf_qtcb_cache;
Expand Down
23 changes: 22 additions & 1 deletion drivers/s390/scsi/zfcp_fc.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,27 @@ static u32 zfcp_fc_rscn_range_mask[] = {
[ELS_ADDR_FMT_FAB] = 0x000000,
};

static bool no_auto_port_rescan;
module_param_named(no_auto_port_rescan, no_auto_port_rescan, bool, 0600);
MODULE_PARM_DESC(no_auto_port_rescan,
"no automatic port_rescan (default off)");

void zfcp_fc_conditional_port_scan(struct zfcp_adapter *adapter)
{
if (no_auto_port_rescan)
return;

queue_work(adapter->work_queue, &adapter->scan_work);
}

void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *adapter)
{
if (!no_auto_port_rescan)
return;

queue_work(adapter->work_queue, &adapter->scan_work);
}

/**
* zfcp_fc_post_event - post event to userspace via fc_transport
* @work: work struct with enqueued events
Expand Down Expand Up @@ -206,7 +227,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
zfcp_fc_enqueue_event(fsf_req->adapter, FCH_EVT_RSCN,
*(u32 *)page);
}
queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work);
zfcp_fc_conditional_port_scan(fsf_req->adapter);
}

static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
Expand Down
2 changes: 1 addition & 1 deletion drivers/s390/scsi/zfcp_fsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED)
zfcp_cfdc_adapter_access_changed(adapter);
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
queue_work(adapter->work_queue, &adapter->scan_work);
zfcp_fc_conditional_port_scan(adapter);
break;
case FSF_STATUS_READ_CFDC_UPDATED:
zfcp_cfdc_adapter_access_changed(adapter);
Expand Down

0 comments on commit 43f60cb

Please sign in to comment.