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-core): use scatter buffers for encryption #1899

Merged
merged 2 commits into from
Aug 24, 2023

Conversation

camshaft
Copy link
Contributor

@camshaft camshaft commented Aug 9, 2023

Description of changes:

In preparation of aws/aws-lc-rs#206 being available, this change refactors the crypto Key interface to take a scatter::Buffer, which allows the encryption method to defer copying of the last chunk of Bytes. This has some pretty big wins for bulk transfer, since the majority of the payload is a Bytes and comes as the last chunk. Since encryption is itself a copy, this sees about a 8% increase in efficiency overall.

Call-outs:

The AWS-LC interface only takes a single extra bytes at the end, instead of an arbitrary list. Our new scatter::Buffer also does the same which makes it so we don't have to allocate a list of Bytes. This could change in the future, but it's unclear if having an arbitrary list of chunks would even help all that much.

Testing:

Without this change

Throughput is ~20Gbps. You can see the memcpy taking about 8% of CPU cycles in the flamegraph:

flamegraph

With this change without AWS-LC-RS scatter method

You can see in the flamegraph that the memcpy has moved to inside the encrypt method, since the copy was deferred until encrypt time:

flamegraph

With this change + AWS-LC-RS scatter method

Throughput is ~21Gbps. You can see in the flamegraph that the memcpy is gone:

flamegraph

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

@camshaft camshaft marked this pull request as ready for review August 9, 2023 22:10

/// Initializes the buffer with extra bytes
///
/// NOTE the EncoderBuffer position should not include the extra bytes. This ensures the bytes
Copy link
Contributor

Choose a reason for hiding this comment

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

any way to debug assert this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not really, unfortunately. Once we've split up the buffer into its parts, we've lost the state required to keep track of where the cursor should be.

Comment on lines +599 to +601
.unwrap_or_else(|err| {
panic!("encryption error; opener={opener_name}, sealer={sealer_name} - {err:?}")
});
Copy link
Contributor

Choose a reason for hiding this comment

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

would this be equivalent to (I think the err gets appended):

Suggested change
.unwrap_or_else(|err| {
panic!("encryption error; opener={opener_name}, sealer={sealer_name} - {err:?}")
});
.expect("encryption error; opener={opener_name}, sealer={sealer_name}");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Formatting requires a macro, since the arguments are variadic. So expect only allows for a static string

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Formatting requires a macro, since the arguments are variadic. So expect only allows for a static string

@camshaft camshaft merged commit a84c704 into main Aug 24, 2023
131 checks passed
@camshaft camshaft deleted the camshaft/vectored-encrypt branch August 24, 2023 16:30
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