NDIS 6.0 BSOD

I’m developing NDISEDGE 6.0 driver for my network device. It is developed with little modification from the NDISEDGE 6.0 driver in the WDK. However sometimes when I am doing some throughput tests (ftp downloads using flashget), I ran into problem that it ASSERT when the file has finished the transfer (embedded in the code for debug mode) while NDIS is returning the ownership of the Netbufferlist.

The exact line of assert:

ASSERT(NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) == NULL);

This would mean that the next buffer list is not null. Is it something wrong with my NDISEDGE driver? or something to do with the TCP/IP stack?

The call stack at the point of assert:
8d825670 8d8256b0 000000b5 nt!DbgBreakPoint
8d2e3008 8d3ee778 00000000 WiMAXEdge!MPReturnNetBufferLists+0xed [c:\ndisedge_driver\new_ndisedge\receive.c @ 181]
8d2e50e8 8d3ee778 00000000 ndis!ndisReturnNetBufferListsInternal+0x48
904fe008 8d3ee778 00000000 ndis!NdisReturnNetBufferLists+0x16
8d3ee778 00000004 00000000 tcpip!FlpReturnNetBufferListChain+0x9a
00000000 00000000 8bdb4008 NETIO!NetioDereferenceNetBufferListChain+0xcf
83cbd100 00000000 00000000 tcpip!IppCompleteAndFreePacketList+0xbf
8d5e29c8 00000006 00000000 tcpip!IppReceiveHeaderBatch+0x276
904f31e8 00000000 00000001 tcpip!IpFlcReceivePackets+0xc06
904fe9c0 8d3ee778 00000000 tcpip!FlpReceiveNonPreValidatedNetBufferListChain+0x6db
904fe9c0 8d3ee778 00000000 tcpip!FlReceiveNetBufferListChain+0x104
004fe008 8d3ee778 00000000 ndis!ndisMIndicateNetBufferListsToOpen+0xab
00000000 81c27c97 8d2e50e8 ndis!ndisIndicateSortedNetBufferLists+0x4a
8d2e50e8 00000000 00000000 ndis!ndisMDispatchReceiveNetBufferLists+0x129
603e9c00 87603f5c 87603f28 ndis!ndisDoPeriodicReceivesIndication+0x170
844146e0 00000000 f2c4fdca ndis!ndisPeriodicReceivesTimer+0x48
00000000 00000000 00009a37 nt!KiTimerExpiration+0x498
878cfa50 00000000 00000000 nt!KiRetireDpcList+0xba
00000000 00000000 00000000 nt!KiDispatchInterrupt+0x3d
WARNING: Frame IP not in any known module. Following frames may be wrong.
0000001a 00c1850f bb830000 0x878cfa50

I don’t know if the last line is trying to tell me.

Can anyone give me any advise on why this happen? I have followed almost the same code as the WDK sample code.

Tony

NDIS is free to return multiple NET_BUFFER_LISTs to your miniport. Why
would you have such an ASSERT()? You should be processing each
NET_BUFFER_LIST in the ‘chain’ of NET_BUFFER_LISTs as if each had been sent
to your MiniportReturnNetBufferLists.

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, October 29, 2009 2:21 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] NDIS 6.0 BSOD

I’m developing NDISEDGE 6.0 driver for my network device. It is developed
with little modification from the NDISEDGE 6.0 driver in the WDK. However
sometimes when I am doing some throughput tests (ftp downloads using
flashget), I ran into problem that it ASSERT when the file has finished the
transfer (embedded in the code for debug mode) while NDIS is returning the
ownership of the Netbufferlist.

The exact line of assert:

ASSERT(NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) == NULL);

This would mean that the next buffer list is not null. Is it something wrong
with my NDISEDGE driver? or something to do with the TCP/IP stack?

