Re: [PATCH v2 10/13] arch, mm: set high_memory in free_area_init()

2025-05-19 Thread Mike Rapoport
Hi Alexandre,

On Mon, May 19, 2025 at 05:54:23PM +0200, Alexandre Ghiti wrote:
> Hi Mike,
> 
> I encountered the same error as Pratyush and the above diff fixes it: do you
> plan on sending this fix for 6.15?
> 
> If so, you can add:
> 
> Tested-by: Alexandre Ghiti 

Thanks!
Here's the patch:
https://lore.kernel.org/linux-mm/20250519171805.1288393-1-r...@kernel.org

> Thanks,
> Alex

-- 
Sincerely yours,
Mike.



Re: [PATCH v2 10/13] arch, mm: set high_memory in free_area_init()

2025-05-19 Thread Alexandre Ghiti

Hi Mike,

On 5/16/25 19:01, Mike Rapoport wrote:

Hi Pratyush,

On Fri, May 16, 2025 at 05:28:17PM +0200, Pratyush Yadav wrote:

Hi Mike, Andrew,

On Thu, Mar 13 2025, Mike Rapoport wrote:


From: "Mike Rapoport (Microsoft)" 

high_memory defines upper bound on the directly mapped memory.
This bound is defined by the beginning of ZONE_HIGHMEM when a system has
high memory and by the end of memory otherwise.

All this is known to generic memory management initialization code that
can set high_memory while initializing core mm structures.

Add a generic calculation of high_memory to free_area_init() and remove
per-architecture calculation except for the architectures that set and
use high_memory earlier than that.

Acked-by: Dave Hansen# x86
Signed-off-by: Mike Rapoport (Microsoft) 
---
  arch/alpha/mm/init.c |  1 -
  arch/arc/mm/init.c   |  2 --
  arch/arm64/mm/init.c |  2 --
  arch/csky/mm/init.c  |  1 -
  arch/hexagon/mm/init.c   |  6 --
  arch/loongarch/kernel/numa.c |  1 -
  arch/loongarch/mm/init.c |  2 --
  arch/microblaze/mm/init.c|  2 --
  arch/mips/mm/init.c  |  2 --
  arch/nios2/mm/init.c |  6 --
  arch/openrisc/mm/init.c  |  2 --
  arch/parisc/mm/init.c|  1 -
  arch/riscv/mm/init.c |  1 -
  arch/s390/mm/init.c  |  2 --
  arch/sh/mm/init.c|  7 ---
  arch/sparc/mm/init_32.c  |  1 -
  arch/sparc/mm/init_64.c  |  2 --
  arch/um/kernel/um_arch.c |  1 -
  arch/x86/kernel/setup.c  |  2 --
  arch/x86/mm/init_32.c|  3 ---
  arch/x86/mm/numa_32.c|  3 ---
  arch/xtensa/mm/init.c|  2 --
  mm/memory.c  |  8 
  mm/mm_init.c | 30 ++
  mm/nommu.c   |  2 --
  25 files changed, 30 insertions(+), 62 deletions(-)

This patch causes a BUG() when built with CONFIG_DEBUG_VIRTUAL and
passing in the cma= commandline parameter:

 [ cut here ]
 kernel BUG at arch/x86/mm/physaddr.c:23!
 ception 0x06 IP 10:812ebbf8 error 0 cr2 0x88903000
 CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.15.0-rc6+ #231 
PREEMPT(undef)
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 
1.16.3-1-1 04/01/2014
 RIP: 0010:__phys_addr+0x58/0x60
 Code: 01 48 89 c2 48 d3 ea 48 85 d2 75 05 e9 91 52 cf 00 0f 0b 48 3d ff ff ff 1f 
77 0f 48 8b 05 20 54 55 01 48 01 d0 e9 78 52 cf 00 <0f> 0b 90 0f 1f 44 00 00 90 
90 90 90 90 90 90 90 90 90 90 90 90 90
 RSP: :82803dd8 EFLAGS: 00010006 ORIG_RAX: 
 RAX: 7fff RBX:  RCX: 
 RDX: 7fff RSI: 00028000 RDI: 
 RBP: 82803e68 R08:  R09: 
 R10: 83153180 R11: 82803e48 R12: 83c9aed0
 R13:  R14: 00104000 R15: 
 FS:  () GS:() 
