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?
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?
----- 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.