Date: Thu, 13 Jul 89 19:02:09 EDT
From: ddl@harvard.harvard.edu (Dan Lanciani)
To: nelson@sun.soe.clarkson.edu
Subject: ni5210 driver

	Consider the following race condition.  Between the time
you examine the receive frame list and the time the decision is made
to restart the RU, a frame is completed.  In fact, since the interrupt
routine handles only a single frame at a time (unless I am misreading
it) there may be several completed frames.  You now restart the RU
and return from the interrupt routine, immediately taking the interrupt
again because of the received packet & no-resources conditions that
occurred previously.  The interrupt routine finds what looks like
a completed frame descriptor, adds up its length, and calls the
primary receive hook.  Meanwhile, the 82586, which ignores the
fact the the frame is already marked "complete" receives a new frame,
possibly altering the length of the last buffer.  Bingo.
	The sample driver in the Intel documentation has a check
in the RU_START routine that refuses to start the RU if the C bit
is set in the first frame descriptor on the list.  This suggests
that the problem is real.  My preferred solution (and what I notice I
did in another 82586 driver) is to run the buffer management code
at least once after seeing that the RU has left the ready
state.  Of course, this assumes that the buffer code will do multiple
buffers.  I really think it should since, on a slow machine, it
can get behind...

				Dan

Return-Path: <ddl@husc6.harvard.edu>
Date: Sun, 27 Aug 89 21:00:47 EDT
From: ddl@husc6.harvard.edu (Dan Lanciani)
To: lakesys!deanr@husc6.harvard.edu
Subject: ni5210 packet driver
Cc: nelson@sun.soe.clarkson.edu

	(I'm a little unsure of the version numbers at this point,
but presumably the changes are mostly the ones I made.)  There
were some severe problems in the old driver, especially on slower cpu's.
I run a stock 4.77Mhz machine with an ni5210 24 hours/day 7 days/week
on Harvard's rather dirty backbone.  The initial problem that
I noticed was that the driver would overwrite more bytes in the
supplied buffer than it indicated in the count.  This would have
no effect on FTP Software's code since they always allocate a
full-length buffer, but my own code uses two buffer sizes and
this caused it to crash.
	The second (related) problem was that after the driver had
been running for a while, things became sluggish.  This was caused
by the fact that the driver serviced at most one packet on each
receiver interrupt and once it got behind, it stayed behind.  That
is, if at some point in the past two receiver interrupts had been missed
you would not see a new packet until two extra ones had been
received.  This second problem provoked the first problem by
frequently restarting the RU with completed frames still on
the receive list.  At the next receiver (or other) interrupt the
cpu could find what it thought was a completed frame which in
reality was still in use by the RU.  Between the time that the
cpu counted the bytes in the frame and the time that the buffer
was copied, the lenght would change and...
	The three main changes I made were:

1.  Process all completed frames at each interrupt.

2.  Before restarting the RU, look again for frames that
    might have finished while you were deciding to restart the RU.

3.  Firewall count of bytes copied to user buffer.

	Before these changes the dirver would not run for more than
a few hours.  Now it runs for weeks.

				Dan Lanciani
				ddl@harvard.*

