DPDK patches and discussions
 help / color / mirror / Atom feed
* [RFC] add Rust API for basic port operations
@ 2025-04-16 11:42 Gregory Etelson
  2025-04-17 12:26 ` Van Haaren, Harry
  0 siblings, 1 reply; 3+ messages in thread
From: Gregory Etelson @ 2025-04-16 11:42 UTC (permalink / raw)
  To: Harry", Bruce"; +Cc: dev

[-- Attachment #1: Type: text/plain, Size: 7244 bytes --]

This RFC proposes Rust API for basic DPDK port management and IO operations.

```rust

/// Configuration details for a DPDK port.
///
/// # Overview
///
/// `DpdkPortConf` is used to initialize and configure ports in a DPDK environment. It includes:
/// - Device information (`dev_info`) pulled from DPDK.
/// - Transmit and receive configurations, including queue settings and memory pools.
/// - Details about the number of queues and descriptors for transmission and reception.
///
/// This struct is typically instantiated using the [`DpdkPortConf::new_from`] method.
///
/// # Example
///
/// ```
/// let conf = DpdkPortConf::new_from(
///     port_id,
///     dev_conf,
///     tx_conf,
///     rx_conf,
///     8,               // Number of RX queues
///     8,               // Number of TX queues
///     512,             // RX descriptors
///     512,             // TX descriptors
///     0,               // RX queue socket ID
///     0,               // TX queue socket ID
///     Some(rx_mempool) // RX queue mempool
/// ).unwrap();
/// ```
///
#[derive(Clone)]
pub struct DpdkPortConf {
    /// Information about the DPDK Ethernet device (e.g., driver, capabilities, etc.).
    pub dev_info: rte_eth_dev_info,

    /// Configuration for the Ethernet device. Determines the overall behavior of the device.
    pub dev_conf: rte_eth_conf,

    /// Configuration for transmitting (Tx) packets on the Ethernet device.
    pub tx_conf: rte_eth_txconf,

    /// Configuration for receiving (Rx) packets on the Ethernet device.
    pub rx_conf: rte_eth_rxconf,

    /// Number of receive (Rx) queues configured on this port.
    pub rxq_num: u16,

    /// Number of transmit (Tx) queues configured on this port.
    pub txq_num: u16,

    /// Number of descriptors for each transmit (Tx) queue.
    /// Descriptors represent items in a queue to handle packets.
    pub tx_desc_num: u16,

    /// Number of descriptors for each receive (Rx) queue.
    pub rx_desc_num: u16,

    /// NUMA socket ID associated with the memory used by receive (Rx) queues.
    pub rxq_socket_id: u32,

    /// NUMA socket ID associated with the memory used by transmit (Tx) queues.
    pub txq_socket_id: u32,

    /// Memory pool associated with receive (Rx) queues.
    /// This manages the buffers used for storing incoming packets.
    pub rxq_mempool: Option<Arc<DpdkMempool>>,
}


/// A trait defining basic operations for managing and interacting with a DPDK port.
///
/// # Overview
///
/// The `DpdkPort` trait standardizes how to operate on DPDK ports, making it possible to:
/// - Configure the Ethernet device using [`configure`].
/// - Start the device using [`start`].
/// - Handle Rx and Tx bursts of packets using [`rx_burst`] and [`tx_burst`].
///
pub trait DpdkPort: Send + Sync {
    /// Returns the port ID of the DPDK port.
    ///
    /// # Return Value
    /// A `u16` that uniquely identifies the DPDK port.
    ///
    /// # Example
    /// ```
    /// let port_id = dpdk_port.port_id();
    /// println!("DPDK port ID: {}", port_id);
    /// ```
    fn port_id(&self) -> u16;

    /// Returns a reference to the configuration object of the DPDK port.
    ///
    /// # Return Value
    /// A reference to [`DpdkPortConf`], which contains various settings like Rx/Tx queue configurations,
    /// memory pools, and NUMA socket IDs.
    ///
    /// # Example
    /// ```
    /// let port_config = dpdk_port.port_conf();
    /// println!("Rx queues: {}", port_config.rxq_num);
    /// ```
    fn port_conf(&self) -> &DpdkPortConf;

