Subject: Proposal for generalized MI soft interrupts
To: None <tech-kern@NetBSD.ORG>
From: Charles M. Hannum <mycroft@mit.edu>
List: tech-kern
Date: 01/30/1997 09:05:05
The goals of this proposal are to:

0) Define a machine-independent mechanism for handling soft
interrupts.

1) Generalize soft interrupts so that they can be used *any* time a
low-priority callback is needed.

2) Allow dynamic registration of soft interrupts, for loadable drivers
and protocol stacks.

3) Allow prioritization and fair queueing of soft interrupts.

4) Keep the run-time cost minimal while still meeting the above goals.

5) Permit, where applicable, handling soft interrupts via the same
mechanism as hard interrupts, to reduce code complexity.


Parts of the proposed interface are similar to the hard interrupt
registration interface used on ISA, EISA, PCI, and TC busses in
several ports.  This is not accidental.


A few new constants are defined:

IPL_SOFTCLOCK		soft IPL for softclock()
IPL_SOFTNET		soft IPL for network callbacks
IPL_SOFTSERIAL		soft IPL for serial driver callbacks

Other constants of the form `IPL_SOFT*' are reserved.


Three new functions are defined:

void *softintr_establish(int level, int (*fun) __P((void *)), void *arg);

  Registers a soft interrupt at level `level', which will call
  fun(arg).  softintr_establish() returns an opaque cookie which must
  be used as an argument to softintr_disestablish() or
  softintr_register().  It may allocate a machine-specific data
  structure.

void softintr_disestablish(cookie)

  Deallocates a soft interrupt previously allocated with
  softintr_establish().

void softintr_register(cookie)

  Registers a soft interrupt previously allocate with
  softintr_establish() to be executed as soon as it is unblocked.
  This function may assume that the interrupt is currently blocked, so
  it need not check to see if the interrupt needs to be executed
  immediately.


The mechanism for calling the soft interrupt routines is left entirely
to the machine-dependent implementation, so that it may be optimized
in whatever fashion is appropriate.

This specification is designed to make it possible for
softintr_register() to be very simple.  On the i386, for example, it
will consist of one TAILQ_INSERT_TAIL() and an `or' into a global
variable, and will be inlined.  On some other systems, it's expected
that it will be one TAILQ_INSERT_TAIL() and a frob to the PSL, using
the CPU's built-in soft interrupt handling.  It's true that this is
more expensive than the current system, but I don't see it being a
real performance issue, and it's considerably more general.

The rationale for allowing softintr_register() to not execute the
interrupt immediately is as follows: Soft interrupts are used as
callbacks for hard interrupts.  Since a soft interrupt is always
registered from a hard interrupt routine, it is always blocked at the
time it is registered.  Therefore, softintr_register() will always be
used when the interrupt is already blocked, and doesn't need to check
this case.


Comments?