The call stack at the point of assert:
8d825670 8d8256b0 000000b5 nt!DbgBreakPoint
8d2e3008 8d3ee778 00000000 WiMAXEdge!MPReturnNetBufferLists+0xed
[c:\ndisedge_driver\new_ndisedge\receive.c @ 181]
8d2e50e8 8d3ee778 00000000 ndis!ndisReturnNetBufferListsInternal+0x48
904fe008 8d3ee778 00000000 ndis!NdisReturnNetBufferLists+0x16
8d3ee778 00000004 00000000 tcpip!FlpReturnNetBufferListChain+0x9a
00000000 00000000 8bdb4008 NETIO!NetioDereferenceNetBufferListChain+0xcf
83cbd100 00000000 00000000 tcpip!IppCompleteAndFreePacketList+0xbf
8d5e29c8 00000006 00000000 tcpip!IppReceiveHeaderBatch+0x276
904f31e8 00000000 00000001 tcpip!IpFlcReceivePackets+0xc06
904fe9c0 8d3ee778 00000000
tcpip!FlpReceiveNonPreValidatedNetBufferListChain+0x6db
904fe9c0 8d3ee778 00000000 tcpip!FlReceiveNetBufferListChain+0x104
004fe008 8d3ee778 00000000 ndis!ndisMIndicateNetBufferListsToOpen+0xab
00000000 81c27c97 8d2e50e8 ndis!ndisIndicateSortedNetBufferLists+0x4a
8d2e50e8 00000000 00000000 ndis!ndisMDispatchReceiveNetBufferLists+0x129
603e9c00 87603f5c 87603f28 ndis!ndisDoPeriodicReceivesIndication+0x170
844146e0 00000000 f2c4fdca ndis!ndisPeriodicReceivesTimer+0x48
00000000 00000000 00009a37 nt!KiTimerExpiration+0x498
878cfa50 00000000 00000000 nt!KiRetireDpcList+0xba
00000000 00000000 00000000 nt!KiDispatchInterrupt+0x3d
WARNING: Frame IP not in any known module. Following frames may be wrong.
0000001a 00c1850f bb830000 0x878cfa50

I don’t know if the last line is trying to tell me.

Can anyone give me any advise on why this happen? I have followed almost the
same code as the WDK sample code.

Tony


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Hi Dave,

Thanks a lot for the suggestion. After I have tweak the driver a bit, I have
freed all the NET_BUFFER_LISTs returned to my MiniportReturnNetBufferLists.
However, I encountered another BSOD with the WDF when I was trying to have
another ftp download (via flashget)…!! and the problem occured when my LWF
usb driver is trying to get an I/O request from the WDF (which it never
happened with my NDISEDGE5.1 driver).

How I free the chain of NET_BUFFER_LISTs:

PNET_BUFFER_LIST CurrNbl = NetBufferLists;

while (CurrNbl != NULL)
{
atDispatchLevel =
(BOOLEAN)NDIS_TEST_RETURN_AT_DISPATCH_LEVEL(ReturnFlags);

pRCB = MP_GET_RCB_FROM_NBL(CurrNbl);

//ASSERT(NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) == NULL); //
this is the assert that i was refering to in previous mail thread

Adapter = pRCB->Adapter;

ASSERT(Adapter);

NdisInterlockedDecrement(&Adapter->nIndicatedNetBufferList);
DEBUGP(MP_DEBUG0, (“Returned Adapter->nIndicatedNetBuffList =
%d\n”, Adapter->nIndicatedNetBufferList));

if (NdisInterlockedDecrement(&pRCB->Ref) == 0)
{
NICFreeRCB(pRCB, atDispatchLevel); // here i free the RCB
}
NextNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
CurrNbl = NextNbl;

}

Line of code where it crashed

status = WdfIoQueueRetrieveNextRequest( pAdapter->PendingReadQueue, &request
);

Below are the crash dump:

