Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 989aa44a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'core-debug-for-linus' of...

Merge branch 'core-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'core-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  debug lockups: Improve lockup detection, fix generic arch fallback
  debug lockups: Improve lockup detection
parents 4004f02d 47cab6a7
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -89,8 +89,8 @@ static inline unsigned long get_softint(void)
	return retval;
}

void __trigger_all_cpu_backtrace(void);
#define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace()
void arch_trigger_all_cpu_backtrace(void);
#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace

extern void *hardirq_stack[NR_CPUS];
extern void *softirq_stack[NR_CPUS];
+2 −2
Original line number Diff line number Diff line
@@ -251,7 +251,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp)
	}
}

void __trigger_all_cpu_backtrace(void)
void arch_trigger_all_cpu_backtrace(void)
{
	struct thread_info *tp = current_thread_info();
	struct pt_regs *regs = get_irq_regs();
@@ -304,7 +304,7 @@ void __trigger_all_cpu_backtrace(void)

static void sysrq_handle_globreg(int key, struct tty_struct *tty)
{
	__trigger_all_cpu_backtrace();
	arch_trigger_all_cpu_backtrace();
}

static struct sysrq_key_op sparc_globalreg_op = {
+2 −2
Original line number Diff line number Diff line
@@ -45,8 +45,8 @@ extern int proc_nmi_enabled(struct ctl_table *, int , struct file *,
			void __user *, size_t *, loff_t *);
extern int unknown_nmi_panic;

void __trigger_all_cpu_backtrace(void);
#define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace()
void arch_trigger_all_cpu_backtrace(void);
#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace

static inline void localise_nmi_watchdog(void)
{
+13 −7
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@
int unknown_nmi_panic;
int nmi_watchdog_enabled;

static cpumask_var_t backtrace_mask;
static cpumask_t backtrace_mask __read_mostly;

/* nmi_active:
 * >0: the lapic NMI watchdog is active, but can be disabled
@@ -138,7 +138,6 @@ int __init check_nmi_watchdog(void)
	if (!prev_nmi_count)
		goto error;

	alloc_cpumask_var(&backtrace_mask, GFP_KERNEL|__GFP_ZERO);
	printk(KERN_INFO "Testing NMI watchdog ... ");

#ifdef CONFIG_SMP
@@ -415,14 +414,17 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
	}

	/* We can be called before check_nmi_watchdog, hence NULL check. */
	if (backtrace_mask != NULL && cpumask_test_cpu(cpu, backtrace_mask)) {
	if (cpumask_test_cpu(cpu, &backtrace_mask)) {
		static DEFINE_SPINLOCK(lock);	/* Serialise the printks */

		spin_lock(&lock);
		printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
		show_regs(regs);
		dump_stack();
		spin_unlock(&lock);
		cpumask_clear_cpu(cpu, backtrace_mask);
		cpumask_clear_cpu(cpu, &backtrace_mask);

		rc = 1;
	}

	/* Could check oops_in_progress here too, but it's safer not to */
@@ -552,14 +554,18 @@ int do_nmi_callback(struct pt_regs *regs, int cpu)
	return 0;
}

void __trigger_all_cpu_backtrace(void)
void arch_trigger_all_cpu_backtrace(void)
{
	int i;

	cpumask_copy(backtrace_mask, cpu_online_mask);
	cpumask_copy(&backtrace_mask, cpu_online_mask);

	printk(KERN_INFO "sending NMI to all CPUs:\n");
	apic->send_IPI_all(NMI_VECTOR);

	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
	for (i = 0; i < 10 * 1000; i++) {
		if (cpumask_empty(backtrace_mask))
		if (cpumask_empty(&backtrace_mask))
			break;
		mdelay(1);
	}
+14 −5
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/sysrq.h>
#include <linux/kbd_kern.h>
#include <linux/proc_fs.h>
#include <linux/nmi.h>
#include <linux/quotaops.h>
#include <linux/perf_counter.h>
#include <linux/kernel.h>
@@ -222,13 +223,21 @@ static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus);

static void sysrq_handle_showallcpus(int key, struct tty_struct *tty)
{
	/*
	 * Fall back to the workqueue based printing if the
	 * backtrace printing did not succeed or the
	 * architecture has no support for it:
	 */
	if (!trigger_all_cpu_backtrace()) {
		struct pt_regs *regs = get_irq_regs();

		if (regs) {
			printk(KERN_INFO "CPU%d:\n", smp_processor_id());
			show_regs(regs);
		}
		schedule_work(&sysrq_showallcpus);
	}
}

static struct sysrq_key_op sysrq_showallcpus_op = {
	.handler	= sysrq_handle_showallcpus,
Loading