aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2009-08-18 09:43:20 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-05 09:49:28 -0400
commit799b76d09aeee558d18c1f5b93e63f58f1d1fc11 (patch)
treea1a05faa773b329246a4fa97ba7c0ac5201b5d40 /drivers
parent564e1c86c810f9ccfe4300afa402815e3db4886d (diff)
[SCSI] zfcp: Decouple gid_pn requests from erp
Don't let the erp wait for gid_pn requests to complete. Instead, queue the gid_pn work, exit erp and let the finished gid_pn work trigger a new port reopen. Reviewed-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c9
-rw-r--r--drivers/s390/scsi/zfcp_def.h1
-rw-r--r--drivers/s390/scsi/zfcp_erp.c28
-rw-r--r--drivers/s390/scsi/zfcp_ext.h6
-rw-r--r--drivers/s390/scsi/zfcp_fc.c45
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c14
6 files changed, 47 insertions, 56 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index ed7211ef04eb..572dcd67e713 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -362,6 +362,11 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
362 if (!adapter->pool.erp_req) 362 if (!adapter->pool.erp_req)
363 return -ENOMEM; 363 return -ENOMEM;
364 364
365 adapter->pool.gid_pn_req =
366 mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
367 if (!adapter->pool.gid_pn_req)
368 return -ENOMEM;
369
365 adapter->pool.scsi_req = 370 adapter->pool.scsi_req =
366 mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req)); 371 mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
367 if (!adapter->pool.scsi_req) 372 if (!adapter->pool.scsi_req)
@@ -379,7 +384,7 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
379 return -ENOMEM; 384 return -ENOMEM;
380 385
381 adapter->pool.qtcb_pool = 386 adapter->pool.qtcb_pool =
382 mempool_create_slab_pool(3, zfcp_data.qtcb_cache); 387 mempool_create_slab_pool(4, zfcp_data.qtcb_cache);
383 if (!adapter->pool.qtcb_pool) 388 if (!adapter->pool.qtcb_pool)
384 return -ENOMEM; 389 return -ENOMEM;
385 390
@@ -652,7 +657,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
652 657
653 init_waitqueue_head(&port->remove_wq); 658 init_waitqueue_head(&port->remove_wq);
654 INIT_LIST_HEAD(&port->unit_list_head); 659 INIT_LIST_HEAD(&port->unit_list_head);
655 INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup); 660 INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
656 INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work); 661 INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
657 INIT_WORK(&port->rport_work, zfcp_scsi_rport_work); 662 INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
658 663
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index bac5c497eab5..9a8ff0553421 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -265,6 +265,7 @@ struct zfcp_fsf_req;
265/* holds various memory pools of an adapter */ 265/* holds various memory pools of an adapter */
266struct zfcp_adapter_mempool { 266struct zfcp_adapter_mempool {
267 mempool_t *erp_req; 267 mempool_t *erp_req;
268 mempool_t *gid_pn_req;
268 mempool_t *scsi_req; 269 mempool_t *scsi_req;
269 mempool_t *scsi_abort; 270 mempool_t *scsi_abort;
270 mempool_t *status_read_req; 271 mempool_t *status_read_req;
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index feda1db56b23..67297d2744fb 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -26,7 +26,6 @@ enum zfcp_erp_steps {
26 ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001, 26 ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001,
27 ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, 27 ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010,
28 ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, 28 ZFCP_ERP_STEP_PORT_CLOSING = 0x0100,
29 ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400,
30 ZFCP_ERP_STEP_PORT_OPENING = 0x0800, 29 ZFCP_ERP_STEP_PORT_OPENING = 0x0800,
31 ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000, 30 ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000,
32 ZFCP_ERP_STEP_UNIT_OPENING = 0x2000, 31 ZFCP_ERP_STEP_UNIT_OPENING = 0x2000,
@@ -842,27 +841,6 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
842 return zfcp_erp_port_strategy_open_port(act); 841 return zfcp_erp_port_strategy_open_port(act);
843} 842}
844 843
845void zfcp_erp_port_strategy_open_lookup(struct work_struct *work)
846{
847 int retval;
848 struct zfcp_port *port = container_of(work, struct zfcp_port,
849 gid_pn_work);
850
851 retval = zfcp_fc_ns_gid_pn(&port->erp_action);
852 if (!retval) {
853 port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
854 goto out;
855 }
856 if (retval == -ENOMEM) {
857 zfcp_erp_notify(&port->erp_action, ZFCP_STATUS_ERP_LOWMEM);
858 goto out;
859 }
860 /* all other error condtions */
861 zfcp_erp_notify(&port->erp_action, 0);
862out:
863 zfcp_port_put(port);
864}
865
866static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) 844static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
867{ 845{
868 struct zfcp_adapter *adapter = act->adapter; 846 struct zfcp_adapter *adapter = act->adapter;
@@ -880,12 +858,8 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
880 if (!queue_work(adapter->work_queue, 858 if (!queue_work(adapter->work_queue,
881 &port->gid_pn_work)) 859 &port->gid_pn_work))
882 zfcp_port_put(port); 860 zfcp_port_put(port);
883 return ZFCP_ERP_CONTINUES; 861 return ZFCP_ERP_EXIT;
884 } 862 }
885 /* fall through */
886 case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
887 if (!port->d_id)
888 return ZFCP_ERP_FAILED;
889 return zfcp_erp_port_strategy_open_port(act); 863 return zfcp_erp_port_strategy_open_port(act);
890 864
891 case ZFCP_ERP_STEP_PORT_OPENING: 865 case ZFCP_ERP_STEP_PORT_OPENING:
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index e97947d2f2ed..7650cec7f71f 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -94,13 +94,12 @@ extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, char *, void *);
94extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *, 94extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
95 void *); 95 void *);
96extern void zfcp_erp_timeout_handler(unsigned long); 96extern void zfcp_erp_timeout_handler(unsigned long);
97extern void zfcp_erp_port_strategy_open_lookup(struct work_struct *);
98 97
99/* zfcp_fc.c */ 98/* zfcp_fc.c */
100extern int zfcp_scan_ports(struct zfcp_adapter *); 99extern int zfcp_scan_ports(struct zfcp_adapter *);
101extern void _zfcp_scan_ports_later(struct work_struct *); 100extern void _zfcp_scan_ports_later(struct work_struct *);
102extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); 101extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
103extern int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *); 102extern void zfcp_fc_port_did_lookup(struct work_struct *);
104extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); 103extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
105extern void zfcp_test_link(struct zfcp_port *); 104extern void zfcp_test_link(struct zfcp_port *);
106extern void zfcp_fc_link_test_work(struct work_struct *); 105extern void zfcp_fc_link_test_work(struct work_struct *);
@@ -128,8 +127,7 @@ extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *,
128extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); 127extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
129extern int zfcp_fsf_status_read(struct zfcp_qdio *); 128extern int zfcp_fsf_status_read(struct zfcp_qdio *);
130extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); 129extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
131extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *, 130extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *);
132 struct zfcp_erp_action *);
133extern int zfcp_fsf_send_els(struct zfcp_send_els *); 131extern int zfcp_fsf_send_els(struct zfcp_send_els *);
134extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *, 132extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
135 struct scsi_cmnd *); 133 struct scsi_cmnd *);
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 8921e16fdab7..bc0c9f54d0d8 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -282,15 +282,15 @@ static void zfcp_fc_ns_gid_pn_eval(unsigned long data)
282 port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; 282 port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK;
283} 283}
284 284
285int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, 285static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port,
286 struct zfcp_gid_pn_data *gid_pn) 286 struct zfcp_gid_pn_data *gid_pn)
287{ 287{
288 struct zfcp_adapter *adapter = erp_action->adapter; 288 struct zfcp_adapter *adapter = port->adapter;
289 struct zfcp_fc_ns_handler_data compl_rec; 289 struct zfcp_fc_ns_handler_data compl_rec;
290 int ret; 290 int ret;
291 291
292 /* setup parameters for send generic command */ 292 /* setup parameters for send generic command */
293 gid_pn->port = erp_action->port; 293 gid_pn->port = port;
294 gid_pn->ct.wka_port = &adapter->gs->ds; 294 gid_pn->ct.wka_port = &adapter->gs->ds;
295 gid_pn->ct.handler = zfcp_fc_ns_handler; 295 gid_pn->ct.handler = zfcp_fc_ns_handler;
296 gid_pn->ct.handler_data = (unsigned long) &compl_rec; 296 gid_pn->ct.handler_data = (unsigned long) &compl_rec;
@@ -309,12 +309,12 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
309 gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS; 309 gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS;
310 gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN; 310 gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN;
311 gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4; 311 gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4;
312 gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; 312 gid_pn->ct_iu_req.wwpn = port->wwpn;
313 313
314 init_completion(&compl_rec.done); 314 init_completion(&compl_rec.done);
315 compl_rec.handler = zfcp_fc_ns_gid_pn_eval; 315 compl_rec.handler = zfcp_fc_ns_gid_pn_eval;
316 compl_rec.handler_data = (unsigned long) gid_pn; 316 compl_rec.handler_data = (unsigned long) gid_pn;
317 ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.erp_req, erp_action); 317 ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.gid_pn_req);
318 if (!ret) 318 if (!ret)
319 wait_for_completion(&compl_rec.done); 319 wait_for_completion(&compl_rec.done);
320 return ret; 320 return ret;
@@ -322,14 +322,14 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
322 322
323/** 323/**
324 * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request 324 * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request
325 * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed 325 * @port: port where GID_PN request is needed
326 * return: -ENOMEM on error, 0 otherwise 326 * return: -ENOMEM on error, 0 otherwise
327 */ 327 */
328int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action) 328static int zfcp_fc_ns_gid_pn(struct zfcp_port *port)
329{ 329{
330 int ret; 330 int ret;
331 struct zfcp_gid_pn_data *gid_pn; 331 struct zfcp_gid_pn_data *gid_pn;
332 struct zfcp_adapter *adapter = erp_action->adapter; 332 struct zfcp_adapter *adapter = port->adapter;
333 333
334 gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC); 334 gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC);
335 if (!gid_pn) 335 if (!gid_pn)
@@ -341,7 +341,7 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action)
341 if (ret) 341 if (ret)
342 goto out; 342 goto out;
343 343
344 ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn); 344 ret = zfcp_fc_ns_gid_pn_request(port, gid_pn);
345 345
346 zfcp_wka_port_put(&adapter->gs->ds); 346 zfcp_wka_port_put(&adapter->gs->ds);
347out: 347out:
@@ -349,6 +349,29 @@ out:
349 return ret; 349 return ret;
350} 350}
351 351
352void zfcp_fc_port_did_lookup(struct work_struct *work)
353{
354 int ret;
355 struct zfcp_port *port = container_of(work, struct zfcp_port,
356 gid_pn_work);
357
358 ret = zfcp_fc_ns_gid_pn(port);
359 if (ret) {
360 /* could not issue gid_pn for some reason */
361 zfcp_erp_adapter_reopen(port->adapter, 0, "fcgpn_1", NULL);
362 goto out;
363 }
364
365 if (!port->d_id) {
366 zfcp_erp_port_failed(port, "fcgpn_2", NULL);
367 goto out;
368 }
369
370 zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
371out:
372 zfcp_port_put(port);
373}
374
352/** 375/**
353 * zfcp_fc_plogi_evaluate - evaluate PLOGI playload 376 * zfcp_fc_plogi_evaluate - evaluate PLOGI playload
354 * @port: zfcp_port structure 377 * @port: zfcp_port structure
@@ -551,7 +574,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
551 574
552 init_completion(&compl_rec.done); 575 init_completion(&compl_rec.done);
553 compl_rec.handler = NULL; 576 compl_rec.handler = NULL;
554 ret = zfcp_fsf_send_ct(ct, NULL, NULL); 577 ret = zfcp_fsf_send_ct(ct, NULL);
555 if (!ret) 578 if (!ret)
556 wait_for_completion(&compl_rec.done); 579 wait_for_completion(&compl_rec.done);
557 return ret; 580 return ret;
@@ -840,7 +863,7 @@ int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job)
840 ct_fc_job->ct.completion = NULL; 863 ct_fc_job->ct.completion = NULL;
841 ct_fc_job->job = job; 864 ct_fc_job->job = job;
842 865
843 ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL, NULL); 866 ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL);
844 if (ret) { 867 if (ret) {
845 kfree(ct_fc_job); 868 kfree(ct_fc_job);
846 zfcp_wka_port_put(ct_fc_job->ct.wka_port); 869 zfcp_wka_port_put(ct_fc_job->ct.wka_port);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index b9a16e4b48b4..048f1a848f34 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1069,10 +1069,8 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
1069 * zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS) 1069 * zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS)
1070 * @ct: pointer to struct zfcp_send_ct with data for request 1070 * @ct: pointer to struct zfcp_send_ct with data for request
1071 * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req 1071 * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req
1072 * @erp_action: if non-null the Generic Service request sent within ERP
1073 */ 1072 */
1074int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, 1073int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool)
1075 struct zfcp_erp_action *erp_action)
1076{ 1074{
1077 struct zfcp_wka_port *wka_port = ct->wka_port; 1075 struct zfcp_wka_port *wka_port = ct->wka_port;
1078 struct zfcp_qdio *qdio = wka_port->adapter->qdio; 1076 struct zfcp_qdio *qdio = wka_port->adapter->qdio;
@@ -1103,13 +1101,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
1103 req->data = ct; 1101 req->data = ct;
1104 1102
1105 zfcp_san_dbf_event_ct_request(req); 1103 zfcp_san_dbf_event_ct_request(req);
1106 1104 zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
1107 if (erp_action) {
1108 erp_action->fsf_req = req;
1109 req->erp_action = erp_action;
1110 zfcp_fsf_start_erp_timer(req);
1111 } else
1112 zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
1113 1105
1114 ret = zfcp_fsf_req_send(req); 1106 ret = zfcp_fsf_req_send(req);
1115 if (ret) 1107 if (ret)
@@ -1119,8 +1111,6 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
1119 1111
1120failed_send: 1112failed_send:
1121 zfcp_fsf_req_free(req); 1113 zfcp_fsf_req_free(req);
1122 if (erp_action)
1123 erp_action->fsf_req = NULL;
1124out: 1114out:
1125 spin_unlock_bh(&qdio->req_q_lock); 1115 spin_unlock_bh(&qdio->req_q_lock);
1126 return ret; 1116 return ret;