Skip to contentSkip to conversation

mm: slab/memcg: fix build on MIPS

PATCH New Roman Gushchin 1 participant 1 message Jul 17, 2020

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

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
index 3f49e9bdbf2d..f47e9f0d42f4 100644
@@ -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
index 92a4104b22b3..6cc323f1313a 100644
@@ -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