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

feat(s2n-quic-platform): add message ring using sync::Cursor #1787

Merged
merged 2 commits into from
Jun 8, 2023

Conversation

camshaft
Copy link
Contributor

@camshaft camshaft commented Jun 5, 2023

Description of changes:

This change uses the s2n_quic_core::sync::Cursor added in #1774 to implement a ring buffer for passing messages between the endpoint and socket tasks. We're also adding an alloc method to the Message trait that allocates the underlying ring buffer for a given message.

Call-outs:

Note that we still maintain the primary/secondary regions on the ring buffer to make it possible to have a single syscall for the mmsg message type. Without the primary/secondary replication, we would be left with 2 slices and would end up roughly doubling the number of syscalls performed.

Testing:

I've included tests for replication behavior of each type of message to make sure that's working properly. Those also implicitly test the alloc methods as well.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@camshaft camshaft changed the title Camshaft/socket ring feat(s2n-quic-platform): add message ring using sync::Cursor Jun 5, 2023
@camshaft camshaft force-pushed the camshaft/socket-ring branch 2 times, most recently from 4d0ba83 to 97ee823 Compare June 6, 2023 15:46
@camshaft camshaft marked this pull request as ready for review June 6, 2023 16:14
@camshaft camshaft requested a review from toidiu June 7, 2023 01:26
quic/s2n-quic-platform/src/message/mmsg.rs Show resolved Hide resolved
Comment on lines +140 to +158
{
let mut entry_ptr = ptr.as_ptr().add(entry_offset) as *mut UnsafeCell<Message>;
let mut payload_ptr = ptr.as_ptr().add(payload_offset) as *mut UnsafeCell<u8>;
for _ in 0..entries {
let entry = (*entry_ptr).get_mut();
entry.payload_ptr = (*payload_ptr).get();
entry.payload_len = payload_len as _;

entry_ptr = entry_ptr.add(1);
debug_assert!(end_pointer >= entry_ptr as *mut u8);
payload_ptr = payload_ptr.add(payload_len as _);
debug_assert!(end_pointer >= payload_ptr as *mut u8);
}

let primary = ptr.as_ptr().add(entry_offset) as *mut Message;
let secondary = primary.add(entries as _);
debug_assert!(end_pointer >= secondary.add(entries as _) as *mut u8);
core::ptr::copy_nonoverlapping(primary, secondary, entries as _);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some docs/diagrams here would be nice

Comment on lines +290 to +291
#[repr(C, align(8))]
struct Aligned<T>(UnsafeCell<T>);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this also an optimization trick? can you add a comment if thats true

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a correctness thing. I added a comment

Comment on lines +238 to +239
#[inline]
unsafe fn builder<T: Message>(ptr: NonNull<u8>, size: u32) -> cursor::Builder<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there power of 2 requirements for size? I know there were for XDP but maybe we also want to enforce them here. Can you add a check for that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's already being checked by the cursor:

debug_assert!(size.is_power_of_two());


/// Releases ready-to-consume messages to the consumer
#[inline]
pub fn release(&mut self, len: u32) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: size and len are confusing. can you add better names


// if messages were also written to the secondary region, we need to copy them back to the
// primary region
if let Some(replication_count) = (idx + len).checked_sub(size).filter(|v| *v > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you simplify or add a comment for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants