diff options
author | Martin Braun <martin.braun@ettus.com> | 2021-11-02 11:25:56 +0100 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2021-12-02 05:49:53 -0800 |
commit | 9f9c75ecd6e4a318dad5c378fbf260c8fd8c2922 (patch) | |
tree | c63b3439e6580e7f25ccaf142829bd5733d7f50a /host/include | |
parent | 38825f4e562b1eda1129b0f02f82c0bf4cf77276 (diff) | |
download | uhd-9f9c75ecd6e4a318dad5c378fbf260c8fd8c2922.tar.gz uhd-9f9c75ecd6e4a318dad5c378fbf260c8fd8c2922.tar.bz2 uhd-9f9c75ecd6e4a318dad5c378fbf260c8fd8c2922.zip |
rfnoc: Clarify usage of MTU vs. max payload size, remove DEFAULT_SPP
These two values where being mixed up in the code. To summarize:
- The MTU is the max CHDR packet size, including header & timestamp.
- The max payload is the total number of bytes regular payload plus
metadata that can be fit into into a CHDR packet. It is strictly
smaller than the MTU. For example, for 64-bit CHDR widths, if
a timestamp is desired, the max payload is 16 bytes smaller than
the MTU.
The other issue was that we were using a magic constant (DEFAULT_SPP)
which was causing conflicts with MTUs and max payloads.
This constant was harmful in multiple ways:
- The explanatory comment was incorrect (it stated it would cap packets
to 1500 bytes, which it didn't)
- It imposed random, hardcoded values that interfered with an 'spp
discovery', i.e., the ability to derive a good spp value from MTUs
- The current value capped packet sizes to 8000 bytes CHDR packets, even
when we wanted to use bigger ones
This patch changes the following:
- noc_block_base now has improved docs for MTU, and additional APIs
(get_max_payload_size(), get_chdr_hdr_len()) which return the
current payload size given MTU and CHDR width, and the CHDR header
length.
- The internally used graph nodes for TX and RX streamers also get
equipped with the same new two API calls.
- The radio, siggen, and replay block all where doing different
calculations for their spp/ipp values. Now, they all use the max
payload value to calculate spp/ipp. Unit tests where adapted
accordingly. Usage of DEFAULT_SPP was removed.
- The replay block used a hardcoded 16 bytes for header lengths, which
was replaced by get_chdr_hdr_len()
- The TX and RX streamers where discarding the MTU value and using the
max payload size as the MTU, which then propagated throughout the
graph. Now, both values are stored and can be used where appropriate.
Diffstat (limited to 'host/include')
-rw-r--r-- | host/include/uhd/rfnoc/defaults.hpp | 3 | ||||
-rw-r--r-- | host/include/uhd/rfnoc/noc_block_base.hpp | 49 | ||||
-rw-r--r-- | host/include/uhd/rfnoc/replay_block_control.hpp | 3 |
3 files changed, 51 insertions, 4 deletions
diff --git a/host/include/uhd/rfnoc/defaults.hpp b/host/include/uhd/rfnoc/defaults.hpp index d0f6c2311..afc018810 100644 --- a/host/include/uhd/rfnoc/defaults.hpp +++ b/host/include/uhd/rfnoc/defaults.hpp @@ -44,9 +44,6 @@ static const std::string DEFAULT_BLOCK_NAME = "Block"; //! This NOC-ID is used to look up the default block static const uint32_t DEFAULT_NOC_ID = 0xFFFFFFFF; static const double DEFAULT_TICK_RATE = 1.0; -// Whenever we need a default spp value use this, unless there are some -// block/device-specific constraints. It will keep the frame size below 1500. -static const int DEFAULT_SPP = 1996; /*! The NoC ID is the unique identifier of the block type. All blocks of the * same type have the same NoC ID. diff --git a/host/include/uhd/rfnoc/noc_block_base.hpp b/host/include/uhd/rfnoc/noc_block_base.hpp index ab002841c..6b1ac5bcd 100644 --- a/host/include/uhd/rfnoc/noc_block_base.hpp +++ b/host/include/uhd/rfnoc/noc_block_base.hpp @@ -115,6 +115,10 @@ public: /*! Return the current MTU on a given edge * + * Note: The MTU is the maximum size of a CHDR packet, including header. In + * order to find out the maximum payload size, calling get_max_payload_size() + * is the recommended alternative. + * * The MTU is determined by the block itself (i.e., how big of a packet can * this block handle on this edge), but also the neighboring block, and * possibly the transport medium between the blocks. This value can thus be @@ -127,6 +131,51 @@ public: */ size_t get_mtu(const res_source_info& edge); + /*! Return the size of a CHDR packet header, in bytes. + * + * This helper function factors in the CHDR width for this block. + * + * \param account_for_ts If true (default), the assumption is that we reserve + * space for a timestamp. It is possible to increase + * the payload if no timestamp is used (only for 64 + * bit CHDR widths!), however, this is advanced usage + * and should only be used in special circumstances, + * as downstream blocks might not be able to handle + * such packets. + * \returns the length of a CHDR header in bytes + */ + size_t get_chdr_hdr_len(const bool account_for_ts = true) const; + + /*! Return the maximum usable payload size on a given edge, in bytes. + * + * This is very similar to get_mtu(), except it also accounts for the + * header. + * + * Example: Say the MTU on a given edge is 8192 bytes. The CHDR width is + * 64 bits. If we wanted to add a timestamp, we would thus require 16 bytes + * for the total header, leaving only 8192-16=8176 bytes for a payload, + * which is what this function would return. + * The same MTU, with a CHDR width of 512 bits however, would require leaving + * 64 bytes for the header (regardless of whether or not a timestamp is + * included). In that case, this function would return 8192-64=8128 bytes + * max payload size. + * + * \param edge The edge on which the max payload size is queried. edge.type + * must be INPUT_EDGE or OUTPUT_EDGE! See also get_mtu(). + * \param account_for_ts If true (default), the assumption is that we reserve + * space for a timestamp. It is possible to increase + * the payload if no timestamp is used (only for 64 + * bit CHDR widths!), however, this is advanced usage + * and should only be used in special circumstances, + * as downstream blocks might not be able to handle + * such packets. + * \returns the max payload size as determined by the overall graph on this + * edge, as well as the CHDR width. + * \throws uhd::value_error if edge is not referring to a valid edge + */ + size_t get_max_payload_size( + const res_source_info& edge, const bool account_for_ts = true); + /*! Return the arguments that were passed into this block from the framework */ uhd::device_addr_t get_block_args() const diff --git a/host/include/uhd/rfnoc/replay_block_control.hpp b/host/include/uhd/rfnoc/replay_block_control.hpp index dc56d59e0..c7624d044 100644 --- a/host/include/uhd/rfnoc/replay_block_control.hpp +++ b/host/include/uhd/rfnoc/replay_block_control.hpp @@ -297,7 +297,8 @@ public: /*! Set the maximum size of a packet * - * Sets the maximum packet size, inclusive of headers and payload. + * Sets the maximum packet size, inclusive of headers and payload. Cannot + * exceed the MTU for this block. * * \param size The size of the packet * \param port Which output port of the replay block to use |