From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mike Rapoport Subject: [PATCH 15/21] mm: memmap_init: iterate over memblock regions rather that check each PFN Date: Sun, 12 Apr 2020 22:48:53 +0300 Message-ID: <20200412194859.12663-16-rppt@kernel.org> References: <20200412194859.12663-1-rppt@kernel.org> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Return-path: DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date :Subject:To:From:Reply-To:Content-Type:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=4ORbky6J9VwKHzNBcoHJ7+hzwn9L5DzzhFOUcH/glz8=; b=GOW7rCzeeb9cZD zpUK1LS5JoPX6zXyR0krae98IN1bT6Nk+r79SXf6A2RtbvstHQ5nLjCGCXpMr+8cRdaPjCvFFsdbB mdTB8/YLD2W+fXG8ChFsoKUe6pDZj5GQHtNSqJWEzovAbPJI52EhRVIB6Cz6uMOFhXvyXHa8fG1MA PbPmgIBnbPXlX2NGvV9zTi/edfsyWDGWk5qMOLkNmBzOUP+1mq9tr3YdjFwd2y2cmdSDbkSabEcDA X7FWEsnzD0JkUbitPMr8Nz0NdrbZJG1SeoO8rgj7ElUU4YJNi9LKkYE8wq9AKDLISijnXTCN1Pq1d SRciSQIt3dYuMSKb6eOw==; DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1586721180; bh=JfG1Siyfl/JGxyNzE0ZLQzUhIkyLD5V0oBKSDMAbENY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=h2BnsmPGm8Cfa+kc9o8EOpWn0BOw67teRHCCzEkMS26EarC59737FlnTapIdTxqRs Z9YlT+5wouIjTX+/tVSAr8/AiZFcWvYuR6+XoHgUrAI7qcRq7EA9dz2P0lWXUvqps7 AwdXw0rVSj2ugoYT6SmhsdRc64B0sLh/VGd+jLmU= In-Reply-To: <20200412194859.12663-1-rppt@kernel.org> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+glpr-linux-riscv=m.gmane-mx.org@lists.infradead.org Content-Type: text/plain; charset="us-ascii" To: linux-kernel@vger.kernel.org Cc: Rich Felker , linux-ia64@vger.kernel.org, linux-doc@vger.kernel.org, Catalin Marinas , Heiko Carstens , Michal Hocko , "James E.J. Bottomley" , Max Filippov , Guo Ren , linux-csky@vger.kernel.org, linux-parisc@vger.kernel.org, sparclinux@vger.kernel.org, linux-hexagon@vger.kernel.org, linux-riscv@lists.infradead.org, Mike Rapoport , Greg Ungerer , linux-arch@vger.kernel.org, linux-s390@vger.kernel.org, linux-c6x-dev@linux-c6x.org, Baoquan He , Jonathan Corbet , linux-sh@vger.kernel.org, Michael Ellerman , Helge Deller , x86@kernel.org, Russell King , Ley Foon Tan From: Baoquan He When called during boot the memmap_init_zone() function checks if each PFN is valid and actually belongs to the node being initialized using early_pfn_valid() and early_pfn_in_nid(). Each such check may cost up to O(log(n)) where n is the number of memory banks, so for large amount of memory overall time spent in early_pfn*() becomes substantial. Since the information is anyway present in memblock, we can iterate over memblock memory regions in memmap_init() and only call memmap_init_zone() for PFN ranges that are know to be valid and in the appropriate node. Signed-off-by: Baoquan He Signed-off-by: Mike Rapoport --- mm/page_alloc.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7f6a3081edb8..c43ce8709457 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5995,14 +5995,6 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, * function. They do not exist on hotplugged memory. */ if (context == MEMMAP_EARLY) { - if (!early_pfn_valid(pfn)) { - pfn = next_pfn(pfn); - continue; - } - if (!early_pfn_in_nid(pfn, nid)) { - pfn++; - continue; - } if (overlap_memmap_init(zone, &pfn)) continue; if (defer_init(nid, pfn, end_pfn)) @@ -6118,9 +6110,23 @@ static void __meminit zone_init_free_lists(struct zone *zone) } void __meminit __weak memmap_init(unsigned long size, int nid, - unsigned long zone, unsigned long start_pfn) + unsigned long zone, + unsigned long range_start_pfn) { - memmap_init_zone(size, nid, zone, start_pfn, MEMMAP_EARLY, NULL); + unsigned long start_pfn, end_pfn; + unsigned long range_end_pfn = range_start_pfn + size; + int i; + + for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) { + start_pfn = clamp(start_pfn, range_start_pfn, range_end_pfn); + end_pfn = clamp(end_pfn, range_start_pfn, range_end_pfn); + + if (end_pfn > start_pfn) { + size = end_pfn - start_pfn; + memmap_init_zone(size, nid, zone, start_pfn, + MEMMAP_EARLY, NULL); + } + } } static int zone_batchsize(struct zone *zone) -- 2.25.1