From patchwork Thu Sep 12 09:52:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tangchen X-Patchwork-Id: 2877381 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 33247BF43F for ; Thu, 12 Sep 2013 10:06:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C04FD201EA for ; Thu, 12 Sep 2013 10:06:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E5A35201F8 for ; Thu, 12 Sep 2013 10:06:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753512Ab3ILKGB (ORCPT ); Thu, 12 Sep 2013 06:06:01 -0400 Received: from cn.fujitsu.com ([222.73.24.84]:60976 "EHLO song.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1757894Ab3ILKDm (ORCPT ); Thu, 12 Sep 2013 06:03:42 -0400 X-IronPort-AV: E=Sophos;i="4.90,890,1371052800"; d="scan'208";a="8503612" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 12 Sep 2013 18:00:18 +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 r8CA3Htt024869; Thu, 12 Sep 2013 18:03:19 +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 2013091217472858-1454119 ; Thu, 12 Sep 2013 17:47:28 +0800 From: Tang Chen To: tj@kernel.org, rjw@sisk.pl, lenb@kernel.org, tglx@linutronix.de, mingo@elte.hu, hpa@zytor.com, akpm@linux-foundation.org, 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, zhangyanfei@cn.fujitsu.com, toshi.kani@hp.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: [RESEND PATCH v2 1/9] memblock: Introduce allocation direction to memblock. Date: Thu, 12 Sep 2013 17:52:09 +0800 Message-Id: <1378979537-21196-2-git-send-email-tangchen@cn.fujitsu.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1378979537-21196-1-git-send-email-tangchen@cn.fujitsu.com> References: <1378979537-21196-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/12 17:47:28, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/09/12 18:01:05, Serialize complete at 2013/09/12 18:01:05 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;