diff options
author | Renn Wu <rewu@nvidia.com> | 2015-02-03 10:27:18 +0800 |
---|---|---|
committer | Matthew Pedro <mapedro@nvidia.com> | 2015-06-08 12:01:04 -0700 |
commit | b1de4caf2f12e1bc9c3a4e08dd60b5de53b7520a (patch) | |
tree | 727935d014482a714ef9808ce4245ca4a6b19efc /arch | |
parent | d89af238e13dbd1f2a01cb5392902313ad367ef2 (diff) |
watchdog: use FIQ WDT for soft lockup stack dump
Using Tegra WDT to trigger FIQ when system is in soft lockup.
Bug 1581432
Change-Id: I853a88a3f6e9402c978db18c5a63e903c582040a
Signed-off-by: Renn Wu <rewu@nvidia.com>
Reviewed-on: http://git-master/r/265871
(cherry picked from commit f115f435d471af22ddec5e9d969662f79193f846)
Reviewed-on: http://git-master/r/680353
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: Winnie Hsu <whsu@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/common/Kconfig | 45 | ||||
-rw-r--r-- | arch/arm/common/fiq_debugger.c | 44 | ||||
-rw-r--r-- | arch/arm/configs/tegra12_defconfig | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/Kconfig | 56 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-ardbeg.c | 1 |
5 files changed, 93 insertions, 63 deletions
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index a73a5bdfd0c9..709d85388621 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -22,51 +22,6 @@ config FIQ_GLUE bool select FIQ -config FIQ_DEBUGGER - bool "FIQ Mode Serial Debugger" - select FIQ - select FIQ_GLUE - default n - help - The FIQ serial debugger can accept commands even when the - kernel is unresponsive due to being stuck with interrupts - disabled. - -config FIQ_DEBUGGER_NO_SLEEP - bool "Keep serial debugger active" - depends on FIQ_DEBUGGER - default n - help - Enables the serial debugger at boot. Passing - fiq_debugger.no_sleep on the kernel commandline will - override this config option. - -config FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON - bool "Don't disable wakeup IRQ when debugger is active" - depends on FIQ_DEBUGGER - default n - help - Don't disable the wakeup irq when enabling the uart clock. This will - cause extra interrupts, but it makes the serial debugger usable with - on some MSM radio builds that ignore the uart clock request in power - collapse. - -config FIQ_DEBUGGER_CONSOLE - bool "Console on FIQ Serial Debugger port" - depends on FIQ_DEBUGGER - default n - help - Enables a console so that printk messages are displayed on - the debugger serial port as the occur. - -config FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE - bool "Put the FIQ debugger into console mode by default" - depends on FIQ_DEBUGGER_CONSOLE - default n - help - If enabled, this puts the fiq debugger into console mode by default. - Otherwise, the fiq debugger will start out in debug mode. - config GIC_SET_MULTIPLE_CPUS bool "Use affinity hint to allow multiple CPUs for IRQ" depends on ARM_GIC && SMP diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c index 4156a7f51d62..2f10fea529b1 100644 --- a/arch/arm/common/fiq_debugger.c +++ b/arch/arm/common/fiq_debugger.c @@ -454,15 +454,21 @@ static void fiq_debugger_help(struct fiq_debugger_state *state) #endif } -static void fiq_debugger_take_affinity(void *info) + +static void change_cpu_affinity(int fiq, int cpu) { - struct fiq_debugger_state *state = info; struct cpumask cpumask; cpumask_clear(&cpumask); - cpumask_set_cpu(get_cpu(), &cpumask); + cpumask_set_cpu(cpu, &cpumask); + irq_set_affinity(fiq, &cpumask); +} - irq_set_affinity(state->uart_irq, &cpumask); +static void fiq_debugger_take_affinity(void *info) +{ + struct fiq_debugger_state *state = info; + + change_cpu_affinity(state->uart_irq, get_cpu()); } static void fiq_debugger_switch_cpu(struct fiq_debugger_state *state, int cpu) @@ -739,11 +745,33 @@ static void fiq_debugger_fiq(struct fiq_glue_handler *h, unsigned int this_cpu = THREAD_INFO(svc_sp)->cpu; bool need_irq; + unsigned int next_cpu; + static bool cpu0_again; + + /* + * 1st FIQ always goes to CPU0. We will change FIQ CPU affinity, if CPU0 + * enter the FIQ handler 2nd time, we know we have already done the + * stack dump for all CPUs and we can enter the debug console. + */ + if (cpu0_again) { + need_irq = fiq_debugger_handle_uart_interrupt(state, + this_cpu, regs, svc_sp); + if (need_irq) + fiq_debugger_force_irq(state); + return; + } + + fiq_debugger_dump_allregs(&state->output, regs); + fiq_debugger_dump_pc(&state->output, regs); + fiq_debugger_dump_stacktrace(&state->output, regs, 100, svc_sp); + /* let another online CPU handle the FIQ */ + next_cpu = cpumask_next(this_cpu, cpu_online_mask); + if (next_cpu >= nr_cpu_ids) { + next_cpu = 0; + cpu0_again = true; + } + change_cpu_affinity(state->fiq, next_cpu); - need_irq = fiq_debugger_handle_uart_interrupt(state, this_cpu, regs, - svc_sp); - if (need_irq) - fiq_debugger_force_irq(state); } #endif diff --git a/arch/arm/configs/tegra12_defconfig b/arch/arm/configs/tegra12_defconfig index 01bcc94e8189..19a64000cc89 100644 --- a/arch/arm/configs/tegra12_defconfig +++ b/arch/arm/configs/tegra12_defconfig @@ -564,13 +564,3 @@ CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_TWOFISH=m # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_TEGRA_SE=y -# CONFIG_FIQ is not set -# CONFIG_TEGRA_FIQ_DEBUGGER is not set -# CONFIG_FIQ_GLUE is not set -# CONFIG_FIQ_DEBUGGER is not set -# CONFIG_FIQ_DEBUGGER_NO_SLEEP is not set -# CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON is not set -# CONFIG_FIQ_DEBUGGER_CONSOLE is not set -# CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE is not set -# CONFIG_CONSOLE_POLL is not set - diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 35f648fe57f2..d79a30000f93 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -240,6 +240,53 @@ config TEGRA_SIMULATION_SPLIT_MEM setup. Select this only if you are an NVIDIA developer working on a simulation platform. +config FIQ_DEBUGGER + bool "FIQ Mode Serial Debugger" + select FIQ + select FIQ_GLUE + default n + help + The FIQ serial debugger can accept commands even when the + kernel is unresponsive due to being stuck with interrupts + disabled. Also, we can save kernel log in FIQ handler. + It will not work if FIQ not work or hardware hang. + +config FIQ_DEBUGGER_NO_SLEEP + bool "Keep serial debugger active" + depends on FIQ_DEBUGGER + default n + help + Enables the serial debugger at boot. Passing + fiq_debugger.no_sleep on the kernel commandline will + override this config option. + Enable this config then serial debugger will never off. + +config FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON + bool "Don't disable wakeup IRQ when debugger is active" + depends on FIQ_DEBUGGER + default n + help + Don't disable the wakeup irq when enabling the uart clock. This will + cause extra interrupts, but it makes the serial debugger usable with + on some MSM radio builds that ignore the uart clock request in power + collapse. + +config FIQ_DEBUGGER_CONSOLE + bool "Console on FIQ Serial Debugger port" + depends on FIQ_DEBUGGER + default n + help + Enables a console so that printk messages are displayed on + the debugger serial port as the occur. + +config FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE + bool "Put the FIQ debugger into console mode by default" + depends on FIQ_DEBUGGER_CONSOLE + default n + help + If enabled, this puts the fiq debugger into console mode by default. + Otherwise, the fiq debugger will start out in debug mode. + config TEGRA_FIQ_DEBUGGER bool "Enable the FIQ serial debugger on Tegra" default n @@ -247,6 +294,15 @@ config TEGRA_FIQ_DEBUGGER help Enables the FIQ serial debugger on Tegra +config TEGRA_WDT_FIQ_SOFT_HANG_STACK_DUMP + bool "Enable Tegra system soft hang stack dump" + default n + help + This option will generate stack dump for all online CPUs upon + soft hang detection by using the FIQ debugger mechanism even + the IRQ is disabled on the CPU. This option is useful if we + only have one watchdog generating FIQ for all CPUs. + config TEGRA_PTM bool "Enable PTM debugger on Tegra" default n diff --git a/arch/arm/mach-tegra/board-ardbeg.c b/arch/arm/mach-tegra/board-ardbeg.c index f83ccfae2930..46c4d3f338e1 100644 --- a/arch/arm/mach-tegra/board-ardbeg.c +++ b/arch/arm/mach-tegra/board-ardbeg.c @@ -415,6 +415,7 @@ static void __init ardbeg_uart_init(void) #if !defined(CONFIG_TRUSTED_FOUNDATIONS) && \ defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER) tegra_serial_debug_init(TEGRA_UARTD_BASE, INT_WDT_AVP, NULL, -1, -1); + platform_device_register(uart_console_debug_device); #else tegra_serial_debug_init(TEGRA_UARTD_BASE, INT_WDT_CPU, NULL, -1, -1); #endif |