Fix incorrect propagation of frozen state during unfreeze #6632
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In the
cgroup_propagate_frozen
function, during unfreezing (whenfrozen
is false), the code subtractsdesc
(which increments for each unfrozen parent) from each ancestor'snr_frozen_descendants
. This results in over-subtraction, leading to negative counts and incorrect frozen states.Example Scenario:
desc=1
from B's count (correctly setting it to 0). Then subtractsdesc=2
from A's count, reducing it from 2 to 0. If A has another frozen child D, this incorrectly sets A's count to 0 instead of 1 (since D is still frozen).Explanation of the Fix
cgrp->freezer.nr_frozen_descendants -= desc;
tocgrp->freezer.nr_frozen_descendants -= 1;
to decrement each ancestor's count by exactly 1, not the accumulateddesc
.nr_frozen_descendants
no longer matchesnr_descendants
. If so, unfreeze and propagate further.desc
Increment: Thedesc
variable isn't needed for unfreezing since each ancestor is handled individually.Additional Considerations
WARN_ON_ONCE
to catch underflows, though proper decrement by 1 should prevent negatives.Test Case: Incorrect unfreezing of parent cgroup when one of multiple frozen descendants is unfrozen.
# Create cgroups mkdir /sys/fs/cgroup/A mkdir /sys/fs/cgroup/A/B mkdir /sys/fs/cgroup/A/D mkdir /sys/fs/cgroup/A/B/C
Expected Behavior:
A
should remain frozen because its descendantD
is still frozen.B
should unfreeze (correctly) because its only descendantC
was unfrozen.Actual Behavior (with Bug):
A
incorrectly unfreezes due to over-decrement innr_frozen_descendants
.