Skip to content

Commit 221ec5c

Browse files
rgushchintorvalds
authored andcommitted
mm: slab: make page_cgroup_ino() to recognize non-compound slab pages properly
page_cgroup_ino() doesn't return a valid memcg pointer for non-compound slab pages, because it depends on PgHead AND PgSlab flags to be set to determine the memory cgroup from the kmem_cache. It's correct for compound pages, but not for generic small pages. Those don't have PgHead set, so it ends up returning zero. Fix this by replacing the condition to PageSlab() && !PageTail(). Before this patch: [root@localhost ~]# ./page-types -c /sys/fs/cgroup/user.slice/user-0.slice/[email protected]/ | grep slab 0x0000000000000080 38 0 _______S___________________________________ slab After this patch: [root@localhost ~]# ./page-types -c /sys/fs/cgroup/user.slice/user-0.slice/[email protected]/ | grep slab 0x0000000000000080 147 0 _______S___________________________________ slab Also, hwpoison_filter_task() uses output of page_cgroup_ino() in order to filter error injection events based on memcg. So if page_cgroup_ino() fails to return memcg pointer, we just fail to inject memory error. Considering that hwpoison filter is for testing, affected users are limited and the impact should be marginal. [[email protected]: changelog additions] Link: http://lkml.kernel.org/r/[email protected] Fixes: 4d96ba3 ("mm: memcg/slab: stop setting page->mem_cgroup pointer for slab pages") Signed-off-by: Roman Gushchin <[email protected]> Reviewed-by: Shakeel Butt <[email protected]> Acked-by: David Rientjes <[email protected]> Cc: Vladimir Davydov <[email protected]> Cc: Daniel Jordan <[email protected]> Cc: Naoya Horiguchi <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 6981b76 commit 221ec5c

File tree

2 files changed

+3
-3
lines changed

2 files changed

+3
-3
lines changed

mm/memcontrol.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ ino_t page_cgroup_ino(struct page *page)
484484
unsigned long ino = 0;
485485

486486
rcu_read_lock();
487-
if (PageHead(page) && PageSlab(page))
487+
if (PageSlab(page) && !PageTail(page))
488488
memcg = memcg_from_slab_page(page);
489489
else
490490
memcg = READ_ONCE(page->mem_cgroup);

mm/slab.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,8 @@ static inline struct kmem_cache *memcg_root_cache(struct kmem_cache *s)
323323
* Expects a pointer to a slab page. Please note, that PageSlab() check
324324
* isn't sufficient, as it returns true also for tail compound slab pages,
325325
* which do not have slab_cache pointer set.
326-
* So this function assumes that the page can pass PageHead() and PageSlab()
327-
* checks.
326+
* So this function assumes that the page can pass PageSlab() && !PageTail()
327+
* check.
328328
*
329329
* The kmem_cache can be reparented asynchronously. The caller must ensure
330330
* the memcg lifetime, e.g. by taking rcu_read_lock() or cgroup_mutex.

0 commit comments

Comments
 (0)