From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Christoph Lameter <cl@linux-foundation.org>,
Peter Zijlstra <peterz@infradead.org>,
linux-mm@kvack.org, mpm@selenic.com,
LKML <linux-kernel@vger.kernel.org>,
Nick Piggin <npiggin@suse.de>
Subject: Re: lockdep complaints in slab allocator
Date: Mon, 23 Nov 2009 12:57:32 -0800 [thread overview]
Message-ID: <20091123205732.GE6774@linux.vnet.ibm.com> (raw)
In-Reply-To: <1259006475.15619.16.camel@penberg-laptop>
On Mon, Nov 23, 2009 at 10:01:15PM +0200, Pekka Enberg wrote:
> On Mon, 2009-11-23 at 21:50 +0200, Pekka Enberg wrote:
> > On Mon, 23 Nov 2009, Pekka Enberg wrote:
> > > > That turns out to be _very_ hard. How about something like the following
> > > > untested patch which delays slab_destroy() while we're under nc->lock.
> >
> > On Mon, 2009-11-23 at 13:30 -0600, Christoph Lameter wrote:
> > > Code changes to deal with a diagnostic issue?
> >
> > OK, fair enough. If I suffer permanent brain damage from staring at the
> > SLAB code for too long, I hope you and Matt will chip in to pay for my
> > medication.
> >
> > I think I was looking at the wrong thing here. The problem is in
> > cache_free_alien() so the comment in slab_destroy() isn't relevant.
> > Looking at init_lock_keys() we already do special lockdep annotations
> > but there's a catch (as explained in a comment on top of
> > on_slab_alc_key):
> >
> > * We set lock class for alien array caches which are up during init.
> > * The lock annotation will be lost if all cpus of a node goes down and
> > * then comes back up during hotplug
> >
> > Paul said he was running CPU hotplug so maybe that explains the problem?
>
> Maybe something like this untested patch fixes the issue...
I will give it a go!
Thanx, Paul
> Pekka
>
> diff --git a/mm/slab.c b/mm/slab.c
> index 7dfa481..84de47e 100644
> --- a/mm/slab.c
> +++ b/mm/slab.c
> @@ -604,6 +604,26 @@ static struct kmem_cache cache_cache = {
>
> #define BAD_ALIEN_MAGIC 0x01020304ul
>
> +/*
> + * chicken and egg problem: delay the per-cpu array allocation
> + * until the general caches are up.
> + */
> +static enum {
> + NONE,
> + PARTIAL_AC,
> + PARTIAL_L3,
> + EARLY,
> + FULL
> +} g_cpucache_up;
> +
> +/*
> + * used by boot code to determine if it can use slab based allocator
> + */
> +int slab_is_available(void)
> +{
> + return g_cpucache_up >= EARLY;
> +}
> +
> #ifdef CONFIG_LOCKDEP
>
> /*
> @@ -620,40 +640,52 @@ static struct kmem_cache cache_cache = {
> static struct lock_class_key on_slab_l3_key;
> static struct lock_class_key on_slab_alc_key;
>
> -static inline void init_lock_keys(void)
> -
> +static void init_node_lock_keys(int q)
> {
> - int q;
> struct cache_sizes *s = malloc_sizes;
>
> - while (s->cs_size != ULONG_MAX) {
> - for_each_node(q) {
> - struct array_cache **alc;
> - int r;
> - struct kmem_list3 *l3 = s->cs_cachep->nodelists[q];
> - if (!l3 || OFF_SLAB(s->cs_cachep))
> - continue;
> - lockdep_set_class(&l3->list_lock, &on_slab_l3_key);
> - alc = l3->alien;
> - /*
> - * FIXME: This check for BAD_ALIEN_MAGIC
> - * should go away when common slab code is taught to
> - * work even without alien caches.
> - * Currently, non NUMA code returns BAD_ALIEN_MAGIC
> - * for alloc_alien_cache,
> - */
> - if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC)
> - continue;
> - for_each_node(r) {
> - if (alc[r])
> - lockdep_set_class(&alc[r]->lock,
> - &on_slab_alc_key);
> - }
> + if (g_cpucache_up != FULL)
> + return;
> +
> + for (s = malloc_sizes; s->cs_size != ULONG_MAX; s++) {
> + struct array_cache **alc;
> + struct kmem_list3 *l3;
> + int r;
> +
> + l3 = s->cs_cachep->nodelists[q];
> + if (!l3 || OFF_SLAB(s->cs_cachep))
> + return;
> + lockdep_set_class(&l3->list_lock, &on_slab_l3_key);
> + alc = l3->alien;
> + /*
> + * FIXME: This check for BAD_ALIEN_MAGIC
> + * should go away when common slab code is taught to
> + * work even without alien caches.
> + * Currently, non NUMA code returns BAD_ALIEN_MAGIC
> + * for alloc_alien_cache,
> + */
> + if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC)
> + return;
> + for_each_node(r) {
> + if (alc[r])
> + lockdep_set_class(&alc[r]->lock,
> + &on_slab_alc_key);
> }
> - s++;
> }
> }
> +
> +static inline void init_lock_keys(void)
> +{
> + int node;
> +
> + for_each_node(node)
> + init_node_lock_keys(node);
> +}
> #else
> +static void init_node_lock_keys(int q)
> +{
> +}
> +
> static inline void init_lock_keys(void)
> {
> }
> @@ -665,26 +697,6 @@ static inline void init_lock_keys(void)
> static DEFINE_MUTEX(cache_chain_mutex);
> static struct list_head cache_chain;
>
> -/*
> - * chicken and egg problem: delay the per-cpu array allocation
> - * until the general caches are up.
> - */
> -static enum {
> - NONE,
> - PARTIAL_AC,
> - PARTIAL_L3,
> - EARLY,
> - FULL
> -} g_cpucache_up;
> -
> -/*
> - * used by boot code to determine if it can use slab based allocator
> - */
> -int slab_is_available(void)
> -{
> - return g_cpucache_up >= EARLY;
> -}
> -
> static DEFINE_PER_CPU(struct delayed_work, reap_work);
>
> static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep)
> @@ -1254,6 +1266,8 @@ static int __cpuinit cpuup_prepare(long cpu)
> kfree(shared);
> free_alien_cache(alien);
> }
> + init_node_lock_keys(node);
> +
> return 0;
> bad:
> cpuup_canceled(cpu);
>
>
WARNING: multiple messages have this Message-ID (diff)
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Christoph Lameter <cl@linux-foundation.org>,
Peter Zijlstra <peterz@infradead.org>,
linux-mm@kvack.org, mpm@selenic.com,
LKML <linux-kernel@vger.kernel.org>,
Nick Piggin <npiggin@suse.de>
Subject: Re: lockdep complaints in slab allocator
Date: Mon, 23 Nov 2009 12:57:32 -0800 [thread overview]
Message-ID: <20091123205732.GE6774@linux.vnet.ibm.com> (raw)
In-Reply-To: <1259006475.15619.16.camel@penberg-laptop>
On Mon, Nov 23, 2009 at 10:01:15PM +0200, Pekka Enberg wrote:
> On Mon, 2009-11-23 at 21:50 +0200, Pekka Enberg wrote:
> > On Mon, 23 Nov 2009, Pekka Enberg wrote:
> > > > That turns out to be _very_ hard. How about something like the following
> > > > untested patch which delays slab_destroy() while we're under nc->lock.
> >
> > On Mon, 2009-11-23 at 13:30 -0600, Christoph Lameter wrote:
> > > Code changes to deal with a diagnostic issue?
> >
> > OK, fair enough. If I suffer permanent brain damage from staring at the
> > SLAB code for too long, I hope you and Matt will chip in to pay for my
> > medication.
> >
> > I think I was looking at the wrong thing here. The problem is in
> > cache_free_alien() so the comment in slab_destroy() isn't relevant.
> > Looking at init_lock_keys() we already do special lockdep annotations
> > but there's a catch (as explained in a comment on top of
> > on_slab_alc_key):
> >
> > * We set lock class for alien array caches which are up during init.
> > * The lock annotation will be lost if all cpus of a node goes down and
> > * then comes back up during hotplug
> >
> > Paul said he was running CPU hotplug so maybe that explains the problem?
>
> Maybe something like this untested patch fixes the issue...
I will give it a go!
Thanx, Paul
> Pekka
>
> diff --git a/mm/slab.c b/mm/slab.c
> index 7dfa481..84de47e 100644
> --- a/mm/slab.c
> +++ b/mm/slab.c
> @@ -604,6 +604,26 @@ static struct kmem_cache cache_cache = {
>
> #define BAD_ALIEN_MAGIC 0x01020304ul
>
> +/*
> + * chicken and egg problem: delay the per-cpu array allocation
> + * until the general caches are up.
> + */
> +static enum {
> + NONE,
> + PARTIAL_AC,
> + PARTIAL_L3,
> + EARLY,
> + FULL
> +} g_cpucache_up;
> +
> +/*
> + * used by boot code to determine if it can use slab based allocator
> + */
> +int slab_is_available(void)
> +{
> + return g_cpucache_up >= EARLY;
> +}
> +
> #ifdef CONFIG_LOCKDEP
>
> /*
> @@ -620,40 +640,52 @@ static struct kmem_cache cache_cache = {
> static struct lock_class_key on_slab_l3_key;
> static struct lock_class_key on_slab_alc_key;
>
> -static inline void init_lock_keys(void)
> -
> +static void init_node_lock_keys(int q)
> {
> - int q;
> struct cache_sizes *s = malloc_sizes;
>
> - while (s->cs_size != ULONG_MAX) {
> - for_each_node(q) {
> - struct array_cache **alc;
> - int r;
> - struct kmem_list3 *l3 = s->cs_cachep->nodelists[q];
> - if (!l3 || OFF_SLAB(s->cs_cachep))
> - continue;
> - lockdep_set_class(&l3->list_lock, &on_slab_l3_key);
> - alc = l3->alien;
> - /*
> - * FIXME: This check for BAD_ALIEN_MAGIC
> - * should go away when common slab code is taught to
> - * work even without alien caches.
> - * Currently, non NUMA code returns BAD_ALIEN_MAGIC
> - * for alloc_alien_cache,
> - */
> - if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC)
> - continue;
> - for_each_node(r) {
> - if (alc[r])
> - lockdep_set_class(&alc[r]->lock,
> - &on_slab_alc_key);
> - }
> + if (g_cpucache_up != FULL)
> + return;
> +
> + for (s = malloc_sizes; s->cs_size != ULONG_MAX; s++) {
> + struct array_cache **alc;
> + struct kmem_list3 *l3;
> + int r;
> +
> + l3 = s->cs_cachep->nodelists[q];
> + if (!l3 || OFF_SLAB(s->cs_cachep))
> + return;
> + lockdep_set_class(&l3->list_lock, &on_slab_l3_key);
> + alc = l3->alien;
> + /*
> + * FIXME: This check for BAD_ALIEN_MAGIC
> + * should go away when common slab code is taught to
> + * work even without alien caches.
> + * Currently, non NUMA code returns BAD_ALIEN_MAGIC
> + * for alloc_alien_cache,
> + */
> + if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC)
> + return;
> + for_each_node(r) {
> + if (alc[r])
> + lockdep_set_class(&alc[r]->lock,
> + &on_slab_alc_key);
> }
> - s++;
> }
> }
> +
> +static inline void init_lock_keys(void)
> +{
> + int node;
> +
> + for_each_node(node)
> + init_node_lock_keys(node);
> +}
> #else
> +static void init_node_lock_keys(int q)
> +{
> +}
> +
> static inline void init_lock_keys(void)
> {
> }
> @@ -665,26 +697,6 @@ static inline void init_lock_keys(void)
> static DEFINE_MUTEX(cache_chain_mutex);
> static struct list_head cache_chain;
>
> -/*
> - * chicken and egg problem: delay the per-cpu array allocation
> - * until the general caches are up.
> - */
> -static enum {
> - NONE,
> - PARTIAL_AC,
> - PARTIAL_L3,
> - EARLY,
> - FULL
> -} g_cpucache_up;
> -
> -/*
> - * used by boot code to determine if it can use slab based allocator
> - */
> -int slab_is_available(void)
> -{
> - return g_cpucache_up >= EARLY;
> -}
> -
> static DEFINE_PER_CPU(struct delayed_work, reap_work);
>
> static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep)
> @@ -1254,6 +1266,8 @@ static int __cpuinit cpuup_prepare(long cpu)
> kfree(shared);
> free_alien_cache(alien);
> }
> + init_node_lock_keys(node);
> +
> return 0;
> bad:
> cpuup_canceled(cpu);
>
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2009-11-23 20:57 UTC|newest]
Thread overview: 121+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-18 18:12 lockdep complaints in slab allocator Paul E. McKenney
2009-11-20 6:49 ` Pekka Enberg
2009-11-20 6:49 ` Pekka Enberg
2009-11-20 9:25 ` Peter Zijlstra
2009-11-20 9:25 ` Peter Zijlstra
2009-11-20 10:38 ` Pekka Enberg
2009-11-20 10:38 ` Pekka Enberg
2009-11-20 10:52 ` Peter Zijlstra
2009-11-20 10:52 ` Peter Zijlstra
2009-11-20 11:05 ` Pekka Enberg
2009-11-20 11:05 ` Pekka Enberg
2009-11-20 14:48 ` Paul E. McKenney
2009-11-20 14:48 ` Paul E. McKenney
2009-11-20 15:17 ` Peter Zijlstra
2009-11-20 15:17 ` Peter Zijlstra
2009-11-20 16:25 ` Paul E. McKenney
2009-11-20 16:25 ` Paul E. McKenney
2009-11-20 15:09 ` Peter Zijlstra
2009-11-20 15:09 ` Peter Zijlstra
2009-11-23 19:00 ` Pekka Enberg
2009-11-23 19:00 ` Pekka Enberg
2009-11-23 19:10 ` Matt Mackall
2009-11-23 19:10 ` Matt Mackall
2009-11-23 19:13 ` Pekka Enberg
2009-11-23 19:13 ` Pekka Enberg
2009-11-24 16:33 ` Peter Zijlstra
2009-11-24 16:33 ` Peter Zijlstra
2009-11-24 17:00 ` Paul E. McKenney
2009-11-24 17:00 ` Paul E. McKenney
2009-11-24 17:12 ` Matt Mackall
2009-11-24 17:12 ` Matt Mackall
2009-11-24 17:58 ` Paul E. McKenney
2009-11-24 17:58 ` Paul E. McKenney
2009-11-24 18:14 ` Peter Zijlstra
2009-11-24 18:14 ` Peter Zijlstra
2009-11-24 18:25 ` Paul E. McKenney
2009-11-24 18:25 ` Paul E. McKenney
2009-11-24 18:31 ` Peter Zijlstra
2009-11-24 18:31 ` Peter Zijlstra
2009-11-24 18:53 ` Christoph Lameter
2009-11-24 18:53 ` Christoph Lameter
2009-11-24 18:54 ` Paul E. McKenney
2009-11-24 18:54 ` Paul E. McKenney
2009-11-24 19:23 ` Matt Mackall
2009-11-24 19:23 ` Matt Mackall
2009-11-24 19:50 ` Paul E. McKenney
2009-11-24 19:50 ` Paul E. McKenney
2009-11-24 20:46 ` Peter Zijlstra
2009-11-24 20:46 ` Peter Zijlstra
2009-11-24 20:53 ` Matt Mackall
2009-11-24 20:53 ` Matt Mackall
2009-11-24 21:01 ` Peter Zijlstra
2009-11-24 21:01 ` Peter Zijlstra
2009-11-24 21:03 ` David Rientjes
2009-11-24 21:03 ` David Rientjes
2009-11-24 21:12 ` Peter Zijlstra
2009-11-24 21:12 ` Peter Zijlstra
2009-11-24 21:19 ` Pekka Enberg
2009-11-24 21:19 ` Pekka Enberg
2009-11-24 21:22 ` David Rientjes
2009-11-24 21:22 ` David Rientjes
2009-11-24 21:35 ` Peter Zijlstra
2009-11-24 21:35 ` Peter Zijlstra
2009-11-24 21:46 ` David Rientjes
2009-11-24 21:46 ` David Rientjes
2009-11-24 22:23 ` Paul E. McKenney
2009-11-24 22:23 ` Paul E. McKenney
2009-11-25 7:12 ` Pekka Enberg
2009-11-25 7:12 ` Pekka Enberg
2009-11-25 7:25 ` Pekka Enberg
2009-11-25 7:25 ` Pekka Enberg
2009-11-27 17:22 ` Christoph Lameter
2009-11-27 17:22 ` Christoph Lameter
2009-11-24 21:48 ` Paul E. McKenney
2009-11-24 21:48 ` Paul E. McKenney
2009-11-24 21:16 ` Pekka Enberg
2009-11-24 21:16 ` Pekka Enberg
2009-11-24 21:07 ` Pekka Enberg
2009-11-24 21:07 ` Pekka Enberg
2009-11-24 22:55 ` Matt Mackall
2009-11-24 22:55 ` Matt Mackall
2009-11-25 21:59 ` David Rientjes
2009-11-25 21:59 ` David Rientjes
2009-11-25 23:06 ` Matt Mackall
2009-11-25 23:06 ` Matt Mackall
2009-11-27 17:28 ` Christoph Lameter
2009-11-27 17:28 ` Christoph Lameter
2009-11-30 23:14 ` David Rientjes
2009-11-30 23:14 ` David Rientjes
2009-12-01 0:21 ` Matt Mackall
2009-12-01 0:21 ` Matt Mackall
2009-12-01 22:41 ` David Rientjes
2009-12-01 22:41 ` David Rientjes
2009-12-01 16:47 ` Christoph Lameter
2009-12-01 16:47 ` Christoph Lameter
2009-11-27 17:26 ` Christoph Lameter
2009-11-27 17:26 ` Christoph Lameter
2009-11-23 19:30 ` Christoph Lameter
2009-11-23 19:30 ` Christoph Lameter
2009-11-23 19:43 ` Paul E. McKenney
2009-11-23 19:43 ` Paul E. McKenney
2009-11-23 19:50 ` Pekka Enberg
2009-11-23 19:50 ` Pekka Enberg
2009-11-23 20:01 ` Pekka Enberg
2009-11-23 20:01 ` Pekka Enberg
2009-11-23 20:57 ` Paul E. McKenney [this message]
2009-11-23 20:57 ` Paul E. McKenney
2009-11-23 21:01 ` Matt Mackall
2009-11-23 21:01 ` Matt Mackall
2009-11-24 16:23 ` Paul E. McKenney
2009-11-24 16:23 ` Paul E. McKenney
2009-11-24 20:59 ` Pekka Enberg
2009-11-24 20:59 ` Pekka Enberg
2009-11-24 21:26 ` Peter Zijlstra
2009-11-24 21:26 ` Peter Zijlstra
2009-11-25 10:42 ` Pekka Enberg
2009-11-25 10:42 ` Pekka Enberg
2009-11-24 21:47 ` Paul E. McKenney
2009-11-24 21:47 ` Paul E. McKenney
2009-11-30 16:18 ` Paul E. McKenney
2009-11-30 16:18 ` Paul E. McKenney
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=20091123205732.GE6774@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=cl@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mpm@selenic.com \
--cc=npiggin@suse.de \
--cc=penberg@cs.helsinki.fi \
--cc=peterz@infradead.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.