mm/memory_hotplug: make add_memory() take the device_hotplug_lock
[muen/linux.git] / mm / memory_hotplug.c
index 8f38e689da25730c0c38d35b3c6dc123d5989d51..39cc887bbdccae393534d386014addcfb6656755 100644 (file)
@@ -1068,7 +1068,12 @@ static int online_memory_block(struct memory_block *mem, void *arg)
        return device_online(&mem->dev);
 }
 
-/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
+/*
+ * NOTE: The caller must call lock_device_hotplug() to serialize hotplug
+ * and online/offline operations (triggered e.g. by sysfs).
+ *
+ * we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG
+ */
 int __ref add_memory_resource(int nid, struct resource *res, bool online)
 {
        u64 start, size;
@@ -1137,9 +1142,9 @@ out:
        mem_hotplug_done();
        return ret;
 }
-EXPORT_SYMBOL_GPL(add_memory_resource);
 
-int __ref add_memory(int nid, u64 start, u64 size)
+/* requires device_hotplug_lock, see add_memory_resource() */
+int __ref __add_memory(int nid, u64 start, u64 size)
 {
        struct resource *res;
        int ret;
@@ -1153,6 +1158,17 @@ int __ref add_memory(int nid, u64 start, u64 size)
                release_memory_resource(res);
        return ret;
 }
+
+int add_memory(int nid, u64 start, u64 size)
+{
+       int rc;
+
+       lock_device_hotplug();
+       rc = __add_memory(nid, start, size);
+       unlock_device_hotplug();
+
+       return rc;
+}
 EXPORT_SYMBOL_GPL(add_memory);
 
 #ifdef CONFIG_MEMORY_HOTREMOVE