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);
VOID
KiIpiSendRequest(ULONG TargetSet,
KiIpiSendRequest(KAFFINITY TargetSet,
ULONG IpiRequest);
VOID

View file

@ -315,9 +315,39 @@ KiInsertQueueApc(PKAPC Apc,
/* Check the Thread State */
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");
#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);
#endif
} else if ((Thread->State == Waiting) && (Thread->WaitIrql == PASSIVE_LEVEL) &&
((Apc->NormalRoutine == NULL) ||

View file

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