diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2009-11-24 10:53:58 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:02:01 -0500 |
commit | ecf0c7721b104c0ce9c8ca534c911f6310cf92a8 (patch) | |
tree | 639032b36bcbbe905c98c6f0b3b521dc2f0b1806 /drivers/s390/scsi/zfcp_erp.c | |
parent | 0a55256d158c18e4821c248a295b7f8f4423660f (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.c | 116 |
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 | ||
107 | static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) | 110 | static 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 | ||
118 | static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, | 124 | static 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 | ||
355 | static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, | 364 | static 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 | */ |
378 | int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref) | 387 | int 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 | ||
434 | static int status_change_set(unsigned long mask, atomic_t *status) | 439 | static 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 | ||
547 | static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, | 554 | static 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 | ||
556 | static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) | 565 | static 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 | ||
605 | static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act) | 612 | static 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) | |||
1214 | static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) | 1221 | static 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 | */ |
1503 | void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref) | 1514 | void 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 | */ |
1536 | void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref) | 1543 | void 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, | |||
1595 | void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id, | 1601 | void 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 | } |