]> git.baikalelectronics.ru Git - kernel.git/commitdiff
nmi_backtrace: generate one-line reports for idle cpus
authorChris Metcalf <cmetcalf@mellanox.com>
Sat, 8 Oct 2016 00:02:55 +0000 (17:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 8 Oct 2016 01:46:30 +0000 (18:46 -0700)
When doing an nmi backtrace of many cores, most of which are idle, the
output is a little overwhelming and very uninformative.  Suppress
messages for cpus that are idling when they are interrupted and just
emit one line, "NMI backtrace for N skipped: idling at pc 0xNNN".

We do this by grouping all the cpuidle code together into a new
.cpuidle.text section, and then checking the address of the interrupted
PC to see if it lies within that section.

This commit suitably tags x86 and tile idle routines, and only adds in
the minimal framework for other architectures.

Link: http://lkml.kernel.org/r/1472487169-14923-5-git-send-email-cmetcalf@mellanox.com
Signed-off-by: Chris Metcalf <cmetcalf@mellanox.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Daniel Thompson <daniel.thompson@linaro.org> [arm]
Tested-by: Petr Mladek <pmladek@suse.com>
Cc: Aaron Tomlin <atomlin@redhat.com>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
49 files changed:
arch/alpha/kernel/vmlinux.lds.S
arch/arc/kernel/vmlinux.lds.S
arch/arm/kernel/vmlinux-xip.lds.S
arch/arm/kernel/vmlinux.lds.S
arch/arm64/kernel/vmlinux.lds.S
arch/avr32/kernel/vmlinux.lds.S
arch/blackfin/kernel/vmlinux.lds.S
arch/c6x/kernel/vmlinux.lds.S
arch/cris/kernel/vmlinux.lds.S
arch/frv/kernel/vmlinux.lds.S
arch/h8300/kernel/vmlinux.lds.S
arch/hexagon/kernel/vmlinux.lds.S
arch/ia64/kernel/vmlinux.lds.S
arch/m32r/kernel/vmlinux.lds.S
arch/m68k/kernel/vmlinux-nommu.lds
arch/m68k/kernel/vmlinux-std.lds
arch/m68k/kernel/vmlinux-sun3.lds
arch/metag/kernel/vmlinux.lds.S
arch/microblaze/kernel/vmlinux.lds.S
arch/mips/kernel/vmlinux.lds.S
arch/mn10300/kernel/vmlinux.lds.S
arch/nios2/kernel/vmlinux.lds.S
arch/openrisc/kernel/vmlinux.lds.S
arch/parisc/kernel/vmlinux.lds.S
arch/powerpc/kernel/vmlinux.lds.S
arch/s390/kernel/vmlinux.lds.S
arch/score/kernel/vmlinux.lds.S
arch/sh/kernel/vmlinux.lds.S
arch/sparc/kernel/vmlinux.lds.S
arch/tile/kernel/entry.S
arch/tile/kernel/vmlinux.lds.S
arch/um/kernel/dyn.lds.S
arch/um/kernel/uml.lds.S
arch/unicore32/kernel/vmlinux.lds.S
arch/x86/include/asm/irqflags.h
arch/x86/kernel/acpi/cstate.c
arch/x86/kernel/process.c
arch/x86/kernel/vmlinux.lds.S
arch/xtensa/kernel/vmlinux.lds.S
drivers/acpi/processor_idle.c
drivers/cpuidle/driver.c
drivers/idle/intel_idle.c
include/asm-generic/vmlinux.lds.h
include/linux/cpu.h
kernel/sched/idle.c
lib/nmi_backtrace.c
scripts/mod/modpost.c
scripts/recordmcount.c
scripts/recordmcount.pl

index 647b84c15382347ec25efae55067e77fff26693e..cebecfb76fbf6e87e02836651d5b7279cff00350 100644 (file)
@@ -22,6 +22,7 @@ SECTIONS
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                *(.fixup)
                *(.gnu.warning)
index 36611072305f151692c967158c248539b0379238..f35ed578e007ec4fd472c0efe6ab6849f281bea9 100644 (file)
@@ -89,6 +89,7 @@ SECTIONS
                _text = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                *(.fixup)
index cba1ec899a693c85113659c98144c26993b8f350..7fa487ef7e2f67fb3e1ac7fa8fd3edb58f2145fc 100644 (file)
@@ -98,6 +98,7 @@ SECTIONS
                        IRQENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
+                       CPUIDLE_TEXT
                        LOCK_TEXT
                        KPROBES_TEXT
                        *(.gnu.warning)
index d24e5dd2aa7a74d98eb718e9edc6cabfbd5341ed..f7f55df0bf7b3b654f40c3c847646f5ec482a0d9 100644 (file)
@@ -111,6 +111,7 @@ SECTIONS
                        SOFTIRQENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
+                       CPUIDLE_TEXT
                        LOCK_TEXT
                        HYPERVISOR_TEXT
                        KPROBES_TEXT
index 5ce9b2929e0d1100dc6e5270f4ee6e336e15013e..1105aab1e6d6af4be3f88c0ee22d4cfafd5c5ce6 100644 (file)
@@ -122,6 +122,7 @@ SECTIONS
                        ENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
+                       CPUIDLE_TEXT
                        LOCK_TEXT
                        KPROBES_TEXT
                        HYPERVISOR_TEXT
index a4589176bed5d7940d1f0e66d144a933892557f5..17f2730eb4978de7660933cbe04c233f6df78f14 100644 (file)
@@ -52,6 +52,7 @@ SECTIONS
                KPROBES_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                *(.fixup)
                *(.gnu.warning)
index d920b959ff3a4b8cb3d6a28d67d40ebf6f7c457b..68069a120055b359b671b5890d2797f63027c007 100644 (file)
@@ -33,6 +33,7 @@ SECTIONS
 #ifndef CONFIG_SCHEDULE_L1
                SCHED_TEXT
 #endif
+               CPUIDLE_TEXT
                LOCK_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
index 50bc10f97bcb4a234bff525d9e120842aa663c99..a1a5c166bc9b8b125bfd4e515ab7a16afad0bc65 100644 (file)
@@ -70,6 +70,7 @@ SECTIONS
                _stext = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
index 7552c255750659c2efd4e3d525dcce6267f3cd94..97958626152000cd24d171ea0fa0c3326f77ffe7 100644 (file)
@@ -43,6 +43,7 @@ SECTIONS
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                *(.fixup)
                *(.text.__*)
index 7e958d829ec9810020c75eca7beef1cbfd44a3c2..aa6e573d57da46d1cb05bec37cb9dfcc7bfac13f 100644 (file)
@@ -63,6 +63,7 @@ SECTIONS
        *(.text..tlbmiss)
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
 #ifdef CONFIG_DEBUG_INFO
        INIT_TEXT
index cb5dfb02c88d412cd67b33827da834a3770d0c7f..7f11da1b895e1351fd93af0804ae228212bd57cd 100644 (file)
@@ -29,6 +29,7 @@ SECTIONS
        _stext = . ;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
 #if defined(CONFIG_ROMKERNEL)
                *(.int_redirect)
index 5f268c1071b3df8f56b4fd4871fbb1b5b19e8d72..ec87e67feb19e4692337fa78c82cc67b6ffd0dce 100644 (file)
@@ -50,6 +50,7 @@ SECTIONS
                _text = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                *(.fixup)
index dc506b05ffbdbf21f5eece65a723ecb178c4564c..f89d20c9741225e4d416713fd32819e6937c00e9 100644 (file)
@@ -46,6 +46,7 @@ SECTIONS {
                __end_ivt_text = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                *(.gnu.linkonce.t*)
index 018e4a711d7927cef577e347dac93fb3a22afd75..ad1fe56455aae60b05b9e1a30294ccd2ab7b48ab 100644 (file)
@@ -31,6 +31,7 @@ SECTIONS
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
index 06a763f49fd34643d5330221a48011be00889b0e..d2c8abf1c8c4eac6688504f2a2dfaa7ea7177e65 100644 (file)
@@ -45,6 +45,7 @@ SECTIONS {
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                *(.fixup)
                . = ALIGN(16);
index d0993594f558b3408317aede57c634c407ea580f..5b5ce1e4d1ed90b9e40dc68fa50c3b87671a8df0 100644 (file)
@@ -16,6 +16,7 @@ SECTIONS
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
index 8080469ee6c11c3e86ab59febaa4773790a2ffc7..fe5ea1974b16c2efcd34b0f134dcf17a24d388b5 100644 (file)
@@ -16,6 +16,7 @@ SECTIONS
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
index 150ace92c7ade9046c9c22b114a979356e7395ac..e6c700eaf207174544687895522cb5b0405b0a01 100644 (file)
@@ -21,6 +21,7 @@ SECTIONS
   .text : {
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        KPROBES_TEXT
        IRQENTRY_TEXT
index 0a47f041055416a90d34a64be3208e3fd74b2b6c..289d0e7f3e3aaed8126c30d109c17c442b848f5b 100644 (file)
@@ -33,6 +33,7 @@ SECTIONS {
                EXIT_TEXT
                EXIT_CALL
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index a82c178d0bb97c8e47b778945af384af620431ea..d5de67591735940c86f5e3b8ba2e186a3e94fbaa 100644 (file)
@@ -55,6 +55,7 @@ SECTIONS
        .text : {
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index 13c4814c29f840dd4ecb95e4e7206da7127aef49..2d5f1c3f1afbc54c9d34afb8396fc8bea326a295 100644 (file)
@@ -30,6 +30,7 @@ SECTIONS
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        KPROBES_TEXT
        *(.fixup)
index e23e89539967713c301c4f452f802f878bb7562f..6a8045bb1a77d06bd2fbc9456b7322c45765d04d 100644 (file)
@@ -37,6 +37,7 @@ SECTIONS
        .text : {
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
index d936de4c07cadd73f00a0700a3781243b8f7852c..d68b9ede84231fe618062a68b190491cd25eeba6 100644 (file)
@@ -47,6 +47,7 @@ SECTIONS
           _stext = .;
          TEXT_TEXT
          SCHED_TEXT
+         CPUIDLE_TEXT
          LOCK_TEXT
          KPROBES_TEXT
          IRQENTRY_TEXT
index f3ead0b6ce461501508c351fdc3246f67f18e218..9ec8ec075daefd5a774eb4da097615dea9fa2ee2 100644 (file)
@@ -69,6 +69,7 @@ SECTIONS
        .text ALIGN(PAGE_SIZE) : {
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index b5fba689fca65475a69db67f05008cb546633b38..7ed59f0d947f5f5098776b47f16236141e91f438 100644 (file)
@@ -52,6 +52,7 @@ SECTIONS
                /* careful! __ftr_alt_* sections need to be close to .text */
                *(.text .fixup __ftr_alt_* .ref.text)
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index 429bfd1119612caa93fbbcf390768d9eaeedc7fe..000e6e91f6a0630c53f35519d450fccf02479e55 100644 (file)
@@ -35,6 +35,7 @@ SECTIONS
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index 7274b5c4287ee4cbaad56a1eb41ad43a0d90c047..4117890b1db1a60dbfde5d26964a669cd53a2a80 100644 (file)
@@ -40,6 +40,7 @@ SECTIONS
                _text = .;      /* Text and read-only data */
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                *(.text.*)
index 235a4101999fe5a4462bd5ec1d78cba49eb49b90..5b9a3cc90c58a770cfd28e0c816048d975f3845e 100644 (file)
@@ -36,6 +36,7 @@ SECTIONS
                TEXT_TEXT
                EXTRA_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index d79b3b7342457b4eace6232b010226a1068a856c..572db686f845830a69f0815f7d274eae4927483c 100644 (file)
@@ -49,6 +49,7 @@ SECTIONS
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index 670a3569450fd39eca59decc0f626565acb3d0b6..101de132e363bec669ac5e542c9afd78d172b304 100644 (file)
@@ -50,7 +50,7 @@ STD_ENTRY(smp_nap)
  * When interrupted at _cpu_idle_nap, we bump the PC forward 8, and
  * as a result return to the function that called _cpu_idle().
  */
-STD_ENTRY(_cpu_idle)
+STD_ENTRY_SECTION(_cpu_idle, .cpuidle.text)
        movei r1, 1
        IRQ_ENABLE_LOAD(r2, r3)
        mtspr INTERRUPT_CRITICAL_SECTION, r1
index 9d449caf8910c709a983a61ada803aaa1fd1dcfa..e1baf094fba45f53f34aabf4730e315e7cc13d98 100644 (file)
@@ -42,6 +42,7 @@ SECTIONS
   .text : AT (ADDR(.text) - LOAD_OFFSET) {
     HEAD_TEXT
     SCHED_TEXT
+    CPUIDLE_TEXT
     LOCK_TEXT
     KPROBES_TEXT
     IRQENTRY_TEXT
index adde088aeefff64f5820fcf1636e5b3afa3577ab..4fdbcf958cd5ad76b9756cb5f201fa384f119b68 100644 (file)
@@ -68,6 +68,7 @@ SECTIONS
     _stext = .;
     TEXT_TEXT
     SCHED_TEXT
+    CPUIDLE_TEXT
     LOCK_TEXT
     *(.fixup)
     *(.stub .text.* .gnu.linkonce.t.*)
index 6899195602b77fd3ed259f41977a2984faa902f4..1840f55ed0420b9ac2cc5db93d31a0b5a93fd48e 100644 (file)
@@ -28,6 +28,7 @@ SECTIONS
     _stext = .;
     TEXT_TEXT
     SCHED_TEXT
+    CPUIDLE_TEXT
     LOCK_TEXT
     *(.fixup)
     /* .gnu.warning sections are handled specially by elf32.em.  */
index 77e407e49a632c84cfb4957580c13dfbbebd1df4..56e788e8ee83cd8f56e54a186981a770fe0bba04 100644 (file)
@@ -37,6 +37,7 @@ SECTIONS
        .text : {               /* Real text segment */
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
 
                *(.fixup)
index b77f5edb03b0c02dc2047d52d07c9da447dba209..ac7692dcfa2e86196f47de38035731e39696d920 100644 (file)
@@ -4,6 +4,10 @@
 #include <asm/processor-flags.h>
 
 #ifndef __ASSEMBLY__
+
+/* Provide __cpuidle; we can't safely include <linux/cpu.h> */
+#define __cpuidle __attribute__((__section__(".cpuidle.text")))
+
 /*
  * Interrupt control:
  */
@@ -44,12 +48,12 @@ static inline void native_irq_enable(void)
        asm volatile("sti": : :"memory");
 }
 
-static inline void native_safe_halt(void)
+static inline __cpuidle void native_safe_halt(void)
 {
        asm volatile("sti; hlt": : :"memory");
 }
 
-static inline void native_halt(void)
+static inline __cpuidle void native_halt(void)
 {
        asm volatile("hlt": : :"memory");
 }
@@ -86,7 +90,7 @@ static inline notrace void arch_local_irq_enable(void)
  * Used in the idle loop; sti takes one instruction cycle
  * to complete:
  */
-static inline void arch_safe_halt(void)
+static inline __cpuidle void arch_safe_halt(void)
 {
        native_safe_halt();
 }
@@ -95,7 +99,7 @@ static inline void arch_safe_halt(void)
  * Used when interrupts are already enabled or to
  * shutdown the processor:
  */
-static inline void halt(void)
+static inline __cpuidle void halt(void)
 {
        native_halt();
 }
index bdfad642123f247d9de09d2d4d7332aa14098d1e..af15f4444330b6c69fe20fc71a993070a9f26a5d 100644 (file)
@@ -152,7 +152,7 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
 }
 EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
 
-void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
+void __cpuidle acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
 {
        unsigned int cpu = smp_processor_id();
        struct cstate_entry *percpu_entry;
index 4002b475171c2064f922e473bb3712608ee93105..28cea7802ecbc456ac3b7f8b8aeb44e0fee00ba0 100644 (file)
@@ -302,7 +302,7 @@ void arch_cpu_idle(void)
 /*
  * We use this if we don't have any better idle routine..
  */
-void default_idle(void)
+void __cpuidle default_idle(void)
 {
        trace_cpu_idle_rcuidle(1, smp_processor_id());
        safe_halt();
@@ -417,7 +417,7 @@ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
  * with interrupts enabled and no flags, which is backwards compatible with the
  * original MWAIT implementation.
  */
-static void mwait_idle(void)
+static __cpuidle void mwait_idle(void)
 {
        if (!current_set_polling_and_test()) {
                trace_cpu_idle_rcuidle(1, smp_processor_id());
index 9297a002d8e5ff3f06b8b8fee118b21f9042a994..dbf67f64d5ecf76cee128b2c89d43a4267b57223 100644 (file)
@@ -97,6 +97,7 @@ SECTIONS
                _stext = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                ENTRY_TEXT
index 72cfe3587dd865c6532874dc56f012ccbb7cdc04..31411fc82662c82ec127188ccdb5fc3ac818e4e9 100644 (file)
@@ -89,6 +89,9 @@ SECTIONS
     VMLINUX_SYMBOL(__sched_text_start) = .;
     *(.sched.literal .sched.text)
     VMLINUX_SYMBOL(__sched_text_end) = .;
+    VMLINUX_SYMBOL(__cpuidle_text_start) = .;
+    *(.cpuidle.literal .cpuidle.text)
+    VMLINUX_SYMBOL(__cpuidle_text_end) = .;
     VMLINUX_SYMBOL(__lock_text_start) = .;
     *(.spinlock.literal .spinlock.text)
     VMLINUX_SYMBOL(__lock_text_end) = .;
index cea52528aa188648a8cb1905da58a1e5bcb6719a..2237d3f24f0e735a1e04294ea273595cce98e049 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/sched.h>       /* need_resched() */
 #include <linux/tick.h>
 #include <linux/cpuidle.h>
+#include <linux/cpu.h>
 #include <acpi/processor.h>
 
 /*
@@ -115,7 +116,7 @@ static const struct dmi_system_id processor_power_dmi_table[] = {
  * Callers should disable interrupts before the call and enable
  * interrupts after return.
  */
-static void acpi_safe_halt(void)
+static void __cpuidle acpi_safe_halt(void)
 {
        if (!tif_need_resched()) {
                safe_halt();
@@ -645,7 +646,7 @@ static int acpi_idle_bm_check(void)
  *
  * Caller disables interrupt before call and enables interrupt after return.
  */
-static void acpi_idle_do_entry(struct acpi_processor_cx *cx)
+static void __cpuidle acpi_idle_do_entry(struct acpi_processor_cx *cx)
 {
        if (cx->entry_method == ACPI_CSTATE_FFH) {
                /* Call into architectural FFH based C-state */
index 389ade4572beb17c71ff44faf2ce884ad16baf54..ab264d393233683c28bac7e0770abb0ffe49b2ec 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
 #include <linux/tick.h>
+#include <linux/cpu.h>
 
 #include "cpuidle.h"
 
@@ -178,8 +179,8 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv)
 }
 
 #ifdef CONFIG_ARCH_HAS_CPU_RELAX
-static int poll_idle(struct cpuidle_device *dev,
-               struct cpuidle_driver *drv, int index)
+static int __cpuidle poll_idle(struct cpuidle_device *dev,
+                              struct cpuidle_driver *drv, int index)
 {
        local_irq_enable();
        if (!current_set_polling_and_test()) {
index 67ec58f9ef99f7c2fbc2115a8d6e8804a37327e1..4466a2f969d7ba5d5cafee13b7359047955cd07a 100644 (file)
@@ -863,8 +863,8 @@ static struct cpuidle_state dnv_cstates[] = {
  *
  * Must be called under local_irq_disable().
  */
-static int intel_idle(struct cpuidle_device *dev,
-               struct cpuidle_driver *drv, int index)
+static __cpuidle int intel_idle(struct cpuidle_device *dev,
+                               struct cpuidle_driver *drv, int index)
 {
        unsigned long ecx = 1; /* break on interrupt flag */
        struct cpuidle_state *state = &drv->states[index];
index 24563970ff7bd04fec252abc9edf72621dd334ea..3e42bcdd014b45b66b95853ee699937666b11b3f 100644 (file)
                *(.spinlock.text)                                       \
                VMLINUX_SYMBOL(__lock_text_end) = .;
 
+#define CPUIDLE_TEXT                                                   \
+               ALIGN_FUNCTION();                                       \
+               VMLINUX_SYMBOL(__cpuidle_text_start) = .;               \
+               *(.cpuidle.text)                                        \
+               VMLINUX_SYMBOL(__cpuidle_text_end) = .;
+
 #define KPROBES_TEXT                                                   \
                ALIGN_FUNCTION();                                       \
                VMLINUX_SYMBOL(__kprobes_text_start) = .;               \
index 7572d9e9dced921e1732226a2c00f5802f58c735..b886dc17f2f3457db43a2523aacb35e74e49e75b 100644 (file)
@@ -231,6 +231,11 @@ void cpu_startup_entry(enum cpuhp_state state);
 
 void cpu_idle_poll_ctrl(bool enable);
 
+/* Attach to any functions which should be considered cpuidle. */
+#define __cpuidle      __attribute__((__section__(".cpuidle.text")))
+
+bool cpu_in_idle(unsigned long pc);
+
 void arch_cpu_idle(void);
 void arch_cpu_idle_prepare(void);
 void arch_cpu_idle_enter(void);
index 9fb873cfc75cfb332c59437bd936e1dd9493d92e..1d8718d5300d81b896f66e9c8c3ca9df97b4cbf4 100644 (file)
@@ -16,6 +16,9 @@
 
 #include "sched.h"
 
+/* Linker adds these: start and end of __cpuidle functions */
+extern char __cpuidle_text_start[], __cpuidle_text_end[];
+
 /**
  * sched_idle_set_state - Record idle state for the current CPU.
  * @idle_state: State to record.
@@ -53,7 +56,7 @@ static int __init cpu_idle_nopoll_setup(char *__unused)
 __setup("hlt", cpu_idle_nopoll_setup);
 #endif
 
-static inline int cpu_idle_poll(void)
+static noinline int __cpuidle cpu_idle_poll(void)
 {
        rcu_idle_enter();
        trace_cpu_idle_rcuidle(0, smp_processor_id());
@@ -84,7 +87,7 @@ void __weak arch_cpu_idle(void)
  *
  * To use when the cpuidle framework cannot be used.
  */
-void default_idle_call(void)
+void __cpuidle default_idle_call(void)
 {
        if (current_clr_polling_and_test()) {
                local_irq_enable();
@@ -271,6 +274,12 @@ static void cpu_idle_loop(void)
        }
 }
 
+bool cpu_in_idle(unsigned long pc)
+{
+       return pc >= (unsigned long)__cpuidle_text_start &&
+               pc < (unsigned long)__cpuidle_text_end;
+}
+
 void cpu_startup_entry(enum cpuhp_state state)
 {
        /*
index 393a3cca1f47660e436131e6dbcf718d125ff6bb..75554754eadfeac67e7ab160ad8e6aa45b2392ce 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/kprobes.h>
 #include <linux/nmi.h>
+#include <linux/cpu.h>
 
 #ifdef arch_trigger_cpumask_backtrace
 /* For reliability, we're prepared to waste bits here. */
@@ -87,11 +88,16 @@ bool nmi_cpu_backtrace(struct pt_regs *regs)
        int cpu = smp_processor_id();
 
        if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
-               pr_warn("NMI backtrace for cpu %d\n", cpu);
-               if (regs)
-                       show_regs(regs);
-               else
-                       dump_stack();
+               if (regs && cpu_in_idle(instruction_pointer(regs))) {
+                       pr_warn("NMI backtrace for cpu %d skipped: idling at pc %#lx\n",
+                               cpu, instruction_pointer(regs));
+               } else {
+                       pr_warn("NMI backtrace for cpu %d\n", cpu);
+                       if (regs)
+                               show_regs(regs);
+                       else
+                               dump_stack();
+               }
                cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
                return true;
        }
index 48958d3cec9e38473ff3296f7f6bf4d5db41612a..bd834975909510335322ec8f34970573a8708dfc 100644 (file)
@@ -888,7 +888,7 @@ static void check_section(const char *modname, struct elf_info *elf,
 
 #define DATA_SECTIONS ".data", ".data.rel"
 #define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
-               ".kprobes.text"
+               ".kprobes.text", ".cpuidle.text"
 #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
                ".fixup", ".entry.text", ".exception.text", ".text.*", \
                ".coldtext"
index a68f03133df9bd30543c7d7190f6e2b8d285c628..5423a58d1b06934cb4cd220355deafed24b27f91 100644 (file)
@@ -365,6 +365,7 @@ is_mcounted_section_name(char const *const txtname)
                strcmp(".irqentry.text", txtname) == 0 ||
                strcmp(".softirqentry.text", txtname) == 0 ||
                strcmp(".kprobes.text", txtname) == 0 ||
+               strcmp(".cpuidle.text", txtname) == 0 ||
                strcmp(".text.unlikely", txtname) == 0;
 }
 
index 2d48011bc36294b39602752c6141fe88075a0135..faac4b10d8eaf9ddd472f2bd6dcba98a49310710 100755 (executable)
@@ -136,6 +136,7 @@ my %text_sections = (
      ".irqentry.text" => 1,
      ".softirqentry.text" => 1,
      ".kprobes.text" => 1,
+     ".cpuidle.text" => 1,
      ".text.unlikely" => 1,
 );