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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox