• Vitaly Kuznetsov's avatar
    hv_balloon: avoid touching uninitialized struct page during tail onlining · da8ced36
    Vitaly Kuznetsov authored
    Hyper-V memory hotplug protocol has 2M granularity and in Linux x86 we use
    128M. To deal with it we implement partial section onlining by registering
    custom page onlining callback (hv_online_page()). Later, when more memory
    arrives we try to online the 'tail' (see hv_bring_pgs_online()).
    
    It was found that in some cases this 'tail' onlining causes issues:
    
     BUG: Bad page state in process kworker/0:2  pfn:109e3a
     page:ffffe08344278e80 count:0 mapcount:1 mapping:0000000000000000 index:0x0
     flags: 0xfffff80000000()
     raw: 000fffff80000000 dead000000000100 dead000000000200 0000000000000000
     raw: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
     page dumped because: nonzero mapcount
     ...
     Workqueue: events hot_add_req [hv_balloon]
     Call Trace:
      dump_stack+0x5c/0x80
      bad_page.cold.112+0x7f/0xb2
      free_pcppages_bulk+0x4b8/0x690
      free_unref_page+0x54/0x70
      hv_page_online_one+0x5c/0x80 [hv_balloon]
      hot_add_req.cold.24+0x182/0x835 [hv_balloon]
      ...
    
    Turns out that we now have deferred struct page initialization for memory
    hotplug so e.g. memory_block_action() in drivers/base/memory.c does
    pages_correctly_probed() check and in that check it avoids inspecting
    struct pages and checks sections instead. But in Hyper-V balloon driver we
    do PageReserved(pfn_to_page()) check and this is now wrong.
    
    Switch to checking online_section_nr() instead.
    Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
    Cc: stable@kernel.org
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    da8ced36
hv_balloon.c 43.6 KB