aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/sn/kernel/xpc.h1
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c87
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c3
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[];
663extern struct device *xpc_part; 663extern struct device *xpc_part;
664extern struct device *xpc_chan; 664extern struct device *xpc_chan;
665extern int xpc_disengage_request_timelimit; 665extern int xpc_disengage_request_timelimit;
666extern int xpc_disengage_request_timedout;
666extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *); 667extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *);
667extern void xpc_dropped_IPI_check(struct xpc_partition *); 668extern void xpc_dropped_IPI_check(struct xpc_partition *);
668extern void xpc_activate_partition(struct xpc_partition *); 669extern 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};
163static struct ctl_table_header *xpc_sysctl; 163static struct ctl_table_header *xpc_sysctl;
164 164
165/* non-zero if any remote partition disengage request was timed out */
166int xpc_disengage_request_timedout;
165 167
166/* #of IRQs received */ 168/* #of IRQs received */
167static atomic_t xpc_act_IRQ_rcvd; 169static atomic_t xpc_act_IRQ_rcvd;
@@ -921,9 +923,9 @@ static void
921xpc_do_exit(enum xpc_retval reason) 923xpc_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 }