Skip to content

Commit

Permalink
Merge pull request #1310 from microsoft/feature-xdp-libos
Browse files Browse the repository at this point in the history
[catpowder] XDP LibOS
  • Loading branch information
ppenna authored Jul 9, 2024
2 parents 53f96a1 + 30491c1 commit bfed5ab
Show file tree
Hide file tree
Showing 33 changed files with 1,691 additions and 12 deletions.
101 changes: 101 additions & 0 deletions .github/workflows/catnapw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,104 @@ jobs:
path: |
**/*.stdout.txt
**/*.stderr.txt
catpowder-debug-pipeline:
name: Catpowder Debug Pipeline
needs: release-pipeline
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup SSH
shell: bash
run: |
mkdir -p $HOME/.ssh/
echo "${{ secrets.SSHKEY }}" > "$HOME/.ssh/id_rsa"
chmod 400 $HOME/.ssh/id_rsa
echo "Host *" > $HOME/.ssh/config
echo -e "\tStrictHostKeyChecking no" >> $HOME/.ssh/config
echo -e "\tIdentityFile $HOME/.ssh/id_rsa" >> $HOME/.ssh/config
echo -e "\tIdentitiesOnly yes" >> $HOME/.ssh/config
echo -e "\tPasswordAuthentication no" >> $HOME/.ssh/config
echo -e "\tUser ${{ secrets.USERNAME }}" >> $HOME/.ssh/config
echo -e "\tPort ${{ secrets.PORTNUM }}" >> $HOME/.ssh/config
- name: Run
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
branch_name="${{ github.head_ref }}"
else
branch_name="${{ github.ref_name }}"
fi
python3 tools/demikernel_ci.py \
--platform windows \
--server $SERVER \
--client $CLIENT \
--repository 'c:\demikernel' \
--config-path 'c:\config.yaml' \
--branch origin/$branch_name \
--libos catpowder \
--test-unit --test-integration --test-system all \
--debug \
--delay 2 \
--server-addr $SERVER_ADDR \
--client-addr $CLIENT_ADDR
- name: Archive Logs
if: always()
uses: actions/upload-artifact@v4
with:
name: catpowder-debug-pipeline-logs
path: |
**/*.stdout.txt
**/*.stderr.txt
catpowder-release-pipeline:
name: Catpowder Release Pipeline
needs: catpowder-debug-pipeline
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup SSH
shell: bash
run: |
mkdir -p $HOME/.ssh/
echo "${{ secrets.SSHKEY }}" > "$HOME/.ssh/id_rsa"
chmod 400 $HOME/.ssh/id_rsa
echo "Host *" > $HOME/.ssh/config
echo -e "\tStrictHostKeyChecking no" >> $HOME/.ssh/config
echo -e "\tIdentityFile $HOME/.ssh/id_rsa" >> $HOME/.ssh/config
echo -e "\tIdentitiesOnly yes" >> $HOME/.ssh/config
echo -e "\tPasswordAuthentication no" >> $HOME/.ssh/config
echo -e "\tUser ${{ secrets.USERNAME }}" >> $HOME/.ssh/config
echo -e "\tPort ${{ secrets.PORTNUM }}" >> $HOME/.ssh/config
- name: Run
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
branch_name="${{ github.head_ref }}"
else
branch_name="${{ github.ref_name }}"
fi
python3 tools/demikernel_ci.py \
--platform windows \
--server $SERVER \
--client $CLIENT \
--repository 'c:\demikernel' \
--config-path 'c:\config.yaml' \
--branch origin/$branch_name \
--libos catpowder \
--test-unit --test-integration --test-system all \
--delay 2 \
--server-addr $SERVER_ADDR \
--client-addr $CLIENT_ADDR
- name: Archive Logs
if: always()
uses: actions/upload-artifact@v4
with:
name: catpowder-release-pipeline-logs
path: |
**/*.stdout.txt
**/*.stderr.txt
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ windows = { version = "0.57.0", features = [
"Win32_System_Pipes",
"Win32_System_Threading",
] }
xdp-rs = { path = "xdp-rs", optional = true }
# for interacting with socket2.
windows-sys = { version = "0.52.0", features = ["Win32_Networking_WinSock"] }