knlGS:
 CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 88903000 CR3: 02838000 CR4: 00b0
 Call Trace:
  
  ? __cma_declare_contiguous_nid+0x6e/0x340
  ? cma_declare_contiguous_nid+0x33/0x70
  ? dma_contiguous_reserve_area+0x2f/0x70
  ? setup_arch+0x6f1/0x870
  ? start_kernel+0x52/0x4b0
  ? x86_64_start_reservations+0x29/0x30
  ? x86_64_start_kernel+0x7c/0x80
  ? common_startup_64+0x13e/0x141

The reason is that __cma_declare_contiguous_nid() does:

highmem_start = __pa(high_memory - 1) + 1;

If dma_contiguous_reserve_area() (or any other CMA declaration) is
called before free_area_init(), high_memory is uninitialized. Without
CONFIG_DEBUG_VIRTUAL, it will likely work but use the wrong value for
highmem_start.

Among the architectures this patch touches, the below call
dma_contiguous_reserve_area() _before_ free_area_init():

- x86
- s390
- mips
- riscv
- xtensa
- loongarch
- csky

For most of those this patch didn't really change anything because they
initialized high_memory in mem_init() which is a part of free_area_init().
In those cases cma just did

highmem_start = __pa(-1) + 1;

and everyone was happy :)
  

The below call it _after_ free_area_init():
- arm64

And the below don't call it at all:
- sparc
- nios2
- openrisc
- hexagon
- sh
- um
- alpha

One possible fix would be to move the calls to
dma_contiguous_reserve_area() after free_area_init(). On x86, it would
look like the diff below. The obvious downside is that moving the call
later increases the chances of allocation failure. I'm not sure how much
that actually matters, but at least on x86, that means crash kernel and
hugetlb reservations go before DMA reservation. Also, adding a patch
like that at rc7 is a bit risky.

I don't think there's a risk of allocation failure, but moving things
around in setup_arch() is always 

Re: [PATCH v2 10/13] arch, mm: set high_memory in free_area_init()

2025-05-16 Thread Pratyush Yadav
Hi Mike, Andrew,

On Thu, Mar 13 2025, Mike Rapoport wrote:

> From: "Mike Rapoport (Microsoft)" 
>
> high_memory defines upper bound on the directly mapped memory.
> This bound is defined by the beginning of ZONE_HIGHMEM when a system has
> high memory and by the end of memory otherwise.
>
> All this is known to generic memory management initialization code that
> can set high_memory while initializing core mm structures.
>
> Add a generic calculation of high_memory to free_area_init() and remove
> per-architecture calculation except for the architectures that set and
> use high_memory earlier than that.
>
> Acked-by: Dave Hansen# x86
> Signed-off-by: Mike Rapoport (Microsoft) 
> ---
>  arch/alpha/mm/init.c |  1 -
>  arch/arc/mm/init.c   |  2 --
>  arch/arm64/mm/init.c |  2 --
>  arch/csky/mm/init.c  |  1 -
>  arch/hexagon/mm/init.c   |  6 --
>  arch/loongarch/kernel/numa.c |  1 -
>  arch/loongarch/mm/init.c |  2 --
>  arch/microblaze/mm/init.c|  2 --
>  arch/mips/mm/init.c  |  2 --
>  arch/nios2/mm/init.c |  6 --
>  arch/openrisc/mm/init.c  |  2 --
>  arch/parisc/mm/init.c|  1 -
>  arch/riscv/mm/init.c |  1 -
>  arch/s390/mm/init.c  |  2 --
>  arch/sh/mm/init.c|  7 ---
>  arch/sparc/mm/init_32.c  |  1 -
>  arch/sparc/mm/init_64.c  |  2 --
>  arch/um/kernel/um_arch.c |  1 -
>  arch/x86/kernel/setup.c  |  2 --
>  arch/x86/mm/init_32.c|  3 ---
>  arch/x86/mm/numa_32.c|  3 ---
>  arch/xtensa/mm/init.c|  2 --
>  mm/memory.c  |  8 
>  mm/mm_init.c | 30 ++
>  mm/nommu.c   |  2 --
>  25 files changed, 30 insertions(+), 62 deletions(-)

This patch causes a BUG() when built with CONFIG_DEBUG_VIRTUAL and
passing in the cma= commandline parameter:

