Re: [PATCH v2 0/3] m68k/mm: switch from DISCONTIGMEM to SPARSEMEM

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Mike,

On Wed, Jun 19, 2019 at 4:18 PM Mike Rapoport <rppt@xxxxxxxxxxxxx> wrote:
On Wed, Jun 19, 2019 at 09:39:40AM +0200, Geert Uytterhoeven wrote:
On Wed, Jun 19, 2019 at 9:06 AM Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> wrote:
On Tue, Jun 18, 2019 at 8:10 AM Mike Rapoport <rppt@xxxxxxxxxxxxx> wrote:
On Mon, Jun 17, 2019 at 10:00:32PM +0200, Geert Uytterhoeven wrote:
On Thu, May 16, 2019 at 8:03 AM Mike Rapoport <rppt@xxxxxxxxxxxxx> wrote:
These pacthes replace DISCONTIGMEM with SPARSEMEM on m68k for systems with
!SINGLE_MEMORY_CHUNK set.

With SPARSEMEM there is a single node for the entire physical memory and to
cope with holes in the physical address space it is divided to sections of
up to 16M.

Each section has it's own memory map which size depends on actual populated
memory.

The section size of 16M was chosen pretty much arbitrarily as I couldn't
find specs for systems with e.g. Zorro memory extensions.

Unfortunately it crashes on my Amiga, cfr. the logs below.

Then I realized the "section size of 16M". My Amiga has a single block
of 12 MiB of FastRAM at 0x07400000, which is not aligned to 16 MiB.
(Yes, base address of motherboard RAM is 0x08000000 - ramsize ;-)

I've tried:

-#define MAX_PHYSMEM_BITS       32
-#define SECTION_SIZE_BITS      24
+#define MAX_PHYSMEM_BITS       30
+#define SECTION_SIZE_BITS      22

but that doesn't seem to make a difference.

Do you have a clue? Thanks!

Not really, at least yet.
Can you please send the entire log with

"mminit_loglevel=4 memblock=debug debug"

in the command line?

Attached, with debug_boot_weak_hash added, which reveals it's a real
NULL (=0x0) pointer dereference.

Looking at the disassembly, it happens in clear_page().
Call chain:

    get_page_from_freelist()
        prep_new_page()
            clear_highpage()
                void *kaddr = kmap_atomic(page);
                    clear_page(kaddr);

get_page_from_freelist() verifies page is non-zero before calling
prep_new_page(), so it must be the kmap_atomic() that returns NULL.

kmap_atomic() basically does page_address(page).
As m68k defines WANT_PAGE_VIRTUAL, that evaluates to page->virtual,
which I assume to be NULL.
Is there a call to set_page_address() missing in the sparsemem code?

Questions:
  1. Why does it work on Atari/ARAnyM?
  2. Why does it work on SPARC64, which also uses WANT_PAGE_VIRTUAL
     and has SPARSEMEM support? (arc uses WANT_PAGE_VIRTUAL, but no
     SPARSEMEM)

Oh, I have CONFIG_SINGLE_MEMORY_CHUNK=y, so SPARSEMEM is
_not_ used.

Well, that means I've managed to break FLATMEM :)

Indeed ^-(

My guess would be that pfn_to_page()/page_to_pfn() are wrong with memory
starting at !0 address.

Can you please try the patch below to see if this helps with your machine?
If yes, I'll think of a proper way to fix the pfn <-> page conversion.

diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h
index 2fa176b1e583..25e300413e0f 100644
--- a/arch/m68k/include/asm/page_mm.h
+++ b/arch/m68k/include/asm/page_mm.h
@@ -167,6 +167,7 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
        ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn;          \
 })
 #else
+#define ARCH_PFN_OFFSET (0x07400000 >> PAGE_SHIFT)
 #include <asm-generic/memory_model.h>
 #endif

Thanks, that hack did fix CONFIG_SINGLE_MEMORY_CHUNK=y.

Back to sparsemem...

With CONFIG_SINGLE_MEMORY_CHUNK=n, and CONFIG_SPARSEMEM=y,
it also fails.  Diff between working single memory chunk and failing
sparsemem:

   -On node 0 totalpages: 3072
   -  DMA zone: 27 pages used for memmap
   +On node 0 totalpages: 32768
   +  DMA zone: 288 pages used for memmap
      DMA zone: 0 pages reserved
   -  DMA zone: 3072 pages, LIFO batch:0
   +  DMA zone: 32768 pages, LIFO batch:7
    initrd: 00b61166 - 00c00000
    pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
    pcpu-alloc: [0] 0
   -Built 1 zonelists, mobility grouping off.  Total pages: 3045
   +Built 1 zonelists, mobility grouping on.  Total pages: 32480
    Kernel command line: console=ttyS0 debug=mem root=/dev/ram
   -Dentry cache hash table entries: 2048 (order: 1, 8192 bytes)
   -Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
   +Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
   +Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
    Sorting __ex_table...
   -Memory: 7796K/12288K available (2555K kernel code, 259K rwdata,
700K rodata, 136K init, 153K bss, 4492K reserved, 0K cma-reserved)
   +Memory: 7816K/131072K available (2556K kernel code, 261K rwdata,
700K rodata, 136K init, 157K bss, 123256K reserved, 0K cma-reserved)

Oops, looks like it thinks there's memory from 0x00000000-0x08000000,
instead of 0x07400000-0x08000000.

And of course it crashes later:

    Trying to unpack rootfs image as initramfs...
    rootfs image is not initramfs (no cpio magic); looks like an initrd
    Unable to handle kernel access at virtual address (ptrval)

Full log with more debugging attached.

Thanks for your comments!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

Attachment: dmesg-5.2.0-rc5-amiga-nomod-01404-g7e958d83f2ef4cd1.1
Description: Binary data


[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux