Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933030Ab2K0CS1 (ORCPT ); Mon, 26 Nov 2012 21:18:27 -0500 Received: from cn.fujitsu.com ([222.73.24.84]:2719 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1755614Ab2K0CSX (ORCPT ); Mon, 26 Nov 2012 21:18:23 -0500 X-IronPort-AV: E=Sophos;i="4.83,325,1352044800"; d="scan'208";a="6280252" Message-ID: <50B42471.6060403@cn.fujitsu.com> Date: Tue, 27 Nov 2012 10:24:49 +0800 From: Wen Congyang User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100413 Fedora/3.0.4-2.fc13 Thunderbird/3.0.4 MIME-Version: 1.0 To: Jianguo Wu CC: x86@kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-acpi@vger.kernel.org, linux-s390@vger.kernel.org, linux-sh@vger.kernel.org, linux-ia64@vger.kernel.org, cmetcalf@tilera.com, sparclinux@vger.kernel.org, David Rientjes , Jiang Liu , Len Brown , benh@kernel.crashing.org, paulus@samba.org, Christoph Lameter , Minchan Kim , Andrew Morton , KOSAKI Motohiro , Yasuaki Ishimatsu , Jianguo Wu Subject: Re: [PATCH v3 11/12] memory-hotplug: remove sysfs file of node References: <1351763083-7905-1-git-send-email-wency@cn.fujitsu.com> <1351763083-7905-12-git-send-email-wency@cn.fujitsu.com> <50B37C52.2060301@gmail.com> In-Reply-To: <50B37C52.2060301@gmail.com> X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2012/11/27 10:17:54, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2012/11/27 10:17:55, Serialize complete at 2012/11/27 10:17:55 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=ISO-8859-1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5668 Lines: 175 At 11/26/2012 10:27 PM, Jianguo Wu Wrote: > On 2012/11/1 17:44, Wen Congyang wrote: >> This patch introduces a new function try_offline_node() to >> remove sysfs file of node when all memory sections of this >> node are removed. If some memory sections of this node are >> not removed, this function does nothing. >> >> CC: David Rientjes >> CC: Jiang Liu >> CC: Len Brown >> CC: Christoph Lameter >> Cc: Minchan Kim >> CC: Andrew Morton >> CC: KOSAKI Motohiro >> CC: Yasuaki Ishimatsu >> Signed-off-by: Wen Congyang >> --- >> drivers/acpi/acpi_memhotplug.c | 8 +++++- >> include/linux/memory_hotplug.h | 2 +- >> mm/memory_hotplug.c | 58 ++++++++++++++++++++++++++++++++++++++++-- >> 3 files changed, 64 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c >> index 24c807f..0780f99 100644 >> --- a/drivers/acpi/acpi_memhotplug.c >> +++ b/drivers/acpi/acpi_memhotplug.c >> @@ -310,7 +310,9 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) >> { >> int result; >> struct acpi_memory_info *info, *n; >> + int node; >> >> + node = acpi_get_node(mem_device->device->handle); >> >> /* >> * Ask the VM to offline this memory range. >> @@ -318,7 +320,11 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) >> */ >> list_for_each_entry_safe(info, n, &mem_device->res_list, list) { >> if (info->enabled) { >> - result = remove_memory(info->start_addr, info->length); >> + if (node < 0) >> + node = memory_add_physaddr_to_nid( >> + info->start_addr); >> + result = remove_memory(node, info->start_addr, >> + info->length); >> if (result) >> return result; >> } >> diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h >> index d4c4402..7b4cfe6 100644 >> --- a/include/linux/memory_hotplug.h >> +++ b/include/linux/memory_hotplug.h >> @@ -231,7 +231,7 @@ extern int arch_add_memory(int nid, u64 start, u64 size); >> extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); >> extern int offline_memory_block(struct memory_block *mem); >> extern bool is_memblock_offlined(struct memory_block *mem); >> -extern int remove_memory(u64 start, u64 size); >> +extern int remove_memory(int node, u64 start, u64 size); >> extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn, >> int nr_pages); >> extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms); >> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c >> index 7bcced0..d965da3 100644 >> --- a/mm/memory_hotplug.c >> +++ b/mm/memory_hotplug.c >> @@ -29,6 +29,7 @@ >> #include >> #include >> #include >> +#include >> >> #include >> >> @@ -1299,7 +1300,58 @@ static int is_memblock_offlined_cb(struct memory_block *mem, void *arg) >> return ret; >> } >> >> -int __ref remove_memory(u64 start, u64 size) >> +static int check_cpu_on_node(void *data) >> +{ >> + struct pglist_data *pgdat = data; >> + int cpu; >> + >> + for_each_present_cpu(cpu) { >> + if (cpu_to_node(cpu) == pgdat->node_id) >> + /* >> + * the cpu on this node isn't removed, and we can't >> + * offline this node. >> + */ >> + return -EBUSY; >> + } >> + >> + return 0; >> +} >> + >> +/* offline the node if all memory sections of this node are removed */ >> +static void try_offline_node(int nid) >> +{ >> + unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; >> + unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages; >> + unsigned long pfn; >> + >> + for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { >> + unsigned long section_nr = pfn_to_section_nr(pfn); >> + >> + if (!present_section_nr(section_nr)) >> + continue; >> + >> + if (pfn_to_nid(pfn) != nid) >> + continue; >> + >> + /* >> + * some memory sections of this node are not removed, and we >> + * can't offline node now. >> + */ >> + return; >> + } >> + >> + if (stop_machine(check_cpu_on_node, NODE_DATA(nid), NULL)) >> + return; > > how about: > if (nr_cpus_node(nid)) If all cpus on the node is offlined, but not removed, nr_cpus_node(nid) will return 0. In this case, we still can't offline the node. Another purpose to use stop_machine() is to prevent cpu hotplug. We can't lock cpuhotplug here. Thanks Wen Congyang > return; >> + >> + /* >> + * all memory/cpu of this node are removed, we can offline this >> + * node now. >> + */ >> + node_set_offline(nid); >> + unregister_one_node(nid); >> +} >> + >> +int __ref remove_memory(int nid, u64 start, u64 size) >> { >> unsigned long start_pfn, end_pfn; >> int ret = 0; >> @@ -1346,6 +1398,8 @@ repeat: >> >> arch_remove_memory(start, size); >> >> + try_offline_node(nid); >> + >> unlock_memory_hotplug(); >> >> return 0; >> @@ -1355,7 +1409,7 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages) >> { >> return -EINVAL; >> } >> -int remove_memory(u64 start, u64 size) >> +int remove_memory(int nid, u64 start, u64 size) >> { >> return -EINVAL; >> } >> > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/