diff options
-rw-r--r-- | arch/ia64/sn/kernel/xpc.h | 1 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/xpc_main.c | 87 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/xpc_partition.c | 3 |
3 files changed, 68 insertions, 23 deletions
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h index 66b17b6aa81f..82e7430be789 100644 --- a/arch/ia64/sn/kernel/xpc.h +++ b/arch/ia64/sn/kernel/xpc.h | |||
@@ -663,6 +663,7 @@ extern struct xpc_registration xpc_registrations[]; | |||
663 | extern struct device *xpc_part; | 663 | extern struct device *xpc_part; |
664 | extern struct device *xpc_chan; | 664 | extern struct device *xpc_chan; |
665 | extern int xpc_disengage_request_timelimit; | 665 | extern int xpc_disengage_request_timelimit; |
666 | extern int xpc_disengage_request_timedout; | ||
666 | extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *); | 667 | extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *); |
667 | extern void xpc_dropped_IPI_check(struct xpc_partition *); | 668 | extern void xpc_dropped_IPI_check(struct xpc_partition *); |
668 | extern void xpc_activate_partition(struct xpc_partition *); | 669 | extern void xpc_activate_partition(struct xpc_partition *); |
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index 6708ef6e0618..948206b13f68 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c | |||
@@ -162,6 +162,8 @@ static ctl_table xpc_sys_dir[] = { | |||
162 | }; | 162 | }; |
163 | static struct ctl_table_header *xpc_sysctl; | 163 | static struct ctl_table_header *xpc_sysctl; |
164 | 164 | ||
165 | /* non-zero if any remote partition disengage request was timed out */ | ||
166 | int xpc_disengage_request_timedout; | ||
165 | 167 | ||
166 | /* #of IRQs received */ | 168 | /* #of IRQs received */ |
167 | static atomic_t xpc_act_IRQ_rcvd; | 169 | static atomic_t xpc_act_IRQ_rcvd; |
@@ -921,9 +923,9 @@ static void | |||
921 | xpc_do_exit(enum xpc_retval reason) | 923 | xpc_do_exit(enum xpc_retval reason) |
922 | { | 924 | { |
923 | partid_t partid; | 925 | partid_t partid; |
924 | int active_part_count; | 926 | int active_part_count, printed_waiting_msg = 0; |
925 | struct xpc_partition *part; | 927 | struct xpc_partition *part; |
926 | unsigned long printmsg_time; | 928 | unsigned long printmsg_time, disengage_request_timeout = 0; |
927 | 929 | ||
928 | 930 | ||
929 | /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */ | 931 | /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */ |
@@ -953,7 +955,8 @@ xpc_do_exit(enum xpc_retval reason) | |||
953 | 955 | ||
954 | /* wait for all partitions to become inactive */ | 956 | /* wait for all partitions to become inactive */ |
955 | 957 | ||
956 | printmsg_time = jiffies; | 958 | printmsg_time = jiffies + (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); |
959 | xpc_disengage_request_timedout = 0; | ||
957 | 960 | ||
958 | do { | 961 | do { |
959 | active_part_count = 0; | 962 | active_part_count = 0; |
@@ -969,20 +972,39 @@ xpc_do_exit(enum xpc_retval reason) | |||
969 | active_part_count++; | 972 | active_part_count++; |
970 | 973 | ||
971 | XPC_DEACTIVATE_PARTITION(part, reason); | 974 | XPC_DEACTIVATE_PARTITION(part, reason); |
972 | } | ||
973 | 975 | ||
974 | if (active_part_count == 0) { | 976 | if (part->disengage_request_timeout > |
975 | break; | 977 | disengage_request_timeout) { |
978 | disengage_request_timeout = | ||
979 | part->disengage_request_timeout; | ||
980 | } | ||
976 | } | 981 | } |
977 | 982 | ||
978 | if (jiffies >= printmsg_time) { | 983 | if (xpc_partition_engaged(-1UL)) { |
979 | dev_info(xpc_part, "waiting for partitions to " | 984 | if (time_after(jiffies, printmsg_time)) { |
980 | "deactivate/disengage, active count=%d, remote " | 985 | dev_info(xpc_part, "waiting for remote " |
981 | "engaged=0x%lx\n", active_part_count, | 986 | "partitions to disengage, timeout in " |
982 | xpc_partition_engaged(1UL << partid)); | 987 | "%ld seconds\n", |
983 | 988 | (disengage_request_timeout - jiffies) | |
984 | printmsg_time = jiffies + | 989 | / HZ); |
990 | printmsg_time = jiffies + | ||
985 | (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); | 991 | (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ); |
992 | printed_waiting_msg = 1; | ||
993 | } | ||
994 | |||
995 | } else if (active_part_count > 0) { | ||
996 | if (printed_waiting_msg) { | ||
997 | dev_info(xpc_part, "waiting for local partition" | ||
998 | " to disengage\n"); | ||
999 | printed_waiting_msg = 0; | ||
1000 | } | ||
1001 | |||
1002 | } else { | ||
1003 | if (!xpc_disengage_request_timedout) { | ||
1004 | dev_info(xpc_part, "all partitions have " | ||
1005 | "disengaged\n"); | ||
1006 | } | ||
1007 | break; | ||
986 | } | 1008 | } |
987 | 1009 | ||
988 | /* sleep for a 1/3 of a second or so */ | 1010 | /* sleep for a 1/3 of a second or so */ |
@@ -1028,7 +1050,7 @@ xpc_die_disengage(void) | |||
1028 | struct xpc_partition *part; | 1050 | struct xpc_partition *part; |
1029 | partid_t partid; | 1051 | partid_t partid; |
1030 | unsigned long engaged; | 1052 | unsigned long engaged; |
1031 | long time, print_time, disengage_request_timeout; | 1053 | long time, printmsg_time, disengage_request_timeout; |
1032 | 1054 | ||
1033 | 1055 | ||
1034 | /* keep xpc_hb_checker thread from doing anything (just in case) */ | 1056 | /* keep xpc_hb_checker thread from doing anything (just in case) */ |
@@ -1055,24 +1077,43 @@ xpc_die_disengage(void) | |||
1055 | } | 1077 | } |
1056 | } | 1078 | } |
1057 | 1079 | ||
1058 | print_time = rtc_time(); | 1080 | time = rtc_time(); |
1059 | disengage_request_timeout = print_time + | 1081 | printmsg_time = time + |
1082 | (XPC_DISENGAGE_PRINTMSG_INTERVAL * sn_rtc_cycles_per_second); | ||
1083 | disengage_request_timeout = time + | ||
1060 | (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); | 1084 | (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); |
1061 | 1085 | ||
1062 | /* wait for all other partitions to disengage from us */ | 1086 | /* wait for all other partitions to disengage from us */ |
1063 | 1087 | ||
1064 | while ((engaged = xpc_partition_engaged(-1UL)) && | 1088 | while (1) { |
1065 | (time = rtc_time()) < disengage_request_timeout) { | 1089 | engaged = xpc_partition_engaged(-1UL); |
1090 | if (!engaged) { | ||
1091 | dev_info(xpc_part, "all partitions have disengaged\n"); | ||
1092 | break; | ||
1093 | } | ||
1066 | 1094 | ||
1067 | if (time >= print_time) { | 1095 | time = rtc_time(); |
1096 | if (time >= disengage_request_timeout) { | ||
1097 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | ||
1098 | if (engaged & (1UL << partid)) { | ||
1099 | dev_info(xpc_part, "disengage from " | ||
1100 | "remote partition %d timed " | ||
1101 | "out\n", partid); | ||
1102 | } | ||
1103 | } | ||
1104 | break; | ||
1105 | } | ||
1106 | |||
1107 | if (time >= printmsg_time) { | ||
1068 | dev_info(xpc_part, "waiting for remote partitions to " | 1108 | dev_info(xpc_part, "waiting for remote partitions to " |
1069 | "disengage, engaged=0x%lx\n", engaged); | 1109 | "disengage, timeout in %ld seconds\n", |
1070 | print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL * | 1110 | (disengage_request_timeout - time) / |
1111 | sn_rtc_cycles_per_second); | ||
1112 | printmsg_time = time + | ||
1113 | (XPC_DISENGAGE_PRINTMSG_INTERVAL * | ||
1071 | sn_rtc_cycles_per_second); | 1114 | sn_rtc_cycles_per_second); |
1072 | } | 1115 | } |
1073 | } | 1116 | } |
1074 | dev_info(xpc_part, "finished waiting for remote partitions to " | ||
1075 | "disengage, engaged=0x%lx\n", engaged); | ||
1076 | } | 1117 | } |
1077 | 1118 | ||
1078 | 1119 | ||
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index cf02a9bcd245..6bc0409628c5 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c | |||
@@ -874,6 +874,9 @@ xpc_partition_disengaged(struct xpc_partition *part) | |||
874 | * request in a timely fashion, so assume it's dead. | 874 | * request in a timely fashion, so assume it's dead. |
875 | */ | 875 | */ |
876 | 876 | ||
877 | dev_info(xpc_part, "disengage from remote partition %d " | ||
878 | "timed out\n", partid); | ||
879 | xpc_disengage_request_timedout = 1; | ||
877 | xpc_clear_partition_engaged(1UL << partid); | 880 | xpc_clear_partition_engaged(1UL << partid); |
878 | disengaged = 1; | 881 | disengaged = 1; |
879 | } | 882 | } |