Skip to content

Commit 825bccd

Browse files
shakeelbgregkh
authored andcommitted
memcg: slub: fix SUnreclaim for post charged objects
commit b7ffecb upstream. Large kmalloc directly allocates from the page allocator and then use lruvec_stat_mod_folio() to increment the unreclaimable slab stats for global and memcg. However when post memcg charging of slab objects was added in commit 9028cde ("memcg: add charging of already allocated slab objects"), it missed to correctly handle the unreclaimable slab stats for memcg. One user visisble effect of that bug is that the node level unreclaimable slab stat will work correctly but the memcg level stat can underflow as kernel correctly handles the free path but the charge path missed to increment the memcg level unreclaimable slab stat. Let's fix by correctly handle in the post charge code path. Fixes: 9028cde ("memcg: add charging of already allocated slab objects") Signed-off-by: Shakeel Butt <[email protected]> Cc: <[email protected]> Signed-off-by: Vlastimil Babka <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 6e564f2 commit 825bccd

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

mm/slub.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,9 +2199,24 @@ bool memcg_slab_post_charge(void *p, gfp_t flags)
21992199

22002200
folio = virt_to_folio(p);
22012201
if (!folio_test_slab(folio)) {
2202-
return folio_memcg_kmem(folio) ||
2203-
(__memcg_kmem_charge_page(folio_page(folio, 0), flags,
2204-
folio_order(folio)) == 0);
2202+
int size;
2203+
2204+
if (folio_memcg_kmem(folio))
2205+
return true;
2206+
2207+
if (__memcg_kmem_charge_page(folio_page(folio, 0), flags,
2208+
folio_order(folio)))
2209+
return false;
2210+
2211+
/*
2212+
* This folio has already been accounted in the global stats but
2213+
* not in the memcg stats. So, subtract from the global and use
2214+
* the interface which adds to both global and memcg stats.
2215+
*/
2216+
size = folio_size(folio);
2217+
node_stat_mod_folio(folio, NR_SLAB_UNRECLAIMABLE_B, -size);
2218+
lruvec_stat_mod_folio(folio, NR_SLAB_UNRECLAIMABLE_B, size);
2219+
return true;
22052220
}
22062221

22072222
slab = folio_slab(folio);

0 commit comments

Comments
 (0)