Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1955498AbdDZIXG (ORCPT ); Wed, 26 Apr 2017 04:23:06 -0400 Received: from mail-pf0-f179.google.com ([209.85.192.179]:33583 "EHLO mail-pf0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1953141AbdDZITd (ORCPT ); Wed, 26 Apr 2017 04:19:33 -0400 From: AKASHI Takahiro To: dyoung@redhat.com, bhe@redhat.com Cc: vgoyal@redhat.com, bauerman@linux.vnet.ibm.com, kexec@lists.infradead.org, linux-kernel@vger.kernel.org, AKASHI Takahiro Subject: [PATCH] kexec: allocate buffer in top-down, if specified, correctly Date: Wed, 26 Apr 2017 17:22:09 +0900 Message-Id: <20170426082209.12127-1-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.11.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2154 Lines: 61 The current kexec_locate_mem_hole(kbuf.top_down == 1) stops searching at the first memory region that has enough space for requested size even if some of higher regions may also have. This behavior is not consistent with locate_hole(hole_end == -1) function of kexec-tools. This patch fixes the bug, going though all the memory regions anyway. Signed-off-by: AKASHI Takahiro --- kernel/kexec_file.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index b118735fea9d..2f131c0d9017 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -373,8 +373,8 @@ static int locate_mem_hole_top_down(unsigned long start, unsigned long end, /* If we are here, we found a suitable memory range */ kbuf->mem = temp_start; - /* Success, stop navigating through remaining System RAM ranges */ - return 1; + /* always return zero, going through all the System RAM ranges */ + return 0; } static int locate_mem_hole_bottom_up(unsigned long start, unsigned long end, @@ -439,18 +439,27 @@ static int locate_mem_hole_callback(u64 start, u64 end, void *arg) * * Return: The memory walk will stop when func returns a non-zero value * and that value will be returned. If all free regions are visited without - * func returning non-zero, then zero will be returned. + * func returning non-zero, then kbuf->mem will be additionally checked + * for top-down search. + * After all, zero will be returned if none of regions fits. */ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf, int (*func)(u64, u64, void *)) { + int ret; + + kbuf->mem = 0; if (kbuf->image->type == KEXEC_TYPE_CRASH) - return walk_iomem_res_desc(crashk_res.desc, + ret = walk_iomem_res_desc(crashk_res.desc, IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY, crashk_res.start, crashk_res.end, kbuf, func); else - return walk_system_ram_res(0, ULONG_MAX, kbuf, func); + ret = walk_system_ram_res(0, ULONG_MAX, kbuf, func); + + if (!ret && kbuf->mem) + ret = 1; /* found for top-down search */ + return ret; } /** -- 2.11.1