Skip site navigation (1)Skip section navigation (2)
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>