Author: cgutman
Date: Sat Apr 4 01:05:22 2009
New Revision: 40354
URL:
http://svn.reactos.org/svn/reactos?rev=40354&view=rev
Log:
- Loopback adapter rewrite
- We don't need to queue a work item to receive so we don't now
- This simplifies the code significantly
- It also increases loopback throughput
Modified:
trunk/reactos/lib/drivers/ip/network/loopback.c
Modified: trunk/reactos/lib/drivers/ip/network/loopback.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/loo…
==============================================================================
--- trunk/reactos/lib/drivers/ip/network/loopback.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/network/loopback.c [iso-8859-1] Sat Apr 4 01:05:22 2009
@@ -1,126 +1,14 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
- * FILE: datalink/loopback.c
+ * FILE: lib/drivers/ip/network/loopback.c
* PURPOSE: Loopback adapter
- * PROGRAMMERS: Casper S. Hornstrup (chorns(a)users.sourceforge.net)
- * REVISIONS:
- * CSH 01/08-2000 Created
+ * PROGRAMMERS: Cameron Gutman (cgutman(a)reactos.org)
*/
#include "precomp.h"
PIP_INTERFACE Loopback = NULL;
-typedef struct _LAN_WQ_ITEM {
- LIST_ENTRY ListEntry;
- PNDIS_PACKET Packet;
- PLAN_ADAPTER Adapter;
- UINT BytesTransferred;
-} LAN_WQ_ITEM, *PLAN_WQ_ITEM;
-
-/* Work around being called back into afd at Dpc level */
-KSPIN_LOCK LoopWorkLock;
-LIST_ENTRY LoopWorkList;
-WORK_QUEUE_ITEM LoopWorkItem;
-BOOLEAN LoopReceiveWorkerBusy = FALSE;
-
-VOID NTAPI LoopReceiveWorker( PVOID Context ) {
- PLIST_ENTRY ListEntry;
- PLAN_WQ_ITEM WorkItem;
- PNDIS_PACKET Packet;
- PLAN_ADAPTER Adapter;
- UINT BytesTransferred;
- PNDIS_BUFFER NdisBuffer;
- IP_PACKET IPPacket;
- KIRQL OldIrql;
-
- TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
-
- TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
- while( !IsListEmpty(&LoopWorkList) )
- {
- ListEntry = RemoveHeadList( &LoopWorkList );
- TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
-
- WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
-
- TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem));
-
- Packet = WorkItem->Packet;
- Adapter = WorkItem->Adapter;
- BytesTransferred = WorkItem->BytesTransferred;
-
- exFreePool( WorkItem );
-
- IPPacket.NdisPacket = Packet;
-
- TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n",
- Packet, Adapter, BytesTransferred));
-
- NdisGetFirstBufferFromPacket(Packet,
- &NdisBuffer,
- &IPPacket.Header,
- &IPPacket.ContigSize,
- &IPPacket.TotalSize);
-
- IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred;
- /* Determine which upper layer protocol that should receive
- this packet and pass it to the correct receive handler */
-
- TI_DbgPrint
- (MID_TRACE,
- ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n",
- IPPacket.ContigSize, IPPacket.TotalSize,
- BytesTransferred));
-
- IPPacket.Position = 0;
-
- IPReceive(Loopback, &IPPacket);
-
- FreeNdisPacket( Packet );
- TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
- }
- TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n"));
- LoopReceiveWorkerBusy = FALSE;
- TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
-}
-
-VOID LoopSubmitReceiveWork(
- NDIS_HANDLE BindingContext,
- PNDIS_PACKET Packet,
- NDIS_STATUS Status,
- UINT BytesTransferred) {
- PLAN_WQ_ITEM WQItem;
- PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
- KIRQL OldIrql;
-
- TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
-
- WQItem = exAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) );
- if( !WQItem ) {
- TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
- return;
- }
-
- WQItem->Packet = Packet;
- WQItem->Adapter = Adapter;
- WQItem->BytesTransferred = BytesTransferred;
- InsertTailList( &LoopWorkList, &WQItem->ListEntry );
-
- TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x BytesTrans %x\n",
- Packet, Adapter, BytesTransferred));
-
- if( !LoopReceiveWorkerBusy ) {
- LoopReceiveWorkerBusy = TRUE;
- ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue );
- TI_DbgPrint(DEBUG_DATALINK,
- ("Work item inserted %x %x\n", &LoopWorkItem, WQItem));
- } else {
- TI_DbgPrint(DEBUG_DATALINK,
- ("LOOP WORKER BUSY %x %x\n", &LoopWorkItem, WQItem));
- }
- TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
-}
VOID LoopTransmit(
PVOID Context,
@@ -138,31 +26,44 @@
* Type = LAN protocol type (unused)
*/
{
+ IP_PACKET IPPacket;
+ PNDIS_PACKET XmitPacket;
+ PNDIS_BUFFER NdisBuffer;
+ NDIS_STATUS NdisStatus;
PCHAR PacketBuffer;
UINT PacketLength;
- PNDIS_PACKET XmitPacket;
- NDIS_STATUS NdisStatus;
- ASSERT_KM_POINTER(NdisPacket);
- ASSERT_KM_POINTER(PC(NdisPacket));
- ASSERT_KM_POINTER(PC(NdisPacket)->DLComplete);
+ ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
- TI_DbgPrint(MAX_TRACE, ("Called (NdisPacket = %x)\n", NdisPacket));
-
- GetDataPtr( NdisPacket, MaxLLHeaderSize, &PacketBuffer, &PacketLength );
+ GetDataPtr( NdisPacket, Offset, &PacketBuffer, &PacketLength );
NdisStatus = AllocatePacketWithBuffer
( &XmitPacket, PacketBuffer, PacketLength );
- if( NT_SUCCESS(NdisStatus) ) {
- LoopSubmitReceiveWork
- ( NULL, XmitPacket, STATUS_SUCCESS, PacketLength );
+ if (NdisStatus != NDIS_STATUS_SUCCESS)
+ {
+ (PC(NdisPacket)->DLComplete)( PC(NdisPacket)->Context, NdisPacket,
NdisStatus );
+ return;
}
- (PC(NdisPacket)->DLComplete)
- ( PC(NdisPacket)->Context, NdisPacket, STATUS_SUCCESS );
+ NdisGetFirstBufferFromPacket(XmitPacket,
+ &NdisBuffer,
+ &IPPacket.Header,
+ &IPPacket.ContigSize,
+ &IPPacket.TotalSize);
- TI_DbgPrint(MAX_TRACE, ("Done\n"));
+ IPPacket.NdisPacket = XmitPacket;
+ IPPacket.Position = 0;
+
+ TI_DbgPrint(MID_TRACE,
+ ("ContigSize: %d, TotalSize: %d\n",
+ IPPacket.ContigSize, IPPacket.TotalSize));
+
+ IPReceive(Loopback, &IPPacket);
+
+ FreeNdisPacket(XmitPacket);
+
+ (PC(NdisPacket)->DLComplete)( PC(NdisPacket)->Context, NdisPacket,
NDIS_STATUS_SUCCESS );
}
NDIS_STATUS LoopRegisterAdapter(
@@ -177,15 +78,9 @@
* Status of operation
*/
{
- NDIS_STATUS Status;
LLIP_BIND_INFO BindInfo;
- Status = NDIS_STATUS_SUCCESS;
-
TI_DbgPrint(MID_TRACE, ("Called.\n"));
-
- InitializeListHead( &LoopWorkList );
- ExInitializeWorkItem( &LoopWorkItem, LoopReceiveWorker, NULL );
/* Bind the adapter to network (IP) layer */
BindInfo.Context = NULL;
@@ -211,7 +106,7 @@
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
- return Status;
+ return NDIS_STATUS_SUCCESS;
}