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

cgroups: Add support for cgroup.kill added in Linux Kernel 5.14 #3199

Closed

Conversation

flouthoc
Copy link
Contributor

@flouthoc flouthoc commented Sep 5, 2021

Following PR adds support for cgroup.kill to kill all the processes in
a cgroup instead of iterating over each process to save cost if
possible.

Linux kernel 5.14 adds support for cgroup.kill.

Ref

@flouthoc
Copy link
Contributor Author

flouthoc commented Sep 5, 2021

@giuseppe @AkihiroSuda @kolyshkin PTAL

@flouthoc
Copy link
Contributor Author

flouthoc commented Sep 5, 2021

PS: this is already added in crun by @giuseppe via containers/crun#724

@AkihiroSuda AkihiroSuda added this to the 1.1.0 milestone Sep 5, 2021
@kolyshkin
Copy link
Contributor

This would fix #3135

@cyphar cyphar linked an issue Sep 7, 2021 that may be closed by this pull request
libcontainer/init_linux.go Outdated Show resolved Hide resolved
@flouthoc
Copy link
Contributor Author

flouthoc commented Sep 7, 2021

@cyphar @AkihiroSuda @kolyshkin Addressed all the feedback points in latest commit. Could you please take a look again.

Comment on lines 499 to 501
if err := m.Freeze(configs.Frozen); err != nil {
logrus.Warn(err)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, the whole point of introducing cgroup.kill is you don't have to freeze/thaw, and yet you do that.

Copy link
Contributor Author

@flouthoc flouthoc Sep 8, 2021

Choose a reason for hiding this comment

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

@kolyshkin ah i moved it after "cgroup.kill" in latest commit but as per man-pages it says

+	Killing a cgroup tree will deal with concurrent forks appropriately and
+	is protected against migrations. If callers require strict guarantees
+	they can issue the cgroup.kill request after a freezing the cgroup via
+	cgroup.freeze.```

Copy link
Contributor

Choose a reason for hiding this comment

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

Please see the discussion between @brauner and @rgushchin, which stars here.

In short, the sentence you quote was only in v1 of the patchset and it was dropped later. IOW freezing is not required, and it's one of the "selling points" of this feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kolyshkin thanks for pointing out this discussion this has been fixed in last commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Marking this block as resolved since this was fixed.

defer m.mu.Unlock()
// Since "cgroup.kill" is not a subsystem and we don't want to regenerate path using pid
// strip dir path from any available subsystem, most likely devices since its always there for v1
dirPath, _ := filepath.Split(m.paths["devices"])
Copy link
Contributor

Choose a reason for hiding this comment

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

So, why are you using filepath.Split here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kolyshkin We want path to tree where we are going to write "cgroup.kill" for v1 , example /sys/fs/cgroup/containerID/cgroup.kill

Copy link
Contributor

Choose a reason for hiding this comment

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

  1. The path you provided as an example does not make sense for cgroup v1.
  2. The path that will be produced as a result of filepath.Split would be different from your example (it will actually be pointing to the parent cgroup, and I don't think it's a good idea to use it).

So, it looks like you're not testing this code at all (at least for v1). Do you?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kolyshkin ah my bad i didn't spent time testing this on v1 but I followed the path construction which was being created on crun let me harden this for v1 and if its not supported i will remove it. But if its not available for v1 i think man-pages should be updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kolyshkin I am unable to write file cgroup.kill when working with v1 under any of the paths even the base path but works when cgroup_hierarchy=1 also tried with root. But since its returning error for v1 so code fallbacks to original slow process killing. PS: did not test this with using v1 + hybrid

Copy link
Contributor Author

@flouthoc flouthoc Sep 9, 2021

Choose a reason for hiding this comment

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

@kolyshkin Now i am thinking should v1 managers just return error("Not supported") but i am not sure if it works with v1+hybrid or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Todo: switch this with m.paths[""] to get the path for v1+hybrid. Wait for : #2087

@kolyshkin
Copy link
Contributor

@flouthoc on what distro are you testing this? Problem is, we don't have 5.14+ kernel in CI yet.

@flouthoc
Copy link
Contributor Author

flouthoc commented Sep 8, 2021

@kolyshkin I am using ubuntu 21.04 but 5.14 is not shipped by default but its available on kernel.ubuntu.com mainline.

@kolyshkin kolyshkin modified the milestones: 1.1.0, 1.2.0 Sep 9, 2021
@kolyshkin
Copy link
Contributor

I have booted 5.14 myself and, as I was suspecting, the feature is only available for cgroup v2 (or when using v1 + hybrid hierarchy).

So, it does not make sense to add to v1 managers (unless they gain hybrid support), and the code you're using to get paths to cgroup.kill in v1 managers is probably not working.

Given the fact that this is not ready, and we don't have kernel 5.14 in CI, I think we have to postpone it to 1.2.0.

@flouthoc
Copy link
Contributor Author

flouthoc commented Sep 9, 2021

@kolyshkin fair points i think we can hold on to this till kernel 5.14 and I'll confirm if this works for v1 at all , if not i will remove the case for v1. Will add a .bats test for v2 does that sounds good ?

@kolyshkin
Copy link
Contributor

and I'll confirm if this works for v1 at all , if not i will remove the case for v1.

There's no cgroup.kill for v1, but it is there in case hybrid hierarchy is used. Support for hybrid hierarchy is added by various PRs. In this particular case, we need #2087, and once it's in, we can use Path("") to get path to the hybrid hierarchy, if available.

@kolyshkin kolyshkin marked this pull request as draft September 14, 2021 00:30
@flouthoc
Copy link
Contributor Author

@kolyshkin Sure makes sense lets wait for hybrid hierarchy.

@kolyshkin
Copy link
Contributor

Marked as draft as we need

Problem is, #3059 needs criu 3.16 which is not yet released.

@flouthoc
Copy link
Contributor Author

@kolyshkin @cyphar Just curious how would m.paths[""] would look like for hybrid+v1 could you please state with an example. I'll try setting up a hybrid+v1 in spare time for myself to work on this till other PR gets merged.

@flouthoc
Copy link
Contributor Author

Just want to do this testing myself here cause i think it will take some time to get new kernel in CI meanwhile i can just do testing on my own and we can keep PR on hold.

@flouthoc
Copy link
Contributor Author

Nvm i'll wait for dependent PRs then will pick this up again. I think would be hard to plumb things temporarily into code.

@flouthoc
Copy link
Contributor Author

Just putting mock code so its easier to revisit, please don't review yet.

@kolyshkin
Copy link
Contributor

@flouthoc can you revisit this? I almost ended up rewriting this from scratch (which would be a colossal waste of time).

@flouthoc
Copy link
Contributor Author

flouthoc commented Jun 1, 2022

@kolyshkin Sure I'll revisit this. Thanks for the reminder.

@cyphar
Copy link
Member

cyphar commented Jun 1, 2022

I completely forgot about this patch. Ping me to review it when you're done rebasing. :D

@kolyshkin
Copy link
Contributor

@flouthoc can you take a look and refresh this PR? This would be nice to have in 1.2.0

Following PR adds support for `cgroup.kill` to kill all the processes in
a cgroup instead of iterating over each process to save cost if
possible.

Linux kernel 5.14 adds support for `cgroup.kill`.

Ref
* https://lwn.net/Articles/855049/
* https://lwn.net/Articles/855924/

Signed-off-by: Aditya Rajan <[email protected]>
Signed-off-by: Aditya R <[email protected]>
@kolyshkin
Copy link
Contributor

I am working on an alternative, implemented without adding a new public method to cgroup managers, and modelled after cgroup.kill kernel tests. Still a WIP.

@flouthoc
Copy link
Contributor Author

@kolyshkin Thanks a lot for taking this over, i am closing this one.

@flouthoc flouthoc closed this Apr 13, 2023
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.

Make use of cgroup.kill
4 participants