Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[catpowder] XDP LibOS #1310

Merged
merged 4 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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