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 647b84c..cebecfb 100644 (file)
@@ -22,6 +22,7 @@ SECTIONS
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                *(.fixup)
                *(.gnu.warning)
                LOCK_TEXT
                *(.fixup)
                *(.gnu.warning)
index 3661107..f35ed57 100644 (file)
@@ -89,6 +89,7 @@ SECTIONS
                _text = .;
                TEXT_TEXT
                SCHED_TEXT
                _text = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                *(.fixup)
                LOCK_TEXT
                KPROBES_TEXT
                *(.fixup)
index cba1ec8..7fa487e 100644 (file)
@@ -98,6 +98,7 @@ SECTIONS
                        IRQENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
                        IRQENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
+                       CPUIDLE_TEXT
                        LOCK_TEXT
                        KPROBES_TEXT
                        *(.gnu.warning)
                        LOCK_TEXT
                        KPROBES_TEXT
                        *(.gnu.warning)
index d24e5dd..f7f55df 100644 (file)
@@ -111,6 +111,7 @@ SECTIONS
                        SOFTIRQENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
                        SOFTIRQENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
+                       CPUIDLE_TEXT
                        LOCK_TEXT
                        HYPERVISOR_TEXT
                        KPROBES_TEXT
                        LOCK_TEXT
                        HYPERVISOR_TEXT
                        KPROBES_TEXT
index 5ce9b29..1105aab 100644 (file)
@@ -122,6 +122,7 @@ SECTIONS
                        ENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
                        ENTRY_TEXT
                        TEXT_TEXT
                        SCHED_TEXT
+                       CPUIDLE_TEXT
                        LOCK_TEXT
                        KPROBES_TEXT
                        HYPERVISOR_TEXT
                        LOCK_TEXT
                        KPROBES_TEXT
                        HYPERVISOR_TEXT
index a458917..17f2730 100644 (file)
@@ -52,6 +52,7 @@ SECTIONS
                KPROBES_TEXT
                TEXT_TEXT
                SCHED_TEXT
                KPROBES_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                *(.fixup)
                *(.gnu.warning)
                LOCK_TEXT
                *(.fixup)
                *(.gnu.warning)
index d920b95..68069a1 100644 (file)
@@ -33,6 +33,7 @@ SECTIONS
 #ifndef CONFIG_SCHEDULE_L1
                SCHED_TEXT
 #endif
 #ifndef CONFIG_SCHEDULE_L1
                SCHED_TEXT
 #endif
+               CPUIDLE_TEXT
                LOCK_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
                LOCK_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
index 50bc10f..a1a5c16 100644 (file)
@@ -70,6 +70,7 @@ SECTIONS
                _stext = .;
                TEXT_TEXT
                SCHED_TEXT
                _stext = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
                LOCK_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
index 7552c25..9795862 100644 (file)
@@ -43,6 +43,7 @@ SECTIONS
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                *(.fixup)
                *(.text.__*)
                LOCK_TEXT
                *(.fixup)
                *(.text.__*)
index 7e958d8..aa6e573 100644 (file)
@@ -63,6 +63,7 @@ SECTIONS
        *(.text..tlbmiss)
        TEXT_TEXT
        SCHED_TEXT
        *(.text..tlbmiss)
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
 #ifdef CONFIG_DEBUG_INFO
        INIT_TEXT
        LOCK_TEXT
 #ifdef CONFIG_DEBUG_INFO
        INIT_TEXT
index cb5dfb0..7f11da1 100644 (file)
@@ -29,6 +29,7 @@ SECTIONS
        _stext = . ;
                TEXT_TEXT
                SCHED_TEXT
        _stext = . ;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
 #if defined(CONFIG_ROMKERNEL)
                *(.int_redirect)
                LOCK_TEXT
 #if defined(CONFIG_ROMKERNEL)
                *(.int_redirect)
index 5f268c1..ec87e67 100644 (file)
@@ -50,6 +50,7 @@ SECTIONS
                _text = .;
                TEXT_TEXT
                SCHED_TEXT
                _text = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                *(.fixup)
                LOCK_TEXT
                KPROBES_TEXT
                *(.fixup)
