From: Kirill Korotaev <dev@openvz.org>
To: devel@openvz.org, Andrew Morton <akpm@osdl.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
xemul@openvz.org, Andi Kleen <ak@suse.de>
Subject: [PATCH][x86_64] IPI calltraces on x86_64
Date: Mon, 17 Apr 2006 15:53:13 +0400 [thread overview]
Message-ID: <444381A9.4020400@openvz.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 399 bytes --]
[PATCH] IPI calltraces on x86_64
This patch makes x86_64 kernel to print calltraces on _all_
CPUs on Alt-SysRq-p and NMI LOCKUP.
This patch supplements the one made for i386
some time ago and included in -mm tree.
Since it proved its usefullness many times already
we did the same patch for x86_64.
Signed-Off-By: Pavel Emelianov <xemul@openvz.org>
Signed-Off-By: Kirill Korotaev <dev@openvz.org>
[-- Attachment #2: diff-smp-nmi-show-regs-emt64 --]
[-- Type: text/plain, Size: 4926 bytes --]
--- ./arch/x86_64/kernel/nmi.c.ve129 2006-03-20 08:53:29.000000000 +0300
+++ ./arch/x86_64/kernel/nmi.c 2006-04-05 17:35:49.000000000 +0400
@@ -522,6 +522,7 @@ static __kprobes int dummy_nmi_callback(
}
static nmi_callback_t nmi_callback = dummy_nmi_callback;
+static nmi_callback_t nmi_ipi_callback = dummy_nmi_callback;
asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
{
@@ -531,9 +532,21 @@ asmlinkage __kprobes void do_nmi(struct
add_pda(__nmi_count,1);
if (!rcu_dereference(nmi_callback)(regs, cpu))
default_do_nmi(regs);
+
+ nmi_ipi_callback(regs, cpu);
nmi_exit();
}
+void set_nmi_ipi_callback(nmi_callback_t callback)
+{
+ nmi_ipi_callback = callback;
+}
+
+void unset_nmi_ipi_callback(void)
+{
+ nmi_ipi_callback = dummy_nmi_callback;
+}
+
void set_nmi_callback(nmi_callback_t callback)
{
rcu_assign_pointer(nmi_callback, callback);
--- ./arch/x86_64/kernel/process.c.ve129 2006-04-05 16:52:55.000000000 +0400
+++ ./arch/x86_64/kernel/process.c 2006-04-05 18:13:16.000000000 +0400
@@ -345,6 +345,21 @@ void show_regs(struct pt_regs *regs)
show_trace(®s->rsp);
}
+void smp_show_regs(struct pt_regs *regs, void *data)
+{
+ static DEFINE_SPINLOCK(show_regs_lock);
+
+ if (regs == NULL)
+ return;
+
+ bust_spinlocks(1);
+ spin_lock(&show_regs_lock);
+ printk("----------- IPI show regs -----------\n");
+ show_regs(regs);
+ spin_unlock(&show_regs_lock);
+ bust_spinlocks(0);
+}
+
/*
* Free current thread data structures etc..
*/
--- ./arch/x86_64/kernel/smp.c.ve129 2006-04-05 15:11:18.000000000 +0400
+++ ./arch/x86_64/kernel/smp.c 2006-04-05 18:15:30.000000000 +0400
@@ -28,6 +28,7 @@
#include <asm/proto.h>
#include <asm/apicdef.h>
#include <asm/idle.h>
+#include <asm/nmi.h>
/*
* Smarter SMP flushing macros.
@@ -444,6 +445,84 @@ int smp_call_function (void (*func) (voi
return 0;
}
+static spinlock_t nmi_call_lock = SPIN_LOCK_UNLOCKED;
+static struct nmi_call_data_struct {
+ smp_nmi_function func;
+ void *info;
+ atomic_t started;
+ atomic_t finished;
+ cpumask_t cpus_called;
+ int wait;
+} *nmi_call_data;
+
+static int smp_nmi_callback(struct pt_regs * regs, int cpu)
+{
+ smp_nmi_function func;
+ void *info;
+ int wait;
+
+ func = nmi_call_data->func;
+ info = nmi_call_data->info;
+ wait = nmi_call_data->wait;
+ ack_APIC_irq();
+ /* prevent from calling func() multiple times */
+ if (cpu_test_and_set(cpu, nmi_call_data->cpus_called))
+ return 0;
+ /*
+ * notify initiating CPU that I've grabbed the data and am
+ * about to execute the function
+ */
+ mb();
+ atomic_inc(&nmi_call_data->started);
+ /* at this point the nmi_call_data structure is out of scope */
+ irq_enter();
+ func(regs, info);
+ irq_exit();
+ if (wait)
+ atomic_inc(&nmi_call_data->finished);
+
+ return 0;
+}
+
+int smp_nmi_call_function(smp_nmi_function func, void *info, int wait)
+{
+ struct nmi_call_data_struct data;
+ int cpus;
+
+ cpus = num_online_cpus() - 1;
+ if (!cpus)
+ return 0;
+
+ data.func = func;
+ data.info = info;
+ data.wait = wait;
+ atomic_set(&data.started, 0);
+ atomic_set(&data.finished, 0);
+ cpus_clear(data.cpus_called);
+ /* prevent this cpu from calling func if NMI happens */
+ cpu_set(smp_processor_id(), data.cpus_called);
+
+ if (!spin_trylock(&nmi_call_lock))
+ return -1;
+
+ nmi_call_data = &data;
+ set_nmi_ipi_callback(smp_nmi_callback);
+ mb();
+
+ /* Send a message to all other CPUs and wait for them to respond */
+ send_IPI_allbutself(APIC_DM_NMI);
+ while (atomic_read(&data.started) != cpus)
+ barrier();
+
+ unset_nmi_ipi_callback();
+ if (wait)
+ while (atomic_read(&data.finished) != cpus)
+ barrier();
+ spin_unlock(&nmi_call_lock);
+
+ return 0;
+}
+
void smp_stop_cpu(void)
{
unsigned long flags;
--- ./arch/x86_64/kernel/traps.c.ve129 2006-04-05 16:52:55.000000000 +0400
+++ ./arch/x86_64/kernel/traps.c 2006-04-05 17:43:53.000000000 +0400
@@ -460,6 +460,7 @@ void __kprobes die_nmi(char *str, struct
show_registers(regs);
if (panic_on_timeout || panic_on_oops)
panic("nmi watchdog");
+ smp_nmi_call_function(smp_show_regs, NULL, 1);
printk("console shuts up ...\n");
oops_end(flags);
do_exit(SIGSEGV);
--- ./drivers/char/sysrq.c.ve129 2006-04-05 16:52:55.000000000 +0400
+++ ./drivers/char/sysrq.c 2006-04-05 17:55:06.000000000 +0400
@@ -178,7 +178,7 @@ static void sysrq_handle_showregs(int ke
if (pt_regs)
show_regs(pt_regs);
bust_spinlocks(0);
-#ifdef __i386__
+#if defined(__i386__) || defined(__x86_64__)
smp_nmi_call_function(smp_show_regs, NULL, 0);
#endif
}
--- ./include/asm-x86_64/nmi.h.ve129 2006-03-20 08:53:29.000000000 +0300
+++ ./include/asm-x86_64/nmi.h 2006-04-05 17:44:44.000000000 +0400
@@ -24,6 +24,9 @@ void set_nmi_callback(nmi_callback_t cal
* Remove the handler previously set.
*/
void unset_nmi_callback(void);
+
+void set_nmi_ipi_callback(nmi_callback_t callback);
+void unset_nmi_ipi_callback(void);
#ifdef CONFIG_PM
next reply other threads:[~2006-04-17 11:45 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-17 11:53 Kirill Korotaev [this message]
2006-04-21 12:02 ` [PATCH][x86_64] IPI calltraces on x86_64 Andi Kleen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=444381A9.4020400@openvz.org \
--to=dev@openvz.org \
--cc=ak@suse.de \
--cc=akpm@osdl.org \
--cc=devel@openvz.org \
--cc=linux-kernel@vger.kernel.org \
--cc=xemul@openvz.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.