From: Dave Hansen <haveblue@us.ibm.com>
To: Benjamin LaHaise <bcrl@redhat.com>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Paul Larson <plars@us.ibm.com>,
"Martin J. Bligh" <mbligh@aracnet.com>
Subject: 4k stacks and BUILD_INTERRUPT
Date: Sun, 26 Jan 2003 23:43:49 -0800 [thread overview]
Message-ID: <3E34E335.1000600@us.ibm.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1160 bytes --]
I was getting some pretty repeatable oopses while large numbers of
processes were exiting on my 16-way PIII while irqstacks, and 4k stacks
were turned on. It is hard to trigger, and only happens when you're
using 4k stacks, not just irqstacks.
I traced it down to when smp_* interrupts were running. It seems that
they use an interrupt entry path that doesn't include do_IRQ or
common_interrupt. They use a BUILD_INTERRUPT macro, instead. They were
blowing their 4k stacks when running softirqs.
So, what I did, was put the irqstack operations in a macro and call it
from common_interrupt, and the BUILD_INTERRUPT macros. I also had to
change the calling conventions of the newly-affected handlers.
Ben, was there a reason that you didn't include these functions in your
original irqstack patches? I always (wrongly) assumed that they were
really quick interrupts, and didn't use the stack heavily enough to be
worth modifying.
The a diff for the -mjb tree is attached. I'll cook up another set of
vanilla ones tomorrow.
Does anybody want to see irqstacks as a config option? These macros
would make it easier.
--
Dave Hansen
haveblue@us.ibm.com
[-- Attachment #2: newirqstack-0.patch --]
[-- Type: text/plain, Size: 6396 bytes --]
diff -ur linux-2.5.59-mjb1/arch/i386/kernel/apic.c linux-2.5.59-numaq-mjb1/arch/i386/kernel/apic.c
--- linux-2.5.59-mjb1/arch/i386/kernel/apic.c Sun Jan 26 23:14:51 2003
+++ linux-2.5.59-numaq-mjb1/arch/i386/kernel/apic.c Sun Jan 26 14:23:22 2003
@@ -1038,7 +1038,8 @@
* interrupt as well. Thus we cannot inline the local irq ... ]
*/
-void smp_apic_timer_interrupt(struct pt_regs regs)
+struct pt_regs * smp_apic_timer_interrupt(struct pt_regs* regs) __attribute__((regparm(1)));
+struct pt_regs * smp_apic_timer_interrupt(struct pt_regs* regs)
{
int cpu = smp_processor_id();
@@ -1058,14 +1059,16 @@
* interrupt lock, which is the WrongThing (tm) to do.
*/
irq_enter();
- smp_local_timer_interrupt(®s);
+ smp_local_timer_interrupt(regs);
irq_exit();
+ return regs;
}
/*
* This interrupt should _never_ happen with our APIC/SMP architecture
*/
-asmlinkage void smp_spurious_interrupt(void)
+struct pt_regs * smp_spurious_interrupt(struct pt_regs* regs) __attribute__((regparm(1)));
+struct pt_regs * smp_spurious_interrupt(struct pt_regs* regs)
{
unsigned long v;
@@ -1083,13 +1086,15 @@
printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n",
smp_processor_id());
irq_exit();
+ return regs;
}
/*
* This interrupt should never happen with our APIC/SMP architecture
*/
-asmlinkage void smp_error_interrupt(void)
+struct pt_regs * smp_error_interrupt(struct pt_regs* regs) __attribute__((regparm(1)));
+struct pt_regs * smp_error_interrupt(struct pt_regs* regs)
{
unsigned long v, v1;
@@ -1114,6 +1119,7 @@
printk (KERN_INFO "APIC error on CPU%d: %02lx(%02lx)\n",
smp_processor_id(), v , v1);
irq_exit();
+ return regs;
}
/*
diff -ur linux-2.5.59-mjb1/arch/i386/kernel/entry.S linux-2.5.59-numaq-mjb1/arch/i386/kernel/entry.S
--- linux-2.5.59-mjb1/arch/i386/kernel/entry.S Sun Jan 26 23:16:19 2003
+++ linux-2.5.59-numaq-mjb1/arch/i386/kernel/entry.S Sun Jan 26 23:13:23 2003
@@ -138,7 +138,42 @@
.long 1b,2b; \
.previous
-
+#define SWITCH_TO_IRQSTACK \
+ GET_THREAD_INFO(%ebx); \
+ movl TI_IRQ_STACK(%ebx),%ecx; \
+ movl TI_TASK(%ebx),%edx; \
+ movl %esp,%eax; \
+ leal (THREAD_SIZE-4)(%ecx),%esi;# %ecx+THREAD_SIZE is next stack\
+ # -4 keeps us in the right one \
+ testl %ecx,%ecx; # is there a valid irq_stack? \
+ \
+ # switch to the irq stack \
+#ifdef CONFIG_X86_HAVE_CMOV
+ cmovnz %esi,%esp; \
+#else \
+ jz 1f; \
+ mov %esi,%esp; \
+1: \
+#endif
+ \
+ # update the task pointer in the irq stack \
+ GET_THREAD_INFO(%esi); \
+ movl %edx,TI_TASK(%esi); \
+ \
+ # update the preempt count in the irq stack \
+ movl TI_PRE_COUNT(%ebx),%ecx; \
+ movl %ecx,TI_PRE_COUNT(%esi);
+
+#define RESTORE_FROM_IRQSTACK \
+ movl %eax,%esp; # potentially restore non-irq stack \
+ \
+ # copy flags from the irq stack back into the tasks thread_info \
+ # esi is saved over the do_IRQ call and contains the irq stack \
+ # thread_info pointer \
+ # ebx contains the original thread_info pointer \
+ movl TI_FLAGS(%esi),%eax; \
+ movl $0,TI_FLAGS(%esi); \
+ LOCK orl %eax,TI_FLAGS(%ebx);
ENTRY(lcall7)
pushfl # We get a different stack layout with call
@@ -391,52 +426,16 @@
ALIGN
common_interrupt:
SAVE_ALL
-
-
- GET_THREAD_INFO(%ebx)
- movl TI_IRQ_STACK(%ebx),%ecx
- movl TI_TASK(%ebx),%edx
- movl %esp,%eax
- leal (THREAD_SIZE-4)(%ecx),%esi # %ecx+THREAD_SIZE is next stack
- # -4 keeps us in the right one
- testl %ecx,%ecx # is there a valid irq_stack?
-
- # switch to the irq stack
-#ifdef CONFIG_X86_HAVE_CMOV
- cmovnz %esi,%esp
-#else
- jz 1f
- mov %esi,%esp
-1:
-#endif
-
- # update the task pointer in the irq stack
- GET_THREAD_INFO(%esi)
- movl %edx,TI_TASK(%esi)
-
- # update the preempt count in the irq stack
- movl TI_PRE_COUNT(%ebx),%ecx
- movl %ecx,TI_PRE_COUNT(%esi)
-
+ SWITCH_TO_IRQSTACK
call do_IRQ
-
- movl %eax,%esp # potentially restore non-irq stack
-
- # copy flags from the irq stack back into the task's thread_info
- # %esi is saved over the do_IRQ call and contains the irq stack
- # thread_info pointer
- # %ebx contains the original thread_info pointer
- movl TI_FLAGS(%esi),%eax
- movl $0,TI_FLAGS(%esi)
- LOCK orl %eax,TI_FLAGS(%ebx)
-
+ RESTORE_FROM_IRQSTACK
jmp ret_from_intr
#define BUILD_INTERRUPT(name, nr) \
ENTRY(name) \
- pushl $nr-256; \
- SAVE_ALL \
- call smp_/**/name; \
+ SWITCH_TO_IRQSTACK \
+ call smp_/**/name; \
+ RESTORE_FROM_IRQSTACK \
jmp ret_from_intr;
/* The include is where all of the SMP etc. interrupts come from */
diff -ur linux-2.5.59-mjb1/arch/i386/kernel/smp.c linux-2.5.59-numaq-mjb1/arch/i386/kernel/smp.c
--- linux-2.5.59-mjb1/arch/i386/kernel/smp.c Sun Jan 26 23:16:19 2003
+++ linux-2.5.59-numaq-mjb1/arch/i386/kernel/smp.c Sun Jan 26 14:37:09 2003
@@ -305,7 +305,8 @@
* 2) Leave the mm if we are in the lazy tlb mode.
*/
-asmlinkage void smp_invalidate_interrupt (void)
+struct pt_regs *smp_invalidate_interrupt(struct pt_regs *regs) __attribute__((regparm(1)));
+struct pt_regs *smp_invalidate_interrupt(struct pt_regs *regs)
{
unsigned long cpu;
@@ -336,6 +337,7 @@
out:
put_cpu_no_resched();
+ return regs;
}
static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
@@ -598,12 +600,17 @@
* all the work is done automatically when
* we return from the interrupt.
*/
-asmlinkage void smp_reschedule_interrupt(void)
+
+asmlinkage struct pt_regs * smp_reschedule_interrupt(struct pt_regs *regs) __attribute__((regparm(1)));
+struct pt_regs * smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
+ return regs;
}
-asmlinkage void smp_call_function_interrupt(struct pt_regs regs)
+
+asmlinkage struct pt_regs * smp_call_function_interrupt(struct pt_regs *regs) __attribute__((regparm(1)));
+struct pt_regs * smp_call_function_interrupt(struct pt_regs *regs)
{
void (*func) (void *info, struct pt_regs *) = (void (*)(void *, struct pt_regs*))call_data->func;
void *info = call_data->info;
@@ -620,12 +627,13 @@
* At this point the info structure may be out of scope unless wait==1
*/
irq_enter();
- (*func)(info, ®s);
+ (*func)(info, regs);
irq_exit();
if (wait) {
mb();
atomic_inc(&call_data->finished);
}
+ return regs;
}
next reply other threads:[~2003-01-27 7:35 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-01-27 7:43 Dave Hansen [this message]
2003-01-27 8:57 ` 4k stacks and BUILD_INTERRUPT Dave Hansen
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=3E34E335.1000600@us.ibm.com \
--to=haveblue@us.ibm.com \
--cc=bcrl@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mbligh@aracnet.com \
--cc=plars@us.ibm.com \
/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.