    /// Configures the DPDK Ethernet device with the settings specified in the port configuration.
    ///
    /// This method is typically called before starting the port to ensure it is prepared for Rx and Tx operations.
    ///
    /// # Return Value
    /// - `Ok(())` if the configuration was applied successfully.
    /// - `Err(String)` with a descriptive error message if the configuration failed.
    ///
    /// # Example
    /// ```
    /// let result = dpdk_port.configure();
    /// if let Err(err) = result {
    ///     eprintln!("Failed to configure the port: {}", err);
    /// }
    /// ```
    fn configure(&mut self) -> Result<(), String>;

    /// Starts the DPDK Ethernet device.
    ///
    /// This method initializes the Rx and Tx queues, making the port ready for data transmission
    /// and reception.
    ///
    /// # Return Value
    /// - `Ok(())` if the port was started successfully.
    /// - `Err(String)` if the startup process failed, with a descriptive error message.
    ///
    /// # Example
    /// ```
    /// let result = dpdk_port.start();
    /// if let Err(err) = result {
    ///     eprintln!("Failed to start the port: {}", err);
    /// }
    /// ```
    fn start(&mut self) -> Result<(), String>;

    /// Receives a burst of packets on the specified Rx queue.
    ///
    /// # Parameters
    /// - `queue_id`: The ID of the Rx queue to receive packets from.
    /// - `pkts`: A mutable reference to an array of packet buffers (`*mut rte_mbuf`) where received packets
    ///   will be written.
    ///
    /// # Return Value
    /// - `Ok(u16)` containing the number of packets successfully received.
    /// - `Err(String)` if the operation failed.
    ///
    /// # Example
    /// ```
    /// let pkts: Vec<*mut rte_mbuf> = vec![std::ptr::null_mut(); 32];
    /// let received = dpdk_port.rx_burst(0, &pkts);
    /// match received {
    ///     Ok(count) => println!("Received {} packets", count),
    ///     Err(err) => eprintln!("Rx burst failed: {}", err),
    /// }
    /// ```
    fn rx_burst(&mut self, queue_id: u16, pkts: &[*mut rte_mbuf]) -> Result<u16, String>;

    /// Sends a burst of packets on the specified Tx queue.
    ///
    /// # Parameters
    /// - `queue_id`: The ID of the Tx queue to send packets on.
    /// - `pkts`: A reference to an array of packet buffers (`*mut rte_mbuf`) to send.
    ///
    /// # Return Value
    /// - `Ok(u16)` containing the number of packets successfully sent.
    /// - `Err(String)` if the operation failed.
    ///
    /// # Example
    /// ```
    /// let pkts: Vec<*mut rte_mbuf> = vec![some_packet_ptr1, some_packet_ptr2];
    /// let sent = dpdk_port.tx_burst(0, &pkts);
    /// match sent {
    ///     Ok(count) => println!("Sent {} packets", count),
    ///     Err(err) => eprintln!("Tx burst failed: {}", err),
    /// }
    /// ```
    fn tx_burst(&mut self, queue_id: u16, pkts: &[*mut rte_mbuf]) -> Result<u16, String>;
}

```

The API uses raw FFI pointers in DpdkPort rx_burst() and tx_burst() to preserve DPDK performance.

The API implementation is here:

API definition:
https://github.com/getelson-at-mellanox/rdpdk/blob/main/lib/port/port.rs

API implementation with RTE function calls:
https://github.com/getelson-at-mellanox/rdpdk/blob/main/lib/port/raw_port.rs

Implement direct calls to mlx5 Rx/Tx IO functions:
https://github.com/getelson-at-mellanox/rdpdk/blob/main/port/mlx5/mlx5_port.rs


Signed-off-by: Gregory Etelson <getelson@nvidia.com>






[-- Attachment #2: Type: text/html, Size: 14562 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-04-17 16:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-16 11:42 [RFC] add Rust API for basic port operations Gregory Etelson
2025-04-17 12:26 ` Van Haaren, Harry
2025-04-17 16:19   ` Etelson, Gregory

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).