Please find the v2 of cma related powerpc fadump fixes.
Patch-1 is a change in mm/cma.c to make sure we return an error if someone uses
cma_init_reserved_mem() before the pageblock_order is initalized.
I guess, it's best if Patch-1 goes via mm tree and since rest of the changes
are powerpc fadump fixes hence those should go via powerpc tree. Right?
v1 -> v2:
=========
1. Review comments from David to call fadump_cma_init() after the
pageblock_order is initialized. Also to catch usages if someone tries
to call cma_init_reserved_mem() before pageblock_order is initialized.
[v1]: https://lore.kernel.org/linuxppc-dev/c1e66d3e69c8d90988c02b84c79db5d9dd93f053.1728386179.git.ritesh.list@gmail.com/
Ritesh Harjani (IBM) (4):
cma: Enforce non-zero pageblock_order during cma_init_reserved_mem()
fadump: Refactor and prepare fadump_cma_init for late init
fadump: Reserve page-aligned boot_memory_size during fadump_reserve_mem
fadump: Move fadump_cma_init to setup_arch() after initmem_init()
arch/powerpc/include/asm/fadump.h | 7 ++++
arch/powerpc/kernel/fadump.c | 55 +++++++++++++++---------------
arch/powerpc/kernel/setup-common.c | 6 ++--
mm/cma.c | 9 +++++
4 files changed, 48 insertions(+), 29 deletions(-)
--
2.46.0
cma_init_reserved_mem() checks base and size alignment with
CMA_MIN_ALIGNMENT_BYTES. However, some users might call this during
early boot when pageblock_order is 0. That means if base and size does
not have pageblock_order alignment, it can cause functional failures
during cma activate area.
So let's enforce pageblock_order to be non-zero during
cma_init_reserved_mem().
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
mm/cma.c | 9 +++++++++
1 file changed, 9 insertions(+)
@@ -182,6 +182,15 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,if(!size||!memblock_is_region_reserved(base,size))return-EINVAL;+/*+*CMAusesCMA_MIN_ALIGNMENT_BYTESasalignmentrequirementwhich+*needspageblock_ordertobeinitialized.Let'senforceit.+*/+if(!pageblock_order){+pr_err("pageblock_order not yet initialized. Called during early boot?\n");+return-EINVAL;+}+/* ensure minimal alignment required by mm core */if(!IS_ALIGNED(base|size,CMA_MIN_ALIGNMENT_BYTES))return-EINVAL;
We anyway don't use any return values from fadump_cma_init(). Since
fadump_reserve_mem() from where fadump_cma_init() gets called today,
already has the required checks.
This patch makes this function return type as void. Let's also handle
extra cases like return if fadump_supported is false or dump_active, so
that in later patches we can call fadump_cma_init() separately from
setup_arch().
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/kernel/fadump.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
@@ -78,27 +78,23 @@ static struct cma *fadump_cma;*Butforsomereasonevenifitfailswestillhavethememoryreservation*withusandwecanstillcontinuedoingfadump.*/-staticint__initfadump_cma_init(void)+staticvoid__initfadump_cma_init(void){unsignedlonglongbase,size;intrc;-if(!fw_dump.fadump_enabled)-return0;-+if(!fw_dump.fadump_supported||!fw_dump.fadump_enabled||+fw_dump.dump_active)+return;/**DonotuseCMAifuserhasprovidedfadump=nocmakernelparameter.-*Return1tocontinuewithfadumpoldbehaviour.*/-if(fw_dump.nocma)-return1;+if(fw_dump.nocma||!fw_dump.boot_memory_size)+return;base=fw_dump.reserve_dump_area_start;size=fw_dump.boot_memory_size;-if(!size)-return0;-rc=cma_init_reserved_mem(base,size,0,"fadump_cma",&fadump_cma);if(rc){pr_err("Failed to init cma area for firmware-assisted dump,%d\n",rc);
@@ -108,7 +104,7 @@ static int __init fadump_cma_init(void)*blockedfromproductionsystemusage.Hencereturn1,*sothatwecancontinuewithfadump.*/-return1;+return;}/*
@@ -638,7 +633,7 @@ int __init fadump_reserve_mem(void)pr_info("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n",(size>>20),base,(memblock_phys_mem_size()>>20));-ret=fadump_cma_init();+fadump_cma_init();}returnret;
This patch refactors all CMA related initialization and alignment code
to within fadump_cma_init() which gets called in the end. This also means
that we keep [reserve_dump_area_start, boot_memory_size] page aligned
during fadump_reserve_mem(). Then later in fadump_cma_init() we extract the
aligned chunk and provide it to CMA. This inherently also fixes an issue in
the current code where the reserve_dump_area_start is not aligned
when the physical memory can have holes and the suitable chunk starts at
an unaligned boundary.
After this we should be able to call fadump_cma_init() independently
later in setup_arch() where pageblock_order is non-zero.
Suggested-by: Sourabh Jain <redacted>
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/kernel/fadump.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
@@ -92,8 +92,24 @@ static void __init fadump_cma_init(void)if(fw_dump.nocma||!fw_dump.boot_memory_size)return;+/*+*[base,end)shouldbereservedduringearlyinitin+*fadump_reserve_mem().Noneedtocheckthishereas+*cma_init_reserved_mem()alreadychecksforoverlap.+*HerewegivethealignedchunkofthisreservedmemorytoCMA.+*/base=fw_dump.reserve_dump_area_start;size=fw_dump.boot_memory_size;+end=base+size;++base=ALIGN(base,CMA_MIN_ALIGNMENT_BYTES);+end=ALIGN_DOWN(end,CMA_MIN_ALIGNMENT_BYTES);+size=end-base;++if(end<=base){+pr_warn("%s: Too less memory to give to CMA\n",__func__);+return;+}rc=cma_init_reserved_mem(base,size,0,"fadump_cma",&fadump_cma);if(rc){
@@ -116,11 +132,12 @@ static void __init fadump_cma_init(void)/**Sowenowhavesuccessfullyinitializedcmaareaforfadump.*/-pr_info("Initialized 0x%lx bytes cma area at %ldMB from 0x%lx "+pr_info("Initialized [0x%llx, %luMB] cma area from [0x%lx, %luMB] ""bytes of memory reserved for firmware-assisted dump\n",-cma_get_size(fadump_cma),-(unsignedlong)cma_get_base(fadump_cma)>>20,-fw_dump.reserve_dump_area_size);+cma_get_base(fadump_cma),cma_get_size(fadump_cma)>>20,+fw_dump.reserve_dump_area_start,+fw_dump.boot_memory_size>>20);+return;}#elsestaticvoid__initfadump_cma_init(void){}
@@ -553,13 +570,6 @@ int __init fadump_reserve_mem(void)if(!fw_dump.dump_active){fw_dump.boot_memory_size=PAGE_ALIGN(fadump_calculate_reserve_size());-#ifdef CONFIG_CMA-if(!fw_dump.nocma){-fw_dump.boot_memory_size=-ALIGN(fw_dump.boot_memory_size,-CMA_MIN_ALIGNMENT_BYTES);-}-#endifbootmem_min=fw_dump.ops->fadump_get_bootmem_min();if(fw_dump.boot_memory_size<bootmem_min){
During early init CMA_MIN_ALIGNMENT_BYTES can be PAGE_SIZE,
since pageblock_order is still zero and it gets initialized
later during initmem_init() e.g.
setup_arch() -> initmem_init() -> sparse_init() -> set_pageblock_order()
One such use case where this causes issues is -
early_setup() -> early_init_devtree() -> fadump_reserve_mem() -> fadump_cma_init()
This causes CMA memory alignment check to be bypassed in
cma_init_reserved_mem(). Then later cma_activate_area() can hit
a VM_BUG_ON_PAGE(pfn & ((1 << order) - 1)) if the reserved memory
area was not pageblock_order aligned.
Fix it by moving the fadump_cma_init() after initmem_init(),
where other such cma reservations also gets called.
<stack trace>
==============
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10010
flags: 0x13ffff800000000(node=1|zone=0|lastcpupid=0x7ffff) CMA
raw: 013ffff800000000 5deadbeef0000100 5deadbeef0000122 0000000000000000
raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: VM_BUG_ON_PAGE(pfn & ((1 << order) - 1))
------------[ cut here ]------------
kernel BUG at mm/page_alloc.c:778!
Call Trace:
__free_one_page+0x57c/0x7b0 (unreliable)
free_pcppages_bulk+0x1a8/0x2c8
free_unref_page_commit+0x3d4/0x4e4
free_unref_page+0x458/0x6d0
init_cma_reserved_pageblock+0x114/0x198
cma_init_reserved_areas+0x270/0x3e0
do_one_initcall+0x80/0x2f8
kernel_init_freeable+0x33c/0x530
kernel_init+0x34/0x26c
ret_from_kernel_user_thread+0x14/0x1c
Fixes: 11ac3e87ce09 ("mm: cma: use pageblock_order as the single alignment")
Suggested-by: David Hildenbrand <redacted>
Reported-by: Sachin P Bappalige <redacted>
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/include/asm/fadump.h | 7 +++++++
arch/powerpc/kernel/fadump.c | 6 +-----
arch/powerpc/kernel/setup-common.c | 6 ++++--
3 files changed, 12 insertions(+), 7 deletions(-)
@@ -642,8 +640,6 @@ int __init fadump_reserve_mem(void)pr_info("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n",(size>>20),base,(memblock_phys_mem_size()>>20));--fadump_cma_init();}returnret;
From: David Hildenbrand <hidden> Date: 2024-10-11 10:12:53
On 11.10.24 09:23, Ritesh Harjani (IBM) wrote:
quoted hunk
cma_init_reserved_mem() checks base and size alignment with
CMA_MIN_ALIGNMENT_BYTES. However, some users might call this during
early boot when pageblock_order is 0. That means if base and size does
not have pageblock_order alignment, it can cause functional failures
during cma activate area.
So let's enforce pageblock_order to be non-zero during
cma_init_reserved_mem().
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
mm/cma.c | 9 +++++++++
1 file changed, 9 insertions(+)
@@ -182,6 +182,15 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,if(!size||!memblock_is_region_reserved(base,size))return-EINVAL;+/*+*CMAusesCMA_MIN_ALIGNMENT_BYTESasalignmentrequirementwhich+*needspageblock_ordertobeinitialized.Let'senforceit.+*/+if(!pageblock_order){+pr_err("pageblock_order not yet initialized. Called during early boot?\n");+return-EINVAL;+}+/* ensure minimal alignment required by mm core */if(!IS_ALIGNED(base|size,CMA_MIN_ALIGNMENT_BYTES))return-EINVAL;
Acked-by: David Hildenbrand <redacted>
--
Cheers,
David / dhildenb
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2024-10-11 10:18:01
"Ritesh Harjani (IBM)" [off-list ref] writes:
Please find the v2 of cma related powerpc fadump fixes.
Patch-1 is a change in mm/cma.c to make sure we return an error if someone uses
cma_init_reserved_mem() before the pageblock_order is initalized.
I guess, it's best if Patch-1 goes via mm tree and since rest of the changes
are powerpc fadump fixes hence those should go via powerpc tree. Right?
Yes I think that will work.
Because there's no actual dependency on patch 1, correct?
Let's see if the mm folks are happy with the approach, and if so you
should send patch 1 on its own, and patches 2-4 as a separate series.
Then I can take the series (2-4) as fixes, and patch 1 can go via the mm
tree (probably in next, not as a fix).
cheers
v1 -> v2:
=========
1. Review comments from David to call fadump_cma_init() after the
pageblock_order is initialized. Also to catch usages if someone tries
to call cma_init_reserved_mem() before pageblock_order is initialized.
[v1]: https://lore.kernel.org/linuxppc-dev/c1e66d3e69c8d90988c02b84c79db5d9dd93f053.1728386179.git.ritesh.list@gmail.com/
Ritesh Harjani (IBM) (4):
cma: Enforce non-zero pageblock_order during cma_init_reserved_mem()
fadump: Refactor and prepare fadump_cma_init for late init
fadump: Reserve page-aligned boot_memory_size during fadump_reserve_mem
fadump: Move fadump_cma_init to setup_arch() after initmem_init()
arch/powerpc/include/asm/fadump.h | 7 ++++
arch/powerpc/kernel/fadump.c | 55 +++++++++++++++---------------
arch/powerpc/kernel/setup-common.c | 6 ++--
mm/cma.c | 9 +++++
4 files changed, 48 insertions(+), 29 deletions(-)
--
2.46.0
From: David Hildenbrand <hidden> Date: 2024-10-11 10:25:28
On 11.10.24 12:17, Michael Ellerman wrote:
"Ritesh Harjani (IBM)" [off-list ref] writes:
quoted
Please find the v2 of cma related powerpc fadump fixes.
Patch-1 is a change in mm/cma.c to make sure we return an error if someone uses
cma_init_reserved_mem() before the pageblock_order is initalized.
I guess, it's best if Patch-1 goes via mm tree and since rest of the changes
are powerpc fadump fixes hence those should go via powerpc tree. Right?
Yes I think that will work.
Because there's no actual dependency on patch 1, correct?
Let's see if the mm folks are happy with the approach, and if so you
should send patch 1 on its own, and patches 2-4 as a separate series.
From: Hari Bathini <hbathini@linux.ibm.com> Date: 2024-10-11 10:51:33
On 11/10/24 12:53 pm, Ritesh Harjani (IBM) wrote:
quoted hunk
This patch refactors all CMA related initialization and alignment code
to within fadump_cma_init() which gets called in the end. This also means
that we keep [reserve_dump_area_start, boot_memory_size] page aligned
during fadump_reserve_mem(). Then later in fadump_cma_init() we extract the
aligned chunk and provide it to CMA. This inherently also fixes an issue in
the current code where the reserve_dump_area_start is not aligned
when the physical memory can have holes and the suitable chunk starts at
an unaligned boundary.
After this we should be able to call fadump_cma_init() independently
later in setup_arch() where pageblock_order is non-zero.
Suggested-by: Sourabh Jain <redacted>
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
arch/powerpc/kernel/fadump.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
@@ -92,8 +92,24 @@ static void __init fadump_cma_init(void)if(fw_dump.nocma||!fw_dump.boot_memory_size)return;+/*+*[base,end)shouldbereservedduringearlyinitin+*fadump_reserve_mem().Noneedtocheckthishereas+*cma_init_reserved_mem()alreadychecksforoverlap.+*HerewegivethealignedchunkofthisreservedmemorytoCMA.+*/base=fw_dump.reserve_dump_area_start;size=fw_dump.boot_memory_size;+end=base+size;++base=ALIGN(base,CMA_MIN_ALIGNMENT_BYTES);+end=ALIGN_DOWN(end,CMA_MIN_ALIGNMENT_BYTES);+size=end-base;++if(end<=base){+pr_warn("%s: Too less memory to give to CMA\n",__func__);+return;+}rc=cma_init_reserved_mem(base,size,0,"fadump_cma",&fadump_cma);if(rc){
Please find the v2 of cma related powerpc fadump fixes.
Patch-1 is a change in mm/cma.c to make sure we return an error if someone uses
cma_init_reserved_mem() before the pageblock_order is initalized.
I guess, it's best if Patch-1 goes via mm tree and since rest of the changes
are powerpc fadump fixes hence those should go via powerpc tree. Right?
Yes I think that will work.
Because there's no actual dependency on patch 1, correct?
There is no dependency, yes.
Let's see if the mm folks are happy with the approach, and if so you
should send patch 1 on its own, and patches 2-4 as a separate series.
Then I can take the series (2-4) as fixes, and patch 1 can go via the mm
tree (probably in next, not as a fix).
Sure. Since David has acked patch-1, let me split this into 2 series
as you mentioned above and re-send both seperately, so that it can be
picked up in their respective trees.
Will just do it in sometime. Thanks!
-ritesh
cheers
quoted
v1 -> v2:
=========
1. Review comments from David to call fadump_cma_init() after the
pageblock_order is initialized. Also to catch usages if someone tries
to call cma_init_reserved_mem() before pageblock_order is initialized.
[v1]: https://lore.kernel.org/linuxppc-dev/c1e66d3e69c8d90988c02b84c79db5d9dd93f053.1728386179.git.ritesh.list@gmail.com/
Ritesh Harjani (IBM) (4):
cma: Enforce non-zero pageblock_order during cma_init_reserved_mem()
fadump: Refactor and prepare fadump_cma_init for late init
fadump: Reserve page-aligned boot_memory_size during fadump_reserve_mem
fadump: Move fadump_cma_init to setup_arch() after initmem_init()
arch/powerpc/include/asm/fadump.h | 7 ++++
arch/powerpc/kernel/fadump.c | 55 +++++++++++++++---------------
arch/powerpc/kernel/setup-common.c | 6 ++--
mm/cma.c | 9 +++++
4 files changed, 48 insertions(+), 29 deletions(-)
--
2.46.0