diff mbox

Boot failures with "mm/sparse: Remove CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER" on powerpc (was Re: mmotm 2018-07-10-16-50 uploaded)

Message ID 20180712095002.GA5342@techadventures.net (mailing list archive)
State New, archived
Headers show

Commit Message

Oscar Salvador July 12, 2018, 9:50 a.m. UTC
> > I just roughly check, but if I checked the right place,
> > vmemmap_populated() checks for the section to contain the flags we are
> > setting in sparse_init_one_section().
> 
> Yes.
> 
> > But with this patch, we populate first everything, and then we call
> > sparse_init_one_section() in sparse_init().
> > As I said I could be mistaken because I just checked the surface.
> 
> Yeah I think that's correct.
> 
> This might just be a bug in our code, let me look at it a bit.

I wonder if something like this could make the trick:

I will try to grab a ppc server and try it out too.
 
Thanks

Comments

Pavel Tatashin July 12, 2018, 3:09 p.m. UTC | #1
On Thu, Jul 12, 2018 at 5:50 AM Oscar Salvador
<osalvador@techadventures.net> wrote:
>
> > > I just roughly check, but if I checked the right place,
> > > vmemmap_populated() checks for the section to contain the flags we are
> > > setting in sparse_init_one_section().
> >
> > Yes.
> >
> > > But with this patch, we populate first everything, and then we call
> > > sparse_init_one_section() in sparse_init().
> > > As I said I could be mistaken because I just checked the surface.

Yes, this is right, sparse_init_one_section() is needed after every
populate call on ppc64. I am adding this to my sparse_init re-write,
and it actually simplifies code, as it avoids one extra loop, and
makes ppc64 to work.

Pavel
diff mbox

Patch

diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 51ce091914f9..e281651f50cd 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -177,6 +177,8 @@  static __meminit void vmemmap_list_populate(unsigned long phys,
        vmemmap_list = vmem_back;
 }
 
+static unsigned long last_addr_populated = 0;
+
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
                struct vmem_altmap *altmap)
 {
@@ -191,7 +193,7 @@  int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
                void *p;
                int rc;
 
-               if (vmemmap_populated(start, page_size))
+               if (start + page_size <= last_addr_populated)
                        continue;
 
                if (altmap)
@@ -212,6 +214,7 @@  int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
                                __func__, rc);
                        return -EFAULT;
                }
+               last_addr_populated = start + page_size;
        }

I know it looks hacky, and chances are that are wrong, but could you give it a try?