aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2014-08-19 15:37:41 +0100
committerDaniel Thompson <daniel.thompson@linaro.org>2022-04-13 17:22:53 +0100
commitb58798cd87e95bdb8832940ba312ce920de71613 (patch)
tree580d11e891aafe925eb514f1b92aef2ffde4bb7e
parent4f886ca3243fd3ede50a2064c548aa6a5ef5a65e (diff)
proc: Provide access to /proc/interrupts from kdbkdb/seq_file
The contents of /proc/interrupts is useful to diagnose problems during boot up or when the system becomes unresponsive (or at least it can be if failure is causes by interrupt problems). This command is also seen in out-of-tree debug systems such as Android's FIQ debugger. This change allows the file to be displayed from kdb. Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
-rw-r--r--fs/proc/interrupts.c4
-rw-r--r--kernel/irq/proc.c7
2 files changed, 10 insertions, 1 deletions
diff --git a/fs/proc/interrupts.c b/fs/proc/interrupts.c
index cb0edc7cbf09..1ab4e4b1c28b 100644
--- a/fs/proc/interrupts.c
+++ b/fs/proc/interrupts.c
@@ -5,6 +5,7 @@
#include <linux/irqnr.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/kdb.h>
/*
* /proc/interrupts
@@ -34,9 +35,12 @@ static const struct seq_operations int_seq_ops = {
.show = show_interrupts
};
+DEFINE_KDB_SEQ_FILE(interrupts, "Show /proc/interrupts", &int_seq_ops)
+
static int __init proc_interrupts_init(void)
{
proc_create_seq("interrupts", 0, NULL, &int_seq_ops);
+ register_kdb_seq_file_interrupts();
return 0;
}
fs_initcall(proc_interrupts_init);
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 623b8136e9af..3fa735257b03 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/mutex.h>
+#include <linux/kgdb.h>
#include "internals.h"
@@ -501,7 +502,11 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", desc->kstat_irqs ?
*per_cpu_ptr(desc->kstat_irqs, j) : 0);
- raw_spin_lock_irqsave(&desc->lock, flags);
+ if (!raw_spin_lock_irqsave_dbg(&desc->lock, flags)) {
+ seq_printf(p, " <descriptor is locked>\n");
+ goto outsparse;
+ }
+
if (desc->irq_data.chip) {
if (desc->irq_data.chip->irq_print_chip)
desc->irq_data.chip->irq_print_chip(&desc->irq_data, p);