aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_erp.c
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2008-10-01 06:42:17 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-10-03 13:11:53 -0400
commit5ab944f97e09a3d52951fe903eed9a7b88d810b2 (patch)
tree266171323bd7c5dfc433efd70ca19aafc891598c /drivers/s390/scsi/zfcp_erp.c
parent44cc76f2d154aa24340354b4711a0fe7f8f08adc (diff)
[SCSI] zfcp: attach and release SAN nameserver port on demand
Changing the zfcp behaviour from always having the nameserver port open to an on-demand strategy. This strategy reduces the use of limited resources like port connections. The patch provides a common infrastructure which could be used for all WKA ports in future. Also reduce the number of nameserver lookups by changing the zfcp behaviour of always querying the nameserver for the corresponding destination ID of the remote port. If the destination ID has changed during the reopen process we will be informed and then trigger a nameserver query on demand. 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@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r--drivers/s390/scsi/zfcp_erp.c149
1 files changed, 40 insertions, 109 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index b18c6dd37294..e7d3bce51429 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -23,7 +23,6 @@ enum zfcp_erp_steps {
23 ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001, 23 ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001,
24 ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, 24 ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010,
25 ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, 25 ZFCP_ERP_STEP_PORT_CLOSING = 0x0100,
26 ZFCP_ERP_STEP_NAMESERVER_OPEN = 0x0200,
27 ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400, 26 ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400,
28 ZFCP_ERP_STEP_PORT_OPENING = 0x0800, 27 ZFCP_ERP_STEP_PORT_OPENING = 0x0800,
29 ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000, 28 ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000,
@@ -532,8 +531,7 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
532 struct zfcp_port *port; 531 struct zfcp_port *port;
533 532
534 list_for_each_entry(port, &adapter->port_list_head, list) 533 list_for_each_entry(port, &adapter->port_list_head, list)
535 if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)) 534 _zfcp_erp_port_reopen(port, clear, id, ref);
536 _zfcp_erp_port_reopen(port, clear, id, ref);
537} 535}
538 536
539static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id, 537static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id,
@@ -777,7 +775,6 @@ static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)
777static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) 775static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
778{ 776{
779 atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | 777 atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
780 ZFCP_STATUS_PORT_DID_DID |
781 ZFCP_STATUS_PORT_PHYS_CLOSING | 778 ZFCP_STATUS_PORT_PHYS_CLOSING |
782 ZFCP_STATUS_PORT_INVALID_WWPN, 779 ZFCP_STATUS_PORT_INVALID_WWPN,
783 &port->status); 780 &port->status);
@@ -830,62 +827,6 @@ static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action)
830 return ZFCP_ERP_CONTINUES; 827 return ZFCP_ERP_CONTINUES;
831} 828}
832 829
833static void zfcp_erp_port_strategy_open_ns_wake(struct zfcp_erp_action *ns_act)
834{
835 unsigned long flags;
836 struct zfcp_adapter *adapter = ns_act->adapter;
837 struct zfcp_erp_action *act, *tmp;
838 int status;
839
840 read_lock_irqsave(&adapter->erp_lock, flags);
841 list_for_each_entry_safe(act, tmp, &adapter->erp_running_head, list) {
842 if (act->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) {
843 status = atomic_read(&adapter->nameserver_port->status);
844 if (status & ZFCP_STATUS_COMMON_ERP_FAILED)
845 zfcp_erp_port_failed(act->port, 27, NULL);
846 zfcp_erp_action_ready(act);
847 }
848 }
849 read_unlock_irqrestore(&adapter->erp_lock, flags);
850}
851
852static int zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *act)
853{
854 int retval;
855
856 switch (act->step) {
857 case ZFCP_ERP_STEP_UNINITIALIZED:
858 case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
859 case ZFCP_ERP_STEP_PORT_CLOSING:
860 return zfcp_erp_port_strategy_open_port(act);
861
862 case ZFCP_ERP_STEP_PORT_OPENING:
863 if (atomic_read(&act->port->status) & ZFCP_STATUS_COMMON_OPEN)
864 retval = ZFCP_ERP_SUCCEEDED;
865 else
866 retval = ZFCP_ERP_FAILED;
867 /* this is needed anyway */
868 zfcp_erp_port_strategy_open_ns_wake(act);
869 return retval;
870
871 default:
872 return ZFCP_ERP_FAILED;
873 }
874}
875
876static int zfcp_erp_port_strategy_open_lookup(struct zfcp_erp_action *act)
877{
878 int retval;
879
880 retval = zfcp_fc_ns_gid_pn_request(act);
881 if (retval == -ENOMEM)
882 return ZFCP_ERP_NOMEM;
883 act->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
884 if (retval)
885 return ZFCP_ERP_FAILED;
886 return ZFCP_ERP_CONTINUES;
887}
888
889static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) 830static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
890{ 831{
891 struct zfcp_adapter *adapter = act->adapter; 832 struct zfcp_adapter *adapter = act->adapter;
@@ -900,11 +841,25 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
900 return zfcp_erp_port_strategy_open_port(act); 841 return zfcp_erp_port_strategy_open_port(act);
901} 842}
902 843
844void zfcp_erp_port_strategy_open_lookup(struct work_struct *work)
845{
846 int retval;
847 struct zfcp_port *port = container_of(work, struct zfcp_port,
848 gid_pn_work);
849
850 retval = zfcp_fc_ns_gid_pn(&port->erp_action);
851 if (retval == -ENOMEM)
852 zfcp_erp_notify(&port->erp_action, ZFCP_ERP_NOMEM);
853 port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
854 if (retval)
855 zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED);
856
857}
858
903static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) 859static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
904{ 860{
905 struct zfcp_adapter *adapter = act->adapter; 861 struct zfcp_adapter *adapter = act->adapter;
906 struct zfcp_port *port = act->port; 862 struct zfcp_port *port = act->port;
907 struct zfcp_port *ns_port = adapter->nameserver_port;
908 int p_status = atomic_read(&port->status); 863 int p_status = atomic_read(&port->status);
909 864
910 switch (act->step) { 865 switch (act->step) {
@@ -913,29 +868,10 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
913 case ZFCP_ERP_STEP_PORT_CLOSING: 868 case ZFCP_ERP_STEP_PORT_CLOSING:
914 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) 869 if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
915 return zfcp_erp_open_ptp_port(act); 870 return zfcp_erp_open_ptp_port(act);
916 if (!ns_port) { 871 if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
917 dev_err(&adapter->ccw_device->dev, 872 schedule_work(&port->gid_pn_work);
918 "Attaching the name server port to the " 873 return ZFCP_ERP_CONTINUES;
919 "FCP device failed\n");
920 return ZFCP_ERP_FAILED;
921 }
922 if (!(atomic_read(&ns_port->status) &
923 ZFCP_STATUS_COMMON_UNBLOCKED)) {
924 /* nameserver port may live again */
925 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING,
926 &ns_port->status);
927 if (zfcp_erp_port_reopen(ns_port, 0, 77, act) >= 0) {
928 act->step = ZFCP_ERP_STEP_NAMESERVER_OPEN;
929 return ZFCP_ERP_CONTINUES;
930 }
931 return ZFCP_ERP_FAILED;
932 } 874 }
933 /* else nameserver port is already open, fall through */
934 case ZFCP_ERP_STEP_NAMESERVER_OPEN:
935 if (!(atomic_read(&ns_port->status) & ZFCP_STATUS_COMMON_OPEN))
936 return ZFCP_ERP_FAILED;
937 return zfcp_erp_port_strategy_open_lookup(act);
938
939 case ZFCP_ERP_STEP_NAMESERVER_LOOKUP: 875 case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
940 if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) { 876 if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) {
941 if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) { 877 if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) {
@@ -948,25 +884,26 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
948 884
949 case ZFCP_ERP_STEP_PORT_OPENING: 885 case ZFCP_ERP_STEP_PORT_OPENING:
950 /* D_ID might have changed during open */ 886 /* D_ID might have changed during open */
951 if ((p_status & ZFCP_STATUS_COMMON_OPEN) && 887 if (p_status & ZFCP_STATUS_COMMON_OPEN) {
952 (p_status & ZFCP_STATUS_PORT_DID_DID)) 888 if (p_status & ZFCP_STATUS_PORT_DID_DID)
953 return ZFCP_ERP_SUCCEEDED; 889 return ZFCP_ERP_SUCCEEDED;
890 else {
891 act->step = ZFCP_ERP_STEP_PORT_CLOSING;
892 return ZFCP_ERP_CONTINUES;
893 }
954 /* fall through otherwise */ 894 /* fall through otherwise */
895 }
955 } 896 }
956 return ZFCP_ERP_FAILED; 897 return ZFCP_ERP_FAILED;
957} 898}
958 899
959static int zfcp_erp_port_strategy_open(struct zfcp_erp_action *act)
960{
961 if (atomic_read(&act->port->status) & (ZFCP_STATUS_PORT_WKA))
962 return zfcp_erp_port_strategy_open_nameserver(act);
963 return zfcp_erp_port_strategy_open_common(act);
964}
965
966static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) 900static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
967{ 901{
968 struct zfcp_port *port = erp_action->port; 902 struct zfcp_port *port = erp_action->port;
969 903
904 if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC)
905 goto close_init_done;
906
970 switch (erp_action->step) { 907 switch (erp_action->step) {
971 case ZFCP_ERP_STEP_UNINITIALIZED: 908 case ZFCP_ERP_STEP_UNINITIALIZED:
972 zfcp_erp_port_strategy_clearstati(port); 909 zfcp_erp_port_strategy_clearstati(port);
@@ -979,12 +916,12 @@ static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
979 return ZFCP_ERP_FAILED; 916 return ZFCP_ERP_FAILED;
980 break; 917 break;
981 } 918 }
919
920close_init_done:
982 if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) 921 if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
983 return ZFCP_ERP_EXIT; 922 return ZFCP_ERP_EXIT;
984 else
985 return zfcp_erp_port_strategy_open(erp_action);
986 923
987 return ZFCP_ERP_FAILED; 924 return zfcp_erp_port_strategy_open_common(erp_action);
988} 925}
989 926
990static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) 927static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
@@ -1296,12 +1233,10 @@ static void zfcp_erp_rport_register(struct zfcp_port *port)
1296static void zfcp_erp_rports_del(struct zfcp_adapter *adapter) 1233static void zfcp_erp_rports_del(struct zfcp_adapter *adapter)
1297{ 1234{
1298 struct zfcp_port *port; 1235 struct zfcp_port *port;
1299 list_for_each_entry(port, &adapter->port_list_head, list) 1236 list_for_each_entry(port, &adapter->port_list_head, list) {
1300 if (port->rport && !(atomic_read(&port->status) & 1237 fc_remote_port_delete(port->rport);
1301 ZFCP_STATUS_PORT_WKA)) { 1238 port->rport = NULL;
1302 fc_remote_port_delete(port->rport); 1239 }
1303 port->rport = NULL;
1304 }
1305} 1240}
1306 1241
1307static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) 1242static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
@@ -1737,9 +1672,8 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id,
1737 1672
1738 if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | 1673 if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED |
1739 ZFCP_STATUS_COMMON_ACCESS_BOXED))) { 1674 ZFCP_STATUS_COMMON_ACCESS_BOXED))) {
1740 if (!(status & ZFCP_STATUS_PORT_WKA)) 1675 list_for_each_entry(unit, &port->unit_list_head, list)
1741 list_for_each_entry(unit, &port->unit_list_head, list) 1676 zfcp_erp_unit_access_changed(unit, id, ref);
1742 zfcp_erp_unit_access_changed(unit, id, ref);
1743 return; 1677 return;
1744 } 1678 }
1745 1679
@@ -1762,10 +1696,7 @@ void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id,
1762 return; 1696 return;
1763 1697
1764 read_lock_irqsave(&zfcp_data.config_lock, flags); 1698 read_lock_irqsave(&zfcp_data.config_lock, flags);
1765 if (adapter->nameserver_port)
1766 zfcp_erp_port_access_changed(adapter->nameserver_port, id, ref);
1767 list_for_each_entry(port, &adapter->port_list_head, list) 1699 list_for_each_entry(port, &adapter->port_list_head, list)
1768 if (port != adapter->nameserver_port) 1700 zfcp_erp_port_access_changed(port, id, ref);
1769 zfcp_erp_port_access_changed(port, id, ref);
1770 read_unlock_irqrestore(&zfcp_data.config_lock, flags); 1701 read_unlock_irqrestore(&zfcp_data.config_lock, flags);
1771} 1702}