From patchwork Wed Apr 7 18:22:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prarit Bhargava X-Patchwork-Id: 91145 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o37IMNNM008354 for ; Wed, 7 Apr 2010 18:22:34 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757477Ab0DGSWX (ORCPT ); Wed, 7 Apr 2010 14:22:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:65495 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755491Ab0DGSWW (ORCPT ); Wed, 7 Apr 2010 14:22:22 -0400 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o37IMMLE021771 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 7 Apr 2010 14:22:22 -0400 Received: from prarit.bos.redhat.com (prarit.bos.redhat.com [10.16.16.23]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o37IMLmv023829; Wed, 7 Apr 2010 14:22:21 -0400 Date: Wed, 7 Apr 2010 14:22:21 -0400 From: Prarit Bhargava To: linux-acpi@vger.kernel.org, trenn@suse.de, mjg@redhat.com, john.l.villalovos@intel.com, bjorn.helgaas@hp.com, len.brown@intel.com Cc: Prarit Bhargava Message-Id: <20100407182221.29073.98804.sendpatchset@prarit.bos.redhat.com> Subject: [PATCH]: Automatically Online Hot Added Memory X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 07 Apr 2010 18:22:37 +0000 (UTC) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 93d2c79..dece6bd 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -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 diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 3597d73..8d40613 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #define ACPI_MEMORY_DEVICE_CLASS "memory" @@ -45,6 +46,11 @@ ACPI_MODULE_NAME("acpi_memhotplug"); MODULE_AUTHOR("Naveen B S "); MODULE_DESCRIPTION("Hotplug Mem Driver"); MODULE_LICENSE("GPL"); +#ifdef CONFIG_ACPI_HOTPLUG_MEMORY_AUTO_ONLINE +static int mem_hotadd_auto = 1; +module_param(mem_hotadd_auto, bool, 0444); +MODULE_PARM_DESC(mem_hotadd_auto, "Disable automatic onlining of memory"); +#endif /* Memory Device States */ #define MEMORY_INVALID_STATE 0 @@ -252,6 +258,20 @@ 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 + if (mem_hotadd_auto) { + result = online_pages(info->start_addr >> PAGE_SHIFT, + info->length >> PAGE_SHIFT); + if (!result) + set_memory_state(info->start_addr >> PAGE_SHIFT, + info->length >> PAGE_SHIFT, + MEM_ONLINE); + else + printk(KERN_ERR PREFIX "Memory online failed " + "for 0x%llx - 0x%llx\n", info->start_addr, + info->start_addr + info->length); + } +#endif info->enabled = 1; num_enabled++; } diff --git a/drivers/base/memory.c b/drivers/base/memory.c index db0848e..219be91 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -515,6 +515,29 @@ 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-swapping memory. + */ +void set_memory_state(unsigned long start_pfn, unsigned long nr_pages, + unsigned long state) +{ + struct mem_section *section; + struct memory_block *mem; + unsigned long start_sec, end_sec, i; + + start_sec = pfn_to_section_nr(start_pfn); + end_sec = pfn_to_section_nr(start_pfn + nr_pages - 1); + for (i = start_sec; i <= end_sec; i++) { + if (valid_section_nr(i) && present_section_nr(i)) { + section = __nr_to_section(i); + mem = find_memory_block(section); + mem->state = state; + } + } +} +EXPORT_SYMBOL(set_memory_state); + +/* * need an interface for the VM to add new memory regions, * but without onlining it. */ diff --git a/include/linux/memory.h b/include/linux/memory.h index 85582e1..5735253 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -114,6 +114,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, unsigned long); #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<