lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Receive path stuck due to pbuf_alloc ret urning NULL


From: Ivan Delamer
Subject: Re: [lwip-users] Receive path stuck due to pbuf_alloc ret urning NULL
Date: Tue, 28 May 2013 09:34:23 -0600

Hello Sebastian,

The example AT91 port from FreeRTOS has some issues that show up in large traffic scenarios, typically with many UDP broadcasts or multicasts, but could also be caused by high volume TCP.

I have optimized the driver in many ways so I don't remember exactly the changes I made to fix this, but it was something like this:

- When pbufs are allocated in ethernetif.c, there are some conditions where the packets aren't freed properly (if not an IP packet?). this led to a memory leak.

- Sometimes there are not enough memp messages to pass packets/messages to the tcpip thread. I increased this from 6? to 20.

There is also sometimes some unexpected behaviors from the AT91 EMAC when receiving packets really fast, so for example if you are in the IRQ for sending and then you receive something during, you need to take care. My ISR looks like this:

void vEMACISR_Handler( void )
{
volatile unsigned portLONG ulIntStatus __attribute__ ((unused));
volatile unsigned portLONG ulTxStatus;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

    /* Find the cause of the interrupt, cleared on read. */
    ulIntStatus = AT91C_BASE_EMAC->EMAC_ISR;

    if ( AT91C_BASE_EMAC->EMAC_RSR & AT91C_EMAC_REC )
    {
/* A frame has been received, signal the lwIP task so it can process
        the Rx descriptors. */
        AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_REC;
        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
    }

    ulTxStatus = AT91C_BASE_EMAC->EMAC_TSR;
    if( ulTxStatus & AT91C_EMAC_COMP )
    {
/* A frame has been transmitted. Mark all the buffers used by the
        frame just transmitted as free again. */
        AT91C_BASE_EMAC->EMAC_TSR = AT91C_EMAC_COMP;
        vClearEMACTxBuffer();
    }
    if( ulTxStatus & (AT91C_EMAC_UND | AT91C_EMAC_BEX))
    {
        /* A frame Tx failed. Reset Tx buffers. */
        AT91C_BASE_EMAC->EMAC_TSR = AT91C_EMAC_UND | AT91C_EMAC_BEX;
        EMAC_Statistics.tx_errors++;
        vResetEMACTxBuffer();
    }


    /* Clear the interrupt. */
    AT91C_BASE_AIC->AIC_EOICR = 0;

/* If a task was woken by either a frame being received then we may need to switch to another task. If the unblocked task was of higher priority then
    the interrupted task it will then execute immediately that the ISR
    completes. */
    if( xHigherPriorityTaskWoken )
    {
        portYIELD_FROM_ISR();
    }
}
/*-----------------------------------------------------------*/

void  vEMACISR_Wrapper( void )
{
    /* Save the context of the interrupted task. */
    portSAVE_CONTEXT();

    /* Call the handler to do the work.  This must be a separate
    function to ensure the stack frame is set up correctly. */
    vEMACISR_Handler();

    /* Restore the context of whichever task will execute next. */
    portRESTORE_CONTEXT();
}

I hope this helps. I've struggled a lot when moving from low-traffic lab network to high-traffic production network.

Cheers
Ivan


Date: Mon, 27 May 2013 10:01:44 -0700 (PDT)
From: Sebastian Gonzalez <address@hidden>
To: address@hidden
Subject: [lwip-users] Receive path stuck due to pbuf_alloc returning
        NULL
Message-ID: <address@hidden>
Content-Type: text/plain; charset=us-ascii

Hi,

I am using lwIP 1.3.2 with an Atmel AT91SAM7X512, and FreeRTOS. We have already used this combination in other projects with no problem, but now we using our design in a network with high density of UDP broadcast traffic
causing the system to stop receiving.
The transmission path keeps working as I can see ARP request messages coming
out in the wireshark traces.
After debugging and searching I found that several people had the same
issue: The pbuf_alloc call from low_level_input in the ethernet driver
returns NULL during the packet storm and keeps returning NULL, as if the TCP/IP task wasn't fast enough to free the pbufs, and thus the packets from
the EMAC do not move to the upper layers.
I do understand that during a packet storm all the packets that can't be processed are dropped, actually that's the behaviour that I expect. But I don't get why the consumer process is unable to free the packets that have
already been passed to the upper layer.
I have tried giving the TCP/IP thread the higher priority with no results. Also changed the number of pbufs from 8 to 16 and noticed that the problem
happened later in time.
Is there a recommended value for the number of pbufs, considering my reduced
schema of memory?

Best regards.

Sebastian




--
View this message in context:
http://lwip.100.n7.nabble.com/Receive-path-stuck-due-to-pbuf-alloc-returning-NULL-tp21461.html
Sent from the lwip-users mailing list archive at Nabble.com.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]