Received: by 10.213.65.68 with SMTP id h4csp2073516imn; Sun, 1 Apr 2018 23:59:35 -0700 (PDT) X-Google-Smtp-Source: AIpwx49nRcGcYMQmHNDerSlCIS06P+eRHKEbzX4XdZW+tC4d8X9NTNXEG8Uz5BdHBGBJbr9qMWmA X-Received: by 2002:a17:902:481:: with SMTP id e1-v6mr8695575ple.377.1522652375286; Sun, 01 Apr 2018 23:59:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522652375; cv=none; d=google.com; s=arc-20160816; b=uP+zHi03z5buI3GMDdpEZ4GSCe5pjPRFgiGYchagv8clu2tXgOFhryB+KI2L2ANvgk wbW/MdXY4yqIVMAvV1yshGSCtJ9ndrIKty3GqrQAD0eY5a6sQuOTsl45xvCVmKKqjRcS TlwEYdMj070Dm+qJxz64fNqJBYcjNfx492YTvoUr9n9w9KrcaDldw/bA3Y8a2UBSDGGF EIXLa2OgtuvEmzfwJrAUrAsf3aL5SjH8kfLufpjqFVCa4EQBjVUaIWd37WND0pPElazZ 6Q64vYFHJnd9CbyPGs1LEw0JtCYTnUWU/bhia9h4040SvCR9Ai1GCczEbH6m+O8bXXtu LmXQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=4rya4s8mZob/vC0LtaiLsDjXbzXaQifKWSE8ohBP2aE=; b=dTR/vHHbBD8mtTASDPuvAvBpPqq4IL2585VwhRZAPzebPwNTicDSWkUz2smlyvBx49 VMBpgojySo/WEBwKdZjFPUgD4MEx7eJ0GeEGXhk6PyKohlMATbi2yFitx/+NxjY1teaG Z9pbj9tEwxMvwI5C4n1zVrFALW4Op4hEZB95bY7u7iYYmOubG/nnDBu5QbdzXfuoDxjq mZIRt6CHjTaUfgsp/UXQcm6cpn9jPXQX6/96dsmnZrTMCJGnjPN1yKk/8YFhhg0lXA0s amveptM7lffJGOXJ9mW0icE5YDXZFhMEF06lfo9cOQbAq76PhARItlMauApxRGPHlhvT VyJQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KYUfmvcE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e11si9305943pgv.483.2018.04.01.23.59.21; Sun, 01 Apr 2018 23:59:35 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KYUfmvcE; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754241AbeDBG5F (ORCPT + 99 others); Mon, 2 Apr 2018 02:57:05 -0400 Received: from mail-it0-f66.google.com ([209.85.214.66]:51816 "EHLO mail-it0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752150AbeDBG5E (ORCPT ); Mon, 2 Apr 2018 02:57:04 -0400 Received: by mail-it0-f66.google.com with SMTP id b5-v6so6960121itj.1 for ; Sun, 01 Apr 2018 23:57:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=4rya4s8mZob/vC0LtaiLsDjXbzXaQifKWSE8ohBP2aE=; b=KYUfmvcEgT2Ds6VVcDjZ5nFwCDPy8jPCrHK7XNRGGhBJ4esqyc814ngkC3Exf4HOL9 19jRsWD2MTneq8KwukB4DwXwj33Vq8JP2ZC2bG/NfNxMLTB/wOFQcHhCs2zIGe9uG3n4 bn97CFii4ifiiiyQZLk9Oesahn3dwbSboF0rg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=4rya4s8mZob/vC0LtaiLsDjXbzXaQifKWSE8ohBP2aE=; b=dKo6VyiTCLoGhDIaaRJDlY599dlbxfekTw0T6dDsBdW3kO+mBd39BFPpzlEp1JrheG a9G1koUp9w0s0XsYTaDZPIvl299huWbGSzXEYggjJH7x6UkSb7Bs+VJ7N497TcLPes5L iFtcbiKXWvEs8c/SfzwBgOqB3B4XkNuBIPCfyUUUzi/VUxtBul5DlLxr+/pDtDYuKi/2 HW6mpN/A4qEOlln4cR79O3otzs/2zx6K4riFnEtmCIkHTRUefO1kE/HnUMk6wkaa2kwI goCa6dNR5xqPFPB52w11gHGkGr3PFAM6a491RkhBqknjd4m2OzlaOXDbcNbX1xvEliNi c7mQ== X-Gm-Message-State: AElRT7ENy+x+jqTny7jw19IP0krUNPZlGQkqyO/PZCHWYKHP+KImDGFC bT4ecxhIT/KLMgOpWx7kwYK6BhzvF5Upy8g2IQMpyQ== X-Received: by 2002:a24:2b0b:: with SMTP id h11-v6mr11301716ita.68.1522652223942; Sun, 01 Apr 2018 23:57:03 -0700 (PDT) MIME-Version: 1.0 Received: by 10.107.187.67 with HTTP; Sun, 1 Apr 2018 23:57:03 -0700 (PDT) In-Reply-To: <1522636236-12625-3-git-send-email-hejianet@gmail.com> References: <1522636236-12625-1-git-send-email-hejianet@gmail.com> <1522636236-12625-3-git-send-email-hejianet@gmail.com> From: Ard Biesheuvel Date: Mon, 2 Apr 2018 08:57:03 +0200 Message-ID: Subject: Re: [PATCH v5 2/5] arm: arm64: page_alloc: reduce unnecessary binary search in memblock_next_valid_pfn() To: Jia He Cc: Russell King , Catalin Marinas , Will Deacon , Mark Rutland , Andrew Morton , Michal Hocko , Wei Yang , Kees Cook , Laura Abbott , Vladimir Murzin , Philip Derrin , Grygorii Strashko , AKASHI Takahiro , James Morse , Steve Capper , Pavel Tatashin , Gioh Kim , Vlastimil Babka , Mel Gorman , Johannes Weiner , Kemi Wang , Petr Tesarik , YASUAKI ISHIMATSU , Andrey Ryabinin , Nikolay Borisov , Daniel Jordan , Daniel Vacek , Eugeniu Rosca , linux-arm-kernel , Linux Kernel Mailing List , Linux-MM , Jia He Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2 April 2018 at 04:30, Jia He wrote: > Commit b92df1de5d28 ("mm: page_alloc: skip over regions of invalid pfns > where possible") optimized the loop in memmap_init_zone(). But there is > still some room for improvement. E.g. if pfn and pfn+1 are in the same > memblock region, we can simply pfn++ instead of doing the binary search > in memblock_next_valid_pfn. > > Signed-off-by: Jia He > --- > arch/arm/include/asm/page.h | 1 + > arch/arm/mm/init.c | 28 ++++++++++++++++++++++------ > arch/arm64/include/asm/page.h | 1 + > arch/arm64/mm/init.c | 28 ++++++++++++++++++++++------ > 4 files changed, 46 insertions(+), 12 deletions(-) > Could we put this in a shared file somewhere? This is the second patch where you put make identical changes to ARM and arm64. > diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h > index 489875c..f38909c 100644 > --- a/arch/arm/include/asm/page.h > +++ b/arch/arm/include/asm/page.h > @@ -157,6 +157,7 @@ extern void copy_page(void *to, const void *from); > typedef struct page *pgtable_t; > > #ifdef CONFIG_HAVE_ARCH_PFN_VALID > +extern int early_region_idx; > extern int pfn_valid(unsigned long); > extern unsigned long memblock_next_valid_pfn(unsigned long pfn); > #define skip_to_last_invalid_pfn(pfn) (memblock_next_valid_pfn(pfn) - 1) > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c > index 0fb85ca..06ed190 100644 > --- a/arch/arm/mm/init.c > +++ b/arch/arm/mm/init.c > @@ -193,6 +193,8 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max_low, > } > > #ifdef CONFIG_HAVE_ARCH_PFN_VALID > +int early_region_idx __meminitdata = -1; > + > int pfn_valid(unsigned long pfn) > { > return memblock_is_map_memory(__pfn_to_phys(pfn)); > @@ -203,28 +205,42 @@ EXPORT_SYMBOL(pfn_valid); > unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn) > { > struct memblock_type *type = &memblock.memory; > + struct memblock_region *regions = type->regions; > unsigned int right = type->cnt; > unsigned int mid, left = 0; > + unsigned long start_pfn, end_pfn; > phys_addr_t addr = PFN_PHYS(++pfn); > > + /* fast path, return pfn+1 if next pfn is in the same region */ > + if (early_region_idx != -1) { > + start_pfn = PFN_DOWN(regions[early_region_idx].base); > + end_pfn = PFN_DOWN(regions[early_region_idx].base + > + regions[early_region_idx].size); > + > + if (pfn >= start_pfn && pfn < end_pfn) > + return pfn; > + } > + > + /* slow path, do the binary searching */ > do { > mid = (right + left) / 2; > > - if (addr < type->regions[mid].base) > + if (addr < regions[mid].base) > right = mid; > - else if (addr >= (type->regions[mid].base + > - type->regions[mid].size)) > + else if (addr >= (regions[mid].base + regions[mid].size)) > left = mid + 1; > else { > - /* addr is within the region, so pfn is valid */ > + early_region_idx = mid; > return pfn; > } > } while (left < right); > > if (right == type->cnt) > return -1UL; > - else > - return PHYS_PFN(type->regions[right].base); > + > + early_region_idx = right; > + > + return PHYS_PFN(regions[early_region_idx].base); > } > EXPORT_SYMBOL(memblock_next_valid_pfn); > #endif /*CONFIG_HAVE_ARCH_PFN_VALID*/ > diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h > index e57d3f2..f0d8c8e5 100644 > --- a/arch/arm64/include/asm/page.h > +++ b/arch/arm64/include/asm/page.h > @@ -38,6 +38,7 @@ extern void clear_page(void *to); > typedef struct page *pgtable_t; > > #ifdef CONFIG_HAVE_ARCH_PFN_VALID > +extern int early_region_idx; > extern int pfn_valid(unsigned long); > extern unsigned long memblock_next_valid_pfn(unsigned long pfn); > #define skip_to_last_invalid_pfn(pfn) (memblock_next_valid_pfn(pfn) - 1) > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c > index 13e43ff..342e4e2 100644 > --- a/arch/arm64/mm/init.c > +++ b/arch/arm64/mm/init.c > @@ -285,6 +285,8 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) > #endif /* CONFIG_NUMA */ > > #ifdef CONFIG_HAVE_ARCH_PFN_VALID > +int early_region_idx __meminitdata = -1; > + > int pfn_valid(unsigned long pfn) > { > return memblock_is_map_memory(pfn << PAGE_SHIFT); > @@ -295,28 +297,42 @@ EXPORT_SYMBOL(pfn_valid); > unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn) > { > struct memblock_type *type = &memblock.memory; > + struct memblock_region *regions = type->regions; > unsigned int right = type->cnt; > unsigned int mid, left = 0; > + unsigned long start_pfn, end_pfn; > phys_addr_t addr = PFN_PHYS(++pfn); > > + /* fast path, return pfn+1 if next pfn is in the same region */ > + if (early_region_idx != -1) { > + start_pfn = PFN_DOWN(regions[early_region_idx].base); > + end_pfn = PFN_DOWN(regions[early_region_idx].base + > + regions[early_region_idx].size); > + > + if (pfn >= start_pfn && pfn < end_pfn) > + return pfn; > + } > + > + /* slow path, do the binary searching */ > do { > mid = (right + left) / 2; > > - if (addr < type->regions[mid].base) > + if (addr < regions[mid].base) > right = mid; > - else if (addr >= (type->regions[mid].base + > - type->regions[mid].size)) > + else if (addr >= (regions[mid].base + regions[mid].size)) > left = mid + 1; > else { > - /* addr is within the region, so pfn is valid */ > + early_region_idx = mid; > return pfn; > } > } while (left < right); > > if (right == type->cnt) > return -1UL; > - else > - return PHYS_PFN(type->regions[right].base); > + > + early_region_idx = right; > + > + return PHYS_PFN(regions[early_region_idx].base); > } > EXPORT_SYMBOL(memblock_next_valid_pfn); > #endif /*CONFIG_HAVE_ARCH_PFN_VALID*/ > -- > 2.7.4 >