Functions to initialize and interface directly with the PCIe device. More...
#include "pcie.h"
#include <arpa/inet.h>
#include <enso/config.h>
#include <enso/consts.h>
#include <enso/helpers.h>
#include <immintrin.h>
#include <sched.h>
#include <string.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
#include <algorithm>
#include <cassert>
#include <cerrno>
#include <cstdint>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <limits>
#include <stdexcept>
#include <dev_backend.h>
Go to the source code of this file.
Functions | |
int | enso::notification_buf_init (uint32_t bdf, int32_t bar, struct NotificationBufPair *notification_buf_pair, const std::string &huge_page_prefix) |
Initializes the notification buffer pair. | |
int | enso::enso_pipe_init (struct RxEnsoPipeInternal *enso_pipe, struct NotificationBufPair *notification_buf_pair, bool fallback) |
Initializes an Enso Pipe. | |
int | enso::dma_init (struct NotificationBufPair *notification_buf_pair, struct RxEnsoPipeInternal *enso_pipe, uint32_t bdf, int32_t bar, const std::string &huge_page_prefix, bool fallback) |
Initializes an enso pipe and the notification buffer if needed. | |
uint16_t | enso::get_new_tails (struct NotificationBufPair *notification_buf_pair) |
Gets latest tails for the pipes associated with the given notification buffer. | |
uint32_t | enso::get_next_batch_from_queue (struct RxEnsoPipeInternal *enso_pipe, struct NotificationBufPair *notification_buf_pair, void **buf) |
Gets the next batch of data from the given Enso Pipe. | |
uint32_t | enso::peek_next_batch_from_queue (struct RxEnsoPipeInternal *enso_pipe, struct NotificationBufPair *notification_buf_pair, void **buf) |
Gets the next batch of data from the given Enso Pipe without consuming it. So the next call to get_next_batch_from_queue or to peek_next_batch_from_queue will return the same data. | |
int32_t | enso::get_next_enso_pipe_id (struct NotificationBufPair *notification_buf_pair) |
Get next Enso Pipe with pending data. | |
uint32_t | enso::get_next_batch (struct NotificationBufPair *notification_buf_pair, struct SocketInternal *socket_entries, int *enso_pipe_id, void **buf) |
Get next batch of data from the next available Enso Pipe. | |
void | enso::advance_pipe (struct RxEnsoPipeInternal *enso_pipe, size_t len) |
Frees the next len bytes in the buffer associated with the socket_entry socket. If len is greater than the number of allocated bytes in the buffer, the behavior is undefined. | |
void | enso::fully_advance_pipe (struct RxEnsoPipeInternal *enso_pipe) |
Frees all the received bytes in the buffer associated with the socket_entry socket. | |
void | enso::prefetch_pipe (struct RxEnsoPipeInternal *enso_pipe) |
Prefetches a given Enso Pipe. | |
uint32_t | enso::send_to_queue (struct NotificationBufPair *notification_buf_pair, uint64_t phys_addr, uint32_t len) |
Sends data through a given queue. | |
uint32_t | enso::get_unreported_completions (struct NotificationBufPair *notification_buf_pair) |
Returns the number of transmission requests that were completed since the last call to this function. | |
void | enso::update_tx_head (struct NotificationBufPair *notification_buf_pair) |
Updates the tx head and the number of TX completions. | |
int | enso::send_config (struct NotificationBufPair *notification_buf_pair, struct TxNotification *config_notification) |
Sends configuration to the NIC. | |
int | enso::get_nb_fallback_queues (struct NotificationBufPair *notification_buf_pair) |
Get number of fallback queues currently in use. | |
int | enso::set_round_robin_status (struct NotificationBufPair *notification_buf_pair, bool round_robin) |
Sets the round robin status for the device. | |
int | enso::get_round_robin_status (struct NotificationBufPair *notification_buf_pair) |
Gets the round robin status for the device. | |
uint64_t | enso::get_dev_addr_from_virt_addr (struct NotificationBufPair *notification_buf_pair, void *virt_addr) |
Converts an address in the application's virtual address space to an address that can be used by the device (typically a physical address). | |
void | enso::notification_buf_free (struct NotificationBufPair *notification_buf_pair) |
Frees the notification buffer pair. | |
void | enso::enso_pipe_free (struct NotificationBufPair *notification_buf_pair, struct RxEnsoPipeInternal *enso_pipe, enso_pipe_id_t enso_pipe_id) |
Frees the Enso Pipe. | |
int | enso::dma_finish (struct SocketInternal *socket_entry) |
Frees the notification buffer and all pipes. | |
uint32_t | enso::get_enso_pipe_id_from_socket (struct SocketInternal *socket_entry) |
Gets the Enso Pipe ID associated with a given socket. | |
void | enso::print_stats (struct SocketInternal *socket_entry, bool print_global) |
Prints statistics for a given socket. | |
Functions to initialize and interface directly with the PCIe device.
Definition in file pcie.cpp.
void enso::advance_pipe | ( | struct RxEnsoPipeInternal * | enso_pipe, |
size_t | len | ||
) |
int enso::dma_finish | ( | struct SocketInternal * | socket_entry | ) |
Frees the notification buffer and all pipes.
int enso::dma_init | ( | struct NotificationBufPair * | notification_buf_pair, |
struct RxEnsoPipeInternal * | enso_pipe, | ||
uint32_t | bdf, | ||
int32_t | bar, | ||
const std::string & | huge_page_prefix, | ||
bool | fallback | ||
) |
Initializes an enso pipe and the notification buffer if needed.
void enso::enso_pipe_free | ( | struct NotificationBufPair * | notification_buf_pair, |
struct RxEnsoPipeInternal * | enso_pipe, | ||
enso_pipe_id_t | enso_pipe_id | ||
) |
int enso::enso_pipe_init | ( | struct RxEnsoPipeInternal * | enso_pipe, |
struct NotificationBufPair * | notification_buf_pair, | ||
bool | fallback | ||
) |
void enso::fully_advance_pipe | ( | struct RxEnsoPipeInternal * | enso_pipe | ) |
uint64_t enso::get_dev_addr_from_virt_addr | ( | struct NotificationBufPair * | notification_buf_pair, |
void * | virt_addr | ||
) |
Converts an address in the application's virtual address space to an address that can be used by the device (typically a physical address).
notification_buf_pair | Notification buffer pair to use. |
virt_addr | Virtual address to convert. |
uint32_t enso::get_enso_pipe_id_from_socket | ( | struct SocketInternal * | socket_entry | ) |
Gets the Enso Pipe ID associated with a given socket.
int enso::get_nb_fallback_queues | ( | struct NotificationBufPair * | notification_buf_pair | ) |
uint16_t enso::get_new_tails | ( | struct NotificationBufPair * | notification_buf_pair | ) |
uint32_t enso::get_next_batch | ( | struct NotificationBufPair * | notification_buf_pair, |
struct SocketInternal * | socket_entries, | ||
int * | enso_pipe_id, | ||
void ** | buf | ||
) |
Get next batch of data from the next available Enso Pipe.
notification_buf_pair | Notification buffer to get data from. |
socket_entries | Array of socket entries. |
enso_pipe_id | ID of the Enso Pipe that the data came from. |
buf | Pointer to the buffer where the data will be stored. |
uint32_t enso::get_next_batch_from_queue | ( | struct RxEnsoPipeInternal * | enso_pipe, |
struct NotificationBufPair * | notification_buf_pair, | ||
void ** | buf | ||
) |
Gets the next batch of data from the given Enso Pipe.
enso_pipe | Enso Pipe to get data from. |
notification_buf_pair | Notification buffer to get data from. |
buf | Pointer to the buffer where the data will be stored, it will be updated to point to the next available data. |
int32_t enso::get_next_enso_pipe_id | ( | struct NotificationBufPair * | notification_buf_pair | ) |
int enso::get_round_robin_status | ( | struct NotificationBufPair * | notification_buf_pair | ) |
uint32_t enso::get_unreported_completions | ( | struct NotificationBufPair * | notification_buf_pair | ) |
Returns the number of transmission requests that were completed since the last call to this function.
Since transmissions are always completed in order, one can figure out which transmissions were completed by keeping track of all the calls to send_to_queue
. There can be only up to kMaxPendingTxRequests
requests completed between two calls to send_to_queue
. However, if send
is called multiple times, without calling get_unreported_completions
the number of completed requests can surpass kMaxPendingTxRequests
.
notification_buf_pair | Notification buffer to get completions from. |
void enso::notification_buf_free | ( | struct NotificationBufPair * | notification_buf_pair | ) |
int enso::notification_buf_init | ( | uint32_t | bdf, |
int32_t | bar, | ||
struct NotificationBufPair * | notification_buf_pair, | ||
const std::string & | huge_page_prefix | ||
) |
Initializes the notification buffer pair.
bdf | BDF of the PCIe device to use. |
bar | PCIe BAR to use (set to -1 to automatically select one). |
notification_buf_pair | Notification buffer pair to initialize. |
huge_page_prefix | File prefix to use when allocating the huge pages. |
uint32_t enso::peek_next_batch_from_queue | ( | struct RxEnsoPipeInternal * | enso_pipe, |
struct NotificationBufPair * | notification_buf_pair, | ||
void ** | buf | ||
) |
Gets the next batch of data from the given Enso Pipe without consuming it. So the next call to get_next_batch_from_queue
or to peek_next_batch_from_queue
will return the same data.
enso_pipe | Enso Pipe to get data from. |
notification_buf_pair | Notification buffer to get data from. |
buf | Pointer to the buffer where the data will be stored, it will be updated to point to the next available data. |
void enso::prefetch_pipe | ( | struct RxEnsoPipeInternal * | enso_pipe | ) |
void enso::print_stats | ( | struct SocketInternal * | socket_entry, |
bool | print_global | ||
) |
Prints statistics for a given socket.
int enso::send_config | ( | struct NotificationBufPair * | notification_buf_pair, |
struct TxNotification * | config_notification | ||
) |
Sends configuration to the NIC.
notification_buf_pair | The notification buffer pair to send the configuration through. |
config_notification | The configuration notification to send. Must be a config notification, i.e., signal >= 2. |
uint32_t enso::send_to_queue | ( | struct NotificationBufPair * | notification_buf_pair, |
uint64_t | phys_addr, | ||
uint32_t | len | ||
) |
Sends data through a given queue.
This function returns as soon as a transmission requests has been enqueued to the TX notification buffer. That means that it is not safe to modify or deallocate the buffer pointed by phys_addr
right after it returns. Instead, the caller must use get_unreported_completions
to figure out when the transmission is complete.
This function currently blocks if there is not enough space in the notification buffer.
notification_buf_pair | Notification buffer to send data through. |
phys_addr | Physical memory address of the data to be sent. |
len | Length, in bytes, of the data. |
int enso::set_round_robin_status | ( | struct NotificationBufPair * | notification_buf_pair, |
bool | round_robin | ||
) |
void enso::update_tx_head | ( | struct NotificationBufPair * | notification_buf_pair | ) |