@@ -350,6 +350,14 @@ config ACPI_HOTPLUG_MEMORY
To compile this driver as a module, choose M here:
the module will be called acpi_memhotplug.
+config ACPI_HOTPLUG_MEMORY_AUTO_ONLINE
+ bool "Automatically online hotplugged memory"
+ depends on ACPI_HOTPLUG_MEMORY
+ default n
+ help
+ This forces memory that is brought into service by ACPI
+ to be automatically onlined.
+
config ACPI_SBS
tristate "Smart Battery System"
depends on X86
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/memory_hotplug.h>
+#include <linux/memory.h>
#include <acpi/acpi_drivers.h>
#define ACPI_MEMORY_DEVICE_CLASS "memory"
@@ -252,6 +253,19 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
result = add_memory(node, info->start_addr, info->length);
if (result)
continue;
+#ifdef CONFIG_ACPI_HOTPLUG_MEMORY_AUTO_ONLINE
+ /*
+ * New processors require memory to be online before cpus.
+ * No notifications are required here as "we" are the only
+ * ones who know about the new memory right now.
+ */
+ result = online_pages(info->start_addr >> PAGE_SHIFT,
+ info->length >> PAGE_SHIFT);
+ if (!result)
+ set_memory_state(info->start_addr, MEM_ONLINE);
+ else
+ printk("Memory online failed.\n");
+#endif
info->enabled = 1;
num_enabled++;
}
@@ -510,6 +510,20 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
}
/*
+ * need an interface for the VM to mark sections on and offline when hot-adding
+ * memory.
+ */
+void set_memory_state(unsigned long addr, unsigned long state)
+{
+ struct mem_section *section;
+ struct memory_block *mem;
+
+ section = __pfn_to_section(addr >> PAGE_SHIFT);
+ mem = find_memory_block(section);
+ mem->state = state;
+}
+
+/*
* need an interface for the VM to add new memory regions,
* but without onlining it.
*/
@@ -112,6 +112,7 @@ extern int remove_memory_block(unsigned long, struct mem_section *, int);
extern int memory_notify(unsigned long val, void *v);
extern int memory_isolate_notify(unsigned long val, void *v);
extern struct memory_block *find_memory_block(struct mem_section *);
+extern void set_memory_state(unsigned long, unsigned long);
#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
enum mem_add_context { BOOT, HOTPLUG };
#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */