From: Manfred Spraul <manfred@colorfullife.com>
To: Donald Becker <becker@scyld.com>
Cc: Jeff Garzik <jgarzik@mandrakesoft.com>,
Andrew Morton <andrewm@uow.edu.au>,
mulder.abg@sni.de, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Re: Q: natsemi.c spinlocks
Date: Mon, 22 Jan 2001 09:51:34 +0100 [thread overview]
Message-ID: <3A6BF496.AE9957D7@colorfullife.com> (raw)
In-Reply-To: <Pine.LNX.4.10.10101220157450.9133-100000@vaio.greennet>
Donald Becker wrote:
>
> > > However, natsemi.c's spinlock needs to be retained, and
> > > extended into start_tx(), because this driver has
> > > a race which has cropped up in a few others:
> > > ...
> > > if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1) {
> > > /* WINDOW HERE */
> > > np->tx_full = 1;
> > > netif_stop_queue(dev);
> > > }
> > > If the ring is currently full and an interrupt comes in
> > > at the indicated window and reaps ALL the packets in the
> > > ring, the driver ends up in state `tx_full = 1' and tramsmit
> > > disabled, but with no outstanding transmit interrupts.
>
> The better solution, which I've been adding to the drivers, is to check
> again for a just-cleared Tx queue after setting tx_full.
> That trades an extra comparison on a rarely followed path for a spinlock
> that is taken for every transmit and interrupt.
>
Please do not forget the memory barrier(s):
tx_full = 1;
if(condition)
...;
That's exactly the sequence that caused deadlocks with wait_queues -
even a Pentium cpu will evaluate the condition before the write to
tx_full is commited. I have a test program (userspace) that reliably
locks up on my P II. I can send you the details if you are interested.
I think you also need a memory barrier in the tx_interrupt codepath.
>
> Remember: spinlocks are expensive!
>
But memory barriers are extremely error prone.
What about
tx_interrupt()
if(netif_queue_stopped(dev)) {
spin_lock(&np->lock);
if(np->cur_tx - np->dirty_tx <= TX_QUEUE_LEN/2)
netif_wake_queue(dev));
spin_unlock(&np->lock);
}
hard_xmit()
if(np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN-1) {
spin_lock_irq(&np->lock);
if(np->cur_tx - np_dirty_tx >= TX_QUEUE_LEN-1)
netif_stop_queue(dev);
spin_unlock_irq(&np->lock);
}
--
Manfred
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
prev parent reply other threads:[~2001-01-22 8:52 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-12-23 17:45 Q: natsemi.c spinlocks Manfred
2000-12-24 0:54 ` Andrew Morton
2000-12-24 11:15 ` Manfred
2001-01-21 14:38 ` Jeff Garzik
2001-01-21 14:43 ` [PATCH] " Jeff Garzik
2001-01-22 7:06 ` Donald Becker
2001-01-22 8:51 ` Manfred Spraul [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3A6BF496.AE9957D7@colorfullife.com \
--to=manfred@colorfullife.com \
--cc=andrewm@uow.edu.au \
--cc=becker@scyld.com \
--cc=jgarzik@mandrakesoft.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mulder.abg@sni.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.