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

libct/seccomp: enable seccomp binary tree optimization #3405

Merged
merged 1 commit into from
Nov 1, 2022

Conversation

kolyshkin
Copy link
Contributor

@kolyshkin kolyshkin commented Mar 8, 2022

This makes libseccomp produce a BPF which uses a binary tree for
syscalls (instead of linear set of if statements).

This should speed up doing syscalls from containers that were created
from OCI spec containing lots of seccomp rules.

@kolyshkin kolyshkin force-pushed the seccomp-bintree branch 2 times, most recently from 534d6de to 6dd9c0e Compare March 9, 2022 01:24
@kolyshkin
Copy link
Contributor Author

Tests hung at

runc run [seccomp] (empty listener path) most probably due to newer libseccomp-golang.

Investigating.

@kolyshkin
Copy link
Contributor Author

OK, this is not caused by the libseccomp-golang bump (as I have suspected), but by SetOptimize(2) call.

@kolyshkin
Copy link
Contributor Author

The only test that hangs is runc run [seccomp] (empty listener path), others run fine.

This test does not set any seccomp rules; it also seems it is not named correctly.

@kolyshkin
Copy link
Contributor Author

OK, so the key is to not enable binary tree optimization when there are no rules.

Also, it makes little sense to enable binary tree optimization when there are just a few rules. I arbitrarily chose 8 as the value of "a few" here.

@kolyshkin
Copy link
Contributor Author

OK, so the key is to not enable binary tree optimization when there are no rules.

This is because of seccomp/libseccomp#370

@kolyshkin
Copy link
Contributor Author

The only test that hangs is runc run [seccomp] (empty listener path), others run fine.

This test does not set any seccomp rules; it also seems it is not named correctly.

Opened #3415 wrt test name and purpose.

@kolyshkin kolyshkin marked this pull request as ready for review March 14, 2022 21:35
@kolyshkin kolyshkin added this to the 1.2.0 milestone Mar 14, 2022
@AkihiroSuda
Copy link
Member

This should speed up doing syscalls from containers that were created
from OCI spec containing lots of seccomp rules.

Any benchmark?

@kolyshkin
Copy link
Contributor Author

Any benchmark?

Some are available from seccomp/libseccomp@c9df088

@kolyshkin
Copy link
Contributor Author

Rebased.

@kolyshkin
Copy link
Contributor Author

Any benchmark?

Some are available from seccomp/libseccomp@c9df088

@AkihiroSuda the above links has a short test result. If that is not enough, please see seccomp/libseccomp#116 and seccomp/libseccomp#152

I tried to do my own tests but apparently measuring syscall latency is some sort of dark art I am not very good at, and later I got carried away with the other stuff.

@kolyshkin kolyshkin force-pushed the seccomp-bintree branch 2 times, most recently from 073ff66 to 8da1ba5 Compare March 31, 2022 03:46
@kolyshkin
Copy link
Contributor Author

Rebased to resolve a conflict due to #3441. @AkihiroSuda @cyphar PTAL

@kolyshkin
Copy link
Contributor Author

@opencontainers/runc-maintainers PTAL

AkihiroSuda
AkihiroSuda previously approved these changes Apr 14, 2022
@kolyshkin
Copy link
Contributor Author

Rebased on top of merged #3465

@kolyshkin kolyshkin requested a review from AkihiroSuda May 19, 2022 22:10
thaJeztah
thaJeztah previously approved these changes May 19, 2022
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

SGTM

would be nice indeed if we had benchmarks on our side as well to allow keeping track of performance regressions

cyphar
cyphar previously requested changes Aug 2, 2022
Copy link
Member

@cyphar cyphar left a comment

Choose a reason for hiding this comment

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

Needs a small comment explaining why > 8 is the threshold.

@thaJeztah
Copy link
Member

Needs a small comment explaining why > 8 is the threshold.

perhaps defining a const for it (where the const is documented) would be nice (just a comment would of course work).

@kolyshkin
Copy link
Contributor Author

  • Rebased to resolve conflicts.
  • Added a (somewhat weak) explanation of why 8 is used as a threshold (copy/pasting it here):
       // Enable libseccomp binary tree optimization. The number 8 is chosen
       // semi-arbitrarily, considering the following:
       // 1. libseccomp <= 2.5.4 misbehaves when binary tree optimization
       // is enabled and there are 0 rules.
       // 2. All known libseccomp versions (2.5.0 to 2.5.4) generate a binary
       // tree with 4 syscalls per node.
       if len(config.Syscalls) > 8 {
               err = filter.SetOptimize(2)
               ....

@drakenclimber perhaps you have a better idea of when we should use bintree optimization (without introducing a knob for it, that it).

@kolyshkin kolyshkin requested review from cyphar and thaJeztah August 4, 2022 16:48
thaJeztah
thaJeztah previously approved these changes Aug 4, 2022
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

still SGTM, thanks for updating!

@drakenclimber
Copy link

  • Rebased to resolve conflicts.

    • Added a (somewhat weak) explanation of why 8 is used as a threshold (copy/pasting it here):
       // Enable libseccomp binary tree optimization. The number 8 is chosen
       // semi-arbitrarily, considering the following:
       // 1. libseccomp <= 2.5.4 misbehaves when binary tree optimization
       // is enabled and there are 0 rules.
       // 2. All known libseccomp versions (2.5.0 to 2.5.4) generate a binary
       // tree with 4 syscalls per node.
       if len(config.Syscalls) > 8 {
               err = filter.SetOptimize(2)
               ....

@drakenclimber perhaps you have a better idea of when we should use bintree optimization (without introducing a knob for it, that it).

The binary tree should help improve performance when the filter is large. Originally I had envisioned automatically turning it on when there were greater than X syscalls in the seccomp filter, but some users preferred to control optimizations themselves.

If you want to avoid a knob, then I would pick a somewhat arbitrary number, say 32, and enable the binary tree when the filter is larger than that.

@drakenclimber
Copy link

@drakenclimber perhaps you have a better idea of when we should use bintree optimization (without introducing a knob for it, that it).

So to actually answer your question :), no I don't have a better answer than what you've done.

@kolyshkin
Copy link
Contributor Author

I would pick a somewhat arbitrary number, say 32, and enable the binary tree when the filter is larger than that.

Changed 8 to 32, slightly improved the comment.

@kolyshkin kolyshkin requested a review from thaJeztah August 5, 2022 01:29
thaJeztah
thaJeztah previously approved these changes Aug 8, 2022
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

libcontainer/seccomp/seccomp_linux.go Outdated Show resolved Hide resolved
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

@AkihiroSuda
Copy link
Member

@cyphar LGTY?

This makes libseccomp produce a BPF which uses a binary tree for
syscalls (instead of linear set of if statements).

It does not make sense to enable binary tree for small set of rules,
so don't do that if we have less than 8 syscalls (the number is chosen
arbitrarily).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
@kolyshkin
Copy link
Contributor Author

@cyphar LGTY?

Assuming @cyphar is good with this change, as his only request was t add an explanation for the number of rules threshold, which was added.

Let's merge it and face the consequences.

@kolyshkin kolyshkin merged commit fdc4d67 into opencontainers:main Nov 1, 2022
@cyphar cyphar mentioned this pull request Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants