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

Add support for io_uring's direct descriptors #102

Merged
merged 55 commits into from
Apr 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
29f1714
Move AsyncFd to its own module
Thomasdezeeuw Feb 17, 2024
15f7b02
Order private module before public ones
Thomasdezeeuw Feb 17, 2024
e6ab753
Add preliminary support for direct descriptors
Thomasdezeeuw Feb 17, 2024
f631f5d
Fix formatting
Thomasdezeeuw Feb 17, 2024
7667cdd
Use generic parameter D for AsyncFd in op_future!
Thomasdezeeuw Feb 17, 2024
175c2c1
Use generic parameter D for AsyncFd in op_async_iter!
Thomasdezeeuw Feb 17, 2024
2b322dc
Make fd::private public in crate
Thomasdezeeuw Feb 18, 2024
1109312
Add AsyncFd::new_direct
Thomasdezeeuw Feb 18, 2024
6518c88
Add AsyncFd::to_file_descriptor
Thomasdezeeuw Feb 18, 2024
ca589fe
Move AsyncFd<Direct> block below the File block
Thomasdezeeuw Feb 18, 2024
6c73abc
Rename AsyncFd::new_direct to from_direct_fd
Thomasdezeeuw Feb 18, 2024
a6acfe2
Remove unused generic type from AsyncFd::to_file_descriptor
Thomasdezeeuw Feb 18, 2024
7ceb5ec
Rename test open_direct to suffix _io
Thomasdezeeuw Feb 18, 2024
c92524b
Add Config::with_direct_descriptors
Thomasdezeeuw Feb 18, 2024
e0243bd
Add AsyncFd::to_direct_descriptor
Thomasdezeeuw Feb 18, 2024
66c875d
Add IORING_OP_FILES_UPDATE to Submission fmt::Debug
Thomasdezeeuw Feb 18, 2024
d1f77d3
Add IORING_OP_FIXED_FD_INSTALL to Submission fmt::Debug
Thomasdezeeuw Feb 18, 2024
35f5b21
Document AsyncFd::to_file_descriptor kernel version
Thomasdezeeuw Feb 18, 2024
220762c
Improve documentation for AsyncFd
Thomasdezeeuw Feb 18, 2024
edd600d
Move is_{send,sync} tests for AsyncFd
Thomasdezeeuw Feb 18, 2024
481d633
Add generic descriptor parameter D in io module
Thomasdezeeuw Feb 18, 2024
353b2a6
Make AsyncFd<Direct> usable with fs operations
Thomasdezeeuw Feb 18, 2024
d617a17
Make AsyncFd<Direct> usable with net operations
Thomasdezeeuw Feb 18, 2024
4227d36
Add direct descriptor support to cancel module
Thomasdezeeuw Feb 18, 2024
fd0ef7a
Add direct descriptor support in signal module
Thomasdezeeuw Feb 18, 2024
d2e2b4e
Add test for AsyncFd::to_direct_descriptor
Thomasdezeeuw Feb 18, 2024
cddf494
Small doc improvements
Thomasdezeeuw Apr 20, 2024
7dcd705
Move ReceiveSignal Future down in code
Thomasdezeeuw Apr 20, 2024
2cd1280
Add Descriptor type to (Set)SocketOption
Thomasdezeeuw Apr 20, 2024
1aec671
Implement fmt::Debug for Signals
Thomasdezeeuw Apr 20, 2024
9255dfd
Test Signals types are Send + Sync with Direct descriptor
Thomasdezeeuw Apr 20, 2024
2cfcc3e
Add test for AsyncFd::to_file_descriptor
Thomasdezeeuw Apr 20, 2024
b53915f
Make AsyncFd::to_file_descriptor a const function
Thomasdezeeuw Apr 20, 2024
7ecb5db
Set direct descriptor flags in AsyncFd::cancel_all
Thomasdezeeuw Apr 20, 2024
92e96ea
Use SubmissionQueue::register
Thomasdezeeuw Apr 20, 2024
fd50490
Set version to v0.2
Thomasdezeeuw Apr 20, 2024
7479015
Add Descriptor generic paramater to OpenOptions methods
Thomasdezeeuw Apr 20, 2024
1c8892e
Remove double setting of direct fd flags
Thomasdezeeuw Apr 20, 2024
9b9d1ed
Doc lack of direct fd support in poll module
Thomasdezeeuw Apr 20, 2024
5200aab
Add Descriptor::create_flags
Thomasdezeeuw Apr 20, 2024
257884f
Support direct descriptors in socket function
Thomasdezeeuw Apr 20, 2024
de0578f
Set descriptor creation flags in accept operations
Thomasdezeeuw Apr 20, 2024
0d783a8
Set descriptor creation flags in Open
Thomasdezeeuw Apr 20, 2024
fec99af
Add more docs on how to create AsyncFds
Thomasdezeeuw Apr 20, 2024
4fccd74
Fix Clippy lint
Thomasdezeeuw Apr 20, 2024
d151100
Add file_index to fmt::Debug for Submission
Thomasdezeeuw Apr 20, 2024
5ab9955
Don't set {O_,SOCK_}CLOEXEC for direct descriptors
Thomasdezeeuw Apr 24, 2024
930569c
Cleanup direct descriptor conversion tests
Thomasdezeeuw Apr 24, 2024
977d5b6
Rename tests::async_fd::fixed to direct
Thomasdezeeuw Apr 24, 2024
20586e7
Make AsyncFd::cancel_all work with direct descriptors
Thomasdezeeuw Apr 24, 2024
08109ca
Make SOCK_CLOEXEC == O_CLOEXEC assertion constant
Thomasdezeeuw Apr 27, 2024
06afd91
Add support for direct descripts in Signals
Thomasdezeeuw Apr 27, 2024
b882070
Add ReceiveSignals::into_inner
Thomasdezeeuw Apr 27, 2024
626a9d4
Add tests for Signals<Direct>
Thomasdezeeuw Apr 27, 2024
a66c909
Don't leak resources when dropping ToSignalsDirect
Thomasdezeeuw Apr 27, 2024
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
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[package]
name = "a10"
description = "A10 is an io_uring library."
version = "0.1.9"
version = "0.2.0"
publish = false # In development.
authors = ["Thomas de Zeeuw <[email protected]>"]
license = "MIT"
documentation = "https://docs.rs/a10"
Expand Down
6 changes: 3 additions & 3 deletions examples/cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::io;