STACK_TEXT:
953cbad8 806d945b badb0d00 00000000 84112008 nt!KiTrap0E+0x2ac
953cbb50 806d95eb 00000000 953cbb6c 842ed608
Wdf01000!FxIrpQueue::RemoveNextIrpFromQueue+0x12
953cbb64 806cfaaa 00000000 00000000 953cbb88
Wdf01000!FxIrpQueue::GetNextRequest+0x19
953cbb78 806e3681 842ed668 00000000 00000000
Wdf01000!FxRequest::GetNextRequest+0x23
953cbbac 806e288a 00000000 00000000 953cbbc8
Wdf01000!FxIoQueue::GetRequest+0x488
953cbbcc a364f97a 842ed608 7bd129f0 953cbc4c
Wdf01000!imp_WdfIoQueueRetrieveNextRequest+0x4b
953cbbe0 a3659f98 7bd129f0 953cbc4c 84139c00
WiMAXU2!WdfIoQueueRetrieveNextRequest+0x1a
[c:\winddk\6000\inc\wdf\kmdf\10\wdfio.h @ 515]
953cbc90 a3658c1d 842bccb8 842a77e0 000006ec WiMAXU2!ReceivePacket+0x3c8
[c:\tmp\usb_winvista\10.00.1.0_src\10.00.1.0\receive.c @ 563]
953cbd7c 81e254a8 842bccb8 953c0680 00000000 WiMAXU2!ReceiveThread+0x96d
[c:\tmp\usb_winvista\10.00.1.0_src\10.00.1.0\receive.c @ 245]
953cbdc0 81c9145e a36582b0 842bccb8 00000000 nt!PspSystemThreadStartup+0x9d
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

Do you have any idea why this API would crash? due to the input arguments?
or maybe resource problem while it is trying to allocate IRP?

Tony

On Thu, Oct 29, 2009 at 11:37 PM, David R. Cattley wrote:

> NDIS is free to return multiple NET_BUFFER_LISTs to your miniport. Why
> would you have such an ASSERT()? You should be processing each
> NET_BUFFER_LIST in the ‘chain’ of NET_BUFFER_LISTs as if each had been sent
> to your MiniportReturnNetBufferLists.
>
> Good Luck,
> Dave Cattley
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
> Sent: Thursday, October 29, 2009 2:21 AM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] NDIS 6.0 BSOD
>
> I’m developing NDISEDGE 6.0 driver for my network device. It is developed
> with little modification from the NDISEDGE 6.0 driver in the WDK. However
> sometimes when I am doing some throughput tests (ftp downloads using
> flashget), I ran into problem that it ASSERT when the file has finished the
> transfer (embedded in the code for debug mode) while NDIS is returning the
> ownership of the Netbufferlist.
>
> The exact line of assert:
>
> ASSERT(NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) == NULL);
>
> This would mean that the next buffer list is not null. Is it something
> wrong
> with my NDISEDGE driver? or something to do with the TCP/IP stack?
>
> The call stack at the point of assert:
> 8d825670 8d8256b0 000000b5 nt!DbgBreakPoint
> 8d2e3008 8d3ee778 00000000 WiMAXEdge!MPReturnNetBufferLists+0xed
> [c:\ndisedge_driver\new_ndisedge\receive.c @ 181]
> 8d2e50e8 8d3ee778 00000000 ndis!ndisReturnNetBufferListsInternal+0x48
> 904fe008 8d3ee778 00000000 ndis!NdisReturnNetBufferLists+0x16
> 8d3ee778 00000004 00000000 tcpip!FlpReturnNetBufferListChain+0x9a
> 00000000 00000000 8bdb4008 NETIO!NetioDereferenceNetBufferListChain+0xcf
> 83cbd100 00000000 00000000 tcpip!IppCompleteAndFreePacketList+0xbf
> 8d5e29c8 00000006 00000000 tcpip!IppReceiveHeaderBatch+0x276
> 904f31e8 00000000 00000001 tcpip!IpFlcReceivePackets+0xc06
> 904fe9c0 8d3ee778 00000000
> tcpip!FlpReceiveNonPreValidatedNetBufferListChain+0x6db
> 904fe9c0 8d3ee778 00000000 tcpip!FlReceiveNetBufferListChain+0x104
> 004fe008 8d3ee778 00000000 ndis!ndisMIndicateNetBufferListsToOpen+0xab
> 00000000 81c27c97 8d2e50e8 ndis!ndisIndicateSortedNetBufferLists+0x4a
> 8d2e50e8 00000000 00000000 ndis!ndisMDispatchReceiveNetBufferLists+0x129
> 603e9c00 87603f5c 87603f28 ndis!ndisDoPeriodicReceivesIndication+0x170
> 844146e0 00000000 f2c4fdca ndis!ndisPeriodicReceivesTimer+0x48
> 00000000 00000000 00009a37 nt!KiTimerExpiration+0x498
> 878cfa50 00000000 00000000 nt!KiRetireDpcList+0xba
> 00000000 00000000 00000000 nt!KiDispatchInterrupt+0x3d
> WARNING: Frame IP not in any known module. Following frames may be wrong.
> 0000001a 00c1850f bb830000 0x878cfa50
>
> I don’t know if the last line is trying to tell me.
>
> Can anyone give me any advise on why this happen? I have followed almost
> the
> same code as the WDK sample code.
>
> Tony
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

