From: "Rafael J. Wysocki" <rjw@sisk.pl> To: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Toshi Kani <toshi.kani@hp.com>, ACPI Devel Maling List <linux-acpi@vger.kernel.org>, LKML <linux-kernel@vger.kernel.org>, isimatu.yasuaki@jp.fujitsu.com, vasilis.liaskovitis@profitbricks.com, Len Brown <lenb@kernel.org>, linux-mm@kvack.org Subject: [PATCH 1/3 RFC] ACPI / memhotplug: Bind removable memory blocks to ACPI device nodes Date: Sat, 04 May 2013 03:03:22 +0200 [thread overview] Message-ID: <2075762.5ZqhFms9cx@vostro.rjw.lan> (raw) In-Reply-To: <1583356.7oqZ7gBy2q@vostro.rjw.lan> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> During ACPI memory hotplug configuration bind memory blocks residing in modules removable through the standard ACPI mechanism to struct acpi_device objects associated with ACPI namespace objects representing those modules. Accordingly, unbind those memory blocks from the struct acpi_device objects when the memory modules in question are being removed. When "offline" operation for devices representing memory blocks is introduced, this will allow the ACPI core's device hot-remove code to use it to carry out remove_memory() for those memory blocks and check the results of that before it actually removes the modules holding them from the system. Since walk_memory_range() is used for accessing all memory blocks corresponding to a given ACPI namespace object, it is exported from memory_hotplug.c so that the code in acpi_memhotplug.c can use it. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/acpi/acpi_memhotplug.c | 53 ++++++++++++++++++++++++++++++++++++++--- include/linux/memory_hotplug.h | 2 + mm/memory_hotplug.c | 4 ++- 3 files changed, 55 insertions(+), 4 deletions(-) Index: linux-pm/mm/memory_hotplug.c =================================================================== --- linux-pm.orig/mm/memory_hotplug.c +++ linux-pm/mm/memory_hotplug.c @@ -1618,6 +1618,7 @@ int offline_pages(unsigned long start_pf { return __offline_pages(start_pfn, start_pfn + nr_pages, 120 * HZ); } +#endif /* CONFIG_MEMORY_HOTREMOVE */ /** * walk_memory_range - walks through all mem sections in [start_pfn, end_pfn) @@ -1631,7 +1632,7 @@ int offline_pages(unsigned long start_pf * * Returns the return value of func. */ -static int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, +int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, void *arg, int (*func)(struct memory_block *, void *)) { struct memory_block *mem = NULL; @@ -1668,6 +1669,7 @@ static int walk_memory_range(unsigned lo return 0; } +#ifdef CONFIG_MEMORY_HOTREMOVE /** * offline_memory_block_cb - callback function for offlining memory block * @mem: the memory block to be offlined Index: linux-pm/include/linux/memory_hotplug.h =================================================================== --- linux-pm.orig/include/linux/memory_hotplug.h +++ linux-pm/include/linux/memory_hotplug.h @@ -245,6 +245,8 @@ static inline int is_mem_section_removab static inline void try_offline_node(int nid) {} #endif /* CONFIG_MEMORY_HOTREMOVE */ +extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, + void *arg, int (*func)(struct memory_block *, void *)); extern int mem_online_node(int nid); extern int add_memory(int nid, u64 start, u64 size); extern int arch_add_memory(int nid, u64 start, u64 size); Index: linux-pm/drivers/acpi/acpi_memhotplug.c =================================================================== --- linux-pm.orig/drivers/acpi/acpi_memhotplug.c +++ linux-pm/drivers/acpi/acpi_memhotplug.c @@ -28,6 +28,7 @@ */ #include <linux/acpi.h> +#include <linux/memory.h> #include <linux/memory_hotplug.h> #include "internal.h" @@ -166,13 +167,50 @@ static int acpi_memory_check_device(stru return 0; } +static unsigned long acpi_meminfo_start_pfn(struct acpi_memory_info *info) +{ + return PFN_DOWN(info->start_addr); +} + +static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info) +{ + return PFN_UP(info->start_addr + info->length-1); +} + +static int acpi_bind_memblk(struct memory_block *mem, void *arg) +{ + return acpi_bind_one(&mem->dev, (acpi_handle)arg); +} + +static int acpi_bind_memory_blocks(struct acpi_memory_info *info, + acpi_handle handle) +{ + return walk_memory_range(acpi_meminfo_start_pfn(info), + acpi_meminfo_end_pfn(info), (void *)handle, + acpi_bind_memblk); +} + +static int acpi_unbind_memblk(struct memory_block *mem, void *arg) +{ + acpi_unbind_one(&mem->dev); + return 0; +} + +static void acpi_unbind_memory_blocks(struct acpi_memory_info *info, + acpi_handle handle) +{ + walk_memory_range(acpi_meminfo_start_pfn(info), + acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk); +} + static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) { + acpi_handle handle = mem_device->device->handle; int result, num_enabled = 0; struct acpi_memory_info *info; int node; - node = acpi_get_node(mem_device->device->handle); + node = acpi_get_node(handle); /* * Tell the VM there is more memory here... * Note: Assume that this function returns zero on success @@ -203,6 +241,12 @@ static int acpi_memory_enable_device(str if (result && result != -EEXIST) continue; + result = acpi_bind_memory_blocks(info, handle); + if (result) { + acpi_unbind_memory_blocks(info, handle); + return -ENODEV; + } + info->enabled = 1; /* @@ -229,10 +273,11 @@ static int acpi_memory_enable_device(str static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) { + acpi_handle handle = mem_device->device->handle; int result = 0, nid; struct acpi_memory_info *info, *n; - nid = acpi_get_node(mem_device->device->handle); + nid = acpi_get_node(handle); list_for_each_entry_safe(info, n, &mem_device->res_list, list) { if (!info->enabled) @@ -240,6 +285,8 @@ static int acpi_memory_remove_memory(str if (nid < 0) nid = memory_add_physaddr_to_nid(info->start_addr); + + acpi_unbind_memory_blocks(info, handle); result = remove_memory(nid, info->start_addr, info->length); if (result) return result; @@ -300,7 +347,7 @@ static int acpi_memory_device_add(struct if (result) { dev_err(&device->dev, "acpi_memory_enable_device() error\n"); acpi_memory_device_free(mem_device); - return -ENODEV; + return result; } dev_dbg(&device->dev, "Memory device configured by ACPI\n"); -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: "Rafael J. Wysocki" <rjw@sisk.pl> To: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Toshi Kani <toshi.kani@hp.com>, ACPI Devel Maling List <linux-acpi@vger.kernel.org>, LKML <linux-kernel@vger.kernel.org>, isimatu.yasuaki@jp.fujitsu.com, vasilis.liaskovitis@profitbricks.com, Len Brown <lenb@kernel.org>, linux-mm@kvack.org Subject: [PATCH 1/3 RFC] ACPI / memhotplug: Bind removable memory blocks to ACPI device nodes Date: Sat, 04 May 2013 03:03:22 +0200 [thread overview] Message-ID: <2075762.5ZqhFms9cx@vostro.rjw.lan> (raw) In-Reply-To: <1583356.7oqZ7gBy2q@vostro.rjw.lan> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> During ACPI memory hotplug configuration bind memory blocks residing in modules removable through the standard ACPI mechanism to struct acpi_device objects associated with ACPI namespace objects representing those modules. Accordingly, unbind those memory blocks from the struct acpi_device objects when the memory modules in question are being removed. When "offline" operation for devices representing memory blocks is introduced, this will allow the ACPI core's device hot-remove code to use it to carry out remove_memory() for those memory blocks and check the results of that before it actually removes the modules holding them from the system. Since walk_memory_range() is used for accessing all memory blocks corresponding to a given ACPI namespace object, it is exported from memory_hotplug.c so that the code in acpi_memhotplug.c can use it. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/acpi/acpi_memhotplug.c | 53 ++++++++++++++++++++++++++++++++++++++--- include/linux/memory_hotplug.h | 2 + mm/memory_hotplug.c | 4 ++- 3 files changed, 55 insertions(+), 4 deletions(-) Index: linux-pm/mm/memory_hotplug.c =================================================================== --- linux-pm.orig/mm/memory_hotplug.c +++ linux-pm/mm/memory_hotplug.c @@ -1618,6 +1618,7 @@ int offline_pages(unsigned long start_pf { return __offline_pages(start_pfn, start_pfn + nr_pages, 120 * HZ); } +#endif /* CONFIG_MEMORY_HOTREMOVE */ /** * walk_memory_range - walks through all mem sections in [start_pfn, end_pfn) @@ -1631,7 +1632,7 @@ int offline_pages(unsigned long start_pf * * Returns the return value of func. */ -static int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, +int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, void *arg, int (*func)(struct memory_block *, void *)) { struct memory_block *mem = NULL; @@ -1668,6 +1669,7 @@ static int walk_memory_range(unsigned lo return 0; } +#ifdef CONFIG_MEMORY_HOTREMOVE /** * offline_memory_block_cb - callback function for offlining memory block * @mem: the memory block to be offlined Index: linux-pm/include/linux/memory_hotplug.h =================================================================== --- linux-pm.orig/include/linux/memory_hotplug.h +++ linux-pm/include/linux/memory_hotplug.h @@ -245,6 +245,8 @@ static inline int is_mem_section_removab static inline void try_offline_node(int nid) {} #endif /* CONFIG_MEMORY_HOTREMOVE */ +extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, + void *arg, int (*func)(struct memory_block *, void *)); extern int mem_online_node(int nid); extern int add_memory(int nid, u64 start, u64 size); extern int arch_add_memory(int nid, u64 start, u64 size); Index: linux-pm/drivers/acpi/acpi_memhotplug.c =================================================================== --- linux-pm.orig/drivers/acpi/acpi_memhotplug.c +++ linux-pm/drivers/acpi/acpi_memhotplug.c @@ -28,6 +28,7 @@ */ #include <linux/acpi.h> +#include <linux/memory.h> #include <linux/memory_hotplug.h> #include "internal.h" @@ -166,13 +167,50 @@ static int acpi_memory_check_device(stru return 0; } +static unsigned long acpi_meminfo_start_pfn(struct acpi_memory_info *info) +{ + return PFN_DOWN(info->start_addr); +} + +static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info) +{ + return PFN_UP(info->start_addr + info->length-1); +} + +static int acpi_bind_memblk(struct memory_block *mem, void *arg) +{ + return acpi_bind_one(&mem->dev, (acpi_handle)arg); +} + +static int acpi_bind_memory_blocks(struct acpi_memory_info *info, + acpi_handle handle) +{ + return walk_memory_range(acpi_meminfo_start_pfn(info), + acpi_meminfo_end_pfn(info), (void *)handle, + acpi_bind_memblk); +} + +static int acpi_unbind_memblk(struct memory_block *mem, void *arg) +{ + acpi_unbind_one(&mem->dev); + return 0; +} + +static void acpi_unbind_memory_blocks(struct acpi_memory_info *info, + acpi_handle handle) +{ + walk_memory_range(acpi_meminfo_start_pfn(info), + acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk); +} + static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) { + acpi_handle handle = mem_device->device->handle; int result, num_enabled = 0; struct acpi_memory_info *info; int node; - node = acpi_get_node(mem_device->device->handle); + node = acpi_get_node(handle); /* * Tell the VM there is more memory here... * Note: Assume that this function returns zero on success @@ -203,6 +241,12 @@ static int acpi_memory_enable_device(str if (result && result != -EEXIST) continue; + result = acpi_bind_memory_blocks(info, handle); + if (result) { + acpi_unbind_memory_blocks(info, handle); + return -ENODEV; + } + info->enabled = 1; /* @@ -229,10 +273,11 @@ static int acpi_memory_enable_device(str static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) { + acpi_handle handle = mem_device->device->handle; int result = 0, nid; struct acpi_memory_info *info, *n; - nid = acpi_get_node(mem_device->device->handle); + nid = acpi_get_node(handle); list_for_each_entry_safe(info, n, &mem_device->res_list, list) { if (!info->enabled) @@ -240,6 +285,8 @@ static int acpi_memory_remove_memory(str if (nid < 0) nid = memory_add_physaddr_to_nid(info->start_addr); + + acpi_unbind_memory_blocks(info, handle); result = remove_memory(nid, info->start_addr, info->length); if (result) return result; @@ -300,7 +347,7 @@ static int acpi_memory_device_add(struct if (result) { dev_err(&device->dev, "acpi_memory_enable_device() error\n"); acpi_memory_device_free(mem_device); - return -ENODEV; + return result; } dev_dbg(&device->dev, "Memory device configured by ACPI\n");
next prev parent reply other threads:[~2013-05-04 1:03 UTC|newest] Thread overview: 105+ messages / expand[flat|nested] mbox.gz Atom feed top 2013-04-29 12:23 [PATCH 0/3 RFC] Driver core / ACPI: Add offline/online for graceful hot-removal of devices Rafael J. Wysocki 2013-04-29 12:26 ` [PATCH 1/3 RFC] Driver core: Add offline/online device operations Rafael J. Wysocki 2013-04-29 23:10 ` Greg Kroah-Hartman 2013-04-30 11:59 ` Rafael J. Wysocki 2013-04-30 15:32 ` Greg Kroah-Hartman 2013-04-30 20:05 ` Rafael J. Wysocki 2013-04-30 23:38 ` Toshi Kani 2013-05-02 0:58 ` Rafael J. Wysocki 2013-05-02 23:29 ` Toshi Kani 2013-05-03 11:48 ` Rafael J. Wysocki 2013-04-29 12:28 ` [PATCH 2/3 RFC] Driver core: Use generic offline/online for CPU offline/online Rafael J. Wysocki 2013-04-29 23:11 ` Greg Kroah-Hartman 2013-04-30 12:01 ` Rafael J. Wysocki 2013-04-30 15:27 ` Greg Kroah-Hartman 2013-04-30 20:06 ` Rafael J. Wysocki 2013-04-30 23:42 ` Toshi Kani 2013-05-01 14:49 ` Rafael J. Wysocki 2013-05-01 20:07 ` Toshi Kani 2013-05-02 0:26 ` Rafael J. Wysocki 2013-04-29 12:29 ` [PATCH 3/3 RFC] ACPI / hotplug: Use device offline/online for graceful hot-removal Rafael J. Wysocki 2013-04-30 23:49 ` Toshi Kani 2013-05-01 15:05 ` Rafael J. Wysocki 2013-05-01 20:20 ` Toshi Kani 2013-05-02 0:53 ` Rafael J. Wysocki 2013-05-02 12:26 ` [PATCH 0/4] Driver core / ACPI: Add offline/online for graceful hot-removal of devices Rafael J. Wysocki 2013-05-02 12:27 ` [PATCH 1/4] Driver core: Add offline/online device operations Rafael J. Wysocki 2013-05-02 13:57 ` Greg Kroah-Hartman 2013-05-02 23:11 ` Toshi Kani 2013-05-02 23:36 ` Rafael J. Wysocki 2013-05-02 23:23 ` Toshi Kani 2013-05-02 12:28 ` [PATCH 2/4] Driver core: Use generic offline/online for CPU offline/online Rafael J. Wysocki 2013-05-02 13:57 ` Greg Kroah-Hartman 2013-05-02 12:29 ` [PATCH 3/4] ACPI / hotplug: Use device offline/online for graceful hot-removal Rafael J. Wysocki 2013-05-02 12:31 ` [PATCH 4/4] ACPI / processor: Use common hotplug infrastructure Rafael J. Wysocki 2013-05-02 13:59 ` Greg Kroah-Hartman 2013-05-02 23:20 ` Toshi Kani 2013-05-03 12:05 ` Rafael J. Wysocki 2013-05-03 12:21 ` Rafael J. Wysocki 2013-05-03 18:27 ` Toshi Kani 2013-05-03 19:31 ` Rafael J. Wysocki 2013-05-03 19:34 ` Toshi Kani 2013-05-04 1:01 ` [PATCH 0/3 RFC] Driver core: Add offline/online callbacks for memory_subsys Rafael J. Wysocki 2013-05-04 1:01 ` Rafael J. Wysocki 2013-05-04 1:03 ` Rafael J. Wysocki [this message] 2013-05-04 1:03 ` [PATCH 1/3 RFC] ACPI / memhotplug: Bind removable memory blocks to ACPI device nodes Rafael J. Wysocki 2013-05-04 1:04 ` [PATCH 2/3 RFC] Driver core: Introduce types of device "online" Rafael J. Wysocki 2013-05-04 1:04 ` Rafael J. Wysocki 2013-05-04 1:06 ` [PATCH 3/3 RFC] Driver core: Introduce offline/online callbacks for memory blocks Rafael J. Wysocki 2013-05-04 1:06 ` Rafael J. Wysocki 2013-05-04 11:11 ` [PATCH 0/2 v2, RFC] Driver core: Add offline/online callbacks for memory_subsys Rafael J. Wysocki 2013-05-04 11:11 ` Rafael J. Wysocki 2013-05-04 11:12 ` [PATCH 1/2 v2, RFC] ACPI / memhotplug: Bind removable memory blocks to ACPI device nodes Rafael J. Wysocki 2013-05-04 11:12 ` Rafael J. Wysocki 2013-05-21 6:50 ` Tang Chen 2013-05-21 6:50 ` Tang Chen 2013-05-04 11:21 ` [PATCH 2/2 v2, RFC] Driver core: Introduce offline/online callbacks for memory blocks Rafael J. Wysocki 2013-05-04 11:21 ` Rafael J. Wysocki 2013-05-06 16:28 ` Vasilis Liaskovitis 2013-05-06 16:28 ` Vasilis Liaskovitis 2013-05-07 0:59 ` Rafael J. Wysocki 2013-05-07 0:59 ` Rafael J. Wysocki 2013-05-07 10:59 ` Vasilis Liaskovitis 2013-05-07 10:59 ` Vasilis Liaskovitis 2013-05-07 12:11 ` Rafael J. Wysocki 2013-05-07 12:11 ` Rafael J. Wysocki 2013-05-07 21:03 ` Toshi Kani 2013-05-07 21:03 ` Toshi Kani 2013-05-07 22:10 ` Rafael J. Wysocki 2013-05-07 22:10 ` Rafael J. Wysocki 2013-05-07 22:45 ` Toshi Kani 2013-05-07 22:45 ` Toshi Kani 2013-05-07 23:17 ` Rafael J. Wysocki 2013-05-07 23:17 ` Rafael J. Wysocki 2013-05-07 23:59 ` Toshi Kani 2013-05-07 23:59 ` Toshi Kani 2013-05-08 0:24 ` Rafael J. Wysocki 2013-05-08 0:24 ` Rafael J. Wysocki 2013-05-08 0:37 ` Toshi Kani 2013-05-08 0:37 ` Toshi Kani 2013-05-08 11:53 ` Rafael J. Wysocki 2013-05-08 11:53 ` Rafael J. Wysocki 2013-05-08 14:38 ` Toshi Kani 2013-05-08 14:38 ` Toshi Kani 2013-05-06 17:20 ` Greg Kroah-Hartman 2013-05-06 17:20 ` Greg Kroah-Hartman 2013-05-06 19:46 ` Rafael J. Wysocki 2013-05-06 19:46 ` Rafael J. Wysocki 2013-05-21 6:37 ` Tang Chen 2013-05-21 6:37 ` Tang Chen 2013-05-21 11:15 ` Rafael J. Wysocki 2013-05-21 11:15 ` Rafael J. Wysocki 2013-05-22 4:45 ` Tang Chen 2013-05-22 4:45 ` Tang Chen 2013-05-22 10:42 ` Rafael J. Wysocki 2013-05-22 10:42 ` Rafael J. Wysocki 2013-05-22 22:06 ` [PATCH] Driver core / memory: Simplify __memory_block_change_state() Rafael J. Wysocki 2013-05-22 22:06 ` Rafael J. Wysocki 2013-05-22 22:14 ` Greg Kroah-Hartman 2013-05-22 22:14 ` Greg Kroah-Hartman 2013-05-22 23:29 ` Rafael J. Wysocki 2013-05-22 23:29 ` Rafael J. Wysocki 2013-05-23 4:37 ` Tang Chen 2013-05-23 4:37 ` Tang Chen 2013-05-06 10:48 ` [PATCH 0/2 v2, RFC] Driver core: Add offline/online callbacks for memory_subsys Rafael J. Wysocki 2013-05-06 10:48 ` Rafael J. Wysocki
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=2075762.5ZqhFms9cx@vostro.rjw.lan \ --to=rjw@sisk.pl \ --cc=gregkh@linuxfoundation.org \ --cc=isimatu.yasuaki@jp.fujitsu.com \ --cc=lenb@kernel.org \ --cc=linux-acpi@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=toshi.kani@hp.com \ --cc=vasilis.liaskovitis@profitbricks.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.