|
@@ -2622,6 +2622,21 @@ static void __init uncore_pci_exit(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/* CPU hot plug/unplug are serialized by cpu_add_remove_lock mutex */
|
|
|
+static LIST_HEAD(boxes_to_free);
|
|
|
+
|
|
|
+static void __cpuinit uncore_kfree_boxes(void)
|
|
|
+{
|
|
|
+ struct intel_uncore_box *box;
|
|
|
+
|
|
|
+ while (!list_empty(&boxes_to_free)) {
|
|
|
+ box = list_entry(boxes_to_free.next,
|
|
|
+ struct intel_uncore_box, list);
|
|
|
+ list_del(&box->list);
|
|
|
+ kfree(box);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void __cpuinit uncore_cpu_dying(int cpu)
|
|
|
{
|
|
|
struct intel_uncore_type *type;
|
|
@@ -2636,7 +2651,7 @@ static void __cpuinit uncore_cpu_dying(int cpu)
|
|
|
box = *per_cpu_ptr(pmu->box, cpu);
|
|
|
*per_cpu_ptr(pmu->box, cpu) = NULL;
|
|
|
if (box && atomic_dec_and_test(&box->refcnt))
|
|
|
- kfree(box);
|
|
|
+ list_add(&box->list, &boxes_to_free);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -2666,8 +2681,11 @@ static int __cpuinit uncore_cpu_starting(int cpu)
|
|
|
if (exist && exist->phys_id == phys_id) {
|
|
|
atomic_inc(&exist->refcnt);
|
|
|
*per_cpu_ptr(pmu->box, cpu) = exist;
|
|
|
- kfree(box);
|
|
|
- box = NULL;
|
|
|
+ if (box) {
|
|
|
+ list_add(&box->list,
|
|
|
+ &boxes_to_free);
|
|
|
+ box = NULL;
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -2806,6 +2824,10 @@ static int
|
|
|
case CPU_DYING:
|
|
|
uncore_cpu_dying(cpu);
|
|
|
break;
|
|
|
+ case CPU_ONLINE:
|
|
|
+ case CPU_DEAD:
|
|
|
+ uncore_kfree_boxes();
|
|
|
+ break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|