mirror of
https://github.com/reactos/reactos.git
synced 2025-07-27 20:32:18 +00:00
[PERF]: Optimize nested interrupt cases (where a pending interrupt exists at the end of a software or system interrupt) just like the old HAL did, by jumping into a second-level handler and completing the outer trap frame instead of the nested trap frame. This saves a lot of cycles in those cases, and they do happen quite often (pending DPC at the end of an interrupt, for example).
[NTOS/HAL]: Rework respective code to handle this by using the VDM Alert field in the KPCR. svn path=/trunk/; revision=45301
This commit is contained in:
parent
55c5579b1d
commit
7509f62a3b
4 changed files with 115 additions and 32 deletions
|
@ -205,6 +205,15 @@ PHAL_SW_INTERRUPT_HANDLER SWInterruptHandlerTable[3] =
|
||||||
HalpDispatchInterrupt
|
HalpDispatchInterrupt
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Handlers for pending software interrupts when we already have a trap frame*/
|
||||||
|
PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2[3] =
|
||||||
|
{
|
||||||
|
(PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY)KiUnexpectedInterrupt,
|
||||||
|
HalpApcInterrupt2ndEntry,
|
||||||
|
HalpDispatchInterrupt2ndEntry
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
USHORT HalpEisaELCR;
|
USHORT HalpEisaELCR;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
@ -552,9 +561,7 @@ HalpEndSoftwareInterrupt(IN KIRQL OldIrql)
|
||||||
|
|
||||||
/* Check for pending software interrupts and compare with current IRQL */
|
/* Check for pending software interrupts and compare with current IRQL */
|
||||||
PendingIrql = SWInterruptLookUpTable[Pcr->IRR];
|
PendingIrql = SWInterruptLookUpTable[Pcr->IRR];
|
||||||
|
if (PendingIrql > OldIrql) HalpNestedTrap(PendingIrql);
|
||||||
/* NOTE: We can do better! We need to support "jumping" a frame for nested cases! */
|
|
||||||
if (PendingIrql > OldIrql) SWInterruptHandlerTable[PendingIrql]();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* INTERRUPT DISMISSAL FUNCTIONS **********************************************/
|
/* INTERRUPT DISMISSAL FUNCTIONS **********************************************/
|
||||||
|
@ -811,26 +818,19 @@ HalEndSystemInterrupt(IN KIRQL OldIrql,
|
||||||
|
|
||||||
/* Check for pending software interrupts and compare with current IRQL */
|
/* Check for pending software interrupts and compare with current IRQL */
|
||||||
PendingIrql = SWInterruptLookUpTable[Pcr->IRR];
|
PendingIrql = SWInterruptLookUpTable[Pcr->IRR];
|
||||||
if (PendingIrql > OldIrql) SWInterruptHandlerTable[PendingIrql]();
|
if (PendingIrql > OldIrql) HalpNestedTrap(PendingIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SOFTWARE INTERRUPT TRAPS ***************************************************/
|
/* SOFTWARE INTERRUPT TRAPS ***************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FORCEINLINE
|
||||||
HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
DECLSPEC_NORETURN
|
||||||
|
_HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
KIRQL CurrentIrql;
|
KIRQL CurrentIrql;
|
||||||
PKPCR Pcr = KeGetPcr();
|
PKPCR Pcr = KeGetPcr();
|
||||||
|
|
||||||
/* Set up a fake INT Stack */
|
|
||||||
TrapFrame->EFlags = __readeflags();
|
|
||||||
TrapFrame->SegCs = KGDT_R0_CODE;
|
|
||||||
TrapFrame->Eip = TrapFrame->Eax;
|
|
||||||
|
|
||||||
/* Build the trap frame */
|
|
||||||
KiEnterInterruptTrap(TrapFrame);
|
|
||||||
|
|
||||||
/* Save the current IRQL and update it */
|
/* Save the current IRQL and update it */
|
||||||
CurrentIrql = Pcr->Irql;
|
CurrentIrql = Pcr->Irql;
|
||||||
Pcr->Irql = APC_LEVEL;
|
Pcr->Irql = APC_LEVEL;
|
||||||
|
@ -847,6 +847,7 @@ HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
|
||||||
/* Disable interrupts and end the interrupt */
|
/* Disable interrupts and end the interrupt */
|
||||||
_disable();
|
_disable();
|
||||||
|
Pcr->VdmAlert = (ULONG_PTR)TrapFrame;
|
||||||
HalpEndSoftwareInterrupt(CurrentIrql);
|
HalpEndSoftwareInterrupt(CurrentIrql);
|
||||||
|
|
||||||
/* Exit the interrupt */
|
/* Exit the interrupt */
|
||||||
|
@ -855,11 +856,18 @@ HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
DECLSPEC_NORETURN
|
||||||
|
HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
KIRQL CurrentIrql;
|
/* Do the work */
|
||||||
PKPCR Pcr = KeGetPcr();
|
_HalpApcInterruptHandler(TrapFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
DECLSPEC_NORETURN
|
||||||
|
HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
/* Set up a fake INT Stack */
|
/* Set up a fake INT Stack */
|
||||||
TrapFrame->EFlags = __readeflags();
|
TrapFrame->EFlags = __readeflags();
|
||||||
TrapFrame->SegCs = KGDT_R0_CODE;
|
TrapFrame->SegCs = KGDT_R0_CODE;
|
||||||
|
@ -868,6 +876,18 @@ HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
/* Build the trap frame */
|
/* Build the trap frame */
|
||||||
KiEnterInterruptTrap(TrapFrame);
|
KiEnterInterruptTrap(TrapFrame);
|
||||||
|
|
||||||
|
/* Do the work */
|
||||||
|
_HalpApcInterruptHandler(TrapFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FORCEINLINE
|
||||||
|
DECLSPEC_NORETURN
|
||||||
|
_HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
KIRQL CurrentIrql;
|
||||||
|
PKPCR Pcr = KeGetPcr();
|
||||||
|
|
||||||
/* Save the current IRQL and update it */
|
/* Save the current IRQL and update it */
|
||||||
CurrentIrql = Pcr->Irql;
|
CurrentIrql = Pcr->Irql;
|
||||||
Pcr->Irql = DISPATCH_LEVEL;
|
Pcr->Irql = DISPATCH_LEVEL;
|
||||||
|
@ -881,11 +901,38 @@ HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
|
||||||
/* Disable interrupts and end the interrupt */
|
/* Disable interrupts and end the interrupt */
|
||||||
_disable();
|
_disable();
|
||||||
|
Pcr->VdmAlert = (ULONG_PTR)TrapFrame;
|
||||||
HalpEndSoftwareInterrupt(CurrentIrql);
|
HalpEndSoftwareInterrupt(CurrentIrql);
|
||||||
|
|
||||||
/* Exit the interrupt */
|
/* Exit the interrupt */
|
||||||
KiEoiHelper(TrapFrame);
|
KiEoiHelper(TrapFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
DECLSPEC_NORETURN
|
||||||
|
HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
/* Do the work */
|
||||||
|
_HalpDispatchInterruptHandler(TrapFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
DECLSPEC_NORETURN
|
||||||
|
HalpDispatchInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
/* Set up a fake INT Stack */
|
||||||
|
TrapFrame->EFlags = __readeflags();
|
||||||
|
TrapFrame->SegCs = KGDT_R0_CODE;
|
||||||
|
TrapFrame->Eip = TrapFrame->Eax;
|
||||||
|
|
||||||
|
/* Build the trap frame */
|
||||||
|
KiEnterInterruptTrap(TrapFrame);
|
||||||
|
|
||||||
|
/* Do the work */
|
||||||
|
_HalpDispatchInterruptHandler(TrapFrame);
|
||||||
|
}
|
||||||
|
|
||||||
KiTrap(HalpApcInterrupt, KI_SOFTWARE_TRAP);
|
KiTrap(HalpApcInterrupt, KI_SOFTWARE_TRAP);
|
||||||
KiTrap(HalpDispatchInterrupt, KI_SOFTWARE_TRAP);
|
KiTrap(HalpDispatchInterrupt, KI_SOFTWARE_TRAP);
|
||||||
|
|
|
@ -22,6 +22,19 @@ typedef struct _HAL_BIOS_FRAME
|
||||||
ULONG Prefix;
|
ULONG Prefix;
|
||||||
} HAL_BIOS_FRAME, *PHAL_BIOS_FRAME;
|
} HAL_BIOS_FRAME, *PHAL_BIOS_FRAME;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
VOID
|
||||||
|
(*PHAL_SW_INTERRUPT_HANDLER)(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef
|
||||||
|
FASTCALL
|
||||||
|
VOID
|
||||||
|
(*PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY)(
|
||||||
|
IN PKTRAP_FRAME TrapFrame
|
||||||
|
);
|
||||||
|
|
||||||
#define HAL_APC_REQUEST 0
|
#define HAL_APC_REQUEST 0
|
||||||
#define HAL_DPC_REQUEST 1
|
#define HAL_DPC_REQUEST 1
|
||||||
|
|
||||||
|
@ -98,6 +111,28 @@ HalpRealModeStack(IN ULONG Alignment,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Nested Trap Trampoline
|
||||||
|
//
|
||||||
|
VOID
|
||||||
|
DECLSPEC_NORETURN
|
||||||
|
FORCEINLINE
|
||||||
|
HalpNestedTrap(IN KIRQL PendingIrql)
|
||||||
|
{
|
||||||
|
/* Use the second interrupt handler table */
|
||||||
|
extern PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2[3];
|
||||||
|
__asm__ __volatile__
|
||||||
|
(
|
||||||
|
"movl %c[t], %%ecx\n"
|
||||||
|
"jmp *%0\n"
|
||||||
|
:
|
||||||
|
: "im"(SWInterruptHandlerTable2[PendingIrql]),
|
||||||
|
[t] "i"(&PCR->VdmAlert)
|
||||||
|
: "%esp"
|
||||||
|
);
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Commonly stated as being 1.19318MHz
|
// Commonly stated as being 1.19318MHz
|
||||||
//
|
//
|
||||||
|
@ -431,12 +466,6 @@ typedef struct _PIC_MASK
|
||||||
};
|
};
|
||||||
} PIC_MASK, *PPIC_MASK;
|
} PIC_MASK, *PPIC_MASK;
|
||||||
|
|
||||||
typedef
|
|
||||||
VOID
|
|
||||||
(*PHAL_SW_INTERRUPT_HANDLER)(
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
__attribute__((regparm(3)))
|
__attribute__((regparm(3)))
|
||||||
|
@ -531,6 +560,8 @@ HalpEnableInterruptHandler(IN UCHAR Flags,
|
||||||
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
|
VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
|
||||||
VOID HalpApcInterrupt(VOID);
|
VOID HalpApcInterrupt(VOID);
|
||||||
VOID HalpDispatchInterrupt(VOID);
|
VOID HalpDispatchInterrupt(VOID);
|
||||||
|
VOID FASTCALL HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
|
||||||
|
VOID FASTCALL HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
|
||||||
|
|
||||||
/* timer.c */
|
/* timer.c */
|
||||||
VOID NTAPI HalpInitializeClock(VOID);
|
VOID NTAPI HalpInitializeClock(VOID);
|
||||||
|
|
|
@ -1452,6 +1452,8 @@ FastExit:
|
||||||
cli
|
cli
|
||||||
|
|
||||||
/* End the interrupt and do EOI */
|
/* End the interrupt and do EOI */
|
||||||
|
lea eax, [esp+8]
|
||||||
|
mov PCR[KPCR_VDM_ALERT], eax
|
||||||
call _HalEndSystemInterrupt@8
|
call _HalEndSystemInterrupt@8
|
||||||
jmp _Kei386EoiHelper@0
|
jmp _Kei386EoiHelper@0
|
||||||
.endif
|
.endif
|
||||||
|
|
|
@ -112,6 +112,9 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
|
||||||
Prcb->InterruptCount++;
|
Prcb->InterruptCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save the nested trap frame address */
|
||||||
|
KeGetPcr()->VdmAlert = (ULONG_PTR)TrapFrame;
|
||||||
|
|
||||||
/* Disable interrupts and end the interrupt */
|
/* Disable interrupts and end the interrupt */
|
||||||
_disable();
|
_disable();
|
||||||
HalEndSystemInterrupt(Irql, CLOCK2_LEVEL);
|
HalEndSystemInterrupt(Irql, CLOCK2_LEVEL);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue