All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Rapoport <rppt@linux.ibm.com>
To: Andreas Larsson <andreas@gaisler.com>
Cc: Sparc kernel list <sparclinux@vger.kernel.org>,
	linux-mm@kvack.org, Mike Rapoport <rppt@linux.vnet.ibm.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Sam Ravnborg <sam@ravnborg.org>, Michal Hocko <mhocko@kernel.org>
Subject: Re: sparc32: boot fails with > 256 MB memory after switch to NO_BOOTMEM
Date: Thu, 28 Jan 2021 09:35:41 +0000	[thread overview]
Message-ID: <20210128093541.GC299309@linux.ibm.com> (raw)
In-Reply-To: <5adb7c41-ad71-b904-6b73-35aef4dfcafe@gaisler.com>

On Wed, Jan 27, 2021 at 04:03:00PM +0100, Andreas Larsson wrote:
> 
> 
> Commit cca079ef8ac29a7c02192d2bad2ffe4c0c5ffdd0 makes sparc32 use
> memblocks instead of the previous bootmem solution. Unfortunately, due
> to this:
> 
> #define PAGE_OFFSET  0xf0000000
> #define __va(x)	     ((void *)((unsigned long) (x) - phys_base +
> PAGE_OFFSET))
> #define phys_to_virt __va
> 
> it makes physical addresses >= 0x10000000 past phys_base wrap around the
> 32-bit memory space when converted to virtual addresses, e.g. in
> memblock_alloc_try_nid. Physical memory exactly 0x10000000 past
> phys_base is returned as an unintended NULL pointer, leading to a panic
> in my boot when percpu memory allocation fails due to it.
> 
> Unfortunately I have had 256 MB memory or less in a lot of my testing,
> so this old one has slipped by me.
> 
> Does anyone has any ideas or pointers on how to resolve this?

I think the simplest way to work around this is to limit early allocations
to 256M with addition of

	memblock_set_current_limit(SZ_256M);
 
somewhere at setup_arch().

The page allocator will anyway see the entire memory, so I cannot think of
any downside here.

> Example follows where I have 512 MB memory at 0x40000000:
> 
> ----->%>%>%>%-----
> memblock_add: [0x40000000-0x5fffafff] bootmem_init+0x1f8/0x210
> 319MB HIGHMEM available.
> memblock_reserve: [0x40000000-0x40e71fff] bootmem_init+0x178/0x210
> memblock_add: [0x40000000-0x40e71fff] bootmem_init+0x188/0x210
> memblock_alloc_try_nid: 5242880 bytes align=0x40000 nid=-1 from=0x00000000
> max_addr=0x00000000 srmmu_nocache_init+0x20/0x25c
> memblock_reserve: [0x40e80000-0x4137ffff]
> memblock_alloc_range_nid+0xcc/0x178
> memblock_alloc_try_nid: 2560 bytes align=0x20 nid=-1 from=0x00000000
> max_addr=0x00000000 srmmu_nocache_init+0x94/0x25c
> memblock_reserve: [0x40e72000-0x40e729ff]
> memblock_alloc_range_nid+0xcc/0x178
> memblock_alloc_try_nid: 4096 bytes align=0x20 nid=-1 from=0x00000000
> max_addr=0x00000000 sparc_context_init+0x1c/0xe4
> memblock_reserve: [0x40e72a00-0x40e739ff]
> memblock_alloc_range_nid+0xcc/0x178
> Zone ranges:
>   DMA      [mem 0x0000000040000000-0x000000004bffffff]
>   Normal   empty
>   HighMem  [mem 0x000000004c000000-0x000000005fffafff]
> Movable zone start for each node
> Early memory node ranges
>   node   0: [mem 0x0000000040000000-0x000000005fffafff]
> Initmem setup node 0 [mem 0x0000000040000000-0x000000005fffafff]
> ----->%>%>%>%-----
> 
> then much much later memblock_alloc_internal gets 0x50000000 from
> memblock_alloc_range_nid and returns a NULL pointer as result of
> phys_to_virt.
> 
> ----->%>%>%>%-----
> memblock_alloc_try_nid: 40960 bytes align=0x1000 nid=-1 from=0x4fffffff
> max_addr=0x00000000 pcpu_dfl_fc_alloc+0x28/0x40
> memblock_reserve: [0x50000000-0x50009fff]
> memblock_alloc_range_nid+0xcc/0x178
> memblock_free: [0x40e7e000-0x40e7efff] pcpu_free_alloc_info+0x1c/0x30
> memblock_free: [0x40e7f000-0x40e7ffff] pcpu_embed_first_chunk+0x194/0x3b8
> Kernel panic - not syncing: Failed to initialize percpu areas.
> CPU: 0 PID: 0 Comm: swapper Not tainted 5.11.0-rc3-00040-gbc4547251e1-dirty
> #28
> ----->%>%>%>%-----
> 
> Adding mem%6M to the command line solves the panic problem but makes
> the extra memory not be available for normal allocation later on either.
> 
> The two first memblock_add calls (seen in the first first set of
> outputs) with overlapping address ranges that is done in bootmem_init
> also looks a bit worrying, but removing the second one does not affect
> this problem.
> 
> -- 
> Best regards,
> 
> Andreas Larsson
> Cobham Gaisler

-- 
Sincerely yours,
Mike.

WARNING: multiple messages have this Message-ID (diff)
From: Mike Rapoport <rppt@linux.ibm.com>
To: Andreas Larsson <andreas@gaisler.com>
Cc: Sparc kernel list <sparclinux@vger.kernel.org>,
	linux-mm@kvack.org, Mike Rapoport <rppt@linux.vnet.ibm.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Sam Ravnborg <sam@ravnborg.org>, Michal Hocko <mhocko@kernel.org>
