Commit fa981992 authored by Nick Piggin's avatar Nick Piggin Committed by Pekka Enberg

slqb: fix deadlock

Fix the lockdep error reported by Fengguang where down_read slqb_lock
is taken twice when reading /proc/slabinfo, with the possibility for a
deadlock.
Reported-by: default avatarWu Fengguang <fengguang.wu@intel.com>
Tested-by: default avatarWu Fengguang <fengguang.wu@intel.com>
Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Signed-off-by: default avatarPekka Enberg <penberg@cs.helsinki.fi>
parent d9ec0d66
...@@ -3079,7 +3079,9 @@ static void __gather_stats(void *arg) ...@@ -3079,7 +3079,9 @@ static void __gather_stats(void *arg)
spin_unlock(&gather->lock); spin_unlock(&gather->lock);
} }
static void gather_stats(struct kmem_cache *s, struct stats_gather *stats) /* must be called with slqb_lock held */
static void gather_stats_locked(struct kmem_cache *s,
struct stats_gather *stats)
{ {
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
int node; int node;
...@@ -3089,8 +3091,6 @@ static void gather_stats(struct kmem_cache *s, struct stats_gather *stats) ...@@ -3089,8 +3091,6 @@ static void gather_stats(struct kmem_cache *s, struct stats_gather *stats)
stats->s = s; stats->s = s;
spin_lock_init(&stats->lock); spin_lock_init(&stats->lock);
down_read(&slqb_lock); /* hold off hotplug */
on_each_cpu(__gather_stats, stats, 1); on_each_cpu(__gather_stats, stats, 1);
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
...@@ -3119,10 +3119,15 @@ static void gather_stats(struct kmem_cache *s, struct stats_gather *stats) ...@@ -3119,10 +3119,15 @@ static void gather_stats(struct kmem_cache *s, struct stats_gather *stats)
} }
#endif #endif
up_read(&slqb_lock);
stats->nr_objects = stats->nr_slabs * s->objects; stats->nr_objects = stats->nr_slabs * s->objects;
} }
static void gather_stats(struct kmem_cache *s, struct stats_gather *stats)
{
down_read(&slqb_lock); /* hold off hotplug */
gather_stats_locked(s, stats);
up_read(&slqb_lock);
}
#endif #endif
/* /*
...@@ -3175,7 +3180,7 @@ static int s_show(struct seq_file *m, void *p) ...@@ -3175,7 +3180,7 @@ static int s_show(struct seq_file *m, void *p)
s = list_entry(p, struct kmem_cache, list); s = list_entry(p, struct kmem_cache, list);
gather_stats(s, &stats); gather_stats_locked(s, &stats);
seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", s->name, stats.nr_inuse, seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", s->name, stats.nr_inuse,
stats.nr_objects, s->size, s->objects, (1 << s->order)); stats.nr_objects, s->size, s->objects, (1 << s->order));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment