Re: [PATCH 0/6] mm: make movable onlining suck less

From: Michal Hocko
Date: Wed Apr 05 2017 - 02:36:22 EST


On Tue 04-04-17 21:41:22, Michal Hocko wrote:
> On Tue 04-04-17 13:30:13, Reza Arbab wrote:
> > On Tue, Apr 04, 2017 at 06:44:53PM +0200, Michal Hocko wrote:
> > >Thanks for your testing! This is highly appreciated.
> > >Can I assume your Tested-by?
> >
> > Of course! Not quite done, though.
>
> Ohh, I didn't mean to rush you to that!
>
> > I think I found another edge case. You
> > get an oops when removing all of a node's memory:
> >
> > __nr_to_section
> > __pfn_to_section
> > find_biggest_section_pfn
> > shrink_pgdat_span
> > __remove_zone
> > __remove_section
> > __remove_pages
> > arch_remove_memory
> > remove_memory
>
> Is this something new or an old issue? I believe the state after the
> online should be the same as before. So if you onlined the full node
> then there shouldn't be any difference. Let me have a look...
>
> > I stuck some debugging prints in, for context:
> >
> > shrink_pgdat_span: start_pfn=0x10000, end_pfn=0x10100, pgdat_start_pfn=0x0, pgdat_end_pfn=0x20000
> > shrink_pgdat_span: start_pfn=0x10100, end_pfn=0x10200, pgdat_start_pfn=0x0, pgdat_end_pfn=0x20000
> > ...%<...
> > shrink_pgdat_span: start_pfn=0x1fe00, end_pfn=0x1ff00, pgdat_start_pfn=0x0, pgdat_end_pfn=0x20000
> > shrink_pgdat_span: start_pfn=0x1ff00, end_pfn=0x20000, pgdat_start_pfn=0x0, pgdat_end_pfn=0x20000
> > find_biggest_section_pfn: start_pfn=0x0, end_pfn=0x1ff00
> > find_biggest_section_pfn loop: pfn=0x1feff, sec_nr = 0x1fe
> > find_biggest_section_pfn loop: pfn=0x1fdff, sec_nr = 0x1fd
> > ...%<...
> > find_biggest_section_pfn loop: pfn=0x1ff, sec_nr = 0x1
> > find_biggest_section_pfn loop: pfn=0xff, sec_nr = 0x0
> > find_biggest_section_pfn loop: pfn=0xffffffffffffffff, sec_nr = 0xffffffffffffff
> > Unable to handle kernel paging request for data at address 0xc000800000f19e78
>
> ...this looks like a straight underflow and it is clear that the code
> is just broken. Have a look at the loop
> pfn = end_pfn - 1;
> for (; pfn >= start_pfn; pfn -= PAGES_PER_SECTION) {
>
> assume that end_pfn is properly PAGES_PER_SECTION aligned (start_pfn
> would be 0 obviously). This is unsigned arithmetic and so it cannot work
> for the first section. So the code is broken and has been broken since
> it has been introduced. Nobody has noticed because the low pfns are
> usually reserved and out of the hotplug reach. We could tweak it but I
> am not even sure we really want/need this behavior. It complicates the
> code and am not really sure we need to support
> online_movable(range)
> offline_movable(range)
> online_kernel(range)

OK, so I managed to confuse myself. This is not about offlining. This is
about arch_remove_memory path which means this is about memory
hotremove. So we are talking about hotremove(N1, range1) and hotadd(N2,
range2) where range1 and range2 have a non-empty intersection. Do we
need to supporst this usecase?
--
Michal Hocko
SUSE Labs