init_bh, remove_bh, mark_bh, disable_bh, enable_bh -
       split-half interrupt handling


SYNOPSIS

       #include <linux/interrupt.h>

       void init_bh(int nr, void (*routine)(void));
       void remove_bh(int nr);
       void mark_bh(int nr);
       void disable_bh(int nr);
       void enable_bh(int nr);


DESCRIPTION

   Theory
       Split-half handling is a means of  dividing  an  interrupt
       handler into two sections, one of which (known as the `top
       half') is time-critical and  one  of  which  (the  `bottom
       half') is not.

       The  top half (the handler registered with request_irq(9))
       normally moves  data  between  the  device  and  a  memory
       buffer,  ensures  that  the device is in a sane state, and
       little else.  While the top half of a handler is  running,
       the  IRQ is question is blocked; if it is a fast interrupt
       handler (i.e., it has SA_INTERRUPT  set),  all  interrupts
       are disabled.

       The  bottom half does whatever remains to be done.  Bottom
       halves run with interrupts  enabled,  although  a  locking
       mechanism  ensures  that only one bottom half will be run­
       ning  at  a  given  time.   Bottom  halves  are   run   by
       do_bottom_half(),  which  is  called  from  schedule() and
       ret_from_sys_call().

   Usage
       init_bh() installs routine() as bottom half number nr.  It
       operates  by  adding  an entry to the bh_base[] table, and
       setting the appropriate bit of the bh_mask vector.  Rather
       than  specifying  a  number  explicitly, one should add an
       entry to the anonymous enum in  include/linux/interrupt.h.

       remove_bh() removes bottom half number nr from the list of
       bottom halves.  It removes the entry  from  bh_base[]  and
       clears the appropriate bit of bh_mask.

       mark_bh()  requests that the kernel run the specified bot­
       tom  half  at  the  first  available  opportunity.    This
       function is normally called from the top half of an inter­
       rupt handler.  It operates by setting the appropriate  bit
       of the bh_active vector.

       disable_bh()  disables  bottom  half number nr by clearing
       nested calls to disable_bh() must be matched by  an  equal
       number of calls to enable_bh().

       enable_bh()  enables  a bottom half previously disabled by
       disable_bh().  This function decrements bh_mask_count[nr].
       Then,  if that value is zero, the specified bottom half is
       enabled by setting the appropriate bit of bh_mask.


RETURN VALUE

       No value is returned.


AVAILABILITY

       Linux 2.0+.  init_bh() and remove_bh() were not present in
       older  versions on Linux.  Under those versions, bh_base[]
       and bh_mask must be modified by hand.


SEE ALSO

       request_irq(9), queue_task(9)

       include/asm*/softirq.h,  include/linux/interrupt.h,   ker­
       nel/softirq.c

       "Kernel  Korner" in issue 26 of The Linux Journal includes
       a discussion of split-half  interrupts  under  Linux.   An
       online   copy   of   this   article   can   be   found  at
       http://www.ssc.com/lj/issue26/interrupt.html.


AUTHOR

       Neil Moore <amethyst@maxwell.ml.org>


BUGS

       Only 32 bottom halves are allowed.  Increasing this number
       requires    changing    the    size   of   bh_base[]   and
       bh_mask_count[]   in   kernel/softirq.c,   and    changing
       bh_active and bh_mask (in the same file) to a larger type.
       A better solution, however, would be to consolidate multi­
       ple  bottom halves into a single one by using task queues.
       See queue_task(9) for details.















Man(1) output converted with man2html