NdisStallExecution or NdisSleep

First, I would like to say that I am writing an Intermediate Miniport driver starting from the WDK “PassThru” sample under NDIS 5.1. I want to slow the throughput of a NIC without having to alter the NIC’s physical layer details (and allow the solution to apply to any NIC, by just adding the choke as a “service” to it).

I shot my foot by calling KeWaitForSingleObject(…,(KTIMER)&foo,…), and learned a lot about IRQLs.

So in order to suppress sending data too fast, I am calling NdisSleep in MiniportSendPackets before actually sending the packet. I found that this works to my liking when my MiniportSendPackets function is called at IRQL == PASSIVE_LEVEL, but sometimes it is called at DISPATCH_LEVEL, but no other levels. My guess, doesn’t matter anyway, is that some SendPackets are requested from a socket in application land, and the others are the result of the kernel deciding to use the network (responding to a ping was one case), which did not originate from userland.

At the DISPATCH_LEVEL, it seems my only option for blocking/waiting is to call NdisStallExecution. Is that true? Why should the stall be for no more than 50 microseconds in that case (as the docs warn [I can only guess it has to do with system-time])? Any better ideas for how to force a wait at the dispatch level?

Thanks,
Greg

A better approach would be to queue send packets in a linked-list. Use a
timer to dequeue and actually send packets at a later time.

The original packet enters your driver at the miniport interface. This means
that you can use the NDIS_PACKET MiniportReserved area for the linked-list
fields that you need to queue the original packets until they are sent.

By all means, find some method other than NdisStallExecution to make the
delay. I don’t know exactly what NdisStallExecution does, but I suspect it
is a really crude mechanism that will stall the whole system until the stall
expires.

Good luck,

Thomas F. Divine

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-273175-
xxxxx@lists.osr.com] On Behalf Of xxxxx@ieee.org
Sent: Friday, December 15, 2006 3:45 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] NdisStallExecution or NdisSleep

First, I would like to say that I am writing an Intermediate Miniport
driver starting from the WDK “PassThru” sample under NDIS 5.1. I want to
slow the throughput of a NIC without having to alter the NIC’s physical
layer details (and allow the solution to apply to any NIC, by just adding
the choke as a “service” to it).

I shot my foot by calling KeWaitForSingleObject(…,(KTIMER)&foo,…), and
learned a lot about IRQLs.

So in order to suppress sending data too fast, I am calling NdisSleep in
MiniportSendPackets before actually sending the packet. I found that this
works to my liking when my MiniportSendPackets function is called at IRQL
== PASSIVE_LEVEL, but sometimes it is called at DISPATCH_LEVEL, but no
other levels. My guess, doesn’t matter anyway, is that some SendPackets
are requested from a socket in application land, and the others are the
result of the kernel deciding to use the network (responding to a ping was
one case), which did not originate from userland.

At the DISPATCH_LEVEL, it seems my only option for blocking/waiting is to
call NdisStallExecution. Is that true? Why should the stall be for no
more than 50 microseconds in that case (as the docs warn [I can only guess it has to do with system-time])? Any better ideas for how to force a wait
at the dispatch level?

Thanks,
Greg


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

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

Queue the packet to some list and then submit it down to the NIC from a
timer callback.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Friday, December 15, 2006 11:44 PM
Subject: [ntdev] NdisStallExecution or NdisSleep

> First, I would like to say that I am writing an Intermediate Miniport driver
starting from the WDK “PassThru” sample under NDIS 5.1. I want to slow the
throughput of a NIC without having to alter the NIC’s physical layer details
(and allow the solution to apply to any NIC, by just adding the choke as a
“service” to it).
>
> I shot my foot by calling KeWaitForSingleObject(…,(KTIMER)&foo,…), and
learned a lot about IRQLs.
>
> So in order to suppress sending data too fast, I am calling NdisSleep in
MiniportSendPackets before actually sending the packet. I found that this
works to my liking when my MiniportSendPackets function is called at IRQL ==
PASSIVE_LEVEL, but sometimes it is called at DISPATCH_LEVEL, but no other
levels. My guess, doesn’t matter anyway, is that some SendPackets are
requested from a socket in application land, and the others are the result of
the kernel deciding to use the network (responding to a ping was one case),
which did not originate from userland.
>
> At the DISPATCH_LEVEL, it seems my only option for blocking/waiting is to
call NdisStallExecution. Is that true? Why should the stall be for no more
than 50 microseconds in that case (as the docs warn [I can only guess it has to<br>do with system-time])? Any better ideas for how to force a wait at the
dispatch level?
>
> Thanks,
> Greg
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Thanks both! I didn’t wish to set a callback on a timer because I thought that W_SEND_PACKETS_HANDLER was supposed to return an NDIS_ or NT_STATUS according to the NdisSend call. But I was wrong (doesn’t even make sense given that packet transmission success is indicated with NdisMSendComplete), and that is a nice way to go.

Greg