[ cut here ]
kernel BUG at arch/x86/mm/physaddr.c:23!
ception 0x06 IP 10:812ebbf8 error 0 cr2 0x88903000
CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.15.0-rc6+ #231 
PREEMPT(undef)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 
1.16.3-1-1 04/01/2014
RIP: 0010:__phys_addr+0x58/0x60
Code: 01 48 89 c2 48 d3 ea 48 85 d2 75 05 e9 91 52 cf 00 0f 0b 48 3d ff ff 
ff 1f 77 0f 48 8b 05 20 54 55 01 48 01 d0 e9 78 52 cf 00 <0f> 0b 90 0f 1f 44 00 
00 90 90 90 90 90 90 90 90 90 90 90 90 90 90
RSP: :82803dd8 EFLAGS: 00010006 ORIG_RAX: 
RAX: 7fff RBX:  RCX: 
RDX: 7fff RSI: 00028000 RDI: 
RBP: 82803e68 R08:  R09: 
R10: 83153180 R11: 82803e48 R12: 83c9aed0
R13:  R14: 00104000 R15: 
FS:  () GS:() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 88903000 CR3: 02838000 CR4: 00b0
Call Trace:
 
 ? __cma_declare_contiguous_nid+0x6e/0x340
 ? cma_declare_contiguous_nid+0x33/0x70
 ? dma_contiguous_reserve_area+0x2f/0x70
 ? setup_arch+0x6f1/0x870
 ? start_kernel+0x52/0x4b0
 ? x86_64_start_reservations+0x29/0x30
 ? x86_64_start_kernel+0x7c/0x80
 ? common_startup_64+0x13e/0x141

The reason is that __cma_declare_contiguous_nid() does:

highmem_start = __pa(high_memory - 1) + 1;

If dma_contiguous_reserve_area() (or any other CMA declaration) is
called before free_area_init(), high_memory is uninitialized. Without
CONFIG_DEBUG_VIRTUAL, it will likely work but use the wrong value for
highmem_start.

Among the architectures this patch touches, the below call
dma_contiguous_reserve_area() _before_ free_area_init():

- x86
- s390
- mips
- riscv
- xtensa
- loongarch
- csky

The below call it _after_ free_area_init():
- arm64

And the below don't call it at all:
- sparc
- nios2
- openrisc
- hexagon
- sh
- um
- alpha

One possible fix would be to move the calls to
dma_contiguous_reserve_area() after free_area_init(). On x86, it would
look like the diff below. The obvious downside is that moving the call
later increases the chances of allocation failure. I'm not sure how much
that actually matters, but at least on x86, that means crash kernel and
hugetlb reservations go before DMA reservation. Also, adding a patch
like that at rc7 is a bit risky.

The other option would be to revert this. I tried a revert, but it isn't
trivial. It runs into merge conflicts in pretty much all of the arch
files. Maybe reverting patches 11, 12, and 13 as well would make it
easier but I didn't try that.

Which option should we take? If we want to move
dma_contiguous_reserve_area() a bit further down the line then I can
send a patch doing that on the rest of the architectures. Otherwise I
can try my hand at the rever

Re: [PATCH v2 10/13] arch, mm: set high_memory in free_area_init()

2025-05-16 Thread Mike Rapoport
Hi Pratyush,