It would be much better if you ?traversed? to the next NBL in the list
before freeing the current NBL. Think about it. You are freeing the very
object you then dereference to get the ?next? pointer from. I am assuming
that NICFreeRCB() will free the associated NBL as well ?

As for why WDF is choking, it is almost surely because you have a bogus
argument.

Good Luck,

Dave Cattley

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tony Chang
Sent: Monday, November 02, 2009 9:51 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] NDIS 6.0 BSOD

Hi Dave,

Thanks a lot for the suggestion. After I have tweak the driver a bit, I have
freed all the NET_BUFFER_LISTs returned to my MiniportReturnNetBufferLists.
However, I encountered another BSOD with the WDF when I was trying to have
another ftp download (via flashget)…!! and the problem occured when my LWF
usb driver is trying to get an I/O request from the WDF (which it never
happened with my NDISEDGE5.1 driver).

How I free the chain of NET_BUFFER_LISTs:

PNET_BUFFER_LIST CurrNbl = NetBufferLists;

while (CurrNbl != NULL)
{
atDispatchLevel =
(BOOLEAN)NDIS_TEST_RETURN_AT_DISPATCH_LEVEL(ReturnFlags);

pRCB = MP_GET_RCB_FROM_NBL(CurrNbl);

//ASSERT(NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) == NULL); //
this is the assert that i was refering to in previous mail thread

Adapter = pRCB->Adapter;

ASSERT(Adapter);

NdisInterlockedDecrement(&Adapter->nIndicatedNetBufferList);
DEBUGP(MP_DEBUG0, (“Returned Adapter->nIndicatedNetBuffList =
%d\n”, Adapter->nIndicatedNetBufferList));

if (NdisInterlockedDecrement(&pRCB->Ref) == 0)
{
NICFreeRCB(pRCB, atDispatchLevel); // here i free the RCB
}
NextNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
CurrNbl = NextNbl;

}

Line of code where it crashed

status = WdfIoQueueRetrieveNextRequest( pAdapter->PendingReadQueue, &request
);

Below are the crash dump:

STACK_TEXT:
953cbad8 806d945b badb0d00 00000000 84112008 nt!KiTrap0E+0x2ac
953cbb50 806d95eb 00000000 953cbb6c 842ed608
Wdf01000!FxIrpQueue::RemoveNextIrpFromQueue+0x12
953cbb64 806cfaaa 00000000 00000000 953cbb88
Wdf01000!FxIrpQueue::GetNextRequest+0x19
953cbb78 806e3681 842ed668 00000000 00000000
Wdf01000!FxRequest::GetNextRequest+0x23
953cbbac 806e288a 00000000 00000000 953cbbc8
Wdf01000!FxIoQueue::GetRequest+0x488
953cbbcc a364f97a 842ed608 7bd129f0 953cbc4c
Wdf01000!imp_WdfIoQueueRetrieveNextRequest+0x4b
953cbbe0 a3659f98 7bd129f0 953cbc4c 84139c00
WiMAXU2!WdfIoQueueRetrieveNextRequest+0x1a
[c:\winddk\6000\inc\wdf\kmdf\10\wdfio.h @ 515]
953cbc90 a3658c1d 842bccb8 842a77e0 000006ec WiMAXU2!ReceivePacket+0x3c8
[c:\tmp\usb_winvista\10.00.1.0_src\10.00.1.0\receive.c @ 563]
953cbd7c 81e254a8 842bccb8 953c0680 00000000 WiMAXU2!ReceiveThread+0x96d
[c:\tmp\usb_winvista\10.00.1.0_src\10.00.1.0\receive.c @ 245]
953cbdc0 81c9145e a36582b0 842bccb8 00000000 nt!PspSystemThreadStartup+0x9d
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

