Skip to content

Commit 2ddded2

Browse files
ehabkostIngo Molnar
authored andcommitted
x86: move nmi_shootdown_cpus() to reboot.c
Impact: make nmi_shootdown_cpus() available to the rest of the x86 platform Now nmi_shootdown_cpus() is ready to be used by non-kdump code also. Move it to reboot.c. Signed-off-by: Eduardo Habkost <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
1 parent c370e5e commit 2ddded2

File tree

2 files changed

+83
-76
lines changed

2 files changed

+83
-76
lines changed

arch/x86/kernel/crash.c

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,6 @@
3232

3333
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
3434

35-
/* This keeps a track of which one is crashing cpu. */
36-
static int crashing_cpu;
37-
static nmi_shootdown_cb shootdown_callback;
38-
39-
static atomic_t waiting_for_crash_ipi;
40-
4135
static void kdump_nmi_callback(int cpu, struct die_args *args)
4236
{
4337
struct pt_regs *regs;
@@ -58,76 +52,6 @@ static void kdump_nmi_callback(int cpu, struct die_args *args)
5852
disable_local_APIC();
5953
}
6054

61-
static int crash_nmi_callback(struct notifier_block *self,
62-
unsigned long val, void *data)
63-
{
64-
int cpu;
65-
66-
if (val != DIE_NMI_IPI)
67-
return NOTIFY_OK;
68-
69-
cpu = raw_smp_processor_id();
70-
71-
/* Don't do anything if this handler is invoked on crashing cpu.
72-
* Otherwise, system will completely hang. Crashing cpu can get
73-
* an NMI if system was initially booted with nmi_watchdog parameter.
74-
*/
75-
if (cpu == crashing_cpu)
76-
return NOTIFY_STOP;
77-
local_irq_disable();
78-
79-
shootdown_callback(cpu, (struct die_args *)data);
80-
81-
atomic_dec(&waiting_for_crash_ipi);
82-
/* Assume hlt works */
83-
halt();
84-
for (;;)
85-
cpu_relax();
86-
87-
return 1;
88-
}
89-
90-
static void smp_send_nmi_allbutself(void)
91-
{
92-
cpumask_t mask = cpu_online_map;
93-
cpu_clear(safe_smp_processor_id(), mask);
94-
if (!cpus_empty(mask))
95-
send_IPI_mask(mask, NMI_VECTOR);
96-
}
97-
98-
static struct notifier_block crash_nmi_nb = {
99-
.notifier_call = crash_nmi_callback,
100-
};
101-
102-
void nmi_shootdown_cpus(nmi_shootdown_cb callback)
103-
{
104-
unsigned long msecs;
105-
106-
/* Make a note of crashing cpu. Will be used in NMI callback.*/
107-
crashing_cpu = safe_smp_processor_id();
108-
109-
shootdown_callback = callback;
110-
111-
atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
112-
/* Would it be better to replace the trap vector here? */
113-
if (register_die_notifier(&crash_nmi_nb))
114-
return; /* return what? */
115-
/* Ensure the new callback function is set before sending
116-
* out the NMI
117-
*/
118-
wmb();
119-
120-
smp_send_nmi_allbutself();
121-
122-
msecs = 1000; /* Wait at most a second for the other cpus to stop */
123-
while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
124-
mdelay(1);
125-
msecs--;
126-
}
127-
128-
/* Leave the nmi callback set */
129-
}
130-
13155
static void kdump_nmi_shootdown_cpus(void)
13256
{
13357
nmi_shootdown_cpus(kdump_nmi_callback);

arch/x86/kernel/reboot.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
# include <asm/iommu.h>
2222
#endif
2323

24+
#include <mach_ipi.h>
25+
26+
2427
/*
2528
* Power off function, if any
2629
*/
@@ -514,3 +517,83 @@ void machine_crash_shutdown(struct pt_regs *regs)
514517
machine_ops.crash_shutdown(regs);
515518
}
516519
#endif
520+
521+
522+
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
523+
524+
/* This keeps a track of which one is crashing cpu. */
525+
static int crashing_cpu;
526+
static nmi_shootdown_cb shootdown_callback;
527+
528+
static atomic_t waiting_for_crash_ipi;
529+
530+
static int crash_nmi_callback(struct notifier_block *self,
531+
unsigned long val, void *data)
532+
{
533+
int cpu;
534+
535+
if (val != DIE_NMI_IPI)
536+
return NOTIFY_OK;
537+
538+
cpu = raw_smp_processor_id();
539+
540+
/* Don't do anything if this handler is invoked on crashing cpu.
541+
* Otherwise, system will completely hang. Crashing cpu can get
542+
* an NMI if system was initially booted with nmi_watchdog parameter.
543+
*/
544+
if (cpu == crashing_cpu)
545+
return NOTIFY_STOP;
546+
local_irq_disable();
547+
548+
shootdown_callback(cpu, (struct die_args *)data);
549+
550+
atomic_dec(&waiting_for_crash_ipi);
551+
/* Assume hlt works */
552+
halt();
553+
for (;;)
554+
cpu_relax();
555+
556+
return 1;
557+
}
558+
559+
static void smp_send_nmi_allbutself(void)
560+
{
561+
cpumask_t mask = cpu_online_map;
562+
cpu_clear(safe_smp_processor_id(), mask);
563+
if (!cpus_empty(mask))
564+
send_IPI_mask(mask, NMI_VECTOR);
565+
}
566+
567+
static struct notifier_block crash_nmi_nb = {
568+
.notifier_call = crash_nmi_callback,
569+
};
570+
571+
void nmi_shootdown_cpus(nmi_shootdown_cb callback)
572+
{
573+
unsigned long msecs;
574+
575+
/* Make a note of crashing cpu. Will be used in NMI callback.*/
576+
crashing_cpu = safe_smp_processor_id();
577+
578+
shootdown_callback = callback;
579+
580+
atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
581+
/* Would it be better to replace the trap vector here? */
582+
if (register_die_notifier(&crash_nmi_nb))
583+
return; /* return what? */
584+
/* Ensure the new callback function is set before sending
585+
* out the NMI
586+
*/
587+
wmb();
588+
589+
smp_send_nmi_allbutself();
590+
591+
msecs = 1000; /* Wait at most a second for the other cpus to stop */
592+
while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
593+
mdelay(1);
594+
msecs--;
595+
}
596+
597+
/* Leave the nmi callback set */
598+
}
599+
#endif

0 commit comments

Comments
 (0)