Expand Down Expand Up @@ -154,6 +155,7 @@ catmem-libos = []
catnip-libos = ["libdpdk"]
catloop-libos = ["catmem-libos"]
libdpdk = ["dpdk-rs"]
libxdp = ["xdp-rs"]
mlx4 = ["dpdk-rs/mlx4"]
mlx5 = ["dpdk-rs/mlx5"]
profiler = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod rawsocket;
//======================================================================================================================

use crate::{
catpowder::runtime::rawsocket::{
catpowder::linux::rawsocket::{
RawSocket,
RawSocketAddr,
},
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//======================================================================================================================

use crate::{
catpowder::runtime::RawSocketAddr,
catpowder::linux::RawSocketAddr,
pal::data_structures::{
SockAddr,
SockAddrIn,
Expand Down
12 changes: 11 additions & 1 deletion src/rust/catpowder/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

pub mod runtime;
#[cfg(target_os = "windows")]
mod win;

#[cfg(target_os = "windows")]
pub use win::runtime::SharedCatpowderRuntime;

#[cfg(target_os = "linux")]
mod linux;

#[cfg(target_os = "linux")]
pub use linux::LinuxRuntime as SharedCatpowderRuntime;
71 changes: 71 additions & 0 deletions src/rust/catpowder/win/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

//======================================================================================================================
// Imports
//======================================================================================================================

use crate::runtime::fail::Fail;
use ::std::ptr;
use ::windows::core::{
Error,
HRESULT,
};

//======================================================================================================================
// Structures
//======================================================================================================================

/// A wrapper structure for n XDP API endpoint.
#[repr(C)]
pub struct XdpApi(*const xdp_rs::XDP_API_TABLE);

//======================================================================================================================
// Implementations
//======================================================================================================================

impl XdpApi {
/// Opens a new XDP API endpoint.
pub fn new() -> Result<Self, Fail> {
let mut api: *const xdp_rs::XDP_API_TABLE = ptr::null_mut();

let result: HRESULT = unsafe { xdp_rs::XdpOpenApi(xdp_rs::XDP_API_VERSION_1, &mut api) };

let error: Error = Error::from_hresult(result);
match error.code().is_ok() {
true => Ok(Self(api)),
false => {
let fail: Fail = Fail::from(&error);
error!("new(): {:?}", &fail);
Err(fail)
},
}
}

/// Gets the API table from the target API endpoint.
pub fn get(&self) -> xdp_rs::XDP_API_TABLE {
unsafe {
// TODO: consider returning individual function pointers instead of the entire table.
let api: *const xdp_rs::XDP_API_TABLE = self.0;
*api
}
}
}

//======================================================================================================================
// Trait Implementations
//======================================================================================================================

impl Drop for XdpApi {
fn drop(&mut self) {
let api: xdp_rs::XDP_API_TABLE = unsafe {
let api: *const xdp_rs::XDP_API_TABLE = self.0;
*api
};

// Closes the XDP API endpoint.
if let Some(close) = api.XdpCloseApi {
unsafe { close(self.0) };
}
}
}
16 changes: 16 additions & 0 deletions src/rust/catpowder/win/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

//======================================================================================================================
// Modules
//======================================================================================================================

mod api;
mod ring;
mod socket;

//======================================================================================================================
// Exports
//======================================================================================================================

pub mod runtime;
100 changes: 100 additions & 0 deletions src/rust/catpowder/win/ring/buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

//======================================================================================================================
// Imports
//======================================================================================================================

use crate::catpowder::win::ring::umemreg::UmemReg;
use ::std::{
cell::RefCell,
ops::{
Deref,
DerefMut,
},
rc::Rc,
vec::Vec,
};

//======================================================================================================================
// Structures
//======================================================================================================================

/// A structure that represents a buffer in the UMEM region.
pub struct XdpBuffer {
/// A pointer to the buffer descriptor.
b: *mut xdp_rs::XSK_BUFFER_DESCRIPTOR,
/// UMEM region that contains the buffer.
umemreg: Rc<RefCell<UmemReg>>,
}

//======================================================================================================================
// Implementations
//======================================================================================================================

impl XdpBuffer {
/// Instantiates a buffer.
pub(super) fn new(b: *mut xdp_rs::XSK_BUFFER_DESCRIPTOR, umemreg: Rc<RefCell<UmemReg>>) -> Self {
Self { b, umemreg }
}

/// Sets the length of the target buffer.
pub(super) fn set_len(&mut self, len: usize) {
unsafe {
(*self.b).Length = len as u32;
}
}

/// Gets the length of the target buffer.
fn len(&self) -> usize {
unsafe { (*self.b).Length as usize }
}

/// Gets the relative base address of the target buffer.
unsafe fn relative_base_address(&self) -> u64 {
(*self.b).Address.__bindgen_anon_1.BaseAddress()
}

unsafe fn offset(&self) -> u64 {
(*self.b).Address.__bindgen_anon_1.Offset()
}

/// Computes the address of the target buffer.
unsafe fn compute_address(&self) -> *mut core::ffi::c_void {
let mut ptr: *mut u8 = self.umemreg.borrow_mut().address() as *mut u8;
ptr = ptr.add(self.relative_base_address() as usize);
ptr = ptr.add(self.offset() as usize);
ptr as *mut core::ffi::c_void
}

/// Creates a vector with the contents of the target buffer.
fn to_vector(&self) -> Vec<u8> {
let mut out: Vec<u8> = Vec::with_capacity(self.len());
self[..].clone_into(&mut out);
out
}
}

//======================================================================================================================
// Trait Implementations
//======================================================================================================================

impl From<XdpBuffer> for Vec<u8> {
fn from(buffer: XdpBuffer) -> Vec<u8> {
buffer.to_vector()
}
}

impl Deref for XdpBuffer {
type Target = [u8];

fn deref(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.compute_address() as *const u8, self.len()) }
}
}

impl DerefMut for XdpBuffer {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe { std::slice::from_raw_parts_mut(self.compute_address() as *mut u8, self.len()) }
}
}
50 changes: 50 additions & 0 deletions src/rust/catpowder/win/ring/generic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

//======================================================================================================================
// Structures
//======================================================================================================================

/// A wrapper structure for a XDP ring.
#[repr(C)]
pub struct XdpRing(xdp_rs::XSK_RING);

//======================================================================================================================
// Implementations
//======================================================================================================================

impl XdpRing {
/// Initializes a XDP ring.
pub(super) fn new(info: &xdp_rs::XSK_RING_INFO) -> Self {
Self(unsafe {
let mut ring: xdp_rs::XSK_RING = std::mem::zeroed();
xdp_rs::_XskRingInitialize(&mut ring, info);
ring
})
}

/// Reserves a consumer slot in the target ring.
pub(super) fn consumer_reserve(&mut self, count: u32, idx: *mut u32) -> u32 {
unsafe { xdp_rs::_XskRingConsumerReserve(&mut self.0, count, idx) }
}

/// Releases a consumer slot in the target ring.
pub(super) fn consumer_release(&mut self, count: u32) {
unsafe { xdp_rs::_XskRingConsumerRelease(&mut self.0, count) }
}

/// Reserves a producer slot in the target ring.
pub(super) fn producer_reserve(&mut self, count: u32, idx: *mut u32) -> u32 {
unsafe { xdp_rs::_XskRingProducerReserve(&mut self.0, count, idx) }
}

/// Submits a producer slot in the target ring.
pub(super) fn producer_submit(&mut self, count: u32) {
unsafe { xdp_rs::_XskRingProducerSubmit(&mut self.0, count) }
}

/// Gets the element at the target index.
pub(super) fn get_element(&self, idx: u32) -> *mut std::ffi::c_void {
unsafe { xdp_rs::_XskRingGetElement(&self.0, idx) }
}
}
Loading

0 comments on commit bfed5ab

Please sign in to comment.