Date: Tue, 05 Feb 2002 19:50:14 -0800 (PST) From: Jonathan Hanna <jhanna@shaw.ca> To: freebsd-stable@FreeBSD.ORG, freebsd-hackers@FreeBSD.ORG Subject: RE: Whats with this -> sendto: No buffer space available Message-ID: <200202060350.g163oFG43139@207-194-143-195.dsl.axion.net> In-Reply-To: <200112071631.fB7GVgr36045@h24-79-126-98.vc.shawcable.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On 07-Dec-01 Jonathan Hanna wrote:
>
> Latest data point here: this time it was fixed mysteriously.
> After noticing it was down, "netstat -m" showed no serious mbuf
> use or peak use. "ep0" had:
> ep0: flags=cc43<UP,BROADCAST,RUNNING,OACTIVE,SIMPLEX,LINK2,MULTICAST> mtu 1500
> and the IP address was set up correctly
>
> "tcpdump -n -i ep0" worked, and after that the behavior was back to normal.
> No restart of natd was done, no firewall rules flushed or reset.
> This is on 4.3-STABLE FreeBSD 4.3-STABLE #3: Sun Jul 15 00:27:41 PDT 2001
I think I may have found the problem; it may be a bug in the ep 3c509 driver.
The OACTIVE flag being set was a clue and I think tcpdump setting promiscuous
mode may have reset the adapter.
I have sent mail to the maintainer, but I am having some mail problems and am
not sure it was received. Can anyone confirm that my number (3) question below
does identify the problem?
I am having ENBUFS problems with a 486 running 4.X stable on an 10BaseT ep interface.
The ENOBUFS comes from ip_output seeing that the send queue is full. When this
happens the OACTIVE flag is set and the interface is stuck untill ifconfig down/up is done.
Looking at the ep driver, a few questions arise:
(This is $FreeBSD: src/sys/dev/ep/if_ep.c,v 1.95.2.2 2000/07/17 21:24:26 archie Exp $)
1) in ep_if_start:
if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) {
/* no room in FIFO */
outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
/* make sure */
if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) {
ifp->if_flags |= IFF_OACTIVE;
return;
}
} else {
outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
}
If the second test of available TX space decides there is enough, should
there be a disabling of the threshold as there is in the else clause?
2) in ep_intr:
void
ep_intr(arg)
void *arg;
{
struct ep_softc *sc;
register int status;
struct ifnet *ifp;
int x;
x = splbio();
sc = (struct ep_softc *)arg;
if (sc->gone)
return;
Should there not be an splx(x) if sc->gone is true?
3) in ep_intr:
rescan:
while ((status = inw(BASE + EP_STATUS)) & S_5_INTS) {
/* first acknowledge all interrupt sources */
outw(BASE + EP_COMMAND, ACK_INTR | (status & S_MASK));
if (status & (S_RX_COMPLETE | S_RX_EARLY)) {
old_status = status;
epread(sc);
continue;
}
It seems that if an RX is done then any TX conditions are lost as an ack of all
sources has been done. I have verified that on the next look after the epread
TX conditions have disappeared without being handled. If OACTIVE is set, then
no if_start will not kikl the driver out of this condition. I suspect this is
the problem I am seeing.
4) if_timer is set when a packet is sent out, but disabled as soon as any TX space
is available. Any reason not to wait for completion?
Thanks.
Jonathan Hanna <jhanna@shaw.ca>
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202060350.g163oFG43139>
