Re: ncr53c8xx + tulip IRQ sharing

Rogier Wolff (R.E.Wolff@BitWizard.nl)
Tue, 17 Feb 1998 11:01:08 +0100 (MET)


Gerard Roudier wrote:
>
>
>
> On Mon, 16 Feb 1998, Rogier Wolff wrote:
>
> > Gerard Roudier wrote:
> > >
> > > IMHO, this is not an hardware limitation, but a Linux limitation,
> > > probably for some performances considerations.
>
> Am I wrong too here?
>
> > > If you hack a SCSI driver regarding request_interrupt flags, you
> > > just break some assumption on interrupts state for this drivers.
> > > It will be at least required to add some code to disable interrupts
> > > at interrupt routine entry point and to restore them on exit from
> > > this routine.
> >
> > No. Linux guarantees that YOUR interrupt will not occur. This means
>
> You are right. But in what was I wrong there?

Ok. Sorry, it is more complicated. Most people are afraid that their
interrupt routine will be called recursively. You don't have to worry
about that.

> > that you have free reign about your own device (the ncr8xx). However
> > if you cannot tolerate being interrupted for a few microseconds, (e.g.
> > if the device has a microsecond timeout after writing a "low word")
> > you can opt for running the whole interrupt routine with interrupts
> > off to keep things "consistent".

> I would want stuff under interrupt to be light but to be able to
> complete heavy handling in some software priority that allows
> interrupts. On the other hand I donnot like to deal with assumed
> fast interrupts routine to be interrupted. For now, the driver uses
> also a timer handler that may access controller data too.

Ok. That Timer is a problem. But what is "shared" between the
interrupt routine and the timer routine?

Usually you have stuff from the device coming in. This gets queued by
the interrupt routine, and processed by the "timer" routine. That way
the interrupt is always adding to the queue, while the timer is
removing entries. When done carfully, you don't even need locking.

The stuff going out is similar: the "normal" user-thread (**) is
putting things into the queue, and the interrupt routine is removing
them from the queue.

If the timer routine is also mucking with the hardware, then things
become more complicated.

> Anyway, when the driver accesses some IO registers, I would prefer the
> interrupt routine not to be interrupted and masking/unmasking interrupts
> has a cost I donnot want to pay.

masking/unmasking would be a possibility. Don't fall for the trap that
all "lines of code take approximately the same time".

> > I don't think that the NCR is that badly designed, and that running
> > with interrupts enabled (all other interrupts) is acceptable.
>
> IMHO, there is a very low ratio of interrupts disabling that is due to
> hardware constraints. Most seem to be due to software considerations.
> If disabling interrupts if bad design, then there are bunches of bad
> designs elsewhere.

There are some cases in the kernel where e.g. there is not a one-way
communication channel. That makes it very hard to prevent the cli/sti.
Also, because we weren't interested in SMP, cli/sti is a reasonably
safe and fast method of locking out uninteded interruptions. As we've
become more and more SMP-aware, we are moving towards "smaller" locks.

Once variables are "read-only" for one "process" (*) and read/write
for another you can make a lock-less communication between the two.

init: head = tail = 0;

put: if ((head+1)%bufsiz == tail)
handle_buffer_full ();
buf[head] = data;
head = (head+1) % bufsiz;

get: if (head == tail)
handle_buffer_empty ();
data = buf[tail];
tail = (tail+1) % bufsiz;

Here you can see, that the "get" process only writes to "tail", while
it has read-only access to "head" (and buf). The opposite goes for
"put". Note that some care has to be taken. ("head++;head %= bufsiz;"
is wrong. Excercise: why?)

The ncr driver in my 2.0.3x kernel seems to safely allow being a
"slow" interrupt. It disables interrupts before moving on to the real
work. I still see "save_flags/cli/sti" stuff in the more recent
driver, inside the "timer" and "interrupt" routines. My guess is that
it runs with interrupts enabled on *BSD, and the fact that it does
SA_INTERRUPT on Linux is "historical".

And remember, there is lots of badly designed software out there. Some
of it even in the Linux kernel. Always try to do better yourself. :-)

Roger.

(*) process here means "user-level-thread"(**), "interrupt routine" or
"timer based processing".

(**) user-level-thread here means the kernel doing things directly on
behalf of a user, i.e. mostly in the user-context, not in an interrupt
routine.

-- 
If it's there and you can see it, it's REAL      |___R.E.Wolff@BitWizard.nl  |
If it's there and you can't see it, it's TRANSPARENT |  Tel: +31-15-2137555  |
If it's not there and you can see it, it's VIRTUAL   |__FAX:_+31-15-2138217  |
If it's not there and you can't see it, it's GONE! -- Roy Wilks, 1983  |_____|

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu