Request the APC_INTERRUPT for the correct processor on smp machines.

svn path=/trunk/; revision=16625
This commit is contained in:
Hartmut Birr 2005-07-17 18:27:46 +00:00
parent d40d2d7c83
commit d3493295ab
3 changed files with 41 additions and 12 deletions

View file

@ -110,7 +110,7 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
IN struct _KEXCEPTION_FRAME* ExceptionFrame); IN struct _KEXCEPTION_FRAME* ExceptionFrame);
VOID VOID
KiIpiSendRequest(ULONG TargetSet, KiIpiSendRequest(KAFFINITY TargetSet,
ULONG IpiRequest); ULONG IpiRequest);
VOID VOID

View file

@ -315,9 +315,39 @@ KiInsertQueueApc(PKAPC Apc,
/* Check the Thread State */ /* Check the Thread State */
if (Thread->State == Running) { if (Thread->State == Running) {
/* FIXME: Use IPI */ #ifdef CONFIG_SMP
PKPRCB Prcb, CurrentPrcb;
LONG i;
KIRQL oldIrql;
#endif
DPRINT ("Requesting APC Interrupt for Running Thread \n"); DPRINT ("Requesting APC Interrupt for Running Thread \n");
#ifdef CONFIG_SMP
oldIrql = KeRaiseIrqlToDpcLevel();
CurrentPrcb = KeGetCurrentPrcb();
if (CurrentPrcb->CurrentThread == Thread)
{
HalRequestSoftwareInterrupt(APC_LEVEL);
}
else
{
for (i = 0; i < KeNumberProcessors; i++)
{
Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb;
if (Prcb->CurrentThread == Thread)
{
ASSERT (CurrentPrcb != Prcb);
KiIpiSendRequest(Prcb->SetMember, IPI_REQUEST_APC);
break;
}
}
ASSERT (i < KeNumberProcessors);
}
KeLowerIrql(oldIrql);
#else
HalRequestSoftwareInterrupt(APC_LEVEL); HalRequestSoftwareInterrupt(APC_LEVEL);
#endif
} else if ((Thread->State == Waiting) && (Thread->WaitIrql == PASSIVE_LEVEL) && } else if ((Thread->State == Waiting) && (Thread->WaitIrql == PASSIVE_LEVEL) &&
((Apc->NormalRoutine == NULL) || ((Apc->NormalRoutine == NULL) ||

View file

@ -22,14 +22,15 @@ KSPIN_LOCK KiIpiLock;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID VOID
KiIpiSendRequest(ULONG TargetSet, ULONG IpiRequest) KiIpiSendRequest(KAFFINITY TargetSet, ULONG IpiRequest)
{ {
LONG i; LONG i;
PKPCR Pcr; PKPCR Pcr;
KAFFINITY Current;
for (i = 0; i < KeNumberProcessors; i++) for (i = 0, Current = 1; i < KeNumberProcessors; i++, Current <<= 1)
{ {
if (TargetSet & (1 << i)) if (TargetSet & Current)
{ {
Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
Ke386TestAndSetBit(IpiRequest, &Pcr->Prcb->IpiFrozen); Ke386TestAndSetBit(IpiRequest, &Pcr->Prcb->IpiFrozen);
@ -116,9 +117,9 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
VOID VOID
STDCALL STDCALL
KiIpiSendPacket(ULONG TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID Argument, ULONG Count, BOOLEAN Synchronize) KiIpiSendPacket(KAFFINITY TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID Argument, ULONG Count, BOOLEAN Synchronize)
{ {
ULONG Processor, CurrentProcessor; KAFFINITY Processor;
LONG i; LONG i;
PKPRCB Prcb, CurrentPrcb; PKPRCB Prcb, CurrentPrcb;
KIRQL oldIrql; KIRQL oldIrql;
@ -133,8 +134,6 @@ KiIpiSendPacket(ULONG TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID Argu
InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[1], Count); InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[1], Count);
InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[2], Synchronize ? 1 : 0); InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[2], Synchronize ? 1 : 0);
CurrentProcessor = 1 << KeGetCurrentProcessorNumber();
for (i = 0, Processor = 1; i < KeNumberProcessors; i++, Processor <<= 1) for (i = 0, Processor = 1; i < KeNumberProcessors; i++, Processor <<= 1)
{ {
if (TargetSet & Processor) if (TargetSet & Processor)
@ -142,13 +141,13 @@ KiIpiSendPacket(ULONG TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID Argu
Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb; Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb;
while(0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0)); while(0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0));
Ke386TestAndSetBit(IPI_REQUEST_FUNCTIONCALL, &Prcb->IpiFrozen); Ke386TestAndSetBit(IPI_REQUEST_FUNCTIONCALL, &Prcb->IpiFrozen);
if (Processor != CurrentProcessor) if (Processor != CurrentPrcb->SetMember)
{ {
HalRequestIpi(i); HalRequestIpi(i);
} }
} }
} }
if (TargetSet & CurrentProcessor) if (TargetSet & CurrentPrcb->SetMember)
{ {
KeRaiseIrql(IPI_LEVEL, &oldIrql); KeRaiseIrql(IPI_LEVEL, &oldIrql);
KiIpiServiceRoutine(NULL, NULL); KiIpiServiceRoutine(NULL, NULL);
@ -160,7 +159,7 @@ VOID
KeIpiGenericCall(VOID (STDCALL *Function)(PVOID), PVOID Argument) KeIpiGenericCall(VOID (STDCALL *Function)(PVOID), PVOID Argument)
{ {
KIRQL oldIrql; KIRQL oldIrql;
ULONG TargetSet; KAFFINITY TargetSet;
DPRINT("KeIpiGenericCall on CPU%d\n", KeGetCurrentProcessorNumber()); DPRINT("KeIpiGenericCall on CPU%d\n", KeGetCurrentProcessorNumber());