On Fri, May 16, 2025 at 05:28:17PM +0200, Pratyush Yadav wrote:
> Hi Mike, Andrew,
> 
> On Thu, Mar 13 2025, Mike Rapoport wrote:
> 
> > From: "Mike Rapoport (Microsoft)" 
> >
> > high_memory defines upper bound on the directly mapped memory.
> > This bound is defined by the beginning of ZONE_HIGHMEM when a system has
> > high memory and by the end of memory otherwise.
> >
> > All this is known to generic memory management initialization code that
> > can set high_memory while initializing core mm structures.
> >
> > Add a generic calculation of high_memory to free_area_init() and remove
> > per-architecture calculation except for the architectures that set and
> > use high_memory earlier than that.
> >
> > Acked-by: Dave Hansen  # x86
> > Signed-off-by: Mike Rapoport (Microsoft) 
> > ---
> >  arch/alpha/mm/init.c |  1 -
> >  arch/arc/mm/init.c   |  2 --
> >  arch/arm64/mm/init.c |  2 --
> >  arch/csky/mm/init.c  |  1 -
> >  arch/hexagon/mm/init.c   |  6 --
> >  arch/loongarch/kernel/numa.c |  1 -
> >  arch/loongarch/mm/init.c |  2 --
> >  arch/microblaze/mm/init.c|  2 --
> >  arch/mips/mm/init.c  |  2 --
> >  arch/nios2/mm/init.c |  6 --
> >  arch/openrisc/mm/init.c  |  2 --
> >  arch/parisc/mm/init.c|  1 -
> >  arch/riscv/mm/init.c |  1 -
> >  arch/s390/mm/init.c  |  2 --
> >  arch/sh/mm/init.c|  7 ---
> >  arch/sparc/mm/init_32.c  |  1 -
> >  arch/sparc/mm/init_64.c  |  2 --
> >  arch/um/kernel/um_arch.c |  1 -
> >  arch/x86/kernel/setup.c  |  2 --
> >  arch/x86/mm/init_32.c|  3 ---
> >  arch/x86/mm/numa_32.c|  3 ---
> >  arch/xtensa/mm/init.c|  2 --
> >  mm/memory.c  |  8 
> >  mm/mm_init.c | 30 ++
> >  mm/nommu.c   |  2 --
> >  25 files changed, 30 insertions(+), 62 deletions(-)
> 
> This patch causes a BUG() when built with CONFIG_DEBUG_VIRTUAL and
> passing in the cma= commandline parameter:
> 
> [ cut here ]
> kernel BUG at arch/x86/mm/physaddr.c:23!
> ception 0x06 IP 10:812ebbf8 error 0 cr2 0x88903000
> CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 6.15.0-rc6+ #231 
> PREEMPT(undef)
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 
> 1.16.3-1-1 04/01/2014
> RIP: 0010:__phys_addr+0x58/0x60
> Code: 01 48 89 c2 48 d3 ea 48 85 d2 75 05 e9 91 52 cf 00 0f 0b 48 3d ff 
> ff ff 1f 77 0f 48 8b 05 20 54 55 01 48 01 d0 e9 78 52 cf 00 <0f> 0b 90 0f 1f 
> 44 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90
> RSP: :82803dd8 EFLAGS: 00010006 ORIG_RAX: 
> RAX: 7fff RBX:  RCX: 
> RDX: 7fff RSI: 00028000 RDI: 
> RBP: 82803e68 R08:  R09: 
> R10: 83153180 R11: 82803e48 R12: 83c9aed0
> R13:  R14: 00104000 R15: 
> FS:  () GS:() 
> knlGS:
> CS:  0010 DS:  ES:  CR0: 80050033
> CR2: 88903000 CR3: 02838000 CR4: 00b0
> Call Trace:
>  
>  ? __cma_declare_contiguous_nid+0x6e/0x340
>  ? cma_declare_contiguous_nid+0x33/0x70
>  ? dma_contiguous_reserve_area+0x2f/0x70
>  ? setup_arch+0x6f1/0x870
>  ? start_kernel+0x52/0x4b0
>  ? x86_64_start_reservations+0x29/0x30
>  ? x86_64_start_kernel+0x7c/0x80
>  ? common_startup_64+0x13e/0x141
> 
> The reason is that __cma_declare_contiguous_nid() does:
> 
>   highmem_start = __pa(high_memory - 1) + 1;
> 
> If dma_contiguous_reserve_area() (or any other CMA declaration) is
> called before free_area_init(), high_memory is uninitialized. Without
> CONFIG_DEBUG_VIRTUAL, it will likely work but use the wrong value for
> highmem_start.
> 
> Among the architectures this patch touches, the below call
> dma_contiguous_reserve_area() _before_ free_area_init():
> 
> - x86
> - s390
> - mips
> - riscv
> - xtensa
> - loongarch
> - csky

For most of those this patch didn't really change anything because they
initialized high_memory in mem_init() which is a part of free_area_init().
In those cases cma just did

highmem_start = __pa(-1) + 1;

and everyone was happy :)
 
> The below call it _after_ free_area_init():
> - arm64
> 
> And the below don't call it at all:
> - sparc
> - nios2
> - openrisc
> - hexagon
> - sh
> - um
> - alpha
> 
> One possible fix would be to move the calls to
> dma_contiguous_reserve_area() after free_area_init(). On x86, it would
> look like the diff below. The obvious downside is that moving the call
> later increases the chances of allocation failure. I'm not sure how much
> that actually matters, but at least on x86, that means crash kernel and
> hug