Skip to content

Commit

Permalink
powerpc/ppc64: Use preempt_schedule_irq instead of preempt_schedule
Browse files Browse the repository at this point in the history
Based on an original patch by Valentine Barshak <vbarshak@ru.mvista.com>

Use preempt_schedule_irq to prevent infinite irq-entry and
eventual stack overflow problems with fast-paced IRQ sources.

This kind of problems has been observed on the PASemi Electra IDE
controller. We have to make sure we are soft-disabled before calling
preempt_schedule_irq and hard disable interrupts after that
to avoid unrecoverable exceptions.

This patch also moves the "clrrdi r9,r1,THREAD_SHIFT" out of
the #ifdef CONFIG_PPC_BOOK3E scope, since r9 is clobbered
and has to be restored in both cases.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Benjamin Herrenschmidt committed Oct 27, 2009
1 parent 01deab9 commit 4f917ba
Showing 1 changed file with 21 additions and 20 deletions.
41 changes: 21 additions & 20 deletions arch/powerpc/kernel/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -658,42 +658,43 @@ do_work:
cmpdi r0,0
crandc eq,cr1*4+eq,eq
bne restore
/* here we are preempting the current task */
1:
#ifdef CONFIG_TRACE_IRQFLAGS
bl .trace_hardirqs_on
/* Note: we just clobbered r10 which used to contain the previous
* MSR before the hard-disabling done by the caller of do_work.
* We don't have that value anymore, but it doesn't matter as
* we will hard-enable unconditionally, we can just reload the
* current MSR into r10

/* Here we are preempting the current task.
*
* Ensure interrupts are soft-disabled. We also properly mark
* the PACA to reflect the fact that they are hard-disabled
* and trace the change
*/
mfmsr r10
#endif /* CONFIG_TRACE_IRQFLAGS */
li r0,1
li r0,0
stb r0,PACASOFTIRQEN(r13)
stb r0,PACAHARDIRQEN(r13)
TRACE_DISABLE_INTS

/* Call the scheduler with soft IRQs off */
1: bl .preempt_schedule_irq

/* Hard-disable interrupts again (and update PACA) */
#ifdef CONFIG_PPC_BOOK3E
wrteei 1
bl .preempt_schedule
wrteei 0
#else
ori r10,r10,MSR_EE
mtmsrd r10,1 /* reenable interrupts */
bl .preempt_schedule
mfmsr r10
clrrdi r9,r1,THREAD_SHIFT
rldicl r10,r10,48,1 /* disable interrupts again */
rldicl r10,r10,48,1
rotldi r10,r10,16
mtmsrd r10,1
#endif /* CONFIG_PPC_BOOK3E */
li r0,0
stb r0,PACAHARDIRQEN(r13)

/* Re-test flags and eventually loop */
clrrdi r9,r1,THREAD_SHIFT
ld r4,TI_FLAGS(r9)
andi. r0,r4,_TIF_NEED_RESCHED
bne 1b
b restore

user_work:
#endif
#endif /* CONFIG_PREEMPT */

/* Enable interrupts */
#ifdef CONFIG_PPC_BOOK3E
wrteei 1
Expand Down

0 comments on commit 4f917ba

Please sign in to comment.