aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSteffen Maier <maier@linux.vnet.ibm.com>2013-04-26 11:34:54 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-25 17:07:30 -0400
commit8f425c63ecda1bab9982892e7890041292e2d5ec (patch)
treed27c45b027b1f31832b5a895582137c361fb6afd /drivers/s390
parentb22b8386992d886aa487b57e000b18512e639710 (diff)
SCSI: zfcp: status read buffers on first adapter open with link down
commit 9edf7d75ee5f21663a0183d21f702682d0ef132f upstream. Commit 64deb6efdc5504ce97b5c1c6f281fffbc150bd93 "[SCSI] zfcp: Use status_read_buf_num provided by FCP channel" started using a value returned by the channel but only evaluated the value if the fabric link is up. Commit 8d88cf3f3b9af4713642caeb221b6d6a42019001 "[SCSI] zfcp: Update status read mempool" introduced mempool resizings based on the above value. On setting an FCP device online for the very first time since boot, a new zeroed adapter object is allocated. If the link is down, the number of status read requests remains zero. Since just the config data exchange is incomplete, we proceed with adapter open recovery. However, we unconditionally call mempool_resize with adapter->stat_read_buf_num == 0 in this case. This causes a kernel message "kernel BUG at mm/mempool.c:131!" in process "zfcperp<FCP-device-bus-ID>" with last function mempool_resize in Krnl PSW and zfcp_erp_thread in the Call Trace. Don't evaluate channel values which are invalid on link down. The number of status read requests is always valid, evaluated, and set to a positive minimum greater than zero. The adapter open recovery can proceed and the channel has status read buffers to inform us on a future link up event. While we are not aware of any other code path that could result in mempool resize attempts of size zero, we still also initialize the number of status read buffers to be posted to a static minimum number on adapter object allocation. Signed-off-by: Steffen Maier <maier@linux.vnet.ibm.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c5
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c23
2 files changed, 20 insertions, 8 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index f6adde44f226..3743ac931231 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Module interface and handling of zfcp data structures. 4 * Module interface and handling of zfcp data structures.
5 * 5 *
6 * Copyright IBM Corp. 2002, 2010 6 * Copyright IBM Corp. 2002, 2013
7 */ 7 */
8 8
9/* 9/*
@@ -23,6 +23,7 @@
23 * Christof Schmitt 23 * Christof Schmitt
24 * Martin Petermann 24 * Martin Petermann
25 * Sven Schuetz 25 * Sven Schuetz
26 * Steffen Maier
26 */ 27 */
27 28
28#define KMSG_COMPONENT "zfcp" 29#define KMSG_COMPONENT "zfcp"
@@ -415,6 +416,8 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
415 adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN; 416 adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN;
416 adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; 417 adapter->ccw_device->dev.dma_parms = &adapter->dma_parms;
417 418
419 adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM;
420
418 if (!zfcp_scsi_adapter_register(adapter)) 421 if (!zfcp_scsi_adapter_register(adapter))
419 return adapter; 422 return adapter;
420 423
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 06760e435259..9152999a0707 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Implementation of FSF commands. 4 * Implementation of FSF commands.
5 * 5 *
6 * Copyright IBM Corp. 2002, 2010 6 * Copyright IBM Corp. 2002, 2013
7 */ 7 */
8 8
9#define KMSG_COMPONENT "zfcp" 9#define KMSG_COMPONENT "zfcp"
@@ -483,12 +483,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
483 483
484 fc_host_port_name(shost) = nsp->fl_wwpn; 484 fc_host_port_name(shost) = nsp->fl_wwpn;
485 fc_host_node_name(shost) = nsp->fl_wwnn; 485 fc_host_node_name(shost) = nsp->fl_wwnn;
486 fc_host_port_id(shost) = ntoh24(bottom->s_id);
487 fc_host_speed(shost) =
488 zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
489 fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; 486 fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
490 487
491 adapter->hydra_version = bottom->adapter_type;
492 adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK; 488 adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK;
493 adapter->stat_read_buf_num = max(bottom->status_read_buf_num, 489 adapter->stat_read_buf_num = max(bottom->status_read_buf_num,
494 (u16)FSF_STATUS_READS_RECOM); 490 (u16)FSF_STATUS_READS_RECOM);
@@ -496,6 +492,19 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
496 if (fc_host_permanent_port_name(shost) == -1) 492 if (fc_host_permanent_port_name(shost) == -1)
497 fc_host_permanent_port_name(shost) = fc_host_port_name(shost); 493 fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
498 494
495 zfcp_scsi_set_prot(adapter);
496
497 /* no error return above here, otherwise must fix call chains */
498 /* do not evaluate invalid fields */
499 if (req->qtcb->header.fsf_status == FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE)
500 return 0;
501
502 fc_host_port_id(shost) = ntoh24(bottom->s_id);
503 fc_host_speed(shost) =
504 zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
505
506 adapter->hydra_version = bottom->adapter_type;
507
499 switch (bottom->fc_topology) { 508 switch (bottom->fc_topology) {
500 case FSF_TOPO_P2P: 509 case FSF_TOPO_P2P:
501 adapter->peer_d_id = ntoh24(bottom->peer_d_id); 510 adapter->peer_d_id = ntoh24(bottom->peer_d_id);
@@ -517,8 +526,6 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
517 return -EIO; 526 return -EIO;
518 } 527 }
519 528
520 zfcp_scsi_set_prot(adapter);
521
522 return 0; 529 return 0;
523} 530}
524 531
@@ -569,6 +576,8 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
569 &adapter->status); 576 &adapter->status);
570 zfcp_fsf_link_down_info_eval(req, 577 zfcp_fsf_link_down_info_eval(req,
571 &qtcb->header.fsf_status_qual.link_down_info); 578 &qtcb->header.fsf_status_qual.link_down_info);
579 if (zfcp_fsf_exchange_config_evaluate(req))
580 return;
572 break; 581 break;
573 default: 582 default:
574 zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3"); 583 zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3");