use a10::fs::OpenOptions;
use a10::io::ReadBufPool;
use a10::{Extract, SubmissionQueue};
use a10::{AsyncFd, Extract, SubmissionQueue};

mod runtime;

Expand Down Expand Up @@ -43,8 +43,8 @@ fn main() -> io::Result<()> {
}

async fn cp(sq: SubmissionQueue, source: String, destination: String) -> io::Result<()> {
let input = OpenOptions::new().open(sq.clone(), source.into()).await?;
let output = OpenOptions::new()
let input: AsyncFd = OpenOptions::new().open(sq.clone(), source.into()).await?;
let output: AsyncFd = OpenOptions::new()
.write()
.create_new()
.open(sq.clone(), destination.into())
Expand Down
4 changes: 2 additions & 2 deletions examples/http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::net::{SocketAddr, SocketAddrV4};
use std::{env, io, mem, str};

use a10::net::socket;
use a10::{Ring, SubmissionQueue};
use a10::{AsyncFd, Ring, SubmissionQueue};

mod runtime;

Expand Down Expand Up @@ -56,7 +56,7 @@ async fn request(sq: SubmissionQueue, host: &str, address: SocketAddrV4) -> io::
let r#type = libc::SOCK_STREAM | libc::SOCK_CLOEXEC;
let protocol = 0;
let flags = 0;
let socket = socket(sq, domain, r#type, protocol, flags).await?;
let socket: AsyncFd = socket(sq, domain, r#type, protocol, flags).await?;

// Connect.
let addr = to_sockaddr_storage(address);
Expand Down
4 changes: 2 additions & 2 deletions examples/read_file.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{env, io, str};

use a10::fs::OpenOptions;
use a10::{Ring, SubmissionQueue};
use a10::{AsyncFd, Ring, SubmissionQueue};

mod runtime;

Expand Down Expand Up @@ -34,7 +34,7 @@ fn main() -> io::Result<()> {

async fn read_file(sq: SubmissionQueue, path: String) -> io::Result<Vec<u8>> {
// Open a file for reading.
let file = OpenOptions::new().open(sq, path.into()).await?;
let file: AsyncFd = OpenOptions::new().open(sq, path.into()).await?;

// Read some bytes from the file.
let buf = file.read(Vec::with_capacity(32 * 1024)).await?;
Expand Down
9 changes: 5 additions & 4 deletions src/cancel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ use std::io;
use std::pin::Pin;
use std::task::{self, Poll};

use crate::fd::{AsyncFd, Descriptor};
use crate::op::{op_future, poll_state, OpState};
use crate::{libc, AsyncFd, OpIndex, QueueFull, SubmissionQueue};
use crate::{libc, OpIndex, QueueFull, SubmissionQueue};

/// Cancelation of operations, also see the [`Cancel`] trait to cancel specific
/// operations.
impl AsyncFd {
impl<D: Descriptor> AsyncFd<D> {
/// Attempt to cancel all in progress operations on this fd.
///
/// If the I/O operations were succesfully canceled this returns `Ok(n)`,
Expand All @@ -32,7 +33,7 @@ impl AsyncFd {
/// Due to the lazyness of [`Future`]s it is possible that this will return
/// `Ok(0)` if operations were never polled only to start it after their
/// first poll.
pub const fn cancel_all<'fd>(&'fd self) -> CancelAll<'fd> {
pub const fn cancel_all<'fd>(&'fd self) -> CancelAll<'fd, D> {
CancelAll::new(self, libc::IORING_ASYNC_CANCEL_ALL)
}
}
Expand All @@ -45,7 +46,7 @@ op_future! {
},
setup_state: flags: u32,
setup: |submission, fd, (), flags| unsafe {
submission.cancel(fd.fd(), flags);
submission.cancel(fd.fd(), flags | D::cancel_flag());
},
map_result: |n| {
#[allow(clippy::cast_sign_loss)] // Negative values are mapped to errors.
Expand Down
33 changes: 33 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct Config<'r> {
kernel_thread: bool,
cpu_affinity: Option<u32>,
idle_timeout: Option<u32>,
direct_descriptors: Option<u32>,
attach: Option<&'r SubmissionQueue>,
}

Expand Down Expand Up @@ -67,6 +68,7 @@ impl<'r> Config<'r> {
kernel_thread: true,
cpu_affinity: None,
idle_timeout: None,
direct_descriptors: None,
attach: None,
}
}
Expand Down Expand Up @@ -194,6 +196,21 @@ impl<'r> Config<'r> {
self
}

/// Enable direct descriptors.
///
/// This registers a sparse array of `size` direct descriptor slots enabling
/// direct descriptors to be used. If this is not used attempts to create a
/// direct descriptor will result in `ENXIO`.
///
/// By default direct descriptors are not enabled.
#[doc(alias = "IORING_REGISTER_FILES")]
#[doc(alias = "IORING_REGISTER_FILES2")]
#[doc(alias = "IORING_RSRC_REGISTER_SPARSE")]
pub const fn with_direct_descriptors(mut self, size: u32) -> Self {
self.direct_descriptors = Some(size);
self
}

/// Attach the new (to be created) ring to `other_ring`.
///
/// This will cause the `Ring` being created to share the asynchronous
Expand Down Expand Up @@ -290,6 +307,22 @@ impl<'r> Config<'r> {

let cq = mmap_completion_queue(fd.as_fd(), &parameters)?;
let sq = mmap_submission_queue(fd, &parameters)?;

if let Some(size) = self.direct_descriptors {
let register = libc::io_uring_rsrc_register {
flags: libc::IORING_RSRC_REGISTER_SPARSE,
nr: size,
resv2: 0,
data: 0,
tags: 0,
};
sq.register(
libc::IORING_REGISTER_FILES2,
(&register as *const libc::io_uring_rsrc_register).cast(),
size_of::<libc::io_uring_rsrc_register>() as _,
)?;
}

Ok(Ring { cq, sq })
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ use crate::cancel::{Cancel, CancelOp, CancelResult};
/// use std::io;
/// use std::path::PathBuf;
///
/// use a10::fd::File;
/// use a10::fs::OpenOptions;
/// use a10::{SubmissionQueue, Extract};
///
/// async fn write_all_to_file(sq: SubmissionQueue, path: PathBuf, buf: Vec<u8>) -> io::Result<(PathBuf, Vec<u8>)> {
/// // This `Future` returns just the opened file.
/// let open_file_future = OpenOptions::new().open(sq, path);
/// let open_file_future = OpenOptions::new().open::<File>(sq, path);
/// // Calling `extract` and awaiting that will return both the file and
/// // the path buffer.
/// let (file, path) = open_file_future.extract().await?;
Expand Down
Loading
Loading