aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_erp.c
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2009-11-24 10:53:58 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:02:01 -0500
commitecf0c7721b104c0ce9c8ca534c911f6310cf92a8 (patch)
tree639032b36bcbbe905c98c6f0b3b521dc2f0b1806 /drivers/s390/scsi/zfcp_erp.c
parent0a55256d158c18e4821c248a295b7f8f4423660f (diff)
[SCSI] zfcp: Replace global config_lock with local list locks
The global config_lock was used to protect the configuration organized in independent lists. It is not necessary to have a lock on driver level for this purpose. This patch replaces the global config_lock with a set of local list locks. Signed-off-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/s390/scsi/zfcp_erp.c')
-rw-r--r--drivers/s390/scsi/zfcp_erp.c116
1 files changed, 61 insertions, 55 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index f73e2180f333..464f0473877a 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -99,9 +99,12 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port)
99 99
100 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) 100 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE)
101 zfcp_erp_action_dismiss(&port->erp_action); 101 zfcp_erp_action_dismiss(&port->erp_action);
102 else 102 else {
103 list_for_each_entry(unit, &port->unit_list_head, list) 103 read_lock(&port->unit_list_lock);
104 zfcp_erp_action_dismiss_unit(unit); 104 list_for_each_entry(unit, &port->unit_list, list)
105 zfcp_erp_action_dismiss_unit(unit);
106 read_unlock(&port->unit_list_lock);
107 }
105} 108}
106 109
107static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) 110static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
@@ -110,9 +113,12 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
110 113
111 if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE) 114 if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE)
112 zfcp_erp_action_dismiss(&adapter->erp_action); 115 zfcp_erp_action_dismiss(&adapter->erp_action);
113 else 116 else {
114 list_for_each_entry(port, &adapter->port_list_head, list) 117 read_lock(&adapter->port_list_lock);
118 list_for_each_entry(port, &adapter->port_list, list)
115 zfcp_erp_action_dismiss_port(port); 119 zfcp_erp_action_dismiss_port(port);
120 read_unlock(&adapter->port_list_lock);
121 }
116} 122}
117 123
118static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, 124static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
@@ -264,11 +270,16 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
264{ 270{
265 unsigned long flags; 271 unsigned long flags;
266 272
267 read_lock_irqsave(&zfcp_data.config_lock, flags); 273 zfcp_erp_adapter_block(adapter, clear);
268 write_lock(&adapter->erp_lock); 274 zfcp_scsi_schedule_rports_block(adapter);
269 _zfcp_erp_adapter_reopen(adapter, clear, id, ref); 275
270 write_unlock(&adapter->erp_lock); 276 write_lock_irqsave(&adapter->erp_lock, flags);
271 read_unlock_irqrestore(&zfcp_data.config_lock, flags); 277 if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
278 zfcp_erp_adapter_failed(adapter, "erareo1", NULL);
279 else
280 zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
281 NULL, NULL, id, ref);
282 write_unlock_irqrestore(&adapter->erp_lock, flags);
272} 283}
273 284
274/** 285/**
@@ -345,11 +356,9 @@ void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id,
345 unsigned long flags; 356 unsigned long flags;
346 struct zfcp_adapter *adapter = port->adapter; 357 struct zfcp_adapter *adapter = port->adapter;
347 358
348 read_lock_irqsave(&zfcp_data.config_lock, flags); 359 write_lock_irqsave(&adapter->erp_lock, flags);
349 write_lock(&adapter->erp_lock);
350 _zfcp_erp_port_forced_reopen(port, clear, id, ref); 360 _zfcp_erp_port_forced_reopen(port, clear, id, ref);
351 write_unlock(&adapter->erp_lock); 361 write_unlock_irqrestore(&adapter->erp_lock, flags);
352 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
353} 362}
354 363
355static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, 364static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
@@ -377,15 +386,13 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
377 */ 386 */
378int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref) 387int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref)
379{ 388{
380 unsigned long flags;
381 int retval; 389 int retval;
390 unsigned long flags;
382 struct zfcp_adapter *adapter = port->adapter; 391 struct zfcp_adapter *adapter = port->adapter;
383 392
384 read_lock_irqsave(&zfcp_data.config_lock, flags); 393 write_lock_irqsave(&adapter->erp_lock, flags);
385 write_lock(&adapter->erp_lock);
386 retval = _zfcp_erp_port_reopen(port, clear, id, ref); 394 retval = _zfcp_erp_port_reopen(port, clear, id, ref);
387 write_unlock(&adapter->erp_lock); 395 write_unlock_irqrestore(&adapter->erp_lock, flags);
388 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
389 396
390 return retval; 397 return retval;
391} 398}
@@ -424,11 +431,9 @@ void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
424 struct zfcp_port *port = unit->port; 431 struct zfcp_port *port = unit->port;
425 struct zfcp_adapter *adapter = port->adapter; 432 struct zfcp_adapter *adapter = port->adapter;
426 433
427 read_lock_irqsave(&zfcp_data.config_lock, flags); 434 write_lock_irqsave(&adapter->erp_lock, flags);
428 write_lock(&adapter->erp_lock);
429 _zfcp_erp_unit_reopen(unit, clear, id, ref); 435 _zfcp_erp_unit_reopen(unit, clear, id, ref);
430 write_unlock(&adapter->erp_lock); 436 write_unlock_irqrestore(&adapter->erp_lock, flags);
431 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
432} 437}
433 438
434static int status_change_set(unsigned long mask, atomic_t *status) 439static int status_change_set(unsigned long mask, atomic_t *status)
@@ -540,8 +545,10 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
540{ 545{
541 struct zfcp_port *port; 546 struct zfcp_port *port;
542 547
543 list_for_each_entry(port, &adapter->port_list_head, list) 548 read_lock(&adapter->port_list_lock);
549 list_for_each_entry(port, &adapter->port_list, list)
544 _zfcp_erp_port_reopen(port, clear, id, ref); 550 _zfcp_erp_port_reopen(port, clear, id, ref);
551 read_unlock(&adapter->port_list_lock);
545} 552}
546 553
547static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, 554static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
@@ -549,8 +556,10 @@ static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
549{ 556{
550 struct zfcp_unit *unit; 557 struct zfcp_unit *unit;
551 558
552 list_for_each_entry(unit, &port->unit_list_head, list) 559 read_lock(&port->unit_list_lock);
560 list_for_each_entry(unit, &port->unit_list, list)
553 _zfcp_erp_unit_reopen(unit, clear, id, ref); 561 _zfcp_erp_unit_reopen(unit, clear, id, ref);
562 read_unlock(&port->unit_list_lock);
554} 563}
555 564
556static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) 565static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
@@ -590,16 +599,14 @@ static void zfcp_erp_wakeup(struct zfcp_adapter *adapter)
590{ 599{
591 unsigned long flags; 600 unsigned long flags;
592 601
593 read_lock_irqsave(&zfcp_data.config_lock, flags); 602 read_lock_irqsave(&adapter->erp_lock, flags);
594 read_lock(&adapter->erp_lock);
595 if (list_empty(&adapter->erp_ready_head) && 603 if (list_empty(&adapter->erp_ready_head) &&
596 list_empty(&adapter->erp_running_head)) { 604 list_empty(&adapter->erp_running_head)) {
597 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, 605 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
598 &adapter->status); 606 &adapter->status);
599 wake_up(&adapter->erp_done_wqh); 607 wake_up(&adapter->erp_done_wqh);
600 } 608 }
601 read_unlock(&adapter->erp_lock); 609 read_unlock_irqrestore(&adapter->erp_lock, flags);
602 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
603} 610}
604 611
605static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act) 612static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act)
@@ -1214,11 +1221,10 @@ static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
1214static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) 1221static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
1215{ 1222{
1216 int retval; 1223 int retval;
1217 struct zfcp_adapter *adapter = erp_action->adapter;
1218 unsigned long flags; 1224 unsigned long flags;
1225 struct zfcp_adapter *adapter = erp_action->adapter;
1219 1226
1220 read_lock_irqsave(&zfcp_data.config_lock, flags); 1227 write_lock_irqsave(&adapter->erp_lock, flags);
1221 write_lock(&adapter->erp_lock);
1222 1228
1223 zfcp_erp_strategy_check_fsfreq(erp_action); 1229 zfcp_erp_strategy_check_fsfreq(erp_action);
1224 1230
@@ -1231,11 +1237,9 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
1231 zfcp_erp_action_to_running(erp_action); 1237 zfcp_erp_action_to_running(erp_action);
1232 1238
1233 /* no lock to allow for blocking operations */ 1239 /* no lock to allow for blocking operations */
1234 write_unlock(&adapter->erp_lock); 1240 write_unlock_irqrestore(&adapter->erp_lock, flags);
1235 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1236 retval = zfcp_erp_strategy_do_action(erp_action); 1241 retval = zfcp_erp_strategy_do_action(erp_action);
1237 read_lock_irqsave(&zfcp_data.config_lock, flags); 1242 write_lock_irqsave(&adapter->erp_lock, flags);
1238 write_lock(&adapter->erp_lock);
1239 1243
1240 if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) 1244 if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED)
1241 retval = ZFCP_ERP_CONTINUES; 1245 retval = ZFCP_ERP_CONTINUES;
@@ -1273,8 +1277,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
1273 zfcp_erp_strategy_followup_failed(erp_action); 1277 zfcp_erp_strategy_followup_failed(erp_action);
1274 1278
1275 unlock: 1279 unlock:
1276 write_unlock(&adapter->erp_lock); 1280 write_unlock_irqrestore(&adapter->erp_lock, flags);
1277 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1278 1281
1279 if (retval != ZFCP_ERP_CONTINUES) 1282 if (retval != ZFCP_ERP_CONTINUES)
1280 zfcp_erp_action_cleanup(erp_action, retval); 1283 zfcp_erp_action_cleanup(erp_action, retval);
@@ -1415,6 +1418,7 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id,
1415 void *ref, u32 mask, int set_or_clear) 1418 void *ref, u32 mask, int set_or_clear)
1416{ 1419{
1417 struct zfcp_port *port; 1420 struct zfcp_port *port;
1421 unsigned long flags;
1418 u32 common_mask = mask & ZFCP_COMMON_FLAGS; 1422 u32 common_mask = mask & ZFCP_COMMON_FLAGS;
1419 1423
1420 if (set_or_clear == ZFCP_SET) { 1424 if (set_or_clear == ZFCP_SET) {
@@ -1429,10 +1433,13 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id,
1429 atomic_set(&adapter->erp_counter, 0); 1433 atomic_set(&adapter->erp_counter, 0);
1430 } 1434 }
1431 1435
1432 if (common_mask) 1436 if (common_mask) {
1433 list_for_each_entry(port, &adapter->port_list_head, list) 1437 read_lock_irqsave(&adapter->port_list_lock, flags);
1438 list_for_each_entry(port, &adapter->port_list, list)
1434 zfcp_erp_modify_port_status(port, id, ref, common_mask, 1439 zfcp_erp_modify_port_status(port, id, ref, common_mask,
1435 set_or_clear); 1440 set_or_clear);
1441 read_unlock_irqrestore(&adapter->port_list_lock, flags);
1442 }
1436} 1443}
1437 1444
1438/** 1445/**
@@ -1449,6 +1456,7 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref,
1449 u32 mask, int set_or_clear) 1456 u32 mask, int set_or_clear)
1450{ 1457{
1451 struct zfcp_unit *unit; 1458 struct zfcp_unit *unit;
1459 unsigned long flags;
1452 u32 common_mask = mask & ZFCP_COMMON_FLAGS; 1460 u32 common_mask = mask & ZFCP_COMMON_FLAGS;
1453 1461
1454 if (set_or_clear == ZFCP_SET) { 1462 if (set_or_clear == ZFCP_SET) {
@@ -1463,10 +1471,13 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref,
1463 atomic_set(&port->erp_counter, 0); 1471 atomic_set(&port->erp_counter, 0);
1464 } 1472 }
1465 1473
1466 if (common_mask) 1474 if (common_mask) {
1467 list_for_each_entry(unit, &port->unit_list_head, list) 1475 read_lock_irqsave(&port->unit_list_lock, flags);
1476 list_for_each_entry(unit, &port->unit_list, list)
1468 zfcp_erp_modify_unit_status(unit, id, ref, common_mask, 1477 zfcp_erp_modify_unit_status(unit, id, ref, common_mask,
1469 set_or_clear); 1478 set_or_clear);
1479 read_unlock_irqrestore(&port->unit_list_lock, flags);
1480 }
1470} 1481}
1471 1482
1472/** 1483/**
@@ -1502,12 +1513,8 @@ void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, char *id, void *ref,
1502 */ 1513 */
1503void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref) 1514void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref)
1504{ 1515{
1505 unsigned long flags;
1506
1507 read_lock_irqsave(&zfcp_data.config_lock, flags);
1508 zfcp_erp_modify_port_status(port, id, ref, 1516 zfcp_erp_modify_port_status(port, id, ref,
1509 ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); 1517 ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET);
1510 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1511 zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); 1518 zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref);
1512} 1519}
1513 1520
@@ -1535,13 +1542,9 @@ void zfcp_erp_unit_boxed(struct zfcp_unit *unit, char *id, void *ref)
1535 */ 1542 */
1536void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref) 1543void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref)
1537{ 1544{
1538 unsigned long flags;
1539
1540 read_lock_irqsave(&zfcp_data.config_lock, flags);
1541 zfcp_erp_modify_port_status(port, id, ref, 1545 zfcp_erp_modify_port_status(port, id, ref,
1542 ZFCP_STATUS_COMMON_ERP_FAILED | 1546 ZFCP_STATUS_COMMON_ERP_FAILED |
1543 ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); 1547 ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
1544 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1545} 1548}
1546 1549
1547/** 1550/**
@@ -1574,12 +1577,15 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id,
1574 void *ref) 1577 void *ref)
1575{ 1578{
1576 struct zfcp_unit *unit; 1579 struct zfcp_unit *unit;
1580 unsigned long flags;
1577 int status = atomic_read(&port->status); 1581 int status = atomic_read(&port->status);
1578 1582
1579 if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | 1583 if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED |
1580 ZFCP_STATUS_COMMON_ACCESS_BOXED))) { 1584 ZFCP_STATUS_COMMON_ACCESS_BOXED))) {
1581 list_for_each_entry(unit, &port->unit_list_head, list) 1585 read_lock_irqsave(&port->unit_list_lock, flags);
1586 list_for_each_entry(unit, &port->unit_list, list)
1582 zfcp_erp_unit_access_changed(unit, id, ref); 1587 zfcp_erp_unit_access_changed(unit, id, ref);
1588 read_unlock_irqrestore(&port->unit_list_lock, flags);
1583 return; 1589 return;
1584 } 1590 }
1585 1591
@@ -1595,14 +1601,14 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id,
1595void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id, 1601void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id,
1596 void *ref) 1602 void *ref)
1597{ 1603{
1598 struct zfcp_port *port;
1599 unsigned long flags; 1604 unsigned long flags;
1605 struct zfcp_port *port;
1600 1606
1601 if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) 1607 if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
1602 return; 1608 return;
1603 1609
1604 read_lock_irqsave(&zfcp_data.config_lock, flags); 1610 read_lock_irqsave(&adapter->port_list_lock, flags);
1605 list_for_each_entry(port, &adapter->port_list_head, list) 1611 list_for_each_entry(port, &adapter->port_list, list)
1606 zfcp_erp_port_access_changed(port, id, ref); 1612 zfcp_erp_port_access_changed(port, id, ref);
1607 read_unlock_irqrestore(&zfcp_data.config_lock, flags); 1613 read_unlock_irqrestore(&adapter->port_list_lock, flags);
1608} 1614}