From 3b268929cc5b1ee09efd27d37b2fe240f2504557 Mon Sep 17 00:00:00 2001 From: Daniel Noland Date: Thu, 23 Jan 2025 14:57:54 -0700 Subject: [PATCH] Bump to new DPDK bindings > [!WARNING] > Do not merge this code until https://github.com/githedgehog/dpdk-sys/pull/69 is merged. In this commit, we begin using the new dpdk-sys bindings. The major changes are: 1. We now have low-level wrappers for basically all `static inline` DPDK functions thanks to dpdk-sys #69. 2. Thanks to new features in bindgen and doxygen-rs we now have rust docs for most DPDK functions. 3. We no longer need `w` prefixed dpdk-sys functions. Signed-off-by: Daniel Noland --- Cargo.lock | 27 ++++++++++++++++++++----- dpdk-sys/Cargo.toml | 4 ++-- dpdk-sys/build.rs | 48 +++++++++++++++++++++++++++++++------------- dpdk/src/dev.rs | 36 ++++++++++++++++----------------- dpdk/src/eal.rs | 4 ++-- dpdk/src/mem.rs | 4 ++-- dpdk/src/queue/rx.rs | 2 +- scratch/src/main.rs | 14 ++++++------- scripts/dpdk-sys.env | 2 +- 9 files changed, 89 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6f4be1d..3a36005d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -32,6 +32,16 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" +[[package]] +name = "annotate-snippets" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" +dependencies = [ + "anstyle", + "unicode-width", +] + [[package]] name = "anstyle" version = "1.0.10" @@ -73,10 +83,11 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.70.1" +version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ + "annotate-snippets", "bitflags", "cexpr", "clang-sys", @@ -857,9 +868,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "ryu" @@ -1090,6 +1101,12 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "valuable" version = "0.1.0" diff --git a/dpdk-sys/Cargo.toml b/dpdk-sys/Cargo.toml index db912aa9..9e8a3d53 100644 --- a/dpdk-sys/Cargo.toml +++ b/dpdk-sys/Cargo.toml @@ -6,6 +6,6 @@ description = "Low-level bindings to the Data Plane Development Kit (DPDK)" publish = false [build-dependencies] -bindgen = { workspace = true, features = ["runtime"] } -doxygen-rs = { workspace = true } +bindgen = { version = "0.71.1", features = ["runtime", "experimental"]} +doxygen-rs = { version = "0.4.2" } dpdk-sysroot-helper = { path = "../dpdk-sysroot-helper", version = "0.0.1" } diff --git a/dpdk-sys/build.rs b/dpdk-sys/build.rs index 23267f4b..8feeb929 100644 --- a/dpdk-sys/build.rs +++ b/dpdk-sys/build.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright Open Network Fabric Authors -use std::env; - use bindgen::callbacks::ParseCallbacks; +use std::env; +use std::panic::catch_unwind; use std::path::{Path, PathBuf}; #[derive(Debug)] @@ -11,20 +11,29 @@ struct Cb; impl ParseCallbacks for Cb { fn process_comment(&self, comment: &str) -> Option { - match doxygen_rs::generator::rustdoc(comment.into()) { - Ok(transformed) => Some(transformed), + match catch_unwind(|| match doxygen_rs::generator::rustdoc(comment.into()) { + Ok(transformed) => transformed, + Err(_) => comment.into(), + }) { + Ok(s) => Some(s), Err(_) => Some(comment.into()), } } } fn bind(path: &Path, sysroot: &str) { + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + let static_fn_path = out_path.join("generated.h"); bindgen::Builder::default() .header(format!("{sysroot}/include/dpdk_wrapper.h")) .anon_fields_prefix("annon") + .use_core() .generate_comments(true) - .generate_inline_functions(false) - .generate_block(true) + .clang_arg("-Wno-deprecated-declarations") + // .clang_arg("-Dinline=") // hack to make bindgen spit out wrappers + .wrap_static_fns(true) + .wrap_static_fns_suffix("_w") + .wrap_static_fns_path(static_fn_path) .array_pointers_in_arguments(false) .detect_include_paths(true) .prepend_enum_name(false) @@ -37,6 +46,7 @@ fn bind(path: &Path, sysroot: &str) { .parse_callbacks(Box::new(Cb)) .layout_tests(true) .default_enum_style(bindgen::EnumVariation::ModuleConsts) + .blocklist_item("rte_atomic.*") .allowlist_item("rte.*") .allowlist_item("wrte_.*") .allowlist_item("RTE.*") @@ -64,7 +74,6 @@ fn bind(path: &Path, sysroot: &str) { .clang_arg(format!("-I{sysroot}/include")) .clang_arg("-fretain-comments-from-system-headers") .clang_arg("-fparse-all-comments") - .clang_arg("-march=native") .generate() .expect("Unable to generate bindings") .write_to_file(path.join("generated.rs")) @@ -72,6 +81,7 @@ fn bind(path: &Path, sysroot: &str) { } fn main() { + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); let sysroot = dpdk_sysroot_helper::get_sysroot(); println!("cargo:rustc-link-arg=--sysroot={sysroot}"); @@ -101,6 +111,22 @@ fn main() { "rte_log", "ibverbs", "mlx5", + "mlx4", + "efa", + "hns", + "mana", + "bnxt_re-rdmav34", + "cxgb4-rdmav34", + "erdma-rdmav34", + "hfi1verbs-rdmav34", + "ipathverbs-rdmav34", + "irdma-rdmav34", + "mthca-rdmav34", + "ocrdma-rdmav34", + "qedr-rdmav34", + "rxe-rdmav34", + "siw-rdmav34", + "vmw_pvrdma-rdmav34", "nl-route-3", "nl-3", "numa", @@ -109,15 +135,9 @@ fn main() { for dep in &depends { println!("cargo:rustc-link-lib=static:+whole-archive,+bundle={dep}"); } - - let rerun_if_changed = ["build.rs"]; - + let rerun_if_changed = ["build.rs", "../scripts/dpdk-sys.env"]; for file in &rerun_if_changed { println!("cargo:rerun-if-changed={file}"); } - - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - // let out_path = PathBuf::from("src"); - bind(&out_path, sysroot.as_str()); } diff --git a/dpdk/src/dev.rs b/dpdk/src/dev.rs index 269af95e..5f9f15d4 100644 --- a/dpdk/src/dev.rs +++ b/dpdk/src/dev.rs @@ -153,7 +153,7 @@ impl DevIndex { pub fn socket_id(&self) -> Result { let socket_id = unsafe { rte_eth_dev_socket_id(self.as_u16()) }; if socket_id == -1 { - match unsafe { wrte_errno() } { + match unsafe { rte_errno_get() } { 0 => { debug!("Unable to determine SocketId for port {self}. Using ANY",); return Ok(SocketId::ANY); @@ -384,7 +384,7 @@ impl Display for TxOffloadConfig { impl From for TxOffload { fn from(value: TxOffloadConfig) -> Self { - use wrte_eth_tx_offload::*; + use rte_eth_tx_offload::*; TxOffload( if value.geneve_tnl_tso { TX_OFFLOAD_GENEVE_TNL_TSO @@ -446,7 +446,7 @@ impl From for TxOffload { impl From for TxOffloadConfig { fn from(value: TxOffload) -> Self { - use wrte_eth_tx_offload::*; + use rte_eth_tx_offload::*; TxOffloadConfig { geneve_tnl_tso: value.0 & TX_OFFLOAD_GENEVE_TNL_TSO != 0, gre_tnl_tso: value.0 & TX_OFFLOAD_GRE_TNL_TSO != 0, @@ -469,38 +469,38 @@ impl From for TxOffloadConfig { impl TxOffload { /// GENEVE tunnel segmentation offload. - pub const GENEVE_TNL_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_GENEVE_TNL_TSO); + pub const GENEVE_TNL_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_GENEVE_TNL_TSO); /// GRE tunnel segmentation offload. - pub const GRE_TNL_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_GRE_TNL_TSO); + pub const GRE_TNL_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_GRE_TNL_TSO); /// IPIP tunnel segmentation offload. - pub const IPIP_TNL_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_IPIP_TNL_TSO); + pub const IPIP_TNL_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_IPIP_TNL_TSO); /// IPv4 checksum calculation. - pub const IPV4_CKSUM: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_IPV4_CKSUM); + pub const IPV4_CKSUM: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_IPV4_CKSUM); /// MACsec insertion. - pub const MACSEC_INSERT: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_MACSEC_INSERT); + pub const MACSEC_INSERT: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_MACSEC_INSERT); /// Outer IPv4 checksum calculation. pub const OUTER_IPV4_CKSUM: TxOffload = - TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_OUTER_IPV4_CKSUM); + TxOffload(rte_eth_tx_offload::TX_OFFLOAD_OUTER_IPV4_CKSUM); /// QinQ (double VLAN) insertion. - pub const QINQ_INSERT: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_QINQ_INSERT); + pub const QINQ_INSERT: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_QINQ_INSERT); /// SCTP checksum calculation. - pub const SCTP_CKSUM: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_SCTP_CKSUM); + pub const SCTP_CKSUM: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_SCTP_CKSUM); /// TCP checksum calculation. - pub const TCP_CKSUM: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_TCP_CKSUM); + pub const TCP_CKSUM: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_TCP_CKSUM); /// TCP segmentation offload. - pub const TCP_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_TCP_TSO); + pub const TCP_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_TCP_TSO); /// UDP checksum calculation. - pub const UDP_CKSUM: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_UDP_CKSUM); + pub const UDP_CKSUM: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_UDP_CKSUM); /// UDP segmentation offload. - pub const UDP_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_UDP_TSO); + pub const UDP_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_UDP_TSO); /// VXLAN tunnel segmentation offload. - pub const VXLAN_TNL_TSO: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_VXLAN_TNL_TSO); + pub const VXLAN_TNL_TSO: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_VXLAN_TNL_TSO); /// VLAN tag insertion. - pub const VLAN_INSERT: TxOffload = TxOffload(wrte_eth_tx_offload::TX_OFFLOAD_VLAN_INSERT); + pub const VLAN_INSERT: TxOffload = TxOffload(rte_eth_tx_offload::TX_OFFLOAD_VLAN_INSERT); /// Union of all [`TxOffload`]s documented at the time of writing. pub const ALL_KNOWN: TxOffload = { - use wrte_eth_tx_offload::*; + use rte_eth_tx_offload::*; TxOffload( TX_OFFLOAD_GENEVE_TNL_TSO | TX_OFFLOAD_GRE_TNL_TSO diff --git a/dpdk/src/eal.rs b/dpdk/src/eal.rs index d0a0ec3e..04700bc2 100644 --- a/dpdk/src/eal.rs +++ b/dpdk/src/eal.rs @@ -107,7 +107,7 @@ pub fn init>(args: Vec) -> Result { let ret = unsafe { rte_eal_init(len, args_as_pointers.as_mut_ptr()) }; if ret < 0 { - let rte_errno = unsafe { wrte_errno() }; + let rte_errno = unsafe { rte_errno_get() }; let error = errno::Errno::from(rte_errno); error!("EAL initialization failed: {error:?} (rte_errno: {rte_errno})"); Err(InitError::InitializationFailed(error)) @@ -154,7 +154,7 @@ impl Eal { /// /// If the err pub fn errno() -> errno::ErrorCode { - errno::ErrorCode::parse_i32(unsafe { wrte_errno() }) + errno::ErrorCode::parse_i32(unsafe { rte_errno_get() }) } } diff --git a/dpdk/src/mem.rs b/dpdk/src/mem.rs index c40fbf20..176dfb9e 100644 --- a/dpdk/src/mem.rs +++ b/dpdk/src/mem.rs @@ -99,7 +99,7 @@ impl PoolHandle { let pool = match NonNull::new(pool) { None => { - let errno = unsafe { wrte_errno() }; + let errno = unsafe { rte_errno_get() }; let c_err_str = unsafe { rte_strerror(errno) }; let err_str = unsafe { CStr::from_ptr(c_err_str) }; #[allow(clippy::expect_used)] @@ -375,7 +375,7 @@ impl Mbuf { /// /// # Safety /// - /// This function is is unsafe if passed an invalid pointer. + /// This function is unsafe if passed an invalid pointer. /// /// The only defense made against invalid pointers here is the use of `NonNull::new` to ensure /// the pointer is not null. diff --git a/dpdk/src/queue/rx.rs b/dpdk/src/queue/rx.rs index b5cffcff..d709a0db 100644 --- a/dpdk/src/queue/rx.rs +++ b/dpdk/src/queue/rx.rs @@ -163,7 +163,7 @@ impl RxQueue { dev = self.dev.as_u16() ); let nb_rx = unsafe { - wrte_eth_rx_burst( + rte_eth_rx_burst( self.dev.as_u16(), self.config.queue_index.as_u16(), pkts.as_mut_ptr(), diff --git a/scratch/src/main.rs b/scratch/src/main.rs index 56101352..89cb6b31 100644 --- a/scratch/src/main.rs +++ b/scratch/src/main.rs @@ -165,7 +165,7 @@ impl Drop for RteFlow { return; } - let rte_err = unsafe { wrte_errno() }; + let rte_err = unsafe { rte_errno_get() }; let err_msg = unsafe { CStr::from_ptr(rte_strerror(res)) } .to_str() .unwrap(); @@ -220,12 +220,12 @@ fn check_hairpin_cap(port_id: u16) { fn init_port2(port_id: u16, mbuf_pool: &mut rte_mempool) { let mut port_conf = rte_eth_conf { txmode: rte_eth_txmode { - offloads: wrte_eth_tx_offload::TX_OFFLOAD_VLAN_INSERT - | wrte_eth_tx_offload::TX_OFFLOAD_IPV4_CKSUM - | wrte_eth_tx_offload::TX_OFFLOAD_UDP_CKSUM - | wrte_eth_tx_offload::TX_OFFLOAD_TCP_CKSUM - | wrte_eth_tx_offload::TX_OFFLOAD_SCTP_CKSUM - | wrte_eth_tx_offload::TX_OFFLOAD_TCP_TSO, + offloads: rte_eth_tx_offload::TX_OFFLOAD_VLAN_INSERT + | rte_eth_tx_offload::TX_OFFLOAD_IPV4_CKSUM + | rte_eth_tx_offload::TX_OFFLOAD_UDP_CKSUM + | rte_eth_tx_offload::TX_OFFLOAD_TCP_CKSUM + | rte_eth_tx_offload::TX_OFFLOAD_SCTP_CKSUM + | rte_eth_tx_offload::TX_OFFLOAD_TCP_TSO, ..Default::default() }, ..Default::default() diff --git a/scripts/dpdk-sys.env b/scripts/dpdk-sys.env index 1e984a6f..a97b47f2 100644 --- a/scripts/dpdk-sys.env +++ b/scripts/dpdk-sys.env @@ -1,2 +1,2 @@ DPDK_SYS_BRANCH="main" -DPDK_SYS_COMMIT="fa00d8c0d874e12208bbea9b48cee62da3f37db0" +DPDK_SYS_COMMIT="35f5284b860154d6ebe0e113b3e5c7c891a7d4ab"