FreeRTOS+UDP buffer already freed

ace0 wrote on Friday, September 15, 2017:


I’m using FreeRTOS+UDP stack and I have encountered two problems (maybe connected).
As the subject says one of them is freeing already free buffer. I’m using BufferAllocation_1 and zero copy principle. Buffer is taken in the defferedRxTask by the function pxNetworkBufferGet() swapped with the buffer from the rx descriptor and propagated to the IP stack trough xNetworkEventQueue. On the other side, I’m using FreeRTOS_select() and FreeRTOS_recvfrom() to get data from the socket. The only place where I’m freeing buffers (execpt the frees caused by IP stack) is after getting data from a socket. And every now and then configASSERT( xListItemAlreadyInFreeList == pdFALSE ); in the vNetworkBufferRelease() called after receiving data from a socket fails. Looks like problem occurs only in high ethernet traffic conditions.
Trying to debug that I have encountered another problem and that is configASSERT( ( listCURRENT_LIST_LENGTH( &( pxSocket->xWaitingPacketsList ) ) > 0U ) ); in the FreeRTOS_recvfrom(); waitingPacketSemaphore has been successfully obtained but the socket list was actually empty…
I don’t know if two problems are connected but I’m having really hard time dealing with them.
Has anyone had similar experience or idea how to deal with it?

I’m using STM32F207 uC.


rtel wrote on Friday, September 15, 2017:

Both symptoms could possibly be concurrency related - I would recommend
scrutinising the driver code, especially if buffers are being used in
both interrupts and tasks. For example, where are the DMA buffers being
swapped. Is that within the ISR? If so, how is the new buffer obtained
from inside the ISR?

ace0 wrote on Saturday, September 16, 2017:

I also believe it is concurrency related problem but I’m having really hard time tracking it down, even with the trace macros defined…
Buffers are swapped (and obtained) in a dedicated deferred Rx thread. I’m only giving notifications from the ISR to trigger the Rx thread, but whole memory process is done outside of the ISR.

With trace macros defined what I can see is:

and then the same buffer again released without being obtained first. And as I mentioned in the previous post the only place where I’m releasing buffers is after receiving data from the socket. And I have no idea how the socket is passing buffer which was not obtained before, nor how to trace that…

heinbali01 wrote on Sunday, September 17, 2017:

You possibly know that FreeRTOS+UDP now has a successor that includes many more protocols? It’s called FreeRTOS+TCP. It is based on the same principles and methods.

But your problem ( double releasing of a network buffer ) should not occur of course.

When it happens to me that network buffers are not properly released, I temporarily add the parameter "pcWhere" to these functions:

    xNetworkBufferDescriptor_t *pxNetworkBufferGet(
        const char *pcWhere, size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )

    void vNetworkBufferRelease(
        const char *pcWhere, xNetworkBufferDescriptor_t * const pxNetworkBuffer )

It forces me to write a description of the calling location, e.g. :

    pxNetworkBufferGet( "deferred_Rx", xSize, xBlockTimeTicks );
    vNetworkBufferRelease( "myTask_2", pxNetworkBuffer );

Make sure that the logging of these events ( “get” / “release” ) is reliable. I normally use a cyclic buffer which can be inspected by the debugger.

Also in FreeRTOS+TCP, BufferAllocation_1 contains some helping code if ipconfigTCP_IP_SANITY is defined:

	BaseType_t prvIsFreeBuffer( const NetworkBufferDescriptor_t *pxDescr );
	UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc );

Crashes with Network buffers are nasty, and these functions help to avoid crashes by checking the validity of pointers.

I bet that the cause of your problem is a simple one. Once found, you will say: ah yes, of course :slight_smile:
Please let us know. Hein

ace0 wrote on Tuesday, September 19, 2017:

No progress so far. If/when I find the problem I let you know.