Prevent some deadlock scenarios by unlocking the FCB while calling into

tcpip.sys.

svn path=/trunk/; revision=11625
This commit is contained in:
Art Yerkes 2004-11-12 07:34:56 +00:00
parent 0af675ba07
commit dea7f87980
6 changed files with 81 additions and 35 deletions

View file

@ -1,4 +1,4 @@
/* $Id: lock.c,v 1.3 2004/09/23 06:42:16 arty Exp $
/* $Id: lock.c,v 1.4 2004/11/12 07:34:56 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/lock.c
@ -100,7 +100,8 @@ VOID UnlockBuffers( PAFD_WSABUF Buf, UINT Count ) {
UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
NTSTATUS Status = STATUS_SUCCESS;
PVOID CurrentThread = KeGetCurrentThread();
KIRQL CurrentIrql = KeGetCurrentIrql();
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
AFD_DbgPrint(MAX_TRACE,("Called on %x, attempting to lock\n", FCB));
@ -122,8 +123,8 @@ UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
}
if( CurrentIrql == PASSIVE_LEVEL ) {
ExAcquireFastMutex( &FCB->Mutex );
while( FCB->Locked ) {
AFD_DbgPrint
(MID_TRACE,("FCB %x is locked, waiting for notification\n",
@ -135,24 +136,23 @@ UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
FALSE,
NULL );
ExAcquireFastMutex( &FCB->Mutex );
if( Status == STATUS_SUCCESS ) break;
}
FCB->Locked = TRUE;
FCB->CurrentThread = CurrentThread;
FCB->LockCount++;
ExReleaseFastMutex( &FCB->Mutex );
} else { /* Nothing since we're not at PASSIVE_LEVEL */
FCB->Locked = TRUE;
FCB->CurrentThread = CurrentThread;
FCB->LockCount++;
}
AFD_DbgPrint(MAX_TRACE,("Got lock (%d).\n", FCB->LockCount));
return TRUE;
}
VOID SocketStateUnlock( PAFD_FCB FCB ) {
PVOID CurrentThread = KeGetCurrentThread();
ASSERT(FCB->LockCount > 0);
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
ExAcquireFastMutex( &FCB->Mutex );
FCB->LockCount--;
if( !FCB->LockCount ) {
@ -162,8 +162,10 @@ VOID SocketStateUnlock( PAFD_FCB FCB ) {
AFD_DbgPrint(MAX_TRACE,("Unlocked.\n"));
KePulseEvent( &FCB->StateLockedEvent, IO_NETWORK_INCREMENT, FALSE );
} else {
AFD_DbgPrint(MID_TRACE,("Lock count %d\n", FCB->LockCount));
AFD_DbgPrint(MAX_TRACE,("New lock count: %d (Thr: %x)\n",
FCB->LockCount, CurrentThread));
}
ExReleaseFastMutex( &FCB->Mutex );
}
NTSTATUS DDKAPI UnlockAndMaybeComplete
@ -204,3 +206,13 @@ NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
return UnlockAndMaybeComplete( FCB, STATUS_PENDING, Irp, 0, NULL, FALSE );
}
VOID SocketCalloutEnter( PAFD_FCB FCB ) {
ASSERT(FCB->Locked);
FCB->Critical = TRUE;
SocketStateUnlock( FCB );
}
VOID SocketCalloutLeave( PAFD_FCB FCB ) {
FCB->Critical = FALSE;
SocketAcquireStateLock( FCB );
}

View file

