From patchwork Fri Sep 13 09:30:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tangchen X-Patchwork-Id: 2882381 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BDD309F1C0 for ; Fri, 13 Sep 2013 09:30:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9138120420 for ; Fri, 13 Sep 2013 09:30:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 540DC2031A for ; Fri, 13 Sep 2013 09:30:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755086Ab3IMJ3b (ORCPT ); Fri, 13 Sep 2013 05:29:31 -0400 Received: from cn.fujitsu.com ([222.73.24.84]:3847 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1751915Ab3IMJ2n (ORCPT ); Fri, 13 Sep 2013 05:28:43 -0400 X-IronPort-AV: E=Sophos;i="4.90,897,1371052800"; d="scan'208";a="8515193" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 13 Sep 2013 17:25:28 +0800 Received: from fnstmail02.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id r8D9SUBe017827; Fri, 13 Sep 2013 17:28:31 +0800 Received: from G08FNSTD090432.fnst.cn.fujitsu.com ([10.167.226.99]) by fnstmail02.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.3) with ESMTP id 2013091317260791-1489957 ; Fri, 13 Sep 2013 17:26:07 +0800 From: Tang Chen To: rjw@sisk.pl, lenb@kernel.org, tglx@linutronix.de, mingo@elte.hu, hpa@zytor.com, akpm@linux-foundation.org, tj@kernel.org, toshi.kani@hp.com, zhangyanfei@cn.fujitsu.com, liwanp@linux.vnet.ibm.com, trenn@suse.de, yinghai@kernel.org, jiang.liu@huawei.com, wency@cn.fujitsu.com, laijs@cn.fujitsu.com, isimatu.yasuaki@jp.fujitsu.com, izumi.taku@jp.fujitsu.com, mgorman@suse.de, minchan@kernel.org, mina86@mina86.com, gong.chen@linux.intel.com, vasilis.liaskovitis@profitbricks.com, lwoodman@redhat.com, riel@redhat.com, jweiner@redhat.com, prarit@redhat.com Cc: x86@kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-acpi@vger.kernel.org Subject: [PATCH v3 1/5] memblock: Introduce allocation direction to memblock. Date: Fri, 13 Sep 2013 17:30:51 +0800 Message-Id: <1379064655-20874-2-git-send-email-tangchen@cn.fujitsu.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1379064655-20874-1-git-send-email-tangchen@cn.fujitsu.com> References: <1379064655-20874-1-git-send-email-tangchen@cn.fujitsu.com> X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/09/13 17:26:07, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/09/13 17:26:15, Serialize complete at 2013/09/13 17:26:15 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00,KHOP_BIG_TO_CC, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The Linux kernel cannot migrate pages used by the kernel. As a result, kernel pages cannot be hot-removed. So we cannot allocate hotpluggable memory for the kernel. ACPI SRAT (System Resource Affinity Table) contains the memory hotplug info. But before SRAT is parsed, memblock has already started to allocate memory for the kernel. So we need to prevent memblock from doing this. In a memory hotplug system, any numa node the kernel resides in should be unhotpluggable. And for a modern server, each node could have at least 16GB memory. So memory around the kernel image is highly likely unhotpluggable. So the basic idea is: Allocate memory from the end of the kernel image and to the higher memory. Since memory allocation before SRAT is parsed won't be too much, it could highly likely be in the same node with kernel image. The current memblock can only allocate memory from high address to low. So this patch introduces the allocation direct to memblock. It could be used to tell memblock to allocate memory from high to low or from low to high. Signed-off-by: Tang Chen Reviewed-by: Zhang Yanfei --- include/linux/memblock.h | 22 ++++++++++++++++++++++ mm/memblock.c | 13 +++++++++++++ 2 files changed, 35 insertions(+), 0 deletions(-) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 31e95ac..a7d3436 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -19,6 +19,11 @@ #define INIT_MEMBLOCK_REGIONS 128 +/* Allocation order. */ +#define MEMBLOCK_DIRECTION_HIGH_TO_LOW 0 +#define MEMBLOCK_DIRECTION_LOW_TO_HIGH 1 +#define MEMBLOCK_DIRECTION_DEFAULT MEMBLOCK_DIRECTION_HIGH_TO_LOW + struct memblock_region { phys_addr_t base; phys_addr_t size; @@ -35,6 +40,7 @@ struct memblock_type { }; struct memblock { + int current_direction; /* allocate from higher or lower address */ phys_addr_t current_limit; struct memblock_type memory; struct memblock_type reserved; @@ -148,6 +154,12 @@ phys_addr_t memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, int nid) phys_addr_t memblock_alloc(phys_addr_t size, phys_addr_t align); +static inline bool memblock_direction_bottom_up(void) +{ + return memblock.current_direction == MEMBLOCK_DIRECTION_LOW_TO_HIGH; +} + + /* Flags for memblock_alloc_base() amd __memblock_alloc_base() */ #define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0) #define MEMBLOCK_ALLOC_ACCESSIBLE 0 @@ -175,6 +187,16 @@ static inline void memblock_dump_all(void) } /** + * memblock_set_current_direction - Set current allocation direction to allow + * allocating memory from higher to lower + * address or from lower to higher address + * + * @direction: In which order to allocate memory. Could be + * MEMBLOCK_DIRECTION_{HIGH_TO_LOW|LOW_TO_HIGH} + */ +void memblock_set_current_direction(int direction); + +/** * memblock_set_current_limit - Set the current allocation limit to allow * limiting allocations to what is currently * accessible during boot diff --git a/mm/memblock.c b/mm/memblock.c index 0ac412a..f24ca2e 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -32,6 +32,7 @@ struct memblock memblock __initdata_memblock = { .reserved.cnt = 1, /* empty dummy entry */ .reserved.max = INIT_MEMBLOCK_REGIONS, + .current_direction = MEMBLOCK_DIRECTION_DEFAULT, .current_limit = MEMBLOCK_ALLOC_ANYWHERE, }; @@ -995,6 +996,18 @@ void __init_memblock memblock_trim_memory(phys_addr_t align) } } +void __init_memblock memblock_set_current_direction(int direction) +{ + if (direction != MEMBLOCK_DIRECTION_HIGH_TO_LOW && + direction != MEMBLOCK_DIRECTION_LOW_TO_HIGH) { + pr_warn("memblock: Failed to set allocation order. " + "Invalid order type: %d\n", direction); + return; + } + + memblock.current_direction = direction; +} + void __init_memblock memblock_set_current_limit(phys_addr_t limit) { memblock.current_limit = limit;