Do you have any idea why this API would crash? due to the input arguments?
or maybe resource problem while it is trying to allocate IRP?

Tony

On Thu, Oct 29, 2009 at 11:37 PM, David R. Cattley wrote:

NDIS is free to return multiple NET_BUFFER_LISTs to your miniport. Why
would you have such an ASSERT()? You should be processing each
NET_BUFFER_LIST in the ‘chain’ of NET_BUFFER_LISTs as if each had been sent
to your MiniportReturnNetBufferLists.

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, October 29, 2009 2:21 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] NDIS 6.0 BSOD

I’m developing NDISEDGE 6.0 driver for my network device. It is developed
with little modification from the NDISEDGE 6.0 driver in the WDK. However
sometimes when I am doing some throughput tests (ftp downloads using
flashget), I ran into problem that it ASSERT when the file has finished the
transfer (embedded in the code for debug mode) while NDIS is returning the
ownership of the Netbufferlist.

The exact line of assert:

ASSERT(NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) == NULL);

This would mean that the next buffer list is not null. Is it something wrong
with my NDISEDGE driver? or something to do with the TCP/IP stack?

The call stack at the point of assert:
8d825670 8d8256b0 000000b5 nt!DbgBreakPoint
8d2e3008 8d3ee778 00000000 WiMAXEdge!MPReturnNetBufferLists+0xed
[c:\ndisedge_driver\new_ndisedge\receive.c @ 181]
8d2e50e8 8d3ee778 00000000 ndis!ndisReturnNetBufferListsInternal+0x48
904fe008 8d3ee778 00000000 ndis!NdisReturnNetBufferLists+0x16
8d3ee778 00000004 00000000 tcpip!FlpReturnNetBufferListChain+0x9a
00000000 00000000 8bdb4008 NETIO!NetioDereferenceNetBufferListChain+0xcf
83cbd100 00000000 00000000 tcpip!IppCompleteAndFreePacketList+0xbf
8d5e29c8 00000006 00000000 tcpip!IppReceiveHeaderBatch+0x276
904f31e8 00000000 00000001 tcpip!IpFlcReceivePackets+0xc06
904fe9c0 8d3ee778 00000000
tcpip!FlpReceiveNonPreValidatedNetBufferListChain+0x6db
904fe9c0 8d3ee778 00000000 tcpip!FlReceiveNetBufferListChain+0x104
004fe008 8d3ee778 00000000 ndis!ndisMIndicateNetBufferListsToOpen+0xab
00000000 81c27c97 8d2e50e8 ndis!ndisIndicateSortedNetBufferLists+0x4a
8d2e50e8 00000000 00000000 ndis!ndisMDispatchReceiveNetBufferLists+0x129
603e9c00 87603f5c 87603f28 ndis!ndisDoPeriodicReceivesIndication+0x170
844146e0 00000000 f2c4fdca ndis!ndisPeriodicReceivesTimer+0x48
00000000 00000000 00009a37 nt!KiTimerExpiration+0x498
878cfa50 00000000 00000000 nt!KiRetireDpcList+0xba
00000000 00000000 00000000 nt!KiDispatchInterrupt+0x3d
WARNING: Frame IP not in any known module. Following frames may be wrong.
0000001a 00c1850f bb830000 0x878cfa50

I don’t know if the last line is trying to tell me.

Can anyone give me any advise on why this happen? I have followed almost the
same code as the WDK sample code.

