aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slub.c
diff options
context:
space:
mode:
authorVlastimil Babka <vbabka@suse.cz>2022-09-30 16:46:18 +0200
committerVlastimil Babka <vbabka@suse.cz>2022-09-30 16:46:18 +0200
commit00a7829ba8a44d720269e8a7562b51d4c68c03f7 (patch)
tree91125fe64735d66744d91fc4ed6778c3d3c82263 /mm/slub.c
parentMerge branch 'slab/for-6.1/kmalloc_size_roundup' into slab/for-next (diff)
parentmm/slub: fix a slab missed to be freed problem (diff)
downloadlinux-dev-00a7829ba8a44d720269e8a7562b51d4c68c03f7.tar.xz
linux-dev-00a7829ba8a44d720269e8a7562b51d4c68c03f7.zip
Merge branch 'slab/for-6.1/slub_validation_locking' into slab/for-next
A fix for a regression in slub_debug caches that could cause slab page leaks and subsequent warnings on cache shutdown, by Feng Tang.
Diffstat (limited to 'mm/slub.c')
-rw-r--r--mm/slub.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/mm/slub.c b/mm/slub.c
index f5ebd177293a..2a6b3f31ce7e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2881,22 +2881,25 @@ out:
set_freepointer(s, tail, prior);
slab->freelist = head;
- /* Do we need to remove the slab from full or partial list? */
+ /*
+ * If the slab is empty, and node's partial list is full,
+ * it should be discarded anyway no matter it's on full or
+ * partial list.
+ */
+ if (slab->inuse == 0 && n->nr_partial >= s->min_partial)
+ slab_free = slab;
+
if (!prior) {
+ /* was on full list */
remove_full(s, n, slab);
- } else if (slab->inuse == 0 &&
- n->nr_partial >= s->min_partial) {
+ if (!slab_free) {
+ add_partial(n, slab, DEACTIVATE_TO_TAIL);
+ stat(s, FREE_ADD_PARTIAL);
+ }
+ } else if (slab_free) {
remove_partial(n, slab);
stat(s, FREE_REMOVE_PARTIAL);
}
-
- /* Do we need to discard the slab or add to partial list? */
- if (slab->inuse == 0 && n->nr_partial >= s->min_partial) {
- slab_free = slab;
- } else if (!prior) {
- add_partial(n, slab, DEACTIVATE_TO_TAIL);
- stat(s, FREE_ADD_PARTIAL);
- }
}
if (slab_free) {