[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20170426082209.12127-1-takahiro.akashi@linaro.org>
Date: Wed, 26 Apr 2017 17:22:09 +0900
From: AKASHI Takahiro <takahiro.akashi@...aro.org>
To: dyoung@...hat.com, bhe@...hat.com
Cc: vgoyal@...hat.com, bauerman@...ux.vnet.ibm.com,
kexec@...ts.infradead.org, linux-kernel@...r.kernel.org,
AKASHI Takahiro <takahiro.akashi@...aro.org>
Subject: [PATCH] kexec: allocate buffer in top-down, if specified, correctly
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 <takahiro.akashi@...aro.org>
---
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
Powered by blists - more mailing lists