Jay Lan (on Mon, 27 Oct 2008 19:00:28 -0700) wrote:
>From: Cliff Wickman <[EMAIL PROTECTED]>
>
>Hi Jay,
>
>Remember the conflict over interrupt vector 0xf8 between KDB and
>UV TLB shootdown?
>
>There didn't seem to be any clean way to resolve that. The dynamic
>interrupt vector scheme that's going into the kernel does not allow
>assigning the same vector to all cpu's, or specifying a vector priority.
>And KDB needs to be higher priority than the timer interrupt, and UV TLB
>shootdown should be too.
>
>But since KDB only needs KDB_VECTOR to ping other cpu's it seems that
>it can use one of the system vectors temporarily (not the UV TLB shootdown's
>however, as it might be in-progress during the entry to KDB). Dimitri
>suggested this approach.
>
>So I tried commandeering 0xfe (ERROR_APIC_VECTOR).
>According to arch/x86/kernel/apic_64.c:
> "This interrupt should never happen with our APIC/SMP architecture"
>
>When a cpu enters kdb, this patch causes it to commandeer that vector,
>send the IPI's, and wait till all other cpu's enter kdb. Then restore
>the IDT to its previous state.
>
>It seems to work. I tested on x86_64 and ia32.
>What do you think?
>
>Diffed against 2.6.27-rc8
>Signed-off-by: Cliff Wickman <[EMAIL PROTECTED]>
>---
> arch/x86/kdb/kdbasupport_32.c | 36 ++++++++++++++++++++++++++++++++----
> arch/x86/kdb/kdbasupport_64.c | 37 +++++++++++++++++++++++++++++++++----
> include/asm-x86/irq_vectors.h | 11 ++++++-----
> 3 files changed, 71 insertions(+), 13 deletions(-)
>
>Index: 081002.linus/arch/x86/kdb/kdbasupport_32.c
>===================================================================
>--- 081002.linus.orig/arch/x86/kdb/kdbasupport_32.c
>+++ 081002.linus/arch/x86/kdb/kdbasupport_32.c
>@@ -883,9 +883,6 @@ kdba_cpu_up(void)
> static int __init
> kdba_arch_init(void)
> {
>-#ifdef CONFIG_SMP
>- set_intr_gate(KDB_VECTOR, kdb_interrupt);
>-#endif
> set_intr_gate(KDBENTER_VECTOR, kdb_call);
> return 0;
> }
>@@ -1027,14 +1024,45 @@ kdba_verify_rw(unsigned long addr, size_
>
> #include <mach_ipi.h>
>
>+gate_desc save_idt[NR_VECTORS];
>+
>+void kdb_takeover_vector(int vector)
>+{
>+ memcpy(&save_idt[vector], &idt_table[vector], sizeof(gate_desc));
>+ set_intr_gate(KDB_VECTOR, kdb_interrupt);
>+ return;
>+}
>+
>+void kdb_giveback_vector(int vector)
>+{
>+ native_write_idt_entry(idt_table, vector, &save_idt[vector]);
>+ return;
>+}
>+
> /* When first entering KDB, try a normal IPI. That reduces backtrace problems
> * on the other cpus.
> */
> void
> smp_kdb_stop(void)
> {
>- if (!KDB_FLAG(NOIPI))
>+ int count;
>+ int cpu;
>+
>+ if (!KDB_FLAG(NOIPI)) {
>+ kdb_takeover_vector(KDB_VECTOR);
> send_IPI_allbutself(KDB_VECTOR);
>+ do {
>+ count = 0;
>+ for_each_possible_cpu(cpu) {
>+ if (cpu_isset(cpu, cpu_online_map)) {
>+ if (!KDB_STATE_CPU(KDB,cpu))
>+ /* count any cpus NOT in kdb */
>+ count++;
>+ }
>+ }
>+ } while (count != 0);
>+ kdb_giveback_vector(KDB_VECTOR);
>+ }
> }
>
> /* The normal KDB IPI handler */
I don't see how this can work. kdba_arch_init() currently maps
KDB_VECTOR to kdb_interrupt() on each cpu as that cpu is brought up.
IOW, KDB_VECTOR ends up being defined on ALL cpus before any KDB
interrupt is sent.
Your kdb_takeover_vector() only maps KDB_VECTOR to kdb_interrupt() on
the CURRENT cpu, then sends KDB_VECTOR to all the other cpus. How do
the other cpus know what to do with KDB_VECTOR when they receive it?
They will have no definition for KDB_VECTOR so they will receive an
unexpected interrupt.
---------------------------
Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.