aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSteffen Maier <maier@linux.vnet.ibm.com>2012-09-04 09:23:35 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-09-24 04:11:02 -0400
commit43f60cbd56c4a3a8f7fb009ac52d6d57ac864921 (patch)
tree3161f846752fb4090b622319c2bf2015394eedba /drivers/s390
parentd99b601b63386f3395dc26a699ae703a273d9982 (diff)
[SCSI] zfcp: No automatic port_rescan on events
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>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c7
-rw-r--r--drivers/s390/scsi/zfcp_erp.c2
-rw-r--r--drivers/s390/scsi/zfcp_ext.h2
-rw-r--r--drivers/s390/scsi/zfcp_fc.c23
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c2
5 files changed, 32 insertions, 4 deletions
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 9646766360d3..f2dd3a0a39eb 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -57,7 +57,7 @@ static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
57 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 57 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
58 tag); 58 tag);
59 zfcp_erp_wait(adapter); 59 zfcp_erp_wait(adapter);
60 flush_work(&adapter->scan_work); 60 flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
61 61
62 zfcp_ccw_adapter_put(adapter); 62 zfcp_ccw_adapter_put(adapter);
63 63
@@ -171,6 +171,11 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev)
171 adapter->req_no = 0; 171 adapter->req_no = 0;
172 172
173 zfcp_ccw_activate(cdev, 0, "ccsonl1"); 173 zfcp_ccw_activate(cdev, 0, "ccsonl1");
174 /* scan for remote ports
175 either at the end of any successful adapter recovery
176 or only after the adapter recovery for setting a device online */
177 zfcp_fc_inverse_conditional_port_scan(adapter);
178 flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
174 zfcp_ccw_adapter_put(adapter); 179 zfcp_ccw_adapter_put(adapter);
175 return 0; 180 return 0;
176} 181}
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 92d3df6ac8ba..4133ab6e20f1 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -1230,7 +1230,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
1230 case ZFCP_ERP_ACTION_REOPEN_ADAPTER: 1230 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
1231 if (result == ZFCP_ERP_SUCCEEDED) { 1231 if (result == ZFCP_ERP_SUCCEEDED) {
1232 register_service_level(&adapter->service_level); 1232 register_service_level(&adapter->service_level);
1233 queue_work(adapter->work_queue, &adapter->scan_work); 1233 zfcp_fc_conditional_port_scan(adapter);
1234 queue_work(adapter->work_queue, &adapter->ns_up_work); 1234 queue_work(adapter->work_queue, &adapter->ns_up_work);
1235 } else 1235 } else
1236 unregister_service_level(&adapter->service_level); 1236 unregister_service_level(&adapter->service_level);
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 03441a7fb463..1d3dd3f7d699 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -99,6 +99,8 @@ extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
99extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *); 99extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
100extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *); 100extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
101extern void zfcp_fc_sym_name_update(struct work_struct *); 101extern void zfcp_fc_sym_name_update(struct work_struct *);
102extern void zfcp_fc_conditional_port_scan(struct zfcp_adapter *);
103extern void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *);
102 104
103/* zfcp_fsf.c */ 105/* zfcp_fsf.c */
104extern struct kmem_cache *zfcp_fsf_qtcb_cache; 106extern struct kmem_cache *zfcp_fsf_qtcb_cache;
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 88688a80b2c1..ff598cd68b2d 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -26,6 +26,27 @@ static u32 zfcp_fc_rscn_range_mask[] = {
26 [ELS_ADDR_FMT_FAB] = 0x000000, 26 [ELS_ADDR_FMT_FAB] = 0x000000,
27}; 27};
28 28
29static bool no_auto_port_rescan;
30module_param_named(no_auto_port_rescan, no_auto_port_rescan, bool, 0600);
31MODULE_PARM_DESC(no_auto_port_rescan,
32 "no automatic port_rescan (default off)");
33
34void zfcp_fc_conditional_port_scan(struct zfcp_adapter *adapter)
35{
36 if (no_auto_port_rescan)
37 return;
38
39 queue_work(adapter->work_queue, &adapter->scan_work);
40}
41
42void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *adapter)
43{
44 if (!no_auto_port_rescan)
45 return;
46
47 queue_work(adapter->work_queue, &adapter->scan_work);
48}
49
29/** 50/**
30 * zfcp_fc_post_event - post event to userspace via fc_transport 51 * zfcp_fc_post_event - post event to userspace via fc_transport
31 * @work: work struct with enqueued events 52 * @work: work struct with enqueued events
@@ -206,7 +227,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
206 zfcp_fc_enqueue_event(fsf_req->adapter, FCH_EVT_RSCN, 227 zfcp_fc_enqueue_event(fsf_req->adapter, FCH_EVT_RSCN,
207 *(u32 *)page); 228 *(u32 *)page);
208 } 229 }
209 queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work); 230 zfcp_fc_conditional_port_scan(fsf_req->adapter);
210} 231}
211 232
212static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn) 233static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 6e2892e7c4be..9ffdc335429c 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -257,7 +257,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
257 if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED) 257 if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED)
258 zfcp_cfdc_adapter_access_changed(adapter); 258 zfcp_cfdc_adapter_access_changed(adapter);
259 if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS) 259 if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
260 queue_work(adapter->work_queue, &adapter->scan_work); 260 zfcp_fc_conditional_port_scan(adapter);
261 break; 261 break;
262 case FSF_STATUS_READ_CFDC_UPDATED: 262 case FSF_STATUS_READ_CFDC_UPDATED:
263 zfcp_cfdc_adapter_access_changed(adapter); 263 zfcp_cfdc_adapter_access_changed(adapter);