Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -10,6 +10,14 @@
#include <asm/acpi.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
 *
@@ -104,3 +112,22 @@ void __init mca_nmi_hook(void)
	printk("NMI generated from unknown source!\n");
}
#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);
+25 −2
Original line number Diff line number Diff line
@@ -4,11 +4,34 @@
void send_IPI_mask_bitmask(cpumask_t mask, 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)
{
	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)
{
	/*
@@ -18,13 +41,13 @@ static inline void send_IPI_allbutself(int vector)
	if (!(num_online_cpus() > 1))
		return;

	__send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
	__local_send_IPI_allbutself(vector);
	return;
}

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 */