From 7b55b5e382ba4c0a9460ba48229a9f6907668ffc Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 14 Sep 2008 13:54:42 +0000 Subject: [PATCH] - Merge aicom-network-fixes up to r36215 - We now queue a work item to do most of the work - Send/SendPackets now get called at the correct IRQL svn path=/trunk/; revision=36240 --- reactos/drivers/network/ndis/ndis/miniport.c | 111 +++++++++++++------ reactos/lib/drivers/ip/network/neighbor.c | 2 + 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/reactos/drivers/network/ndis/ndis/miniport.c b/reactos/drivers/network/ndis/ndis/miniport.c index f6449aecf22..6dc10ff5d43 100644 --- a/reactos/drivers/network/ndis/ndis/miniport.c +++ b/reactos/drivers/network/ndis/ndis/miniport.c @@ -748,35 +748,22 @@ NdisMQueryInformationComplete( KeLowerIrql(OldIrql); } - -VOID NTAPI MiniportDpc( - IN PKDPC Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) -/* - * FUNCTION: Deferred routine to handle serialization - * ARGUMENTS: - * Dpc = Pointer to DPC object - * DeferredContext = Pointer to context information (LOGICAL_ADAPTER) - * SystemArgument1 = Unused - * SystemArgument2 = Unused - */ +VOID NTAPI MiniportWorker(IN PVOID WorkItem) { + PNDIS_WORK_ITEM NdisWorkItem = WorkItem; + PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(NdisWorkItem->Context); + KIRQL OldIrql, RaiseOldIrql; NDIS_STATUS NdisStatus; PVOID WorkItemContext; NDIS_WORK_ITEM_TYPE WorkItemType; - PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(DeferredContext); - NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); - - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); NdisStatus = MiniDequeueWorkItem (Adapter, &WorkItemType, &WorkItemContext); - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); if (NdisStatus == NDIS_STATUS_SUCCESS) { @@ -791,27 +778,45 @@ VOID NTAPI MiniportDpc( #endif if(Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler) { - NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's SendPackets handler\n")); + if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE) + { + NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's SendPackets handler\n")); + (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, (PPNDIS_PACKET)&WorkItemContext, 1); + } + else + { + /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */ + KeRaiseIrql(DISPATCH_LEVEL, &RaiseOldIrql); + { + NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's SendPackets handler\n")); + (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, (PPNDIS_PACKET)&WorkItemContext, 1); + } + KeLowerIrql(RaiseOldIrql); + } - /* - * XXX assumes single-packet - prolly OK since we'll call something - * different on multi-packet sends - */ - (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)( - Adapter->NdisMiniportBlock.MiniportAdapterContext, (PPNDIS_PACKET)&WorkItemContext, 1); - NdisStatus = - NDIS_GET_PACKET_STATUS((PNDIS_PACKET)WorkItemContext); - - NDIS_DbgPrint(MAX_TRACE, ("back from miniport's SendPackets handler\n")); + NdisStatus = NDIS_GET_PACKET_STATUS((PNDIS_PACKET)WorkItemContext); } else { - NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n")); - - NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendHandler)( - Adapter->NdisMiniportBlock.MiniportAdapterContext, (PNDIS_PACKET)WorkItemContext, 0); - - NDIS_DbgPrint(MAX_TRACE, ("back from miniport's Send handler\n")); + if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE) + { + NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n")); + NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, (PNDIS_PACKET)WorkItemContext, 0); + NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n")); + } + else + { + /* Send is called at DISPATCH_LEVEL for all serialized miniports */ + KeRaiseIrql(DISPATCH_LEVEL, &RaiseOldIrql); + NDIS_DbgPrint(MAX_TRACE, ("Calling miniport's Send handler\n")); + NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, (PNDIS_PACKET)WorkItemContext, 0); + NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n")); + KeLowerIrql(RaiseOldIrql); + } } if( NdisStatus != NDIS_STATUS_PENDING ) { NdisMSendComplete @@ -870,6 +875,40 @@ VOID NTAPI MiniportDpc( break; } } + + ExFreePool(WorkItem); +} + + + +VOID NTAPI MiniportDpc( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +/* + * FUNCTION: Deferred routine to handle serialization + * ARGUMENTS: + * Dpc = Pointer to DPC object + * DeferredContext = Pointer to context information (LOGICAL_ADAPTER) + * SystemArgument1 = Unused + * SystemArgument2 = Unused + */ +{ + PNDIS_WORK_ITEM NdisWorkItem; + PWORK_QUEUE_ITEM WorkItem; + + NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); + + NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(PNDIS_WORK_ITEM)); + + WorkItem = (PWORK_QUEUE_ITEM)NdisWorkItem->WrapperReserved; + + NdisWorkItem->Context = DeferredContext; + + ExInitializeWorkItem(WorkItem, MiniportWorker, NdisWorkItem); + + ExQueueWorkItem(WorkItem, CriticalWorkQueue); } diff --git a/reactos/lib/drivers/ip/network/neighbor.c b/reactos/lib/drivers/ip/network/neighbor.c index 330caa48117..6f924110d8f 100644 --- a/reactos/lib/drivers/ip/network/neighbor.c +++ b/reactos/lib/drivers/ip/network/neighbor.c @@ -157,7 +157,9 @@ VOID NBTimeout(VOID) NCE->EventTimer--; if (NCE->EventTimer == 0) { /* Call timeout handler for NCE */ + TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql); NCETimeout(NCE); + TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql); } } }