powerpc: Streamline ret_from_except_lite for non-iSeries platforms
There is a small passage of code in ret_from_except_lite which is only required on iSeries. For a multi-platform kernel on non-iSeries machines this means we end up executing ~15 nops in ret_from_except_lite. It would be nicer if non-iSeries could skip the code entirely, and on iSeries we can jump out of line to execute the code. I have no performance numbers to justify this, other than the assertion that executing 15 nops takes longer than executing 0. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Родитель
cd5aeb9f6c
Коммит
01f3880dd8
|
@ -512,31 +512,12 @@ _GLOBAL(ret_from_except_lite)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
restore:
|
restore:
|
||||||
ld r5,SOFTE(r1)
|
|
||||||
#ifdef CONFIG_PPC_ISERIES
|
|
||||||
BEGIN_FW_FTR_SECTION
|
BEGIN_FW_FTR_SECTION
|
||||||
cmpdi 0,r5,0
|
ld r5,SOFTE(r1)
|
||||||
beq 4f
|
FW_FTR_SECTION_ELSE
|
||||||
/* Check for pending interrupts (iSeries) */
|
b iseries_check_pending_irqs
|
||||||
ld r3,PACALPPACAPTR(r13)
|
ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
|
||||||
ld r3,LPPACAANYINT(r3)
|
2:
|
||||||
cmpdi r3,0
|
|
||||||
beq+ 4f /* skip do_IRQ if no interrupts */
|
|
||||||
|
|
||||||
li r3,0
|
|
||||||
stb r3,PACASOFTIRQEN(r13) /* ensure we are soft-disabled */
|
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
|
||||||
bl .trace_hardirqs_off
|
|
||||||
mfmsr r10
|
|
||||||
#endif
|
|
||||||
ori r10,r10,MSR_EE
|
|
||||||
mtmsrd r10 /* hard-enable again */
|
|
||||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
|
||||||
bl .do_IRQ
|
|
||||||
b .ret_from_except_lite /* loop back and handle more */
|
|
||||||
4:
|
|
||||||
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
|
||||||
#endif
|
|
||||||
TRACE_AND_RESTORE_IRQ(r5);
|
TRACE_AND_RESTORE_IRQ(r5);
|
||||||
|
|
||||||
/* extract EE bit and use it to restore paca->hard_enabled */
|
/* extract EE bit and use it to restore paca->hard_enabled */
|
||||||
|
@ -592,6 +573,30 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
|
||||||
rfid
|
rfid
|
||||||
b . /* prevent speculative execution */
|
b . /* prevent speculative execution */
|
||||||
|
|
||||||
|
iseries_check_pending_irqs:
|
||||||
|
#ifdef CONFIG_PPC_ISERIES
|
||||||
|
ld r5,SOFTE(r1)
|
||||||
|
cmpdi 0,r5,0
|
||||||
|
beq 2b
|
||||||
|
/* Check for pending interrupts (iSeries) */
|
||||||
|
ld r3,PACALPPACAPTR(r13)
|
||||||
|
ld r3,LPPACAANYINT(r3)
|
||||||
|
cmpdi r3,0
|
||||||
|
beq+ 2b /* skip do_IRQ if no interrupts */
|
||||||
|
|
||||||
|
li r3,0
|
||||||
|
stb r3,PACASOFTIRQEN(r13) /* ensure we are soft-disabled */
|
||||||
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
|
bl .trace_hardirqs_off
|
||||||
|
mfmsr r10
|
||||||
|
#endif
|
||||||
|
ori r10,r10,MSR_EE
|
||||||
|
mtmsrd r10 /* hard-enable again */
|
||||||
|
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||||
|
bl .do_IRQ
|
||||||
|
b .ret_from_except_lite /* loop back and handle more */
|
||||||
|
#endif
|
||||||
|
|
||||||
do_work:
|
do_work:
|
||||||
#ifdef CONFIG_PREEMPT
|
#ifdef CONFIG_PREEMPT
|
||||||
andi. r0,r3,MSR_PR /* Returning to user mode? */
|
andi. r0,r3,MSR_PR /* Returning to user mode? */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче