A class that represents a device. More...
#include <pipe.h>
Public Member Functions | |
Device (const Device &)=delete | |
Device & | operator= (const Device &)=delete |
Device (Device &&)=delete | |
Device & | operator= (Device &&)=delete |
RxPipe * | AllocateRxPipe (bool fallback=false) noexcept |
Allocates an RX pipe. | |
TxPipe * | AllocateTxPipe (uint8_t *buf=nullptr) noexcept |
Allocates a TX pipe. | |
int | GetNbFallbackQueues () noexcept |
Retrieves the number of fallback queues for this device. | |
RxTxPipe * | AllocateRxTxPipe (bool fallback=false) noexcept |
Allocates an RX/TX pipe. | |
RxPipe * | NextRxPipeToRecv () |
Gets the next RxPipe that has data pending. | |
RxTxPipe * | NextRxTxPipeToRecv () |
Gets the next RxTxPipe that has data pending. | |
void | ProcessCompletions () |
Processes completions for all pipes associated with this device. | |
int | EnableTimeStamping (uint8_t offset=kDefaultRttOffset) |
Enables hardware time stamping. | |
int | DisableTimeStamping () |
Disables hardware time stamping. | |
int | EnableRateLimiting (uint16_t num, uint16_t den) |
Enables hardware rate limiting. | |
int | DisableRateLimiting () |
Disables hardware rate limiting. | |
int | EnableRoundRobin () |
Enables round robing of packets among the fallback pipes. | |
int | DisableRoundRobin () |
Disables round robing of packets among the fallback pipes. Will use a hash of the five-tuple to direct flows not binded to any pipe. | |
int | GetRoundRobinStatus () noexcept |
Gets the round robin status for the device. | |
int | ApplyConfig (struct TxNotification *config_notification) |
Sends the given config notification to the device. | |
Static Public Member Functions | |
static std::unique_ptr< Device > | Create (const std::string &pcie_addr="", const std::string &huge_page_prefix="") noexcept |
Factory method to create a device. | |
Friends | |
class | RxPipe |
class | TxPipe |
class | RxTxPipe |
A class that represents a device.
Should be instantiated using the factory method Create()
. Use separate instances for each thread.
Example:
|
noexcept |
Allocates an RX pipe.
fallback | Whether this pipe is a fallback pipe. Fallback pipes can receive data from any flow but are also guaranteed to receive data from all flows that they Bind() to. |
|
noexcept |
Allocates an RX/TX pipe.
fallback | Whether this pipe is a fallback pipe. Fallback pipes can receive data from any flow but are also guaranteed to receive data from all flows that they Bind() to. |
|
noexcept |
int enso::Device::ApplyConfig | ( | struct TxNotification * | config_notification | ) |
|
staticnoexcept |
Factory method to create a device.
pcie_addr | The PCIe address of the device. If empty, uses the first device found. |
huge_page_prefix | The prefix to use for huge pages file. If empty, uses the default prefix. |
int enso::Device::DisableRateLimiting | ( | ) |
Disables hardware rate limiting.
int enso::Device::DisableRoundRobin | ( | ) |
Disables round robing of packets among the fallback pipes. Will use a hash of the five-tuple to direct flows not binded to any pipe.
int enso::Device::DisableTimeStamping | ( | ) |
Disables hardware time stamping.
int enso::Device::EnableRateLimiting | ( | uint16_t | num, |
uint16_t | den | ||
) |
Enables hardware rate limiting.
Once rate limiting is enabled, packets from all queues are sent at a rate of num / den * kMaxHardwareFlitRate
flits per second (a flit is 64 bytes). Note that this is slightly different from how we typically define throughput and you will need to take the packet sizes into account to set this properly.
For example, suppose that you are sending 64-byte packets. Each packet occupies exactly one flit. For this packet size, line rate at 100Gbps is 148.8Mpps. So if kMaxHardwareFlitRate
is 200MHz, line rate actually corresponds to a 744/1000 rate. Therefore, if you want to send at 50Gbps (50% of line rate), you can use a 372/1000 (or 93/250) rate.
The other thing to notice is that, while it might be tempting to use a large denominator in order to increase the rate precision. This has the side effect of increasing burstiness. The way the rate limit is implemented, we send a burst of num
consecutive flits every den
cycles. Which means that if num
is too large, it might overflow the receiver buffer. For instance, in the example above, 93/250 would be a better rate than 372/1000. And 3/8 would be even better with a slight loss in precision.
You can find the maximum packet rate for any packet size by using the expression: line_rate / ((pkt_size + 20) * 8)
. So for 100Gbps and 128-byte packets we have: 100e9 / ((128 + 20) * 8)
packets per second. Given that each packet is two flits, for kMaxHardwareFlitRate = 200e6
, the maximum rate is 100e9 / ((128 + 20) * 8) * 2 / 200e6
, which is approximately 125/148. Therefore, if you want to send packets at 20Gbps (20% of line rate), you should use a 25/148 rate.
num | Rate numerator. |
den | Rate denominator. |
int enso::Device::EnableRoundRobin | ( | ) |
Enables round robing of packets among the fallback pipes.
int enso::Device::EnableTimeStamping | ( | uint8_t | offset = kDefaultRttOffset | ) |
Enables hardware time stamping.
All outgoing packets will receive a timestamp and all incoming packets will have an RTT (in number of cycles). Use get_pkt_rtt
to retrieve the value.
offset | Packet offset to place the timestamp, default is kDefaultRttOffset bytes. |
|
noexcept |
|
noexcept |
RxPipe * enso::Device::NextRxPipeToRecv | ( | ) |
Gets the next RxPipe that has data pending.
RxTxPipe * enso::Device::NextRxTxPipeToRecv | ( | ) |
Gets the next RxTxPipe that has data pending.
void enso::Device::ProcessCompletions | ( | ) |