@ -1,4 +1,4 @@
/* $Id: main.c,v 1.7 2004/09/23 06:42:16 arty Exp $
/* $Id: main.c,v 1.8 2004/11/12 07:34:56 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/main.c
@ -151,7 +151,8 @@ VOID DestroySocket( PAFD_FCB FCB ) {
InFlightRequest[2] = &FCB->SendIrp;
/* Return early here because we might be called in the mean time. */
if( FCB->ListenIrp.InFlightRequest ||
if( FCB->Critical ||
FCB->ListenIrp.InFlightRequest ||
FCB->ReceiveIrp.InFlightRequest ||
FCB->SendIrp.InFlightRequest ) {
AFD_DbgPrint(MIN_TRACE,("Leaving socket alive (%x %x %x)\n",

View file

@ -1,4 +1,4 @@
/* $Id: read.c,v 1.7 2004/10/03 20:36:45 arty Exp $
/* $Id: read.c,v 1.8 2004/11/12 07:34:56 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/read.c
@ -139,6 +139,8 @@ NTSTATUS DDKAPI ReceiveComplete
AFD_DbgPrint(MID_TRACE,
("Exhausted our buffer. Requesting new: %x\n", FCB));
SocketCalloutEnter( FCB );
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
IrpSp->FileObject,
TDI_RECEIVE_NORMAL,
@ -147,6 +149,8 @@ NTSTATUS DDKAPI ReceiveComplete
&FCB->ReceiveIrp.Iosb,
ReceiveComplete,
FCB );
SocketCalloutLeave( FCB );
}
} else {
while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
@ -204,6 +208,9 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
FCB->Recv.Content = 0;
FCB->Recv.BytesUsed = 0;
AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
SocketCalloutEnter( FCB );
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
FCB->Connection.Object,
TDI_RECEIVE_NORMAL,
@ -212,6 +219,8 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
&FCB->ReceiveIrp.Iosb,
ReceiveComplete,
FCB );
SocketCalloutLeave( FCB );
} else Status = STATUS_SUCCESS;
if( NT_SUCCESS(Status) )
@ -346,6 +355,8 @@ PacketSocketRecvComplete(
if( NT_SUCCESS(Irp->IoStatus.Status) ) {
/* Now relaunch the datagram request */
SocketCalloutEnter( FCB );
Status = TdiReceiveDatagram
( &FCB->ReceiveIrp.InFlightRequest,
FCB->AddressFile.Object,
@ -356,6 +367,8 @@ PacketSocketRecvComplete(
&FCB->ReceiveIrp.Iosb,
PacketSocketRecvComplete,
FCB );
SocketCalloutLeave( FCB );
}
SocketStateUnlock( FCB );
@ -381,8 +394,8 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
return UnlockAndMaybeComplete
( FCB, STATUS_UNSUCCESSFUL, Irp, 0, NULL, FALSE );
if( !(RecvReq = LockRequest( Irp, IrpSp )) )
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
Irp, 0, NULL, FALSE );
return UnlockAndMaybeComplete
( FCB, STATUS_NO_MEMORY, Irp, 0, NULL, FALSE );
if( !IsListEmpty( &FCB->DatagramList ) ) {
ListEntry = RemoveHeadList( &FCB->DatagramList );

View file

@ -1,4 +1,4 @@
/* $Id: write.c,v 1.9 2004/10/03 21:16:27 arty Exp $
/* $Id: write.c,v 1.10 2004/11/12 07:34:56 arty Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/write.c
@ -109,6 +109,9 @@ NTSTATUS DDKAPI SendComplete
/* Some data is still waiting */
if( FCB->Send.BytesUsed ) {
FCB->PollState &= ~AFD_EVENT_SEND;
SocketCalloutEnter( FCB );
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
IrpSp->FileObject,
0,
@ -117,6 +120,8 @@ NTSTATUS DDKAPI SendComplete
&FCB->SendIrp.Iosb,
SendComplete,
FCB );
SocketCalloutLeave( FCB );
} else {
FCB->PollState |= AFD_EVENT_SEND;
PollReeval( FCB->DeviceExt, FCB->FileObject );
@ -219,6 +224,10 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if( TotalBytesCopied > 0 ) {
UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount );
FCB->SendIrp.InFlightRequest = (PVOID)1; /* Placeholder */
SocketCalloutEnter( FCB );
Status = TdiSend( &FCB->SendIrp.InFlightRequest,
FCB->Connection.Object,
0,
@ -228,6 +237,8 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
SendComplete,
FCB );
SocketCalloutLeave( FCB );
if( Status == STATUS_PENDING )
Status = STATUS_SUCCESS;
@ -265,6 +276,8 @@ NTSTATUS DDKAPI PacketSocketSendComplete
return STATUS_SUCCESS;
}
SocketStateUnlock( FCB );
return STATUS_SUCCESS;
}
@ -301,6 +314,8 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
/* Check the size of the Address given ... */
if( TargetAddress ) {
SocketCalloutEnter( FCB );
Status = TdiSendDatagram
( &FCB->SendIrp.InFlightRequest,
FCB->AddressFile.Object,
@ -311,6 +326,8 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PacketSocketSendComplete,
FCB );
SocketCalloutLeave( FCB );
ExFreePool( TargetAddress );
} else Status = STATUS_NO_MEMORY;

View file

@ -1,4 +1,4 @@
/* $Id: afd.h,v 1.20 2004/09/05 04:26:30 arty Exp $
/* $Id: afd.h,v 1.21 2004/11/12 07:34:56 arty Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -21,6 +21,7 @@
#include <shared.h>
#ifndef _MSC_VER
#include <roscfg.h>
#include <rosrtl/string.h>
#include <winsock2.h>
#include <ddk/tdi.h>
@ -109,7 +110,7 @@ typedef struct _AFD_STORED_DATAGRAM {
} AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM;
typedef struct _AFD_FCB {
BOOLEAN Locked;
BOOLEAN Locked, Critical;
UINT State, Flags;
KIRQL OldIrql;
UINT LockCount;
@ -182,6 +183,8 @@ VOID SocketStateUnlock( PAFD_FCB FCB );
NTSTATUS LostSocket( PIRP Irp, BOOL ShouldUnlockIrp );
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
VOID SocketCalloutEnter( PAFD_FCB FCB );
VOID SocketCalloutLeave( PAFD_FCB FCB );
/* main.c */

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.13 2004/08/15 22:51:57 chorns Exp $
# $Id: makefile,v 1.14 2004/11/12 07:34:55 arty Exp $
PATH_TO_TOP = ../../..
@ -11,7 +11,7 @@ TARGET_PCH = include/afd.h
TARGET_DDKLIBS = \
$(PATH_TO_TOP)/dk/w32/lib/pseh.a
TARGET_CFLAGS = -I./include -I$(PATH_TO_TOP)/w32api/include/ddk -I$(PATH_TO_TOP)/include/afd -DDBG -D__USE_W32API -Werror -Wall
TARGET_CFLAGS = -I./include -I$(PATH_TO_TOP)/w32api/include/ddk -I$(PATH_TO_TOP)/include/afd -D__USE_W32API -Werror -Wall
TARGET_OBJECTS = \
afd/bind.o \