Skip to content

Commit 48cc56e

Browse files
committed
mm: page_counter: mitigate consequences of a page_counter underflow
jira LE-802 bugfix page_counter_underflow commit 9317d0f When the unsigned page_counter underflows, even just by a few pages, a cgroup will not be able to run anything afterwards and trigger the OOM killer in a loop. Underflows shouldn't happen, but when they do in practice, we may just be off by a small amount that doesn't interfere with the normal operation - consequences don't need to be that dire. Reset the page_counter to 0 upon underflow. We'll issue a warning that the accounting will be off and then try to keep limping along. [ We used to do this with the original res_counter, where it was a more straight-forward correction inside the spinlock section. I didn't carry it forward into the lockless page counters for simplicity, but it turns out this is quite useful in practice. ] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Johannes Weiner <[email protected]> Acked-by: Michal Hocko <[email protected]> Acked-by: Chris Down <[email protected]> Reviewed-by: Shakeel Butt <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Roman Gushchin <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> (cherry picked from commit 9317d0f) Signed-off-by: Jonathan Maple <[email protected]>
1 parent bf4fc49 commit 48cc56e

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

mm/page_counter.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,13 @@ void page_counter_cancel(struct page_counter *counter, unsigned long nr_pages)
5151
long new;
5252

5353
new = atomic_long_sub_return(nr_pages, &counter->usage);
54-
propagate_protected_usage(counter, new);
5554
/* More uncharges than charges? */
56-
WARN_ON_ONCE(new < 0);
55+
if (WARN_ONCE(new < 0, "page_counter underflow: %ld nr_pages=%lu\n",
56+
new, nr_pages)) {
57+
new = 0;
58+
atomic_long_set(&counter->usage, new);
59+
}
60+
propagate_protected_usage(counter, new);
5761
}
5862

5963
/**

0 commit comments

Comments
 (0)