Tony


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Sorry that I might provided the wrong information. What NICFreeRCB() does is
to insert the list entry from the RCB (receive control block) to the
adaptor’s received free list (total of 256 is allocated for sending read
request to my LWF usb driver), so we know how many free and busy requests
the driver has left in the lower level driver. It also set the mdl address
of current irp to NULL and also adjusting the mdl of the current RCB (that
is associated with the NET_BUFFER_LIST. It does not make call to
NdisFreeNetBufferList, therefore it does not directly release the
NET_BUFFER_LIST. Therefore the NET_BUFFER_LIST should not get dereferenced
right? Or maybe modifying the MDLs have some effects on the NET_BUFFER_LIST?

NICFreeRCB(
IN PRCB pRCB,
IN BOOLEAN AtDispatchLevel
)
/*++

Routine Description:

pRCB - pointer to RCB block

Arguments:

This routine reinitializes the RCB block and puts it back
into the RecvFreeList for reuse.

Return Value:

VOID

–*/
{
PMP_ADAPTER Adapter = pRCB->Adapter;
WDF_REQUEST_REUSE_PARAMS params;
PIRP irp;
PIO_STACK_LOCATION nextStack;
NTSTATUS status;
BOOLEAN completePause = FALSE;

DEBUGP(MP_TRACE, (“–> NICFreeRCB %p\n”, pRCB));

ASSERT(pRCB->Mdl->Next == NULL);
ASSERT(pRCB->Request != NULL);
ASSERT(pRCB->Ref == 0);
ASSERT(pRCB->Adapter != NULL);

WDF_REQUEST_REUSE_PARAMS_INIT(&params, WDF_REQUEST_REUSE_NO_FLAGS,
STATUS_SUCCESS);

status = WdfRequestReuse(pRCB->Request, &params);
if (!NT_SUCCESS(status)){
DEBUGP(MP_ERROR, (“WdfRequestReuse failed 0x%x\n”, status));
ASSERT(FALSE);
return;
}

//
// Set the MDL field to NULL so that we don’t end up free the
// MDL in our call to Free Request.
//
irp = WdfRequestWdmGetIrp(pRCB->Request);
nextStack = IoGetNextIrpStackLocation( irp );
irp->MdlAddress = NULL;

//
// Re adjust the length to the originl size
//
NdisAdjustMdlLength(pRCB->Mdl, NIC_BUFFER_SIZE);

//
// Insert the RCB back in the Recv free list
//
MP_ACQUIRE_SPIN_LOCK(&Adapter->RecvLock, AtDispatchLevel);

RemoveEntryList(&pRCB->List);

InsertTailList(&Adapter->RecvFreeList, &pRCB->List);

NdisInterlockedDecrement(&Adapter->nBusyRecv);
ASSERT(Adapter->nBusyRecv >= 0);

if (Adapter->nIndicatedNetBufferList == 0 &&
(Adapter->AdapterState == NicPausing))
{
//
// If all the NetBufferLists are returned and miniport is pausing,
// complete the pause
//
Adapter->AdapterState = NicPaused;
completePause = TRUE;
}

MP_RELEASE_SPIN_LOCK(&Adapter->RecvLock, AtDispatchLevel);

if (completePause) {
DEBUGP(MP_TRACE, (“Completed Pause\n”));
NdisMPauseComplete(Adapter->AdapterHandle);
}

//
// For performance, instead of scheduling a workitem at the end of
// every read completion, we will do it only when the number of
// outstanding Requests goes below NIC_SEND_LOW_WATERMARK.
// We shouldn’t queue a workitem if it’s already scheduled and waiting
in
// the system workitem queue to be fired.
//

if ((!NIC_SEND_LOW_WATERMARK || Adapter->nBusyRecv <=
NIC_SEND_LOW_WATERMARK)
&& MP_TEST_FLAG(Adapter, fMP_POST_READS) &&
#pragma warning(disable:4127)
(InterlockedExchange(&Adapter->IsReadWorkItemQueued, TRUE) ==
FALSE) )
#pragma warning(default:4127)
{
Adapter->nReadWorkItemScheduled++;
WdfWorkItemEnqueue(Adapter->ReadWorkItem);
DEBUGP(MP_DEBUG0, (“Num of Busy Recv = %d\n”, Adapter->nBusyRecv));
}

DEBUGP(MP_TRACE, (“<– NICFreeRCB %d\n”, Adapter->nBusyRecv));
}

The only place I see the NET_BUFFER_LISTs are freed is when the driver is
halted. And the allocation of the NET_BUFFER_LISTs is only done during the
initialization of the driver. They are now allocated or deallocated during
the operation.

I’m not sure if this is the correct way of handing the MDLs and
NET_BUFFER_LIST since I directly used the NDISEDGE 6.0 sample from the WDK.
Should I always free the NET_BUFFER_LIST when they are returned from the
protocol driver and reallocate them again?

Tony Chang

On Mon, Nov 2, 2009 at 11:03 PM, David R. Cattley wrote:

> It would be much better if you ?traversed? to the next NBL in the list
> before freeing the current NBL. Think about it. You are freeing the very
> object you then dereference to get the ?next? pointer from. I am assuming
> that NICFreeRCB() will free the associated NBL as well ?
>
>
>
> As for why WDF is choking, it is almost surely because you have a bogus
> argument.
>
>
>
> Good Luck,
>
> Dave Cattley
>
>
>
>
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *Tony Chang
> Sent: Monday, November 02, 2009 9:51 AM
>
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] NDIS 6.0 BSOD
>
>
>
> Hi Dave,
>
> Thanks a lot for the suggestion. After I have tweak the driver a bit, I
> have freed all the NET_BUFFER_LISTs returned to my
> MiniportReturnNetBufferLists. However, I encountered another BSOD with the
> WDF when I was trying to have another ftp download (via flashget)…!! and
> the problem occured when my LWF usb driver is trying to get an I/O request
> from the WDF (which it never happened with my NDISEDGE5.1 driver).
>
> How I free the chain of NET_BUFFER_LISTs:
>
> PNET_BUFFER_LIST CurrNbl = NetBufferLists;
>
> while (CurrNbl != NULL)
> {
> atDispatchLevel =
> (BOOLEAN)NDIS_TEST_RETURN_AT_DISPATCH_LEVEL(ReturnFlags);
>
> pRCB = MP_GET_RCB_FROM_NBL(CurrNbl);
>
> //ASSERT(NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) == NULL); //
> this is the assert that i was refering to in previous mail thread
>
> Adapter = pRCB->Adapter;
>
> ASSERT(Adapter);
>
> NdisInterlockedDecrement(&Adapter->nIndicatedNetBufferList);
> DEBUGP(MP_DEBUG0, (“Returned Adapter->nIndicatedNetBuffList =
> %d\n”, Adapter->nIndicatedNetBufferList));
>
> if (NdisInterlockedDecrement(&pRCB->Ref) == 0)
> {
> NICFreeRCB(pRCB, atDispatchLevel); // here i free the RCB
> }
> NextNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
> CurrNbl = NextNbl;
>
> }
>
> Line of code where it crashed
>
> status = WdfIoQueueRetrieveNextRequest( pAdapter->PendingReadQueue,
> &request );
>
> Below are the crash dump:
>
> STACK_TEXT:
> 953cbad8 806d945b badb0d00 00000000 84112008 nt!KiTrap0E+0x2ac
> 953cbb50 806d95eb 00000000 953cbb6c 842ed608
> Wdf01000!FxIrpQueue::RemoveNextIrpFromQueue+0x12
> 953cbb64 806cfaaa 00000000 00000000 953cbb88
> Wdf01000!FxIrpQueue::GetNextRequest+0x19
> 953cbb78 806e3681 842ed668 00000000 00000000
> Wdf01000!FxRequest::GetNextRequest+0x23
> 953cbbac 806e288a 00000000 00000000 953cbbc8
> Wdf01000!FxIoQueue::GetRequest+0x488
> 953cbbcc a364f97a 842ed608 7bd129f0 953cbc4c
> Wdf01000!imp_WdfIoQueueRetrieveNextRequest+0x4b
> 953cbbe0 a3659f98 7bd129f0 953cbc4c 84139c00
> WiMAXU2!WdfIoQueueRetrieveNextRequest+0x1a
> [c:\winddk\6000\inc\wdf\kmdf\10\wdfio.h @ 515]
> 953cbc90 a3658c1d 842bccb8 842a77e0 000006ec WiMAXU2!ReceivePacket+0x3c8
> [c:\tmp\usb_winvista\10.00.1.0_src\10.00.1.0\receive.c @ 563]
> 953cbd7c 81e254a8 842bccb8 953c0680 00000000 WiMAXU2!ReceiveThread+0x96d
> [c:\tmp\usb_winvista\10.00.1.0_src\10.00.1.0\receive.c @ 245]
> 953cbdc0 81c9145e a36582b0 842bccb8 00000000 nt!PspSystemThreadStartup+0x9d
> 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
>
> Do you have any idea why this API would crash? due to the input arguments?
> or maybe resource problem while it is trying to allocate IRP?
>
> Tony
>
>
>
> On Thu, Oct 29, 2009 at 11:37 PM, David R. Cattley
> wrote:
>
> NDIS is free to return multiple NET_BUFFER_LISTs to your miniport. Why
> would you have such an ASSERT()? You should be processing each
> NET_BUFFER_LIST in the ‘chain’ of NET_BUFFER_LISTs as if each had been sent
> to your MiniportReturnNetBufferLists.
>
> Good Luck,
> Dave Cattley
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
> Sent: Thursday, October 29, 2009 2:21 AM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] NDIS 6.0 BSOD
>
> I’m developing NDISEDGE 6.0 driver for my network device. It is developed
> with little modification from the NDISEDGE 6.0 driver in the WDK. However
> sometimes when I am doing some throughput tests (ftp downloads using
> flashget), I ran into problem that it ASSERT when the file has finished the
> transfer (embedded in the code for debug mode) while NDIS is returning the
> ownership of the Netbufferlist.
>
> The exact line of assert:
>
> ASSERT(NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) == NULL);
>
> This would mean that the next buffer list is not null. Is it something
> wrong
> with my NDISEDGE driver? or something to do with the TCP/IP stack?
>
> The call stack at the point of assert:
> 8d825670 8d8256b0 000000b5 nt!DbgBreakPoint
> 8d2e3008 8d3ee778 00000000 WiMAXEdge!MPReturnNetBufferLists+0xed
> [c:\ndisedge_driver\new_ndisedge\receive.c @ 181]
> 8d2e50e8 8d3ee778 00000000 ndis!ndisReturnNetBufferListsInternal+0x48
> 904fe008 8d3ee778 00000000 ndis!NdisReturnNetBufferLists+0x16
> 8d3ee778 00000004 00000000 tcpip!FlpReturnNetBufferListChain+0x9a
> 00000000 00000000 8bdb4008 NETIO!NetioDereferenceNetBufferListChain+0xcf
> 83cbd100 00000000 00000000 tcpip!IppCompleteAndFreePacketList+0xbf
> 8d5e29c8 00000006 00000000 tcpip!IppReceiveHeaderBatch+0x276
> 904f31e8 00000000 00000001 tcpip!IpFlcReceivePackets+0xc06
> 904fe9c0 8d3ee778 00000000
> tcpip!FlpReceiveNonPreValidatedNetBufferListChain+0x6db
> 904fe9c0 8d3ee778 00000000 tcpip!FlReceiveNetBufferListChain+0x104
> 004fe008 8d3ee778 00000000 ndis!ndisMIndicateNetBufferListsToOpen+0xab
> 00000000 81c27c97 8d2e50e8 ndis!ndisIndicateSortedNetBufferLists+0x4a
> 8d2e50e8 00000000 00000000 ndis!ndisMDispatchReceiveNetBufferLists+0x129
> 603e9c00 87603f5c 87603f28 ndis!ndisDoPeriodicReceivesIndication+0x170
> 844146e0 00000000 f2c4fdca ndis!ndisPeriodicReceivesTimer+0x48
> 00000000 00000000 00009a37 nt!KiTimerExpiration+0x498
> 878cfa50 00000000 00000000 nt!KiRetireDpcList+0xba
> 00000000 00000000 00000000 nt!KiDispatchInterrupt+0x3d
> WARNING: Frame IP not in any known module. Following frames may be wrong.
> 0000001a 00c1850f bb830000 0x878cfa50
>
> I don’t know if the last line is trying to tell me.
>
> Can anyone give me any advise on why this happen? I have followed almost
> the
> same code as the WDK sample code.
>
> Tony
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
> — NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
> other seminars visit: http://www.osr.com/seminars To unsubscribe, visit
> the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>