- Process the timer event directly from the DPC instead of queuing a work item then raising to DISPATCH_LEVEL later when acquiring a spin lock
- Optimize the spin lock operations in NBTimeout and IPDatagramReassemblyTimeout for being called at DISPATCH_LEVEL

svn path=/trunk/; revision=48833
This commit is contained in:
Cameron Gutman 2010-09-20 19:08:40 +00:00
parent a5a6cf644d
commit 12d05b7eb8
5 changed files with 23 additions and 36 deletions

View file

@ -205,7 +205,6 @@ extern LIST_ENTRY InterfaceListHead;
extern KSPIN_LOCK InterfaceListLock;
extern LIST_ENTRY NetTableListHead;
extern KSPIN_LOCK NetTableListLock;
extern BOOLEAN IpWorkItemQueued;
PIP_PACKET IPCreatePacket(
ULONG Type);
@ -232,7 +231,10 @@ BOOLEAN IPRegisterInterface(
VOID IPUnregisterInterface(
PIP_INTERFACE IF);
VOID NTAPI IPTimeout( PVOID Context );
VOID NTAPI IPTimeoutDpcFn(PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2);
VOID IPDispatchProtocol(
PIP_INTERFACE Interface,

View file

@ -24,8 +24,6 @@ UDP_STATISTICS UDPStats;
/* Network timers */
KTIMER IPTimer;
KDPC IPTimeoutDpc;
KSPIN_LOCK IpWorkLock;
WORK_QUEUE_ITEM IpWorkItem;
VOID TiWriteErrorLog(
PDRIVER_OBJECT DriverContext,
@ -578,28 +576,6 @@ VOID NTAPI TiUnload(
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID NTAPI IPTimeoutDpcFn(
PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2)
/*
* FUNCTION: Timeout DPC
* ARGUMENTS:
* Dpc = Pointer to our DPC object
* DeferredContext = Pointer to context information (unused)
* SystemArgument1 = Unused
* SystemArgument2 = Unused
* NOTES:
* This routine is dispatched once in a while to do maintainance jobs
*/
{
if( !IpWorkItemQueued ) {
ExQueueWorkItem( &IpWorkItem, DelayedWorkQueue );
IpWorkItemQueued = TRUE;
}
}
NTSTATUS NTAPI
DriverEntry(
PDRIVER_OBJECT DriverObject,
@ -630,7 +606,6 @@ DriverEntry(
/* Initialize our periodic timer and its associated DPC object. When the
timer expires, the IPTimeout deferred procedure call (DPC) is queued */
ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL );
KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
KeInitializeTimer(&IPTimer);

View file

@ -63,9 +63,21 @@ PIP_PACKET IPInitializePacket(
}
void NTAPI IPTimeout( PVOID Context ) {
IpWorkItemQueued = FALSE;
VOID NTAPI IPTimeoutDpcFn(PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2)
/*
* FUNCTION: Timeout DPC
* ARGUMENTS:
* Dpc = Pointer to our DPC object
* DeferredContext = Pointer to context information (unused)
* SystemArgument1 = Unused
* SystemArgument2 = Unused
* NOTES:
* This routine is dispatched once in a while to do maintainance jobs
*/
{
/* Check if datagram fragments have taken too long to assemble */
IPDatagramReassemblyTimeout();

View file

@ -97,12 +97,11 @@ VOID NBTimeout(VOID)
*/
{
UINT i;
KIRQL OldIrql;
PNEIGHBOR_CACHE_ENTRY *PrevNCE;
PNEIGHBOR_CACHE_ENTRY NCE;
for (i = 0; i <= NB_HASHMASK; i++) {
TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);
TcpipAcquireSpinLockAtDpcLevel(&NeighborCache[i].Lock);
for (PrevNCE = &NeighborCache[i].Cache;
(NCE = *PrevNCE) != NULL;) {
@ -136,7 +135,7 @@ VOID NBTimeout(VOID)
PrevNCE = &NCE->Next;
}
TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
TcpipReleaseSpinLockFromDpcLevel(&NeighborCache[i].Lock);
}
}

View file

@ -510,11 +510,10 @@ VOID IPDatagramReassemblyTimeout(
* to hold IP fragments that have taken too long to reassemble
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry, NextEntry;
PIPDATAGRAM_REASSEMBLY CurrentIPDR;
TcpipAcquireSpinLock(&ReassemblyListLock, &OldIrql);
TcpipAcquireSpinLockAtDpcLevel(&ReassemblyListLock);
CurrentEntry = ReassemblyListHead.Flink;
while (CurrentEntry != &ReassemblyListHead)
@ -539,7 +538,7 @@ VOID IPDatagramReassemblyTimeout(
CurrentEntry = NextEntry;
}
TcpipReleaseSpinLock(&ReassemblyListLock, OldIrql);
TcpipReleaseSpinLockFromDpcLevel(&ReassemblyListLock);
}
VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)