As the crashkernel reserve memory at 128MB offset in the first memory
block, it leaves less than 128MB memory to accommodate other essential
system resources that need memory reservation in the same block. This
creates kernel boot failure on large config LPARs having core count
greater than 192.
Setting the crashkernel to mid of RMA size which can be 512MB or more
instead of capping it to 128MB by default leaves enough space to allocate
memory to another system resource in the first memory block.
Now keeping the crashkernel at mid of RMA size works fine for the primary
kernel but creates boot failure for the kdump kernel when the crashekernel
reservation start offset crosses 256MB. The reason is, in the early boot
MMU feature of 1T segments support is not detected which restricts the paca
allocation for boot CPU below 256MB. When the crashkernel itself is
starting at 256MB offset, attempt to allocate paca below 256MB leads to the
kdump kernel boot failure.
Moving the detection of segment sizes before identifying the boot CPU
removes the restriction of 256MB limit for boot CPU paca allocation
which allows the kdump kernel to successfully boot and capture vmcore.
While allocating paca for boot CPU we found that there is a small window
during kernel boot where early_radix_enabled returns True even though
the radix is disabled using command-line. This leads to an invalid bolated
size calculation on which paca limit of boot CPU is dependent. Patch 0001
closes that window that by fixing the radix bit in mmu_feature.
Mahesh Salgaonkar (2):
fixup mmu_features immediately after getting cpu pa features.
Remove 256MB limit restriction for boot cpu paca allocation
Sourabh Jain (1):
powerpc: Set crashkernel offset to mid of RMA region
arch/powerpc/include/asm/book3s/64/mmu.h | 2 ++
arch/powerpc/include/asm/mmu.h | 1 +
arch/powerpc/kernel/prom.c | 5 +++++
arch/powerpc/kernel/rtas.c | 3 +++
arch/powerpc/kexec/core.c | 13 +++++++++----
arch/powerpc/mm/book3s64/hash_utils.c | 5 ++++-
arch/powerpc/mm/init_64.c | 5 ++++-
7 files changed, 28 insertions(+), 6 deletions(-)
--
2.31.1
From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
On system with radix support available, early_radix_enabled() starts
returning true for a small window (until mmu_early_init_devtree() is
called) even when radix mode disabled on kernel command line. This causes
ppc64_bolted_size() to return ULONG_MAX in HPT mode instead of supported
segment size, during boot cpu paca allocation.
With kernel command line = "... disable_radix":
early_init_devtree: <- early_radix_enabled() = false
early_init_dt_scan_cpus: <- early_radix_enabled() = false
...
check_cpu_pa_features: <- early_radix_enabled() = false
... ^ <- early_radix_enabled() = TRUE
allocate_paca: | <- early_radix_enabled() = TRUE
... |
ppc64_bolted_size: | <- early_radix_enabled() = TRUE
if (early_radix_enabled())| <- early_radix_enabled() = TRUE
return ULONG_MAX; |
... |
... | <- early_radix_enabled() = TRUE
... | <- early_radix_enabled() = TRUE
mmu_early_init_devtree() V
... <- early_radix_enabled() = false
So far we have not seen any issue because allocate_paca() takes minimum of
ppc64_bolted_size and rma_size while allocating paca. However it is better
to close this window by fixing up the mmu features as early as possible.
This fixes early_radix_enabled() and ppc64_bolted_size() to return valid
values in radix disable mode. This patch will help subsequent patch to
depend on early_radix_enabled() check while detecting supported segment
size in HPT mode.
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Signed-off-by: Sourabh Jain <redacted>
Reported-and-tested-by: Abdul haleem <redacted>
---
arch/powerpc/include/asm/book3s/64/mmu.h | 1 +
arch/powerpc/include/asm/mmu.h | 1 +
arch/powerpc/kernel/prom.c | 1 +
arch/powerpc/mm/init_64.c | 5 ++++-
4 files changed, 7 insertions(+), 1 deletion(-)
@@ -380,6 +380,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,check_cpu_pa_features(node);}+mmu_cpu_feature_fixup();identical_pvr_fixup(node);init_mmu_slb_size(node);
From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
At the time when we detect and allocate paca for boot cpu, we havn't yet
detected mmu feature of 1T segments support (not until
mmu_early_init_devtree() call). This causes ppc64_bolted_size() to return
256MB as limit forcing boot cpu paca allocation below 256MB always.
This works fine for kdump kernel boot as long as crashkernel reservation is
at offset below 256MB. But when we move kdump offset to 256MB or above,
kdump kernel fails to allocate paca for boot cpu below 256MB and crashes in
allocate_paca().
Moving the detection of segment sizes just before paca allocation for boot
cpu removes this restriction of 256MB limit. This allows kdump kernel to
successfully boot and capture vmcore.
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Signed-off-by: Sourabh Jain <redacted>
Reported-and-tested-by: Abdul haleem <redacted>
---
arch/powerpc/include/asm/book3s/64/mmu.h | 1 +
arch/powerpc/kernel/prom.c | 4 ++++
arch/powerpc/mm/book3s64/hash_utils.c | 5 ++++-
3 files changed, 9 insertions(+), 1 deletion(-)
On large config LPARs (having 192 and more cores), Linux fails to boot
due to insufficient memory in the first memory block. It is due to the
reserve crashkernel area starts at 128MB offset by default and which
doesn't leave enough space in the first memory block to accommodate
memory for other essential system resources.
Given that the RMA region size can be 512MB or more, setting the
crashkernel offset to mid of RMA size will leave enough space to
kernel to allocate memory for other system resources in the first
memory block.
Signed-off-by: Sourabh Jain <redacted>
Reported-and-tested-by: Abdul haleem <redacted>
---
arch/powerpc/kernel/rtas.c | 3 +++
arch/powerpc/kexec/core.c | 13 +++++++++----
2 files changed, 12 insertions(+), 4 deletions(-)
@@ -1235,6 +1235,9 @@ int __init early_init_dt_scan_rtas(unsigned long node,entryp=of_get_flat_dt_prop(node,"linux,rtas-entry",NULL);sizep=of_get_flat_dt_prop(node,"rtas-size",NULL);+if(of_get_flat_dt_prop(node,"ibm,hypertas-functions",NULL))+powerpc_firmware_features|=FW_FEATURE_LPAR;+if(basep&&entryp&&sizep){rtas.base=*basep;rtas.entry=*entryp;
From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
On system with radix support available, early_radix_enabled() starts
returning true for a small window (until mmu_early_init_devtree() is
called) even when radix mode disabled on kernel command line. This causes
ppc64_bolted_size() to return ULONG_MAX in HPT mode instead of supported
segment size, during boot cpu paca allocation.
With kernel command line = "... disable_radix":
early_init_devtree: <- early_radix_enabled() = false
early_init_dt_scan_cpus: <- early_radix_enabled() = false
...
check_cpu_pa_features: <- early_radix_enabled() = false
... ^ <- early_radix_enabled() = TRUE
allocate_paca: | <- early_radix_enabled() = TRUE
... |
ppc64_bolted_size: | <- early_radix_enabled() = TRUE
if (early_radix_enabled())| <- early_radix_enabled() = TRUE
return ULONG_MAX; |
... |
... | <- early_radix_enabled() = TRUE
... | <- early_radix_enabled() = TRUE
mmu_early_init_devtree() V
... <- early_radix_enabled() = false
So far we have not seen any issue because allocate_paca() takes minimum of
ppc64_bolted_size and rma_size while allocating paca. However it is better
to close this window by fixing up the mmu features as early as possible.
This fixes early_radix_enabled() and ppc64_bolted_size() to return valid
values in radix disable mode. This patch will help subsequent patch to
depend on early_radix_enabled() check while detecting supported segment
size in HPT mode.
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Signed-off-by: Sourabh Jain <redacted>
Reported-and-tested-by: Abdul haleem <redacted>
---
arch/powerpc/include/asm/book3s/64/mmu.h | 1 +
arch/powerpc/include/asm/mmu.h | 1 +
arch/powerpc/kernel/prom.c | 1 +
arch/powerpc/mm/init_64.c | 5 ++++-
4 files changed, 7 insertions(+), 1 deletion(-)
@@ -380,6 +380,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,check_cpu_pa_features(node);}+mmu_cpu_feature_fixup();
can you do that call inside check_cpu_pa_features? or is it because we
have the same issue with baremetal platforms?
Can we also rename this to indicate we are sanitizing the feature flag
based on kernel command line. Something like
/* Update cpu features based on kernel command line */
update_cpu_features();
On large config LPARs (having 192 and more cores), Linux fails to boot
due to insufficient memory in the first memory block. It is due to the
reserve crashkernel area starts at 128MB offset by default and which
doesn't leave enough space in the first memory block to accommodate
memory for other essential system resources.
Given that the RMA region size can be 512MB or more, setting the
crashkernel offset to mid of RMA size will leave enough space to
kernel to allocate memory for other system resources in the first
memory block.
Signed-off-by: Sourabh Jain <redacted>
Reported-and-tested-by: Abdul haleem <redacted>
---
arch/powerpc/kernel/rtas.c | 3 +++
arch/powerpc/kexec/core.c | 13 +++++++++----
2 files changed, 12 insertions(+), 4 deletions(-)
@@ -1235,6 +1235,9 @@ int __init early_init_dt_scan_rtas(unsigned long node,entryp=of_get_flat_dt_prop(node,"linux,rtas-entry",NULL);sizep=of_get_flat_dt_prop(node,"rtas-size",NULL);+if(of_get_flat_dt_prop(node,"ibm,hypertas-functions",NULL))+powerpc_firmware_features|=FW_FEATURE_LPAR;+
The equivalent check that we currently do more than checking
ibm,hypertas-functions.
if (!strcmp(uname, "rtas") || !strcmp(uname, "rtas@0")) {
prop = of_get_flat_dt_prop(node, "ibm,hypertas-functions",
&len);
if (prop) {
powerpc_firmware_features |= FW_FEATURE_LPAR;
fw_hypertas_feature_init(prop, len);
}
also do we expect other firmware features to be set along with
FW_FEATURE_LPAR?
The equivalent check that we currently do more than checking
ibm,hypertas-functions.
if (!strcmp(uname, "rtas") || !strcmp(uname, "rtas@0")) {
prop = of_get_flat_dt_prop(node, "ibm,hypertas-functions",
&len);
if (prop) {
powerpc_firmware_features |= FW_FEATURE_LPAR;
fw_hypertas_feature_init(prop, len);
}
If ibm,hypertas-functions prop has to be part of rtas or rtas@0 node to
decide we are on LPAR then how about splitting the probe_fw_features
functions into two functions, one to detect FW_FEATURE_LPAR and another
function to do the rest?
also do we expect other firmware features to be set along with
FW_FEATURE_LPAR?
No only FW_FEATURE_LPAR feature so that kernel can decide the
crashkernel offset accordingly.
Thanks for the review.
- Sourabh Jain
On 2021-10-04 21:02:21 Mon, Aneesh Kumar K.V wrote:
On 10/4/21 20:41, Sourabh Jain wrote:
quoted
From: Mahesh Salgaonkar <mahesh@linux.ibm.com>
On system with radix support available, early_radix_enabled() starts
returning true for a small window (until mmu_early_init_devtree() is
called) even when radix mode disabled on kernel command line. This causes
ppc64_bolted_size() to return ULONG_MAX in HPT mode instead of supported
segment size, during boot cpu paca allocation.
With kernel command line = "... disable_radix":
early_init_devtree: <- early_radix_enabled() = false
early_init_dt_scan_cpus: <- early_radix_enabled() = false
...
check_cpu_pa_features: <- early_radix_enabled() = false
... ^ <- early_radix_enabled() = TRUE
allocate_paca: | <- early_radix_enabled() = TRUE
... |
ppc64_bolted_size: | <- early_radix_enabled() = TRUE
if (early_radix_enabled())| <- early_radix_enabled() = TRUE
return ULONG_MAX; |
... |
... | <- early_radix_enabled() = TRUE
... | <- early_radix_enabled() = TRUE
mmu_early_init_devtree() V
... <- early_radix_enabled() = false
So far we have not seen any issue because allocate_paca() takes minimum of
ppc64_bolted_size and rma_size while allocating paca. However it is better
to close this window by fixing up the mmu features as early as possible.
This fixes early_radix_enabled() and ppc64_bolted_size() to return valid
values in radix disable mode. This patch will help subsequent patch to
depend on early_radix_enabled() check while detecting supported segment
size in HPT mode.
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Signed-off-by: Sourabh Jain <redacted>
Reported-and-tested-by: Abdul haleem <redacted>
---
arch/powerpc/include/asm/book3s/64/mmu.h | 1 +
arch/powerpc/include/asm/mmu.h | 1 +
arch/powerpc/kernel/prom.c | 1 +
arch/powerpc/mm/init_64.c | 5 ++++-
4 files changed, 7 insertions(+), 1 deletion(-)
@@ -380,6 +380,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,check_cpu_pa_features(node);}+mmu_cpu_feature_fixup();
can you do that call inside check_cpu_pa_features? or is it because we have
the same issue with baremetal platforms?
Yup same issue exist on baremetal as well in case of dt_cpu_ftrs_in_use
is true. Hence calling it after the if (!dt_cpu_ftrs_in_use) code block
takes care of both pseries and baremetal platforms.
Can we also rename this to indicate we are sanitizing the feature flag based
on kernel command line. Something like
/* Update cpu features based on kernel command line */
update_cpu_features();
arch/powerpc/kernel/prom.c:389:17: error: implicit declaration of function 'hash__early_detect_seg_size' [-Werror=implicit-function-declaration]
389 | hash__early_detect_seg_size();
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/hash__early_detect_seg_size +389 arch/powerpc/kernel/prom.c
307
308 static int __init early_init_dt_scan_cpus(unsigned long node,
309 const char *uname, int depth,
310 void *data)
311 {
312 const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
313 const __be32 *prop;
314 const __be32 *intserv;
315 int i, nthreads;
316 int len;
317 int found = -1;
318 int found_thread = 0;
319
320 /* We are scanning "cpu" nodes only */
321 if (type == NULL || strcmp(type, "cpu") != 0)
322 return 0;
323
324 /* Get physical cpuid */
325 intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
326 if (!intserv)
327 intserv = of_get_flat_dt_prop(node, "reg", &len);
328
329 nthreads = len / sizeof(int);
330
331 /*
332 * Now see if any of these threads match our boot cpu.
333 * NOTE: This must match the parsing done in smp_setup_cpu_maps.
334 */
335 for (i = 0; i < nthreads; i++) {
336 if (be32_to_cpu(intserv[i]) ==
337 fdt_boot_cpuid_phys(initial_boot_params)) {
338 found = boot_cpu_count;
339 found_thread = i;
340 }
341 #ifdef CONFIG_SMP
342 /* logical cpu id is always 0 on UP kernels */
343 boot_cpu_count++;
344 #endif
345 }
346
347 /* Not the boot CPU */
348 if (found < 0)
349 return 0;
350
351 DBG("boot cpu: logical %d physical %d\n", found,
352 be32_to_cpu(intserv[found_thread]));
353 boot_cpuid = found;
354
355 /*
356 * PAPR defines "logical" PVR values for cpus that
357 * meet various levels of the architecture:
358 * 0x0f000001 Architecture version 2.04
359 * 0x0f000002 Architecture version 2.05
360 * If the cpu-version property in the cpu node contains
361 * such a value, we call identify_cpu again with the
362 * logical PVR value in order to use the cpu feature
363 * bits appropriate for the architecture level.
364 *
365 * A POWER6 partition in "POWER6 architected" mode
366 * uses the 0x0f000002 PVR value; in POWER5+ mode
367 * it uses 0x0f000001.
368 *
369 * If we're using device tree CPU feature discovery then we don't
370 * support the cpu-version property, and it's the responsibility of the
371 * firmware/hypervisor to provide the correct feature set for the
372 * architecture level via the ibm,powerpc-cpu-features binding.
373 */
374 if (!dt_cpu_ftrs_in_use()) {
375 prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
376 if (prop && (be32_to_cpup(prop) & 0xff000000) == 0x0f000000)
377 identify_cpu(0, be32_to_cpup(prop));
378
379 check_cpu_feature_properties(node);
380 check_cpu_pa_features(node);
381 }
382
383 mmu_cpu_feature_fixup();
384 identical_pvr_fixup(node);
385 init_mmu_slb_size(node);
386
387 /* Initialize segment sizes */
388 if (!early_radix_enabled())
> 389 hash__early_detect_seg_size();
390
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On large config LPARs (having 192 and more cores), Linux fails to boot
due to insufficient memory in the first memory block. It is due to the
reserve crashkernel area starts at 128MB offset by default and which
doesn't leave enough space in the first memory block to accommodate
memory for other essential system resources.
Given that the RMA region size can be 512MB or more, setting the
crashkernel offset to mid of RMA size will leave enough space to
kernel to allocate memory for other system resources in the first
memory block.
Signed-off-by: Sourabh Jain <redacted>
Reported-and-tested-by: Abdul haleem <redacted>
---
arch/powerpc/kernel/rtas.c | 3 +++
arch/powerpc/kexec/core.c | 13 +++++++++----
2 files changed, 12 insertions(+), 4 deletions(-)
The equivalent check that we currently do more than checking
ibm,hypertas-functions.
if (!strcmp(uname, "rtas") || !strcmp(uname, "rtas@0")) {
prop = of_get_flat_dt_prop(node, "ibm,hypertas-functions",
&len);
if (prop) {
powerpc_firmware_features |= FW_FEATURE_LPAR;
fw_hypertas_feature_init(prop, len);
}
also do we expect other firmware features to be set along with
FW_FEATURE_LPAR?
This patch needs to move crash kernel reservation to mid point of rma
size for LPAR in reserve_crashkernel() function. Since
reserve_crashkernel() is called too early even before
powerpc_firmware_features is set with FW_FEATURE_LPAR, the check for if
(firmware_has_feature(FW_FEATURE_LPAR)) fails and hence we only need to
make sure that we set this flag early during early_init_dt_scan_rtas().
The rest of the LPAR specific initialization isn't required at this
point and will be still done during pseries_probe_fw_features() as usual.
Thanks,
Sourabh Jain