mm: slab/memcg: fix build on MIPS
Subsystems (3)
PATCH 1/1 mm: slab/memcg: fix build on MIPS
Naresh reported that linux-next build is broken on MIPS. The problem is reproducible using gcc 8 and 9, but not 10.
make -sk KBUILD_BUILD_USER=TuxBuild -C/linux -j16 ARCH=mips CROSS_COMPILE=mips-linux-gnu- HOSTCC=gcc CC="sccache mips-linux-gnu-gcc" O=build../mm/slub.c: In function ‘slab_alloc.constprop’:../mm/slub.c:2897:30: error: inlining failed in call to always_inline ‘slab_alloc.constprop’: recursive inlining
2897 | static __always_inline void *slab_alloc(struct kmem_cache *s,
| ^~~~~~~~~~
../mm/slub.c:2905:14: note: called from here
2905 | void *ret = slab_alloc(s, gfpflags, _RET_IP_);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~../mm/slub.c: In function ‘sysfs_slab_alias’:../mm/slub.c:2897:30: error: inlining failed in call to always_inline ‘slab_alloc.constprop’: recursive inlining
2897 | static __always_inline void *slab_alloc(struct kmem_cache *s,
| ^~~~~~~~~~
../mm/slub.c:2905:14: note: called from here
2905 | void *ret = slab_alloc(s, gfpflags, _RET_IP_);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~../mm/slub.c: In function ‘sysfs_slab_add’:../mm/slub.c:2897:30: error: inlining failed in call to always_inline ‘slab_alloc.constprop’: recursive inlining
2897 | static __always_inline void *slab_alloc(struct kmem_cache *s,
| ^~~~~~~~~~
../mm/slub.c:2905:14: note: called from here
2905 | void *ret = slab_alloc(s, gfpflags, _RET_IP_);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~The problem was introduced by commit "mem: memcg/slab: use a single set of kmem_caches for all allocations", which added an allocation of the space for the obj_cgroup vector into the slab post hook and created a recursive inlining.
The easies way to fix this is to move memcg_alloc_page_obj_cgroups() to memcontrol.c and make it a generic (not static inline) function. It breaks the inlining recursion and fixes the build.
--- mm/memcontrol.c | 20 ++++++++++++++++++++ mm/slab.h | 21 ++------------------- 2 files changed, 22 insertions(+), 19 deletions(-)
mm/memcontrol.c +20 -0
@@ -2831,6 +2831,26 @@ static void commit_charge(struct page *page, struct mem_cgroup *memcg) }#ifdef CONFIG_MEMCG_KMEM +int memcg_alloc_page_obj_cgroups (struct page *page,struct kmem_cache *s, +gfp_t gfp) +{ +unsigned int objects =objs_per_slab_page (s, page); +void *vec; + + vec =kcalloc_node (objects,sizeof (struct obj_cgroup *), gfp, +page_to_nid (page)); +if (!vec) +return -ENOMEM ; + +if (cmpxchg (&page->obj_cgroups,NULL , + (struct obj_cgroup **) ((unsigned long )vec |0x1UL ))) +kfree (vec); +else +kmemleak_not_leak (vec); + +return 0 ; +} +/* * Returns a pointer to the memory cgroup to which the kernel object is charged. *
mm/slab.h +2 -19
@@ -257,25 +257,8 @@ static inline bool page_has_obj_cgroups(struct page *page)return ((unsigned long )page->obj_cgroups &0x1UL ); } -static inline int memcg_alloc_page_obj_cgroups (struct page *page, -struct kmem_cache *s,gfp_t gfp) -{ -unsigned int objects =objs_per_slab_page (s, page); -void *vec; - - vec =kcalloc_node (objects,sizeof (struct obj_cgroup *), gfp, -page_to_nid (page)); -if (!vec) -return -ENOMEM ; - -if (cmpxchg (&page->obj_cgroups,NULL , - (struct obj_cgroup **) ((unsigned long )vec |0x1UL ))) -kfree (vec); -else -kmemleak_not_leak (vec); - -return 0 ; -} +int memcg_alloc_page_obj_cgroups (struct page *page,struct kmem_cache *s, +gfp_t gfp);static inline void memcg_free_page_obj_cgroups (struct page *page) {
Signature · 1 line
2.26.2