diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-07-15 21:55:59 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-07-15 21:55:59 +0200 | 
| commit | 1a781a777b2f6ac46523fe92396215762ced624d (patch) | |
| tree | 4f34bb4aade85c0eb364b53d664ec7f6ab959006 /arch/alpha | |
| parent | b9d2252c1e44fa83a4e65fdc9eb93db6297c55af (diff) | |
| parent | 42a2f217a5e324ed5f2373ab1b7a0a15187c4d6c (diff) | |
| download | linux-1a781a777b2f6ac46523fe92396215762ced624d.tar.bz2 | |
Merge branch 'generic-ipi' into generic-ipi-for-linus
Conflicts:
	arch/powerpc/Kconfig
	arch/s390/kernel/time.c
	arch/x86/kernel/apic_32.c
	arch/x86/kernel/cpu/perfctr-watchdog.c
	arch/x86/kernel/i8259_64.c
	arch/x86/kernel/ldt.c
	arch/x86/kernel/nmi_64.c
	arch/x86/kernel/smpboot.c
	arch/x86/xen/smp.c
	include/asm-x86/hw_irq_32.h
	include/asm-x86/hw_irq_64.h
	include/asm-x86/mach-default/irq_vectors.h
	include/asm-x86/mach-voyager/irq_vectors.h
	include/asm-x86/smp.h
	kernel/Makefile
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/alpha')
| -rw-r--r-- | arch/alpha/Kconfig | 1 | ||||
| -rw-r--r-- | arch/alpha/kernel/core_marvel.c | 6 | ||||
| -rw-r--r-- | arch/alpha/kernel/process.c | 2 | ||||
| -rw-r--r-- | arch/alpha/kernel/smp.c | 180 | ||||
| -rw-r--r-- | arch/alpha/oprofile/common.c | 6 | 
5 files changed, 23 insertions, 172 deletions
| diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 729cdbdf8036..dbe8c280fea9 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -528,6 +528,7 @@ config ARCH_MAY_HAVE_PC_FDC  config SMP  	bool "Symmetric multi-processing support"  	depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL +	select USE_GENERIC_SMP_HELPERS  	---help---  	  This enables support for systems with more than one CPU. If you have  	  a system with only one CPU, like most personal computers, say N. If diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index b04f1feb1dda..04dcc5e5d4c1 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c @@ -660,9 +660,9 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write)  #ifdef CONFIG_SMP  		if (smp_processor_id() != boot_cpuid) -			smp_call_function_on_cpu(__marvel_access_rtc, -						 &rtc_access, 1, 1, -						 cpumask_of_cpu(boot_cpuid)); +			smp_call_function_single(boot_cpuid, +						 __marvel_access_rtc, +						 &rtc_access, 1);  		else  			__marvel_access_rtc(&rtc_access);  #else diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 96ed82fd9eef..351407e07e71 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -160,7 +160,7 @@ common_shutdown(int mode, char *restart_cmd)  	struct halt_info args;  	args.mode = mode;  	args.restart_cmd = restart_cmd; -	on_each_cpu(common_shutdown_1, &args, 1, 0); +	on_each_cpu(common_shutdown_1, &args, 0);  }  void diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 2525692db0ab..83df541650fc 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -62,6 +62,7 @@ static struct {  enum ipi_message_type {  	IPI_RESCHEDULE,  	IPI_CALL_FUNC, +	IPI_CALL_FUNC_SINGLE,  	IPI_CPU_STOP,  }; @@ -558,51 +559,6 @@ send_ipi_message(cpumask_t to_whom, enum ipi_message_type operation)  		wripir(i);  } -/* Structure and data for smp_call_function.  This is designed to  -   minimize static memory requirements.  Plus it looks cleaner.  */ - -struct smp_call_struct { -	void (*func) (void *info); -	void *info; -	long wait; -	atomic_t unstarted_count; -	atomic_t unfinished_count; -}; - -static struct smp_call_struct *smp_call_function_data; - -/* Atomicly drop data into a shared pointer.  The pointer is free if -   it is initially locked.  If retry, spin until free.  */ - -static int -pointer_lock (void *lock, void *data, int retry) -{ -	void *old, *tmp; - -	mb(); - again: -	/* Compare and swap with zero.  */ -	asm volatile ( -	"1:	ldq_l	%0,%1\n" -	"	mov	%3,%2\n" -	"	bne	%0,2f\n" -	"	stq_c	%2,%1\n" -	"	beq	%2,1b\n" -	"2:" -	: "=&r"(old), "=m"(*(void **)lock), "=&r"(tmp) -	: "r"(data) -	: "memory"); - -	if (old == 0) -		return 0; -	if (! retry) -		return -EBUSY; - -	while (*(void **)lock) -		barrier(); -	goto again; -} -  void  handle_ipi(struct pt_regs *regs)  { @@ -632,31 +588,12 @@ handle_ipi(struct pt_regs *regs)  			break;  		case IPI_CALL_FUNC: -		    { -			struct smp_call_struct *data; -			void (*func)(void *info); -			void *info; -			int wait; - -			data = smp_call_function_data; -			func = data->func; -			info = data->info; -			wait = data->wait; - -			/* Notify the sending CPU that the data has been -			   received, and execution is about to begin.  */ -			mb(); -			atomic_dec (&data->unstarted_count); - -			/* At this point the structure may be gone unless -			   wait is true.  */ -			(*func)(info); - -			/* Notify the sending CPU that the task is done.  */ -			mb(); -			if (wait) atomic_dec (&data->unfinished_count); +			generic_smp_call_function_interrupt(); +			break; + +		case IPI_CALL_FUNC_SINGLE: +			generic_smp_call_function_single_interrupt();  			break; -		    }  		case IPI_CPU_STOP:  			halt(); @@ -700,102 +637,15 @@ smp_send_stop(void)  	send_ipi_message(to_whom, IPI_CPU_STOP);  } -/* - * Run a function on all other CPUs. - *  <func>	The function to run. This must be fast and non-blocking. - *  <info>	An arbitrary pointer to pass to the function. - *  <retry>	If true, keep retrying until ready. - *  <wait>	If true, wait until function has completed on other CPUs. - *  [RETURNS]   0 on success, else a negative status code. - * - * Does not return until remote CPUs are nearly ready to execute <func> - * or are or have executed. - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. - */ - -int -smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry, -			  int wait, cpumask_t to_whom) +void arch_send_call_function_ipi(cpumask_t mask)  { -	struct smp_call_struct data; -	unsigned long timeout; -	int num_cpus_to_call; -	 -	/* Can deadlock when called with interrupts disabled */ -	WARN_ON(irqs_disabled()); - -	data.func = func; -	data.info = info; -	data.wait = wait; - -	cpu_clear(smp_processor_id(), to_whom); -	num_cpus_to_call = cpus_weight(to_whom); - -	atomic_set(&data.unstarted_count, num_cpus_to_call); -	atomic_set(&data.unfinished_count, num_cpus_to_call); - -	/* Acquire the smp_call_function_data mutex.  */ -	if (pointer_lock(&smp_call_function_data, &data, retry)) -		return -EBUSY; - -	/* Send a message to the requested CPUs.  */ -	send_ipi_message(to_whom, IPI_CALL_FUNC); - -	/* Wait for a minimal response.  */ -	timeout = jiffies + HZ; -	while (atomic_read (&data.unstarted_count) > 0 -	       && time_before (jiffies, timeout)) -		barrier(); - -	/* If there's no response yet, log a message but allow a longer -	 * timeout period -- if we get a response this time, log -	 * a message saying when we got it..  -	 */ -	if (atomic_read(&data.unstarted_count) > 0) { -		long start_time = jiffies; -		printk(KERN_ERR "%s: initial timeout -- trying long wait\n", -		       __func__); -		timeout = jiffies + 30 * HZ; -		while (atomic_read(&data.unstarted_count) > 0 -		       && time_before(jiffies, timeout)) -			barrier(); -		if (atomic_read(&data.unstarted_count) <= 0) { -			long delta = jiffies - start_time; -			printk(KERN_ERR  -			       "%s: response %ld.%ld seconds into long wait\n", -			       __func__, delta / HZ, -			       (100 * (delta - ((delta / HZ) * HZ))) / HZ); -		} -	} - -	/* We either got one or timed out -- clear the lock. */ -	mb(); -	smp_call_function_data = NULL; - -	/*  -	 * If after both the initial and long timeout periods we still don't -	 * have a response, something is very wrong... -	 */ -	BUG_ON(atomic_read (&data.unstarted_count) > 0); - -	/* Wait for a complete response, if needed.  */ -	if (wait) { -		while (atomic_read (&data.unfinished_count) > 0) -			barrier(); -	} - -	return 0; +	send_ipi_message(mask, IPI_CALL_FUNC);  } -EXPORT_SYMBOL(smp_call_function_on_cpu); -int -smp_call_function (void (*func) (void *info), void *info, int retry, int wait) +void arch_send_call_function_single_ipi(int cpu)  { -	return smp_call_function_on_cpu (func, info, retry, wait, -					 cpu_online_map); +	send_ipi_message(cpumask_of_cpu(cpu), IPI_CALL_FUNC_SINGLE);  } -EXPORT_SYMBOL(smp_call_function);  static void  ipi_imb(void *ignored) @@ -807,7 +657,7 @@ void  smp_imb(void)  {  	/* Must wait other processors to flush their icache before continue. */ -	if (on_each_cpu(ipi_imb, NULL, 1, 1)) +	if (on_each_cpu(ipi_imb, NULL, 1))  		printk(KERN_CRIT "smp_imb: timed out\n");  }  EXPORT_SYMBOL(smp_imb); @@ -823,7 +673,7 @@ flush_tlb_all(void)  {  	/* Although we don't have any data to pass, we do want to  	   synchronize with the other processors.  */ -	if (on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1)) { +	if (on_each_cpu(ipi_flush_tlb_all, NULL, 1)) {  		printk(KERN_CRIT "flush_tlb_all: timed out\n");  	}  } @@ -860,7 +710,7 @@ flush_tlb_mm(struct mm_struct *mm)  		}  	} -	if (smp_call_function(ipi_flush_tlb_mm, mm, 1, 1)) { +	if (smp_call_function(ipi_flush_tlb_mm, mm, 1)) {  		printk(KERN_CRIT "flush_tlb_mm: timed out\n");  	} @@ -913,7 +763,7 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)  	data.mm = mm;  	data.addr = addr; -	if (smp_call_function(ipi_flush_tlb_page, &data, 1, 1)) { +	if (smp_call_function(ipi_flush_tlb_page, &data, 1)) {  		printk(KERN_CRIT "flush_tlb_page: timed out\n");  	} @@ -965,7 +815,7 @@ flush_icache_user_range(struct vm_area_struct *vma, struct page *page,  		}  	} -	if (smp_call_function(ipi_flush_icache_page, mm, 1, 1)) { +	if (smp_call_function(ipi_flush_icache_page, mm, 1)) {  		printk(KERN_CRIT "flush_icache_page: timed out\n");  	} diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c index 9fc0eeb4f0ab..7c3d5ec6ec67 100644 --- a/arch/alpha/oprofile/common.c +++ b/arch/alpha/oprofile/common.c @@ -65,7 +65,7 @@ op_axp_setup(void)  	model->reg_setup(®, ctr, &sys);  	/* Configure the registers on all cpus.  */ -	(void)smp_call_function(model->cpu_setup, ®, 0, 1); +	(void)smp_call_function(model->cpu_setup, ®, 1);  	model->cpu_setup(®);  	return 0;  } @@ -86,7 +86,7 @@ op_axp_cpu_start(void *dummy)  static int  op_axp_start(void)  { -	(void)smp_call_function(op_axp_cpu_start, NULL, 0, 1); +	(void)smp_call_function(op_axp_cpu_start, NULL, 1);  	op_axp_cpu_start(NULL);  	return 0;  } @@ -101,7 +101,7 @@ op_axp_cpu_stop(void *dummy)  static void  op_axp_stop(void)  { -	(void)smp_call_function(op_axp_cpu_stop, NULL, 0, 1); +	(void)smp_call_function(op_axp_cpu_stop, NULL, 1);  	op_axp_cpu_stop(NULL);  } |