From: Heiko Carstens Date: Fri, 14 Nov 2008 17:18:07 +0000 (+0100) Subject: [S390] cpu topology: fix locking X-Git-Tag: v2.6.28-rc5~8^2~2 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=74af283102b358b0da545460d0d176f473e110f6;p=linux-2.6-omap-h63xx.git [S390] cpu topology: fix locking cpu_coregroup_map used to grab a mutex on s390 since it was only called from process context. Since c7c22e4d5c1fdebfac4dba76de7d0338c2b0d832 "block: add support for IO CPU affinity" this is not true anymore. It now also gets called from softirq context. To prevent possible deadlocks change this in architecture code and use a spinlock instead of a mutex. Cc: stable@kernel.org Cc: Jens Axboe Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 632b13e1005..a947899dcba 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -65,18 +65,21 @@ static int machine_has_topology_irq; static struct timer_list topology_timer; static void set_topology_timer(void); static DECLARE_WORK(topology_work, topology_work_fn); +/* topology_lock protects the core linked list */ +static DEFINE_SPINLOCK(topology_lock); cpumask_t cpu_core_map[NR_CPUS]; cpumask_t cpu_coregroup_map(unsigned int cpu) { struct core_info *core = &core_info; + unsigned long flags; cpumask_t mask; cpus_clear(mask); if (!machine_has_topology) return cpu_present_map; - mutex_lock(&smp_cpu_state_mutex); + spin_lock_irqsave(&topology_lock, flags); while (core) { if (cpu_isset(cpu, core->mask)) { mask = core->mask; @@ -84,7 +87,7 @@ cpumask_t cpu_coregroup_map(unsigned int cpu) } core = core->next; } - mutex_unlock(&smp_cpu_state_mutex); + spin_unlock_irqrestore(&topology_lock, flags); if (cpus_empty(mask)) mask = cpumask_of_cpu(cpu); return mask; @@ -133,7 +136,7 @@ static void tl_to_cores(struct tl_info *info) union tl_entry *tle, *end; struct core_info *core = &core_info; - mutex_lock(&smp_cpu_state_mutex); + spin_lock_irq(&topology_lock); clear_cores(); tle = info->tle; end = (union tl_entry *)((unsigned long)info + info->length); @@ -157,7 +160,7 @@ static void tl_to_cores(struct tl_info *info) } tle = next_tle(tle); } - mutex_unlock(&smp_cpu_state_mutex); + spin_unlock_irq(&topology_lock); } static void topology_update_polarization_simple(void)