From: Mark Brown Date: Fri, 19 Jul 2013 09:42:11 +0000 (+0100) Subject: Merge branch 'experimental/android-3.10' of https://android.googlesource.com/kernel... X-Git-Tag: firefly_0821_release~3680^2~234 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0b37fbf7508ff30e1d3668fea74e82f842448354;p=firefly-linux-kernel-4.4.55.git Merge branch 'experimental/android-3.10' of https://android.googlesource.com/kernel/common into linux-linaro-lsk-android Conflicts: arch/arm/include/asm/smp.h arch/arm/kernel/smp.c kernel/futex.c --- 0b37fbf7508ff30e1d3668fea74e82f842448354 diff --cc arch/arm/include/asm/hardirq.h index 3d7351c844aa,3d7351c844aa..fe3ea776dc34 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h @@@ -5,7 -5,7 +5,7 @@@ #include #include --#define NR_IPI 7 ++#define NR_IPI 8 typedef struct { unsigned int __softirq_pending; diff --cc arch/arm/include/asm/smp.h index 610ccf33f5e7,c5aa088c0a8b..67a18a5ed9fa --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@@ -81,7 -81,7 +81,8 @@@ extern void arch_send_call_function_sin extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask); +extern int register_ipi_completion(struct completion *completion, int cpu); + extern void smp_send_all_cpu_backtrace(void); struct smp_operations { #ifdef CONFIG_SMP diff --cc arch/arm/kernel/smp.c index dc05ca77963b,0c96b2d343ed..84d55da02e6a --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@@ -66,7 -66,7 +66,8 @@@ enum ipi_msg_type IPI_CALL_FUNC, IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP, + IPI_COMPLETION, + IPI_CPU_BACKTRACE, }; static DECLARE_COMPLETION(cpu_running); @@@ -464,7 -464,7 +465,8 @@@ static const char *ipi_types[NR_IPI] = S(IPI_CALL_FUNC, "Function call interrupts"), S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"), S(IPI_CPU_STOP, "CPU stop interrupts"), + S(IPI_COMPLETION, "completion interrupts"), + S(IPI_CPU_BACKTRACE, "CPU backtrace"), }; void show_ipi_list(struct seq_file *p, int prec) @@@ -590,19 -590,58 +592,71 @@@ static void ipi_cpu_stop(unsigned int c cpu_relax(); } +static DEFINE_PER_CPU(struct completion *, cpu_completion); + +int register_ipi_completion(struct completion *completion, int cpu) +{ + per_cpu(cpu_completion, cpu) = completion; + return IPI_COMPLETION; +} + +static void ipi_complete(unsigned int cpu) +{ + complete(per_cpu(cpu_completion, cpu)); +} + + static cpumask_t backtrace_mask; + static DEFINE_RAW_SPINLOCK(backtrace_lock); + + /* "in progress" flag of arch_trigger_all_cpu_backtrace */ + static unsigned long backtrace_flag; + + void smp_send_all_cpu_backtrace(void) + { + unsigned int this_cpu = smp_processor_id(); + int i; + + if (test_and_set_bit(0, &backtrace_flag)) + /* + * If there is already a trigger_all_cpu_backtrace() in progress + * (backtrace_flag == 1), don't output double cpu dump infos. + */ + return; + + cpumask_copy(&backtrace_mask, cpu_online_mask); + cpu_clear(this_cpu, backtrace_mask); + + pr_info("Backtrace for cpu %d (current):\n", this_cpu); + dump_stack(); + + pr_info("\nsending IPI to all other CPUs:\n"); + smp_cross_call(&backtrace_mask, IPI_CPU_BACKTRACE); + + /* Wait for up to 10 seconds for all other CPUs to do the backtrace */ + for (i = 0; i < 10 * 1000; i++) { + if (cpumask_empty(&backtrace_mask)) + break; + mdelay(1); + } + + clear_bit(0, &backtrace_flag); + smp_mb__after_clear_bit(); + } + + /* + * ipi_cpu_backtrace - handle IPI from smp_send_all_cpu_backtrace() + */ + static void ipi_cpu_backtrace(unsigned int cpu, struct pt_regs *regs) + { + if (cpu_isset(cpu, backtrace_mask)) { + raw_spin_lock(&backtrace_lock); + pr_warning("IPI backtrace for cpu %d\n", cpu); + show_regs(regs); + raw_spin_unlock(&backtrace_lock); + cpu_clear(cpu, backtrace_mask); + } + } + /* * Main handler for inter-processor interrupts */ @@@ -653,12 -692,10 +707,16 @@@ void handle_IPI(int ipinr, struct pt_re irq_exit(); break; + case IPI_COMPLETION: + irq_enter(); + ipi_complete(cpu); + irq_exit(); + break; + + case IPI_CPU_BACKTRACE: + ipi_cpu_backtrace(cpu, regs); + break; + default: printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); diff --cc kernel/futex.c index 49dacfb45745,d710fae8abbe..c3a1a55a5214 --- a/kernel/futex.c +++ b/kernel/futex.c @@@ -61,7 -61,7 +61,8 @@@ #include #include #include +#include + #include #include