On Thu, 2010-01-14 at 04:19 -0500, xxxxx@hotmail.com wrote:
> Because the documentation for EvtInterruptDpc() states: The system does not add the DPC
> object to the DPC queue if the object is already queued. An EvtInterruptIsr callback function
> might be called several times before the system calls the EvtInterruptDpc callback function.
> Therefore, the EvtInterruptDpc callback function must be able to process information from several >interrupts, and it must process all interrupts that have occurred since the last time it was called.
> Since in my case, I could be contending for a spin lock, I need an async (to the interrupt handling
> itself) method of the disposition of the data passed in the interrupt.
If you don’t mind, could you please expand it a bit and explain to us what you want to do and why you think DpcForIsr is not going to work for you. Look -as long as DPC is in a queue it means that it is due for execution so that it will be able to get all information about hardware events that occurred before it got dequeued, from device registers. Therefore, it does not make sense to invoke the same routine more than once, so that the system is not going to queue DPC that has already been enqueued.
This is all that the quote that you have provided says - it does not say that DPC cannot get queued successfully until DPC routine returns control, does it??? If your target hardware event occurs while DPC routine is running ISR will be able to enqueue DPC successfully, because DPC is already dequeued at the time DPC routine starts execution. Once you are going to contend for a spinlock at DPC level your code can be interrupted if you target hardware event occurs. ISR will queue DPC once again, so that your DPC routine is going to do a delayed processing upon the next invocation.
What is the problem??? Why do you think DpcForIsr is not going to work for you???
It does work for us and it is used.
Recall that this ‘NIC’ is a pure software device in virtualization
space. The actual ‘bus’ is a lockless shared memory (between guest and
host) ring and has a software signaling mechanism that is multiplexed
via the bus driver’s interrupt object. This bus allows us to bypass
the traditional hardware emulation used in para-virtual space and save a
significant amount of hardware emulation overhead (and thus gain
performance, and much lower latency).
The DpcForIsr in the bus driver is used to post a signal to a specific
instance of the ring. This signal implies that this ring has some
specific work to do for the associated ring. This signaling mechanism
takes the place of the traditional ISR in a purely hardware scenario.
There is a kernel software driver on the ‘other side’ of the ring that
communicates directly with the NIC.
In the case of tx, we need to validate the completion status of the sent
packets and set the completion of the associated NET_BUFFER_LISTs. In
addition, we need to reclaim the elements of the ring associated with
the packets on those NET_BUFFER_LISTs.
In the case of rx, we need to pull packets off the ring and forward them
up the stack, and reclaim the elements of the ring.
These rings operate completely independently of each other. It takes 3
rings for each device: an event ring for the device itself, and a tx and
rx). The event ring is used (in the NIC case) for things such as link
up/down state, and hotplug. The tx and rx rings are self-explanatory.
Right now, the bus DpcForIsr merely queues a custom dpc for each ring
that performs its associated work.
So while we could do all the work with within the context of the bus
DpcForIsr, we would impact performance of the other rings within the
system.
In the Linux guests, we use tasklets for this purpose, which are a very
lightweight async mechanism. It appears that Windows DPCs are the
similar mechanism.
Best,
-PWM
Anton Bassov
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