All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Vlastimil Babka <vbabka@suse.cz>, Roman Gushchin <guro@fb.com>,
	Christoph Lameter <cl@linux.com>,
	Pekka Enberg <penberg@kernel.org>,
	David Rientjes <rientjes@google.com>,
	Joonsoo Kim <iamjoonsoo.kim@lge.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	kernel-team@android.com, vinmenon@codeaurora.org,
	Matthew Garrett <mjg59@google.com>, Jann Horn <jannh@google.com>,
	Vijayanand Jitta <vjitta@codeaurora.org>
Subject: Re: [PATCH 9/9] mm, slab/slub: move and improve cache_from_obj()
Date: Fri, 19 Jun 2020 12:02:47 -0700	[thread overview]
Message-ID: <202006191201.C30D8AAFB@keescook> (raw)
In-Reply-To: <20200618200553.GE110603@carbon.dhcp.thefacebook.com>

On Thu, Jun 18, 2020 at 01:05:53PM -0700, Roman Gushchin wrote:
> On Thu, Jun 18, 2020 at 12:10:38PM +0200, Vlastimil Babka wrote:
> > To prvent the churn of your patch moving the cache_from_obj() back to slab.h, I
> > think it's best if we modify my patch. The patch below should be squashed into
> > the current version in mmots, with the commit log used for the whole result.
> > 
> > This will cause conflicts while reapplying Roman's
> > mm-memcg-slab-use-a-single-set-of-kmem_caches-for-all-allocations.patch which
> > can be fixed by
> > a) throwing away the conflicting hunks for cache_from_obj() in slab.c and slub.c
> > b) applying this hunk instead:
> > 
> > --- a/mm/slab.h
> > +++ b/mm/slab.h
> > @@ -455,12 +455,11 @@ 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),
> > +	if (WARN(cachep && cachep != s,
> >  		  "%s: Wrong slab cache. %s but object is from %s\n",
> >  		  __func__, s->name, cachep->name))
> >  		print_tracking(cachep, x);
> > 
> > The fixup patch itself:
> > ----8<----
> > From b8df607d92b37e5329ce7bda62b2b364cc249893 Mon Sep 17 00:00:00 2001
> > From: Vlastimil Babka <vbabka@suse.cz>
> > Date: Thu, 18 Jun 2020 11:52:03 +0200
> > Subject: [PATCH] mm, slab/slub: improve error reporting and overhead of
> >  cache_from_obj()

Andrew, do you need this separately, or can you extract this fixup from
this thread?

-Kees