Subject: Re: sparc32: boot fails with > 256 MB memory after switch to NO_BOOTMEM
Date: Thu, 28 Jan 2021 11:35:41 +0200	[thread overview]
Message-ID: <20210128093541.GC299309@linux.ibm.com> (raw)
In-Reply-To: <5adb7c41-ad71-b904-6b73-35aef4dfcafe@gaisler.com>

On Wed, Jan 27, 2021 at 04:03:00PM +0100, Andreas Larsson wrote:
> 
> 
> Commit cca079ef8ac29a7c02192d2bad2ffe4c0c5ffdd0 makes sparc32 use
> memblocks instead of the previous bootmem solution. Unfortunately, due
> to this:
> 
> #define PAGE_OFFSET  0xf0000000
> #define __va(x)	     ((void *)((unsigned long) (x) - phys_base +
> PAGE_OFFSET))
> #define phys_to_virt __va
> 
> it makes physical addresses >= 0x10000000 past phys_base wrap around the
> 32-bit memory space when converted to virtual addresses, e.g. in
> memblock_alloc_try_nid. Physical memory exactly 0x10000000 past
> phys_base is returned as an unintended NULL pointer, leading to a panic
> in my boot when percpu memory allocation fails due to it.
> 
> Unfortunately I have had 256 MB memory or less in a lot of my testing,
> so this old one has slipped by me.
> 
> Does anyone has any ideas or pointers on how to resolve this?

I think the simplest way to work around this is to limit early allocations
to 256M with addition of

	memblock_set_current_limit(SZ_256M);
 
somewhere at setup_arch().

The page allocator will anyway see the entire memory, so I cannot think of
any downside here.

> Example follows where I have 512 MB memory at 0x40000000:
> 
> ----->%>%>%>%-----
> memblock_add: [0x40000000-0x5fffafff] bootmem_init+0x1f8/0x210
> 319MB HIGHMEM available.
> memblock_reserve: [0x40000000-0x40e71fff] bootmem_init+0x178/0x210
> memblock_add: [0x40000000-0x40e71fff] bootmem_init+0x188/0x210
> memblock_alloc_try_nid: 5242880 bytes align=0x40000 nid=-1 from=0x00000000
> max_addr=0x00000000 srmmu_nocache_init+0x20/0x25c
> memblock_reserve: [0x40e80000-0x4137ffff]
> memblock_alloc_range_nid+0xcc/0x178
> memblock_alloc_try_nid: 2560 bytes align=0x20 nid=-1 from=0x00000000
> max_addr=0x00000000 srmmu_nocache_init+0x94/0x25c
> memblock_reserve: [0x40e72000-0x40e729ff]
> memblock_alloc_range_nid+0xcc/0x178
> memblock_alloc_try_nid: 4096 bytes align=0x20 nid=-1 from=0x00000000
> max_addr=0x00000000 sparc_context_init+0x1c/0xe4
> memblock_reserve: [0x40e72a00-0x40e739ff]
> memblock_alloc_range_nid+0xcc/0x178
> Zone ranges:
>   DMA      [mem 0x0000000040000000-0x000000004bffffff]
>   Normal   empty
>   HighMem  [mem 0x000000004c000000-0x000000005fffafff]
> Movable zone start for each node
> Early memory node ranges
>   node   0: [mem 0x0000000040000000-0x000000005fffafff]
> Initmem setup node 0 [mem 0x0000000040000000-0x000000005fffafff]
> ----->%>%>%>%-----
> 
> then much much later memblock_alloc_internal gets 0x50000000 from
> memblock_alloc_range_nid and returns a NULL pointer as result of
> phys_to_virt.
> 
> ----->%>%>%>%-----
> memblock_alloc_try_nid: 40960 bytes align=0x1000 nid=-1 from=0x4fffffff
> max_addr=0x00000000 pcpu_dfl_fc_alloc+0x28/0x40
> memblock_reserve: [0x50000000-0x50009fff]
> memblock_alloc_range_nid+0xcc/0x178
> memblock_free: [0x40e7e000-0x40e7efff] pcpu_free_alloc_info+0x1c/0x30
> memblock_free: [0x40e7f000-0x40e7ffff] pcpu_embed_first_chunk+0x194/0x3b8
> Kernel panic - not syncing: Failed to initialize percpu areas.
> CPU: 0 PID: 0 Comm: swapper Not tainted 5.11.0-rc3-00040-gbc4547251e1-dirty
> #28
> ----->%>%>%>%-----
> 
> Adding mem=256M to the command line solves the panic problem but makes
> the extra memory not be available for normal allocation later on either.
> 
> The two first memblock_add calls (seen in the first first set of
> outputs) with overlapping address ranges that is done in bootmem_init
> also looks a bit worrying, but removing the second one does not affect
> this problem.
> 
> -- 
> Best regards,
> 
> Andreas Larsson
> Cobham Gaisler

-- 
Sincerely yours,
Mike.


  reply	other threads:[~2021-01-28  9:35 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-27 15:03 sparc32: boot fails with > 256 MB memory after switch to NO_BOOTMEM Andreas Larsson
2021-01-27 15:03 ` Andreas Larsson
2021-01-28  9:35 ` Mike Rapoport [this message]
2021-01-28  9:35   ` Mike Rapoport
2021-01-28 11:05   ` Andreas Larsson
2021-01-28 11:05     ` Andreas Larsson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210128093541.GC299309@linux.ibm.com \
    --to=rppt@linux.ibm.com \
    --cc=andreas@gaisler.com \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@kernel.org \
    --cc=rppt@linux.vnet.ibm.com \
    --cc=sam@ravnborg.org \
    --cc=sparclinux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.