Commit 67664c8f authored by Ashok Raj's avatar Ashok Raj Committed by Linus Torvalds

[PATCH] i386: Dont use IPI broadcast when using cpu hotplug.

This patch introduces a startup parameter no_broadcast.  When we enable
CONFIG_HOTPLUG_CPU, we dont want to use broadcast shortcut as it has ill
effects on a offline cpu.  If we issue broadcast, the IPI is also delivered
to offline cpus, or partially up cpu causing stale IPI's to be handled,
which is a problem and can cause undesirable effects.

Introduces a new startup cmdline option no_ipi_broadcast, that can be
switched at cmdline if necessary.
Signed-off-by: default avatarAshok Raj <ashok.raj@intel.com>
Acked-by: default avatarShaohua Li <shaohua.li@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f3705136
...@@ -10,6 +10,14 @@ ...@@ -10,6 +10,14 @@
#include <asm/acpi.h> #include <asm/acpi.h>
#include <asm/arch_hooks.h> #include <asm/arch_hooks.h>
#ifdef CONFIG_HOTPLUG_CPU
#define DEFAULT_SEND_IPI (1)
#else
#define DEFAULT_SEND_IPI (0)
#endif
int no_broadcast=DEFAULT_SEND_IPI;
/** /**
* pre_intr_init_hook - initialisation prior to setting up interrupt vectors * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
* *
...@@ -104,3 +112,22 @@ void __init mca_nmi_hook(void) ...@@ -104,3 +112,22 @@ void __init mca_nmi_hook(void)
printk("NMI generated from unknown source!\n"); printk("NMI generated from unknown source!\n");
} }
#endif #endif
static __init int no_ipi_broadcast(char *str)
{
get_option(&str, &no_broadcast);
printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" :
"IPI Broadcast");
return 1;
}
__setup("no_ipi_broadcast", no_ipi_broadcast);
static int __init print_ipi_mode(void)
{
printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" :
"Shortcut");
return 0;
}
late_initcall(print_ipi_mode);
...@@ -4,11 +4,34 @@ ...@@ -4,11 +4,34 @@
void send_IPI_mask_bitmask(cpumask_t mask, int vector); void send_IPI_mask_bitmask(cpumask_t mask, int vector);
void __send_IPI_shortcut(unsigned int shortcut, int vector); void __send_IPI_shortcut(unsigned int shortcut, int vector);
extern int no_broadcast;
static inline void send_IPI_mask(cpumask_t mask, int vector) static inline void send_IPI_mask(cpumask_t mask, int vector)
{ {
send_IPI_mask_bitmask(mask, vector); send_IPI_mask_bitmask(mask, vector);
} }
static inline void __local_send_IPI_allbutself(int vector)
{
if (no_broadcast) {
cpumask_t mask = cpu_online_map;
int this_cpu = get_cpu();
cpu_clear(this_cpu, mask);
send_IPI_mask(mask, vector);
put_cpu();
} else
__send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
}
static inline void __local_send_IPI_all(int vector)
{
if (no_broadcast)
send_IPI_mask(cpu_online_map, vector);
else
__send_IPI_shortcut(APIC_DEST_ALLINC, vector);
}
static inline void send_IPI_allbutself(int vector) static inline void send_IPI_allbutself(int vector)
{ {
/* /*
...@@ -18,13 +41,13 @@ static inline void send_IPI_allbutself(int vector) ...@@ -18,13 +41,13 @@ static inline void send_IPI_allbutself(int vector)
if (!(num_online_cpus() > 1)) if (!(num_online_cpus() > 1))
return; return;
__send_IPI_shortcut(APIC_DEST_ALLBUT, vector); __local_send_IPI_allbutself(vector);
return; return;
} }
static inline void send_IPI_all(int vector) static inline void send_IPI_all(int vector)
{ {
__send_IPI_shortcut(APIC_DEST_ALLINC, vector); __local_send_IPI_all(vector);
} }
#endif /* __ASM_MACH_IPI_H */ #endif /* __ASM_MACH_IPI_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment