You need to synchronize with a mutex that is initialized with an 
appropriately high level interrupt block cookie.

Anytime is_running is checked, or is changed, that mutex should be 
held.  The mutex basically is implemented in a way that prevents the 
high level interrupt from running while you hold it.  Obviously, you 
don't want to hold any longer than you absolutely have to, and you 
shouldn't do anything that requires sleeping, etc. while holding it.  
(Such locks should always, I believe, be leaf locks...)

A fundamental question arises though: why do you need hi-level 
interrupts?  You can have "hard interrupts" that are not high level -- 
by default most PCI devices do *not* use high level interrupt handling.  
If you don't use high level interrupts, then you don't need any of this 
ugly hand off code to a soft interrupt.

As far as synchronization issues go with work queue management, there 
are several solutions:

    * kmem_alloc()/zalloc() can be used with KM_NOSLEEP -- in which case 
you need to be prepared to deal with errors.

    * you can preallocate what you need, so you can't run out

    * if your work queue is relatively fixed, and you don't need to pass 
data, you can use taskq's to have a different thread.  You can avoid 
having to worry about ddi_taskq_dispatch() by using a master loop and a 
cv synchronization.  (You can use bitfields to indicate which tasks to 
perform, in such a case.) The sdcard code does this: see 
"sda_slot_thread()" in usr/src/uts/common/io/sdcard/impl/sda_slot.c for 
example code.

    -- Garrett

Joachim Worringen wrote:
> Greetings,
>
> a more generic follow-up question on dispatching soft-interrupts from 
> hi-level (hard) interrupts: as described in the Sun documentation at 
> several places (device driver tutorial, or 
> http://developers.sun.com/solaris/articles/interrupt_handlers.html), the 
> softintr and hardintr handler synchronize via a "is_running" flag, 
> protected by a mutex.
>
> If 'is_running' is true, the softintr handler will not be triggered 
> (again). However, what about the race between the softintr handler 
> setting 'is_running' to false (and releasing the lock), and the time 
> that it is actually returning from the handler function and is declared 
> "non-running", so that it can be triggered again?
>
> The hardintr handler may come in in this very moment, assume the 
> softintr handler is not running, trigger it, get EPENDING and quits => 
> an interrupt would be lost.
>
> Admitted, the race is small - or am I wrong?
>
> Additionally, what is best practise for the work queue maintained 
> between these two handlers? As we can not allocate memory within the 
> hardirq-handler, we need to use some statically allocated queue. 
> Assuming the worst, this queue could be full when the hardintr handler 
> wants to queue something => interrupt lost.
>
> We are trying to prevent this by letting the softintr handler increase 
> the number of available queue entries depending on a low-water mark, but 
> still not bullet proof, or is it?
>
>   Joachim
>
>
>   

_______________________________________________
opensolaris-code mailing list
opensolaris-code@opensolaris.org
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to