FreeRTOS Support Archive

The FreeRTOS support forum can be used for active support both from Amazon Web Services
and the community. In return for using our software for
free, we request you play fair and do your bit to help others! Sign up
to receive notifications of new support topics then help where you can.

This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.

+TCP zero copy implementation

The example for how to implement zero copy buffers on receive in prvEMACDeferredInterruptHandlerTask
show that it is easily accomplished by buffer pointer swap. The example doesn't show the extra data in front of the DMA buffer being updated to point to the new NetworkBufferDescriptor_t it is now associated with. It would need to wouldn't it?

Regards

+TCP zero copy implementation

The first 4 bytes at ( pucEthernetBuffer - 10 ) are in fact a pointer to the owner, and when two NetworkBufferDescriptor_t's swap their pucEthernetBuffer's, these pointers must be set correctly after the swap.

This pointer is used when accessing UDP messages with the zero-copy flag: a pointer to an UDP payload buffer can be translated to a NetworkBufferDescriptor_t and v.v.

+TCP zero copy implementation

Hein,
Thanks for clarifying. I read somewhere either in code comments or elsewhere in documentation (precise reference eludes me now) that in future +TCP code that data in front of buffer will not be required. If this is likely then should user supplied implementation code prepare now by putting various "in front of buffer prep" in a macro so it can easily be removed (or enhanced)?

+TCP zero copy implementation

+TCP zero copy implementation

that in future +TCP code that data in front of buffer will not be required

You read that on the same page in a comment: "/\* The following line is also required, but will not be required in future versions \*/".
The 2 alignment bytes have proven to be useful for efficiency. The back-pointer is necessary for zero-copy calls to sendto() and recvfrom().
I agree that the 10 hidden bytes are a bit confusing, but I can not think of a good alternative.

You may also wonder why there are 10 bytes and not 6 : some DMA controllers require an 8-byte alignment, and so 8 bytes were skipped from the start before the packet begins.

Regards.

+TCP zero copy implementation

Hein,
May I suggest a possible solution that has memory requirement trade off but simpler implementation. I am in the process of acessing port from lwip to +TCP and have not read through enough code to determine if my idea is feasable but anyway here is a description.

The emac driver code provided by Microsemi for A2F processor creates all structures including DMA descriptors that point to buffers sized for max packet size right off. These buffers are all "owned" by the driver. I would assume that most driver code for other devices would work similarly or provide API to assign user supplied buffer.

I modify emac driver code to initialize DMA descriptors to use buffers supplied by +TCP. That is, all DMA RX and TX descriptors as well as +TCP xNetworkBufferDescriptort are initialized at start to point to a +TCP supplied buffer. Static DMA buffer requirement is DMA RX descriptors count + DMA TX descriptors count + xNetworkBufferDescriptort count.

When packets are transmitted or received the buffer held by xNetworkBufferDescriptort is swapped with DMA descriptor buffer. There is no need to track association of buffer with xNetworkBufferDescriptort. The life cycle of xNetworkBufferDescriptort would follow same path as copy because when transmit or receive function called xNetworkBufferDescriptort is not tied up with emac driver.

Is this feasable despite possibly requiring more static buffers?

Regards

+TCP zero copy implementation

It looks like you can have any alignment for the transmission buffers:

~~~~
31:0 TBA1 Transmit buffer 1 address
Contains the address of the first data buffer. For the setup frame,
this address must be 32-bit word aligned.
In all other cases, there are no restrictions on buffer alignment.
31:0 TBA2 Transmit buffer 2 address
Contains the address of the second data buffer. There are
no restrictions on buffer alignment.
~~~~

For reception, a 32-bit alignment seems to be expected:

~~~~
31:0 RBA1 Receive buffer 1 address
Indicates the length, in bytes, of memory allocated for the
first receive buffer. This number must be 32-bit word aligned.
31:0 RBA2 Receive buffer 2 address
Indicates the length, in bytes, of memory allocated for the second
receive buffer. This number must be 32-bit word aligned.
~~~~

I'm not sure if I understand your proposal correctly. But I'll try to sketch some possibilities:

For the TX path, you can pass pucEthernetBuffer pointers to DMA. After every transmission, there will be a TX-ready interrupt which will wake-up the EMAC task. The task will then release the TX buffers that are transmitted.

There is no need to track association of buffer with NetworkBufferDescriptor_t.

Not sure what you mean here? The pointer to the owner is sometimes needed by the IP task and the application.

Regards.

+TCP zero copy implementation

Hein,
I sucessfully ported to +TCP zero copy from lwip (copy) doing what I tried to explain in previous post. Initial testing indicates it is working quite well. I can send you all pertinent files for you to look at if you like. In short, my implementation requires more static DMA/buffers but implementation is simpler. In fact is nearly identical to copy except instead of copy does buffer swap.

If you don't think I missed anything I am ok with Including it with +TCP examples.