> > 
> > The function cache_from_obj() was added by commit b9ce5ef49f00 ("sl[au]b:
> > always get the cache from its page in kmem_cache_free()") to support
> > kmemcg, where per-memcg cache can be different from the root one, so we
> > can't use the kmem_cache pointer given to kmem_cache_free().
> > 
> > Prior to that commit, SLUB already had debugging check+warning that could
> > be enabled to compare the given kmem_cache pointer to one referenced by
> > the slab page where the object-to-be-freed resides.  This check was moved
> > to cache_from_obj().  Later the check was also enabled for
> > SLAB_FREELIST_HARDENED configs by commit 598a0717a816 ("mm/slab: validate
> > cache membership under freelist hardening").
> > 
> > These checks and warnings can be useful especially for the debugging,
> > which can be improved.  Commit 598a0717a816 changed the pr_err() with
> > WARN_ON_ONCE() to WARN_ONCE() so only the first hit is now reported,
> > others are silent.  This patch changes it to WARN() so that all errors are
> > reported.
> > 
> > It's also useful to print SLUB allocation/free tracking info for the offending
> > object, if tracking is enabled. Thus, export the SLUB print_tracking() function
> > and provide an empty one for SLAB.
> > 
> > For SLUB we can also benefit from the static key check in
> > kmem_cache_debug_flags(), but we need to move this function to slab.h and
> > declare the static key there.
> > 
> > [1] https://lore.kernel.org/r/20200608230654.828134-18-guro@fb.com
> > 
> > Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
> 
> Acked-by: Roman Gushchin <guro@fb.com>
> 
> Thanks!
> 
> > ---
> >  mm/slab.c |  8 --------
> >  mm/slab.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
> >  mm/slub.c | 38 +-------------------------------------
> >  3 files changed, 46 insertions(+), 45 deletions(-)
> > 
> > diff --git a/mm/slab.c b/mm/slab.c
> > index 6134c4c36d4c..9350062ffc1a 100644
> > --- a/mm/slab.c
> > +++ b/mm/slab.c
> > @@ -3672,14 +3672,6 @@ 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 a2696d306b62..a9f5ba9ce9a7 100644
> > --- a/mm/slab.h
> > +++ b/mm/slab.h
> > @@ -275,6 +275,34 @@ static inline int cache_vmstat_idx(struct kmem_cache *s)
> >  		NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE;
> >  }
> >  
> > +#ifdef CONFIG_SLUB_DEBUG
> > +#ifdef CONFIG_SLUB_DEBUG_ON
> > +DECLARE_STATIC_KEY_TRUE(slub_debug_enabled);
> > +#else
> > +DECLARE_STATIC_KEY_FALSE(slub_debug_enabled);
> > +#endif
> > +extern void print_tracking(struct kmem_cache *s, void *object);
> > +#else
> > +static inline void print_tracking(struct kmem_cache *s, void *object)
> > +{
> > +}
> > +#endif
> > +
> > +/*
> > + * Returns true if any of the specified slub_debug flags is enabled for the
> > + * cache. Use only for flags parsed by setup_slub_debug() as it also enables
> > + * the static key.
> > + */
> > +static inline bool kmem_cache_debug_flags(struct kmem_cache *s, slab_flags_t flags)
> > +{
> > +	VM_WARN_ON_ONCE(!(flags & SLAB_DEBUG_FLAGS));
> > +#ifdef CONFIG_SLUB_DEBUG
> > +	if (static_branch_unlikely(&slub_debug_enabled))
> > +		return s->flags & flags;
> > +#endif
> > +	return false;
> > +}
> > +
> >  #ifdef CONFIG_MEMCG_KMEM
> >  
> >  /* List of all root caches. */
> > @@ -503,6 +531,23 @@ 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;
> > +
> > +	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;
> > +}
> > +
> >  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 202fb423d195..0e635a8aa340 100644
> > --- a/mm/slub.c
> > +++ b/mm/slub.c
> > @@ -122,21 +122,6 @@ DEFINE_STATIC_KEY_FALSE(slub_debug_enabled);
> >  #endif
> >  #endif
> >  
> > -/*
> > - * Returns true if any of the specified slub_debug flags is enabled for the
> > - * cache. Use only for flags parsed by setup_slub_debug() as it also enables
> > - * the static key.
> > - */
> > -static inline bool kmem_cache_debug_flags(struct kmem_cache *s, slab_flags_t flags)
> > -{
> > -	VM_WARN_ON_ONCE(!(flags & SLAB_DEBUG_FLAGS));
> > -#ifdef CONFIG_SLUB_DEBUG
> > -	if (static_branch_unlikely(&slub_debug_enabled))
> > -		return s->flags & flags;
> > -#endif
> > -	return false;
> > -}
> > -
> >  static inline bool kmem_cache_debug(struct kmem_cache *s)
> >  {
> >  	return kmem_cache_debug_flags(s, SLAB_DEBUG_FLAGS);
> > @@ -653,7 +638,7 @@ static void print_track(const char *s, struct track *t, unsigned long pr_time)
> >  #endif
> >  }
> >  
> > -static void print_tracking(struct kmem_cache *s, void *object)
> > +void print_tracking(struct kmem_cache *s, void *object)
> >  {
> >  	unsigned long pr_time = jiffies;
> >  	if (!(s->flags & SLAB_STORE_USER))
> > @@ -1525,10 +1510,6 @@ 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 */
> >  
> >  /*
> > @@ -3180,23 +3161,6 @@ 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);
> > -- 
> > 2.27.0
> > 
> > 

-- 
Kees Cook

  reply	other threads:[~2020-06-19 19:02 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-10 16:31 [PATCH 0/9] slub_debug fixes and improvements Vlastimil Babka
2020-06-10 16:31 ` [PATCH 1/9] mm, slub: extend slub_debug syntax for multiple blocks Vlastimil Babka
2020-06-10 16:31 ` [PATCH 2/9] mm, slub: make some slub_debug related attributes read-only Vlastimil Babka
2020-06-10 16:31 ` [PATCH 3/9] mm, slub: remove runtime allocation order changes Vlastimil Babka
2020-06-10 16:31 ` [PATCH 4/9] mm, slub: make remaining slub_debug related attributes read-only Vlastimil Babka
2020-06-10 16:31 ` [PATCH 5/9] mm, slub: make reclaim_account attribute read-only Vlastimil Babka
2020-06-10 16:31 ` [PATCH 6/9] mm, slub: introduce static key for slub_debug() Vlastimil Babka
2020-06-10 21:59   ` Roman Gushchin
2020-06-17 17:54   ` Kees Cook
2020-06-10 16:31 ` [PATCH 7/9] mm, slub: introduce kmem_cache_debug_flags() Vlastimil Babka
2020-06-10 22:06   ` Roman Gushchin
2020-06-17 17:56   ` Kees Cook
2020-06-18  8:32     ` Vlastimil Babka
2020-06-18  8:37   ` Vlastimil Babka
2020-06-18 19:54     ` Roman Gushchin
2020-06-18 19:56     ` Kees Cook
2020-06-10 16:31 ` [PATCH 8/9] mm, slub: extend checks guarded by slub_debug static key Vlastimil Babka
2020-06-10 22:09   ` Roman Gushchin
2020-06-10 16:31 ` [PATCH 9/9] mm, slab/slub: move and improve cache_from_obj() Vlastimil Babka
2020-06-10 22:46   ` Roman Gushchin
2020-06-11  9:56     ` Vlastimil Babka
2020-06-11 20:04       ` Roman Gushchin
2020-06-17 17:49   ` Kees Cook
2020-06-18 10:10     ` Vlastimil Babka
2020-06-18 19:59       ` Kees Cook
2020-06-18 20:05       ` Roman Gushchin
2020-06-19 19:02         ` Kees Cook [this message]
2020-06-24  7:57       ` Vlastimil Babka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202006191201.C30D8AAFB@keescook \
    --to=keescook@chromium.org \
    --cc=akpm@linux-foundation.org \
    --cc=cl@linux.com \
    --cc=guro@fb.com \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=jannh@google.com \
    --cc=kernel-team@android.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mjg59@google.com \
    --cc=penberg@kernel.org \
    --cc=rientjes@google.com \
    --cc=vbabka@suse.cz \
    --cc=vinmenon@codeaurora.org \
    --cc=vjitta@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.