Send packets without copying fragments data:
- Poll all the Tx descriptors and place them into a circular_buffer.
We will take them from there when we need to send new packets.
- PMD will return the completed buffers descriptors to the Tx mempool.
This way we are going to know that we may release the buffer.
- "move" the packet object into the last segment's descriptor's private data.
When this fragment is completed means the whole packet has been sent
and its memory may be released. So, we will do it by calling the packet's
destructor.
Exceptions:
- Copy if hugepages backend is not enabled.
- Copy when we failed to send in a zero-copy flow (e.g. when we failed
to translate a buffer virtual address).
- Copy if first frag requires fragmentation below 128 bytes level - this is
in order to avoid headers splitting.
Signed-off-by: Vlad Zolotarov <vladz@cloudius-systems.com>
New in v5:
- NULL -> nullptr across the board.
- Removed unused macros: MBUF_ZC_PRIVATE() and max_frags_zc.
- Improved the local variables localization according to Nadav's remarks.
- tx_buf class:
- Don't regress the whole packet to the copy-send if a single fragment failed to be sent
in a zero-copy manner (e.g. its data failed the virt2phys translation). Send only such a
fragment in a copy way and try to send the rest of the fragments in a zero-copy way.
- Make set_packet() receive packet&&.
- Fixed the comments in check_frag0(): we check first 128 bytes and not first 2KB.
starting from v2.
- Use assert() instead of rte_exit() in do_one_frag().
- Rename in set_one_data_buf() and in copy_one_data_buf(): l -> buf_len
- Improve the assert about the size of private data in the tx_buf class:
- Added two MARKER fields at the beginning and at the end of the private fields section
which are going to be allocated on the mbuf's private data section.
- Assert on the distance between these two markers.
- Replace the sanity_check() (checks that packet doesn't have a zero-length) in a
copy-flow by an assert() in a general function since this check
is relevant both for a copy and for a zero-copy flows.
- Make a sanity_check to be explicitly called frag0_check.
- Make from_packet() receive packet&&.
- In case frag0_check() fails - copy only the first fragment and
not the whole packet.
- tx_buf_factory class:
- Change the interface to work with tx_buf* instead of tx_buf&.
- Better utilize for-loop facilities in gc().
- Kill the extra if() in the init_factory().
- Use std::deque instead of circular_buffer for storing elements in tx_buf_factory.
- Optimize the tx_buf_factory::get():
- First take the completed buffers from the mempool and only if there
aren't any - take from the factory's cache.
- Make Tx mempools using cache: this significantly improves the performance despite the fact that it's
not the right mempool configuration for a single-producer+single-consumer mode.
- Remove empty() and size() methods.
- Add comments near the assert()s in the fast-path.
- Removed the not-needed "inline" qualifiers:
- There is no need to specify "inline" qualifier for in-class defined
methods INCLUDING static methods.
- Defining process_packets() and poll_rx_once() as inline degraded the
performance by about 1.5%.
- Added a _tx_gc_poller: it will call tx_buf_factory::gc().
- Don't check a pointer before calling free().
- alloc_mempool_xmem(): Use posix_memalign() instead of memalign().
New in v4:
- Improve the info messages.
- Simplified the mempool name creation code.
- configure.py: Opt-out the invalid-offsetof compilation warning.
New in v3:
- Add missing macros definitions dropped in v2 by mistake.
New in v2:
- Use Tx mbufs in a LIFO way for better cache utilization.
- Lower the frag0 non-split thresh to 128 bytes.
- Use new (iterators) semantics in circular_buffer.
- Use optional<packet> for storing the packing in the mbuf.
- Use rte_pktmbuf_alloc() instead of __rte_mbuf_raw_alloc().
- Introduce tx_buf class:
- Hide the private rte_mbuf area handling.
- Hide packet to rte_mbuf cluster translation handling.
- Introduce a "Tx buffers factory" class:
- Hide the rte_mbuf flow details:
mempool->circular_buffer->(PMD->)mempool
- Templatization:
- Make huge_pages_mem_backend a dpdk_qp class template parameter.
- Unite the from_packet_xxx() code into a single template function.
- Unite the translate_one_frag() and copy_one_frag() into a single
template function.