diff options
Diffstat (limited to 'arch/ia64/kernel/mca.c')
-rw-r--r-- | arch/ia64/kernel/mca.c | 88 |
1 files changed, 44 insertions, 44 deletions
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 63b73f3d4c9f..cc87025e8f54 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -701,8 +701,7 @@ ia64_mca_cmc_vector_enable_keventd(struct work_struct *unused) | |||
701 | /* | 701 | /* |
702 | * ia64_mca_wakeup | 702 | * ia64_mca_wakeup |
703 | * | 703 | * |
704 | * Send an inter-cpu interrupt to wake-up a particular cpu | 704 | * Send an inter-cpu interrupt to wake-up a particular cpu. |
705 | * and mark that cpu to be out of rendez. | ||
706 | * | 705 | * |
707 | * Inputs : cpuid | 706 | * Inputs : cpuid |
708 | * Outputs : None | 707 | * Outputs : None |
@@ -711,14 +710,12 @@ static void | |||
711 | ia64_mca_wakeup(int cpu) | 710 | ia64_mca_wakeup(int cpu) |
712 | { | 711 | { |
713 | platform_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0); | 712 | platform_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0); |
714 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; | ||
715 | |||
716 | } | 713 | } |
717 | 714 | ||
718 | /* | 715 | /* |
719 | * ia64_mca_wakeup_all | 716 | * ia64_mca_wakeup_all |
720 | * | 717 | * |
721 | * Wakeup all the cpus which have rendez'ed previously. | 718 | * Wakeup all the slave cpus which have rendez'ed previously. |
722 | * | 719 | * |
723 | * Inputs : None | 720 | * Inputs : None |
724 | * Outputs : None | 721 | * Outputs : None |
@@ -741,7 +738,10 @@ ia64_mca_wakeup_all(void) | |||
741 | * | 738 | * |
742 | * This is handler used to put slave processors into spinloop | 739 | * This is handler used to put slave processors into spinloop |
743 | * while the monarch processor does the mca handling and later | 740 | * while the monarch processor does the mca handling and later |
744 | * wake each slave up once the monarch is done. | 741 | * wake each slave up once the monarch is done. The state |
742 | * IA64_MCA_RENDEZ_CHECKIN_DONE indicates the cpu is rendez'ed | ||
743 | * in SAL. The state IA64_MCA_RENDEZ_CHECKIN_NOTDONE indicates | ||
744 | * the cpu has come out of OS rendezvous. | ||
745 | * | 745 | * |
746 | * Inputs : None | 746 | * Inputs : None |
747 | * Outputs : None | 747 | * Outputs : None |
@@ -778,6 +778,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg) | |||
778 | (long)&nd, 0, 0) == NOTIFY_STOP) | 778 | (long)&nd, 0, 0) == NOTIFY_STOP) |
779 | ia64_mca_spin(__FUNCTION__); | 779 | ia64_mca_spin(__FUNCTION__); |
780 | 780 | ||
781 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; | ||
781 | /* Enable all interrupts */ | 782 | /* Enable all interrupts */ |
782 | local_irq_restore(flags); | 783 | local_irq_restore(flags); |
783 | return IRQ_HANDLED; | 784 | return IRQ_HANDLED; |
@@ -1135,30 +1136,27 @@ no_mod: | |||
1135 | static void | 1136 | static void |
1136 | ia64_wait_for_slaves(int monarch, const char *type) | 1137 | ia64_wait_for_slaves(int monarch, const char *type) |
1137 | { | 1138 | { |
1138 | int c, wait = 0, missing = 0; | 1139 | int c, i , wait; |
1139 | for_each_online_cpu(c) { | 1140 | |
1140 | if (c == monarch) | 1141 | /* |
1141 | continue; | 1142 | * wait 5 seconds total for slaves (arbitrary) |
1142 | if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) { | 1143 | */ |
1143 | udelay(1000); /* short wait first */ | 1144 | for (i = 0; i < 5000; i++) { |
1144 | wait = 1; | 1145 | wait = 0; |
1145 | break; | 1146 | for_each_online_cpu(c) { |
1146 | } | 1147 | if (c == monarch) |
1147 | } | 1148 | continue; |
1148 | if (!wait) | 1149 | if (ia64_mc_info.imi_rendez_checkin[c] |
1149 | goto all_in; | 1150 | == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) { |
1150 | for_each_online_cpu(c) { | 1151 | udelay(1000); /* short wait */ |
1151 | if (c == monarch) | 1152 | wait = 1; |
1152 | continue; | 1153 | break; |
1153 | if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) { | 1154 | } |
1154 | udelay(5*1000000); /* wait 5 seconds for slaves (arbitrary) */ | ||
1155 | if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) | ||
1156 | missing = 1; | ||
1157 | break; | ||
1158 | } | 1155 | } |
1156 | if (!wait) | ||
1157 | goto all_in; | ||
1159 | } | 1158 | } |
1160 | if (!missing) | 1159 | |
1161 | goto all_in; | ||
1162 | /* | 1160 | /* |
1163 | * Maybe slave(s) dead. Print buffered messages immediately. | 1161 | * Maybe slave(s) dead. Print buffered messages immediately. |
1164 | */ | 1162 | */ |
@@ -1224,26 +1222,27 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1224 | if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0) | 1222 | if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0) |
1225 | == NOTIFY_STOP) | 1223 | == NOTIFY_STOP) |
1226 | ia64_mca_spin(__FUNCTION__); | 1224 | ia64_mca_spin(__FUNCTION__); |
1225 | |||
1226 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA; | ||
1227 | if (sos->monarch) { | 1227 | if (sos->monarch) { |
1228 | ia64_wait_for_slaves(cpu, "MCA"); | 1228 | ia64_wait_for_slaves(cpu, "MCA"); |
1229 | |||
1230 | /* Wakeup all the processors which are spinning in the | ||
1231 | * rendezvous loop. They will leave SAL, then spin in the OS | ||
1232 | * with interrupts disabled until this monarch cpu leaves the | ||
1233 | * MCA handler. That gets control back to the OS so we can | ||
1234 | * backtrace the other cpus, backtrace when spinning in SAL | ||
1235 | * does not work. | ||
1236 | */ | ||
1237 | ia64_mca_wakeup_all(); | ||
1238 | if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, (long)&nd, 0, 0) | ||
1239 | == NOTIFY_STOP) | ||
1240 | ia64_mca_spin(__FUNCTION__); | ||
1229 | } else { | 1241 | } else { |
1230 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA; | ||
1231 | while (cpu_isset(cpu, mca_cpu)) | 1242 | while (cpu_isset(cpu, mca_cpu)) |
1232 | cpu_relax(); /* spin until monarch wakes us */ | 1243 | cpu_relax(); /* spin until monarch wakes us */ |
1233 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; | ||
1234 | } | 1244 | } |
1235 | 1245 | ||
1236 | /* Wakeup all the processors which are spinning in the rendezvous loop. | ||
1237 | * They will leave SAL, then spin in the OS with interrupts disabled | ||
1238 | * until this monarch cpu leaves the MCA handler. That gets control | ||
1239 | * back to the OS so we can backtrace the other cpus, backtrace when | ||
1240 | * spinning in SAL does not work. | ||
1241 | */ | ||
1242 | ia64_mca_wakeup_all(); | ||
1243 | if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, (long)&nd, 0, 0) | ||
1244 | == NOTIFY_STOP) | ||
1245 | ia64_mca_spin(__FUNCTION__); | ||
1246 | |||
1247 | /* Get the MCA error record and log it */ | 1246 | /* Get the MCA error record and log it */ |
1248 | ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); | 1247 | ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); |
1249 | 1248 | ||
@@ -1277,21 +1276,22 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1277 | /* wake up the next monarch cpu, | 1276 | /* wake up the next monarch cpu, |
1278 | * and put this cpu in the rendez loop. | 1277 | * and put this cpu in the rendez loop. |
1279 | */ | 1278 | */ |
1280 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA; | ||
1281 | for_each_online_cpu(i) { | 1279 | for_each_online_cpu(i) { |
1282 | if (cpu_isset(i, mca_cpu)) { | 1280 | if (cpu_isset(i, mca_cpu)) { |
1283 | monarch_cpu = i; | 1281 | monarch_cpu = i; |
1284 | cpu_clear(i, mca_cpu); /* wake next cpu */ | 1282 | cpu_clear(i, mca_cpu); /* wake next cpu */ |
1285 | while (monarch_cpu != -1) | 1283 | while (monarch_cpu != -1) |
1286 | cpu_relax(); /* spin until last cpu leaves */ | 1284 | cpu_relax(); /* spin until last cpu leaves */ |
1287 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; | ||
1288 | set_curr_task(cpu, previous_current); | 1285 | set_curr_task(cpu, previous_current); |
1286 | ia64_mc_info.imi_rendez_checkin[cpu] | ||
1287 | = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; | ||
1289 | return; | 1288 | return; |
1290 | } | 1289 | } |
1291 | } | 1290 | } |
1292 | } | 1291 | } |
1293 | set_curr_task(cpu, previous_current); | 1292 | set_curr_task(cpu, previous_current); |
1294 | monarch_cpu = -1; | 1293 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; |
1294 | monarch_cpu = -1; /* This frees the slaves and previous monarchs */ | ||
1295 | } | 1295 | } |
1296 | 1296 | ||
1297 | static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd); | 1297 | static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd); |