aboutsummaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2021-11-02 11:25:56 +0100
committerAaron Rossetto <aaron.rossetto@ni.com>2021-12-02 05:49:53 -0800
commit9f9c75ecd6e4a318dad5c378fbf260c8fd8c2922 (patch)
treec63b3439e6580e7f25ccaf142829bd5733d7f50a /host/include
parent38825f4e562b1eda1129b0f02f82c0bf4cf77276 (diff)
downloaduhd-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.hpp3
-rw-r--r--host/include/uhd/rfnoc/noc_block_base.hpp49
-rw-r--r--host/include/uhd/rfnoc/replay_block_control.hpp3
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