index dc506b0..f89d20c 100644 (file)
@@ -46,6 +46,7 @@ SECTIONS {
                __end_ivt_text = .;
                TEXT_TEXT
                SCHED_TEXT
                __end_ivt_text = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                *(.gnu.linkonce.t*)
                LOCK_TEXT
                KPROBES_TEXT
                *(.gnu.linkonce.t*)
index 018e4a7..ad1fe56 100644 (file)
@@ -31,6 +31,7 @@ SECTIONS
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
index 06a763f..d2c8abf 100644 (file)
@@ -45,6 +45,7 @@ SECTIONS {
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                *(.fixup)
                . = ALIGN(16);
                LOCK_TEXT
                *(.fixup)
                . = ALIGN(16);
index d099359..5b5ce1e 100644 (file)
@@ -16,6 +16,7 @@ SECTIONS
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
index 8080469..fe5ea19 100644 (file)
@@ -16,6 +16,7 @@ SECTIONS
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
index 150ace9..e6c700e 100644 (file)
@@ -21,6 +21,7 @@ SECTIONS
   .text : {
        TEXT_TEXT
        SCHED_TEXT
   .text : {
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        KPROBES_TEXT
        IRQENTRY_TEXT
        LOCK_TEXT
        KPROBES_TEXT
        IRQENTRY_TEXT
index 0a47f04..289d0e7 100644 (file)
@@ -33,6 +33,7 @@ SECTIONS {
                EXIT_TEXT
                EXIT_CALL
                SCHED_TEXT
                EXIT_TEXT
                EXIT_CALL
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index a82c178..d5de675 100644 (file)
@@ -55,6 +55,7 @@ SECTIONS
        .text : {
                TEXT_TEXT
                SCHED_TEXT
        .text : {
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index 13c4814..2d5f1c3 100644 (file)
@@ -30,6 +30,7 @@ SECTIONS
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
        HEAD_TEXT
        TEXT_TEXT
        SCHED_TEXT
+       CPUIDLE_TEXT
        LOCK_TEXT
        KPROBES_TEXT
        *(.fixup)
        LOCK_TEXT
        KPROBES_TEXT
        *(.fixup)
index e23e895..6a8045b 100644 (file)
@@ -37,6 +37,7 @@ SECTIONS
        .text : {
                TEXT_TEXT
                SCHED_TEXT
        .text : {
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
                LOCK_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
index d936de4..d68b9ed 100644 (file)
@@ -47,6 +47,7 @@ SECTIONS
           _stext = .;
          TEXT_TEXT
          SCHED_TEXT
           _stext = .;
          TEXT_TEXT
          SCHED_TEXT
+         CPUIDLE_TEXT
          LOCK_TEXT
          KPROBES_TEXT
          IRQENTRY_TEXT
          LOCK_TEXT
          KPROBES_TEXT
          IRQENTRY_TEXT
index f3ead0b..9ec8ec0 100644 (file)
@@ -69,6 +69,7 @@ SECTIONS
        .text ALIGN(PAGE_SIZE) : {
                TEXT_TEXT
                SCHED_TEXT
        .text ALIGN(PAGE_SIZE) : {
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index b5fba68..7ed59f0 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
                /* 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
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index 429bfd1..000e6e9 100644 (file)
@@ -35,6 +35,7 @@ SECTIONS
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index 7274b5c..4117890 100644 (file)
@@ -40,6 +40,7 @@ SECTIONS
                _text = .;      /* Text and read-only data */
                TEXT_TEXT
                SCHED_TEXT
                _text = .;      /* Text and read-only data */
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                *(.text.*)
                LOCK_TEXT
                KPROBES_TEXT
                *(.text.*)
index 235a410..5b9a3cc 100644 (file)
@@ -36,6 +36,7 @@ SECTIONS
                TEXT_TEXT
                EXTRA_TEXT
                SCHED_TEXT
                TEXT_TEXT
                EXTRA_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index d79b3b7..572db68 100644 (file)
@@ -49,6 +49,7 @@ SECTIONS
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
                HEAD_TEXT
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
index 670a356..101de13 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().
  */
  * 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
        movei r1, 1
        IRQ_ENABLE_LOAD(r2, r3)
        mtspr INTERRUPT_CRITICAL_SECTION, r1
index 9d449ca..e1baf09 100644 (file)
@@ -42,6 +42,7 @@ SECTIONS
   .text : AT (ADDR(.text) - LOAD_OFFSET) {
     HEAD_TEXT
     SCHED_TEXT
   .text : AT (ADDR(.text) - LOAD_OFFSET) {
     HEAD_TEXT
     SCHED_TEXT
+    CPUIDLE_TEXT
     LOCK_TEXT
     KPROBES_TEXT
     IRQENTRY_TEXT
     LOCK_TEXT
     KPROBES_TEXT
     IRQENTRY_TEXT
index adde088..4fdbcf9 100644 (file)
@@ -68,6 +68,7 @@ SECTIONS
     _stext = .;
     TEXT_TEXT
     SCHED_TEXT
     _stext = .;
     TEXT_TEXT
     SCHED_TEXT
+    CPUIDLE_TEXT
     LOCK_TEXT
     *(.fixup)
     *(.stub .text.* .gnu.linkonce.t.*)
     LOCK_TEXT
     *(.fixup)
     *(.stub .text.* .gnu.linkonce.t.*)
index 6899195..1840f55 100644 (file)
@@ -28,6 +28,7 @@ SECTIONS
     _stext = .;
     TEXT_TEXT
     SCHED_TEXT
     _stext = .;
     TEXT_TEXT
     SCHED_TEXT
+    CPUIDLE_TEXT
     LOCK_TEXT
     *(.fixup)
     /* .gnu.warning sections are handled specially by elf32.em.  */
     LOCK_TEXT
     *(.fixup)
     /* .gnu.warning sections are handled specially by elf32.em.  */
index 77e407e..56e788e 100644 (file)
@@ -37,6 +37,7 @@ SECTIONS
        .text : {               /* Real text segment */
                TEXT_TEXT
                SCHED_TEXT
        .text : {               /* Real text segment */
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
 
                *(.fixup)
                LOCK_TEXT
 
                *(.fixup)
index b77f5ed..ac7692d 100644 (file)
@@ -4,6 +4,10 @@
 #include <asm/processor-flags.h>
 
 #ifndef __ASSEMBLY__
 #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:
  */
 /*
  * Interrupt control:
  */
@@ -44,12 +48,12 @@ static inline void native_irq_enable(void)
        asm volatile("sti": : :"memory");
 }
 
        asm volatile("sti": : :"memory");
 }
 
-static inline void native_safe_halt(void)
+static inline __cpuidle void native_safe_halt(void)
 {
        asm volatile("sti; hlt": : :"memory");
 }
 
 {
        asm volatile("sti; hlt": : :"memory");
 }
 
-static inline void native_halt(void)
+static inline __cpuidle void native_halt(void)
 {
        asm volatile("hlt": : :"memory");
 }
 {
        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:
  */
  * 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();
 }
 {
        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:
  */
  * Used when interrupts are already enabled or to
  * shutdown the processor:
  */
-static inline void halt(void)
+static inline __cpuidle void halt(void)
 {
        native_halt();
 }
 {
        native_halt();
 }
index bdfad64..af15f44 100644 (file)
@@ -152,7 +152,7 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
 }
 EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
 
 }
 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;
 {
        unsigned int cpu = smp_processor_id();
        struct cstate_entry *percpu_entry;
index 4002b47..28cea78 100644 (file)
@@ -302,7 +302,7 @@ void arch_cpu_idle(void)
 /*
  * We use this if we don't have any better idle routine..
  */
 /*
  * 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();
 {
        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.
  */
  * 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());
 {
        if (!current_set_polling_and_test()) {
                trace_cpu_idle_rcuidle(1, smp_processor_id());
index 9297a00..dbf67f6 100644 (file)
@@ -97,6 +97,7 @@ SECTIONS
                _stext = .;
                TEXT_TEXT
                SCHED_TEXT
                _stext = .;
                TEXT_TEXT
                SCHED_TEXT
+               CPUIDLE_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                ENTRY_TEXT
                LOCK_TEXT
                KPROBES_TEXT
                ENTRY_TEXT
index 72cfe35..31411fc 100644 (file)
@@ -89,6 +89,9 @@ SECTIONS
     VMLINUX_SYMBOL(__sched_text_start) = .;
     *(.sched.literal .sched.text)
     VMLINUX_SYMBOL(__sched_text_end) = .;
     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) = .;
     VMLINUX_SYMBOL(__lock_text_start) = .;
     *(.spinlock.literal .spinlock.text)
     VMLINUX_SYMBOL(__lock_text_end) = .;
index cea5252..2237d3f 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/sched.h>       /* need_resched() */
 #include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/sched.h>       /* need_resched() */
 #include <linux/tick.h>
 #include <linux/cpuidle.h>
+#include <linux/cpu.h>
 #include <acpi/processor.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.
  */
  * 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();
 {
        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.
  */
  *
  * 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 */
 {
        if (cx->entry_method == ACPI_CSTATE_FFH) {
                /* Call into architectural FFH based C-state */
index 389ade4..ab264d3 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
 #include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
 #include <linux/tick.h>
+#include <linux/cpu.h>
 
 #include "cpuidle.h"
 
 
 #include "cpuidle.h"
 
@@ -178,8 +179,8 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv)
 }
 
 #ifdef CONFIG_ARCH_HAS_CPU_RELAX
 }
 
 #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()) {
 {
        local_irq_enable();
        if (!current_set_polling_and_test()) {
index 67ec58f..4466a2f 100644 (file)
@@ -863,8 +863,8 @@ static struct cpuidle_state dnv_cstates[] = {
  *
  * Must be called under local_irq_disable().
  */
  *
  * 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];
 {
        unsigned long ecx = 1; /* break on interrupt flag */
        struct cpuidle_state *state = &drv->states[index];
index 2456397..3e42bcd 100644 (file)
                *(.spinlock.text)                                       \
                VMLINUX_SYMBOL(__lock_text_end) = .;
 
                *(.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) = .;               \
 #define KPROBES_TEXT                                                   \
                ALIGN_FUNCTION();                                       \
                VMLINUX_SYMBOL(__kprobes_text_start) = .;               \
index 7572d9e..b886dc1 100644 (file)
@@ -231,6 +231,11 @@ void cpu_startup_entry(enum cpuhp_state state);
 
 void cpu_idle_poll_ctrl(bool enable);
 
 
 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);
 void arch_cpu_idle(void);
 void arch_cpu_idle_prepare(void);
 void arch_cpu_idle_enter(void);
index 9fb873c..1d8718d 100644 (file)
@@ -16,6 +16,9 @@
 
 #include "sched.h"
 
 
 #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.
 /**
  * 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
 
 __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());
 {
        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.
  */
  *
  * 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();
 {
        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)
 {
        /*
 void cpu_startup_entry(enum cpuhp_state state)
 {
        /*
index 393a3cc..7555475 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/kprobes.h>
 #include <linux/nmi.h>
 #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. */
 
 #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))) {
        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;
        }
                cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
                return true;
        }
index 48958d3..bd83497 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", \
 
 #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"
 #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
                ".fixup", ".entry.text", ".exception.text", ".text.*", \
                ".coldtext"
index a68f031..5423a58 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(".irqentry.text", txtname) == 0 ||
                strcmp(".softirqentry.text", txtname) == 0 ||
                strcmp(".kprobes.text", txtname) == 0 ||
+               strcmp(".cpuidle.text", txtname) == 0 ||
                strcmp(".text.unlikely", txtname) == 0;
 }
 
                strcmp(".text.unlikely", txtname) == 0;
 }
 
index 2d48011..faac4b1 100755 (executable)
@@ -136,6 +136,7 @@ my %text_sections = (
      ".irqentry.text" => 1,
      ".softirqentry.text" => 1,
      ".kprobes.text" => 1,
      ".irqentry.text" => 1,
      ".softirqentry.text" => 1,
      ".kprobes.text" => 1,
+     ".cpuidle.text" => 1,
      ".text.unlikely" => 1,
 );
 
      ".text.unlikely" => 1,
 );