[444] in linux-net channel archive
Tx timeout fcns in 1.3.x net drivers
daemon@ATHENA.MIT.EDU (Paul Gortmaker)
Sun Jun 11 13:50:07 1995
Date: Mon, 12 Jun 1995 02:33:06 +1000
From: Paul Gortmaker <gpg109@rsphy1.anu.edu.au>
To: Michael.Hipp@student.uni-tuebingen.de, becker@cesdis1.gsfc.nasa.gov,
bj0rn@blox.se, davies@wanton.lkg.dec.com, dp@hydra.carleton.ca,
dplatt@3do.com, iialan@iifeak.swan.ac.uk, jlaiho@ichaos.nullnet.fi,
linux-net@vger.rutgers.edu, simon@ncm.com, slouken@cs.ucdavis.edu,
stud11@cc4.kuleuven.ac.be
To all net driver authors:
I have finally converted all drivers (>30 !!) to have a separate
Tx timeout function, as I said I'd do earlier. This was something that
Donald suggested that should have been done long ago. This means that the
Tx function doesn't have to check/lock dev->tbusy anymore. Instead dev.c
calls the function dev->tx_timeout(dev) when a Tx has exceeded
dev->max_tx_time jiffies. If a device does not want/need a tx_timeout
function, (eg. loopback, dummy, eql, tunnel) it just has to leave dev->tbusy
as zero all the time.
This combined with the locking of the xmit fcn that went into 1.2.9 dev.c
means that we can get rid of 99% of the set_bit() calls on the byte sized
dev->tbusy, which are bad for performance according to the boss.
I also slipped in a few more 8390 cleanups that we can now use due
to the aforementioned locking fixes (start/end_bh_atomic in dev.c).
There are also various typos and stuff fixed here and there.
The patch is quite large (>100k) due to the fact that it moves a fair bit
of code around. Compressed it is only ~25kB.
I have compiled all the drivers to make sure there are no obvious stupid
mistakes both under 1.2.9 and "pre130". There is also a backwards
compatibility, so that if dev->tx_timeout is NULL, it will revert to
the old style behaviour after printing a warning. This gives separately
distributed drivers like the PCMCIA ones a chance to catch up.
======================================================================
Here is how to update a driver:
1) Add a function (+prototype) like this
static void my_cards_tx_timeout(struct device *dev)
2) move the Tx timeout handling (enclosed in a if(dev->tbusy) {...} )
code from the Tx function to the new tx_timeout function. Throw
away the dev->tbusy and the (jiffies- dev->trans_start) checks.
3) where you assign dev->open, also add these two lines.
dev->tx_timeout = &my_cards_tx_timeout;
dev->max_tx_time = 20; /* use your old value, in jiffies */
The code in dev.c will now check for timeout conditions, and call your
tx_timeout function when required.
4) Remove the if(set_bit(0,dev->tbusy) printk("Tx access conflict"); check
and get right to sending the packet. Don't set dev->tbusy yet, unless you
are using it to block something in the card's interrupt handler like
the 3c501 does. The set_bit check is is a wasted check now that dev.c makes
sure the Tx routine remains single-threaded.
5) Just before exiting the tx function, set dev->tbusy according to whether
the card is ready to accept another packet or not. Something like:
dev->tbusy = tx_buffer_1_full && tx_buffer_2_full;
for a ping-pong driver is appropriate.
======================================================================
I have made the patch against 1.2.9 and "pre130.tar.gz" that is now
on Linus' site. The patch against pre130 includes the changes to the
token ring, equalizer, pi2, and tunnel pseudo-device. It also fixes
a bug in the new 3c501 driver, where if it "burps" (Alan's choice
of words :-) it will execute an unpaired restore_flags().
Due to the size of the patch(es) I decided against posting them. You
can get them via anon. ftp from rasty.anu.edu.au in the directory
/pub/linux/net_patches. Look for 129.net.diff.gz and 130.net.diff.gz
The 1.2.9 patch only exists because 1.3.0 wasn't available when I
started on this. If you are a driver developer and can't get to them
due to a firewall at your end, mail me and I will send them.
Paul.