From patchwork Mon Sep 8 15:28:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 4863311 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id ED627C0338 for ; Mon, 8 Sep 2014 15:31:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B220C20155 for ; Mon, 8 Sep 2014 15:31:19 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 75FFA20145 for ; Mon, 8 Sep 2014 15:31:18 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XR0sa-0005pF-A7; Mon, 08 Sep 2014 15:29:20 +0000 Received: from mail-wg0-f48.google.com ([74.125.82.48]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XR0sX-0005ba-ET for linux-arm-kernel@lists.infradead.org; Mon, 08 Sep 2014 15:29:18 +0000 Received: by mail-wg0-f48.google.com with SMTP id m15so1676595wgh.31 for ; Mon, 08 Sep 2014 08:28:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/+96yEWfkxFwHBFjqx62ht8j6Wmq0SW+plNwxHeYZ1A=; b=cENHTNikQku7Y5HAQZtMr6AV7Xs+NeWZ3fkRmASIDpIK6O8ImCgN1p0xqpgJfjf2PD lrH41B+CajLAa15HgodWc2uIa0uG3ifUSybKv+Q0cwn/RXC25BOP+xntZB4A78Xu4GjQ ClcrNWLagWURY6boTtAiQr7qQo/mn34MLSMDdGQoiLahmXDHZ5bG8RbQpLc0+MzRtj7s jaJa2cpMB4CH6ZC8rDg/mxzDrqynjzMie59uV9e0qVnHE96aVoBRYt4FNIizIqOOMOTJ ehOOVOF7dOMSVnmOQ34L6DSFpC6jZsvpO4vYf2ESmZSlC4I5kW95PC/p32bP2c6YgrxH b9gQ== X-Gm-Message-State: ALoCoQkKoOEm7NVYzWkX9qiWiElI4hVpv90kn8lUa3BQij8swyCGRTX1oDGw+fTqKQxXWEOgSrwt X-Received: by 10.180.212.110 with SMTP id nj14mr23584392wic.51.1410190137467; Mon, 08 Sep 2014 08:28:57 -0700 (PDT) Received: from sundance.lan (cpc4-aztw19-0-0-cust157.18-1.cable.virginm.net. [82.33.25.158]) by mx.google.com with ESMTPSA id xm4sm12120613wib.9.2014.09.08.08.28.55 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 08 Sep 2014 08:28:56 -0700 (PDT) From: Daniel Thompson To: Russell King Subject: [PATCH v3 2/5] ARM: add basic support for on-demand backtrace of other CPUs Date: Mon, 8 Sep 2014 16:28:32 +0100 Message-Id: <1410190115-32604-3-git-send-email-daniel.thompson@linaro.org> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1410190115-32604-1-git-send-email-daniel.thompson@linaro.org> References: <1409931198-22600-1-git-send-email-daniel.thompson@linaro.org> <1410190115-32604-1-git-send-email-daniel.thompson@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140908_082917_667635_10D1DF67 X-CRM114-Status: GOOD ( 17.98 ) X-Spam-Score: -0.7 (/) Cc: linaro-kernel@lists.linaro.org, patches@linaro.org, linux-kernel@vger.kernel.org, John Stultz , Russell King , Thomas Gleixner , Sumit Semwal , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Russell King Add basic infrastructure for triggering a backtrace of other CPUs via an IPI, preferably at FIQ level. It is intended that this shall be used for cases where we have detected that something has already failed in the kernel. Signed-off-by: Russell King --- arch/arm/include/asm/irq.h | 5 ++++ arch/arm/kernel/smp.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 53c15de..be1d07d 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -35,6 +35,11 @@ extern void (*handle_arch_irq)(struct pt_regs *); extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); #endif +#ifdef CONFIG_SMP +extern void arch_trigger_all_cpu_backtrace(bool); +#define arch_trigger_all_cpu_backtrace(x) arch_trigger_all_cpu_backtrace(x) +#endif + #endif #endif diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 9388a3d..94959f9 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -72,8 +72,12 @@ enum ipi_msg_type { IPI_CPU_STOP, IPI_IRQ_WORK, IPI_COMPLETION, + IPI_CPU_BACKTRACE, }; +/* For reliability, we're prepared to waste bits here. */ +static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly; + static DECLARE_COMPLETION(cpu_running); static struct smp_operations smp_ops; @@ -539,6 +543,21 @@ static void ipi_cpu_stop(unsigned int cpu) cpu_relax(); } +static void ipi_cpu_backtrace(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + + if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { + static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED; + + arch_spin_lock(&lock); + printk(KERN_WARNING "FIQ backtrace for cpu %d\n", cpu); + show_regs(regs); + arch_spin_unlock(&lock); + cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); + } +} + static DEFINE_PER_CPU(struct completion *, cpu_completion); int register_ipi_completion(struct completion *completion, int cpu) @@ -618,6 +637,12 @@ void handle_IPI(int ipinr, struct pt_regs *regs) irq_exit(); break; + case IPI_CPU_BACKTRACE: + irq_enter(); + ipi_cpu_backtrace(regs); + irq_exit(); + break; + default: printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); @@ -712,3 +737,40 @@ static int __init register_cpufreq_notifier(void) core_initcall(register_cpufreq_notifier); #endif + +void arch_trigger_all_cpu_backtrace(bool include_self) +{ + static unsigned long backtrace_flag; + int i, cpu = get_cpu(); + + 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. + */ + put_cpu(); + return; + } + + cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask); + if (!include_self) + cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); + + if (!cpumask_empty(to_cpumask(backtrace_mask))) { + pr_info("Sending FIQ to %s CPUs:\n", + (include_self ? "all" : "other")); + smp_cross_call(to_cpumask(backtrace_mask), IPI_CPU_BACKTRACE); + } + + /* Wait for up to 10 seconds for all CPUs to do the backtrace */ + for (i = 0; i < 10 * 1000; i++) { + if (cpumask_empty(to_cpumask(backtrace_mask))) + break; + + mdelay(1); + } + + clear_bit(0, &backtrace_flag); + smp_mb__after_atomic(); + put_cpu(); +}