WskReceive() holds IRP in pending state

Hi,

I am using Winsock to send/receive data in my minifilter driver (mydrv.sys). One of the customer has been randomly facing issues of system hang wherein, he is unable to RDP to the machine or start any new sessions, but the existing sessions are working fine. I got the complete memory dump from one such hang instance. This is what I found:

  • One of my driver thread is waiting infinitely in KeWaitForSingleObject(). I make this call immediately after WskReceive() if it returns STATUS_PENDING.

  • When I check the IRP in question, it gives the following output:
    0: kd> !irp 0xffffe001`850bd880
    Irp is active with 1 stacks 1 is current (= 0xffffe001850bd950)
    No Mdl: No System Buffer: Thread 00000000: Irp stack trace.
    cmd flg cl Device File Completion-Context

[IRP_MJ_INTERNAL_DEVICE_CONTROL(f), N/A(d)]
0 e1 ffffe0017fb31c30 00000000 fffff8017caa7490-ffffd00021252a08 Success Error Cancel pending
\Driver\AFD mydrv!my_wsk_recv_data_complete
Args: ffffe00183d4f7d0 ffffd000212529e8 0x0 00000000

  • Here is my code snippet:

int my_wsk_recv_data
{
NTSTATUS status = STATUS_SUCCESS;
WSK_BUF wsk_buf;
KEVENT event;
ULONG recv_data_len = 0;
PWSKSOCKET p_wsk_socket = NULL;

if ( !socket || !p_data ){
return STATUS_INVALID_PARAMETER;
}

p_wsk_socket = (PWSKSOCKET) socket;
if ( p_wsk_socket && !p_wsk_socket->isConnected ){
return STATUS_INVALID_PARAMETER_1;
}

KeInitializeEvent( &event, NotificationEvent, FALSE );

if (data_len){
wsk_buf.Mdl = IoAllocateMdl( p_data, data_len, FALSE, FALSE, NULL );
if ( !wsk_buf.Mdl ){
return STATUS_INSUFFICIENT_RESOURCES;
}

__try{
MmProbeAndLockPages( wsk_buf.Mdl,KernelMode,IoWriteAccess);
status = STATUS_SUCCESS;
}
__except (EXCEPTION_EXECUTE_HANDLER){
IoFreeMdl( wsk_buf.Mdl);
status = STATUS_INVALID_USER_BUFFER;
}
if (!NT_SUCCESS(status)){
return status;
}

wsk_buf.Offset = 0;
wsk_buf.Length = data_len;
}
else{
wsk_buf.Mdl = NULL;
wsk_buf.Offset = 0;
wsk_buf.Length = 0;
}

IoReuseIrp(p_wsk_socket->irp, status );
if ( !p_wsk_socket->irp ){
if ( wsk_buf.Mdl ){
MmUnlockPages( wsk_buf.Mdl);
IoFreeMdl( wsk_buf.Mdl );
}
return STATUS_INSUFFICIENT_RESOURCES;
}

IoSetCompletionRoutine( p_wsk_socket->irp, my_wsk_recv_data_complete, &event, TRUE, TRUE, TRUE );

status = ((PWSK_PROVIDER_CONNECTION_DISPATCH)( p_wsk_socket->wskSocket->Dispatch ))->WskReceive( p_wsk_socket->wskSocket,
&wsk_buf, 0, p_wsk_socket->irp );
if ( status == STATUS_PENDING ){

status = KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, p_timeout ); //---------driver thread waits infinitely
if ( status == STATUS_TIMEOUT ){
IoCancelIrp( p_wsk_socket->irp );
KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );

if ( wsk_buf.Mdl ) {
MmUnlockPages( wsk_buf.Mdl);
IoFreeMdl( wsk_buf.Mdl );
}

return STATUS_IO_TIMEOUT;
}
status = p_wsk_socket->irp->IoStatus.Status;
}

recv_data_len = (ULONG)p_wsk_socket->irp->IoStatus.Information;
if ( wsk_buf.Mdl ){
MmUnlockPages( wsk_buf.Mdl);
IoFreeMdl( wsk_buf.Mdl );
}

return NT_SUCCESS(status) ? recv_data_len : status;
}

int my_wsk_recv_data_complete( PDEVICE_OBJECT p_devobj, PIRP irp, PVOID p_context )
{
UNREFERENCED_PARAMETER(p_devobj);
UNREFERENCED_PARAMETER(irp);

KeSetEvent( (PKEVENT)p_context, IO_NO_INCREMENT, FALSE );

return STATUS_MORE_PROCESSING_REQUIRED;
}


Why AFD is holding the IRP ? Is there anything else I can check in the dump as to who is causing the issue?

Thanks
Kunal

Just another info that I am passing p_timeout as NULL in KeWaitForSingleObject().

Thanks,
Kunal

Here is another observation:

!irpfind shows a very high number of pending IRPs for \Driver\AFD. In one dump I can see 333 IRPs and in another dump 160 IRPs in pending state.

THanks

  • Kunal

You’re not providing a lot of detail…Is the other side of this network
connection on a remote machine? On the same machine? Per the documentation,
this API returns pending if there is currently no data to receive so pending
isn’t a bad thing.

You also really want to re-ask this on NTDEV as this is a network related
question.

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntfsd…

Here is another observation:

!irpfind shows a very high number of pending IRPs for \Driver\AFD. In one
dump I can see 333 IRPs and in another dump 160 IRPs in pending state.

THanks

  • Kunal