summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mm/slab.c8
-rw-r--r--mm/slab.h23
-rw-r--r--mm/slub.c21
3 files changed, 29 insertions, 23 deletions
diff --git a/mm/slab.c b/mm/slab.c
index 390e249aaa8d..af3d3887b9b8 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3678,6 +3678,14 @@ void *__kmalloc_track_caller(size_t size, gfp_t flags, unsigned long caller)
}
EXPORT_SYMBOL(__kmalloc_track_caller);
+static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
+{
+ if (memcg_kmem_enabled())
+ return virt_to_cache(x);
+ else
+ return s;
+}
+
/**
* kmem_cache_free - Deallocate an object
* @cachep: The cache the allocation was from.
diff --git a/mm/slab.h b/mm/slab.h
index 58ed025a0b23..a21c78eccee7 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -504,29 +504,6 @@ static __always_inline void uncharge_slab_page(struct page *page, int order,
memcg_uncharge_slab(page, order, s);
}
-static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
-{
- struct kmem_cache *cachep;
-
- /*
- * When kmemcg is not being used, both assignments should return the
- * same value. but we don't want to pay the assignment price in that
- * case. If it is not compiled in, the compiler should be smart enough
- * to not do even the assignment. In that case, slab_equal_or_root
- * will also be a constant.
- */
- if (!memcg_kmem_enabled() &&
- !IS_ENABLED(CONFIG_SLAB_FREELIST_HARDENED) &&
- !unlikely(s->flags & SLAB_CONSISTENCY_CHECKS))
- return s;
-
- cachep = virt_to_cache(x);
- WARN_ONCE(cachep && !slab_equal_or_root(cachep, s),
- "%s: Wrong slab cache. %s but object is from %s\n",
- __func__, s->name, cachep->name);
- return cachep;
-}
-
static inline size_t slab_ksize(const struct kmem_cache *s)
{
#ifndef CONFIG_SLUB
diff --git a/mm/slub.c b/mm/slub.c
index 0b80a8409836..6a99a3c945cb 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1525,6 +1525,10 @@ static bool freelist_corrupted(struct kmem_cache *s, struct page *page,
{
return false;
}
+
+static void print_tracking(struct kmem_cache *s, void *object)
+{
+}
#endif /* CONFIG_SLUB_DEBUG */
/*
@@ -3171,6 +3175,23 @@ void ___cache_free(struct kmem_cache *cache, void *x, unsigned long addr)
}
#endif
+static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
+{
+ struct kmem_cache *cachep;
+
+ if (!IS_ENABLED(CONFIG_SLAB_FREELIST_HARDENED) &&
+ !memcg_kmem_enabled() &&
+ !kmem_cache_debug_flags(s, SLAB_CONSISTENCY_CHECKS))
+ return s;
+
+ cachep = virt_to_cache(x);
+ if (WARN(cachep && !slab_equal_or_root(cachep, s),
+ "%s: Wrong slab cache. %s but object is from %s\n",
+ __func__, s->name, cachep->name))
+ print_tracking(cachep, x);
+ return cachep;
+}
+
void kmem_cache_free(struct kmem_cache *s, void *x)
{
s = cache_from_obj(s, x);