DragonFly kernel List (threaded) for 2008-01
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
Re: Interrupt recursion smashes kernel memory
Ok, it is definitely able to recurse. Critical sections prevent
interrupt recursion but also prevent thread preemption, so its a
chicken and egg problem... I want to prevent interrupt recursion but
ALLOW thread preemption when scheduling an interrupt thread from
inside a slow interrupt.
The slow interrupt code is STI'ing and calling sched_ithd() without
a critical section held in order to allow it to preempt. If it does
preempt, however, the interrupt thread can run, unmask the interrupt,
and recurse because interrupts are enabled prior to actually getting
through the doreti.
I can't use critical sections because those will disable the desired
thread preemption along with preventing interrupt recursion.
I can't use gd->intr_nesting_level because the trap code uses doreti
and isn't expecting intr_nesting_level to be non-zero in most cases.
I can't leave us CLI'd because, well, its just a bad idea to do that.
I think the solution is to use TD_NEST_COUNT (curthread->td_nest_count)
to prevent recursive interrupts from blowing up the stack.
Please try this patch.
-Matt
Index: platform/pc32/apic/apic_vector.s
===================================================================
RCS file: /cvs/src/sys/platform/pc32/apic/apic_vector.s,v
retrieving revision 1.36
diff -u -p -r1.36 apic_vector.s
--- platform/pc32/apic/apic_vector.s 22 Jan 2007 19:37:04 -0000 1.36
+++ platform/pc32/apic/apic_vector.s 14 Jan 2008 00:37:34 -0000
@@ -154,6 +154,8 @@ movl $0, lapic_eoi ; \
movl PCPU(curthread),%ebx ; \
movl $0,%eax ; /* CURRENT CPL IN FRAME (REMOVED) */ \
pushl %eax ; \
+ testl $-1,TD_NEST_COUNT(%ebx) ; \
+ jne 1f ; \
cmpl $TDPRI_CRIT,TD_PRI(%ebx) ; \
jl 2f ; \
1: ; \
@@ -208,6 +210,8 @@ movl $0, lapic_eoi ; \
movl PCPU(curthread),%ebx ; \
movl $0,%eax ; /* CURRENT CPL IN FRAME (REMOVED) */ \
pushl %eax ; /* cpl do restore */ \
+ testl $-1,TD_NEST_COUNT(%ebx) ; \
+ jne 1f ; \
cmpl $TDPRI_CRIT,TD_PRI(%ebx) ; \
jl 2f ; \
1: ; \
@@ -218,10 +222,13 @@ jmp 5f ; \
2: ; \
/* set running bit, clear pending bit, run handler */ \
andl $~IRQ_LBIT(irq_num), PCPU(ipending) ; \
+ incl TD_NEST_COUNT(%ebx) ; \
sti ; \
pushl $irq_num ; \
call sched_ithd ; \
addl $4,%esp ; \
+ cli ; \
+ decl TD_NEST_COUNT(%ebx) ; \
5: ; \
MEXITCOUNT ; \
jmp doreti ; \
Index: platform/pc32/icu/icu_vector.s
===================================================================
RCS file: /cvs/src/sys/platform/pc32/icu/icu_vector.s,v
retrieving revision 1.30
diff -u -p -r1.30 icu_vector.s
--- platform/pc32/icu/icu_vector.s 22 Jan 2007 19:37:04 -0000 1.30
+++ platform/pc32/icu/icu_vector.s 14 Jan 2008 00:38:37 -0000
@@ -144,6 +144,8 @@ MASK_IRQ(icu, irq_num) ; \
enable_icus ; \
movl PCPU(curthread),%ebx ; \
pushl $0 ; /* DUMMY CPL FOR DORETI */ \
+ testl $-1,TD_NEST_COUNT(%ebx) ; \
+ jne 1f ; \
cmpl $TDPRI_CRIT,TD_PRI(%ebx) ; \
jl 2f ; \
1: ; \
@@ -198,6 +200,8 @@ incl PCPU(cnt) + V_INTR ;
enable_icus ; \
movl PCPU(curthread),%ebx ; \
pushl $0 ; /* DUMMY CPL FOR DORETI */ \
+ testl $-1,TD_NEST_COUNT(%ebx) ; \
+ jne 1f ; \
cmpl $TDPRI_CRIT,TD_PRI(%ebx) ; \
jl 2f ; \
1: ; \
@@ -208,10 +212,13 @@ jmp 5f ; \
2: ; \
/* set running bit, clear pending bit, run handler */ \
andl $~IRQ_LBIT(irq_num), PCPU(ipending) ; \
+ incl TD_NEST_COUNT(%ebx) ; \
sti ; \
pushl $irq_num ; \
call sched_ithd ; \
addl $4,%esp ; \
+ cli ; \
+ decl TD_NEST_COUNT(%ebx) ; \
5: ; \
MEXITCOUNT ; \
jmp doreti ; \
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]