]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/s390/kernel/topology.c
[S390] cpu topology: fix locking
[linux-2.6-omap-h63xx.git] / arch / s390 / kernel / topology.c
index 212d618b00952a17152e9985b8a3d27a3ac657cd..a947899dcba1d55f56f8e00af05ab738293df6a3 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/device.h>
 #include <linux/bootmem.h>
 #include <linux/sched.h>
-#include <linux/kthread.h>
 #include <linux/workqueue.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
@@ -66,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;
@@ -85,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;
@@ -134,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);
@@ -158,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)
@@ -230,20 +232,9 @@ void arch_update_cpu_topology(void)
        }
 }
 
-static int topology_kthread(void *data)
-{
-       arch_reinit_sched_domains();
-       return 0;
-}
-
 static void topology_work_fn(struct work_struct *work)
 {
-       /* We can't call arch_reinit_sched_domains() from a multi-threaded
-        * workqueue context since it may deadlock in case of cpu hotplug.
-        * So we have to create a kernel thread in order to call
-        * arch_reinit_sched_domains().
-        */
-       kthread_run(topology_kthread, NULL, "topology_update");
+       arch_reinit_sched_domains();
 }
 
 void topology_schedule_update(void)