[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210223174540.5526d843@thinkpad>
Date: Tue, 23 Feb 2021 17:45:40 +0100
From: Gerald Schaefer <gerald.schaefer@...ux.ibm.com>
To: Mike Kravetz <mike.kravetz@...cle.com>
Cc: Andrew Morton <akpm@...ux-foundation.org>, linux-mm@...ck.org,
linux-kernel@...r.kernel.org, Michal Hocko <mhocko@...e.com>,
Heiko Carstens <hca@...ux.ibm.com>,
Sven Schnelle <svens@...ux.ibm.com>
Subject: Re: [RFC] linux-next panic in hugepage_subpool_put_pages()
On Tue, 23 Feb 2021 15:57:40 +0100
Gerald Schaefer <gerald.schaefer@...ux.ibm.com> wrote:
[...]
> What I do not understand is how __free_huge_page() would be called at all
> in the call trace below (set_max_huge_pages -> alloc_pool_huge_page ->
> __free_huge_page -> hugepage_subpool_put_pages). From the code it seems
> that this should not be possible, so I must be missing something.
Ok, looking more closely at the dump and code, I see that __free_huge_page()
was called via alloc_pool_huge_page -> put_page() -> destroy_compound_page()
-> compound_page_dtors[2].
It doesn't feel right that alloc_pool_huge_page() ends up freeing the
newly allocated page again. Maybe some refcounting race, so that put_page()
wrongly assumes it was the last reference?
Also from the dump, I could reconstruct the (head) struct page pointer
that __free_huge_page() was called with. Here is the content of the
head and the first tail page, maybe it can help. page->private in the tail
page was zeroed already in __free_huge_page(), but its original value was
the broken *spool pointer 0000004e00000000, as seen in the register output
of the backtrace.
crash> struct -x page 0000037203dec000
struct page {
flags = 0x3ffff00000010000,
{
{
lru = {
next = 0x37203dec008,
prev = 0x37203dec008
},
mapping = 0x0,
index = 0x0,
private = 0x0
},
{
dma_addr = 0x37203dec008
},
{
{
slab_list = {
next = 0x37203dec008,
prev = 0x37203dec008
},
{
next = 0x37203dec008,
pages = 0x372,
pobjects = 0x3dec008
}
},
slab_cache = 0x0,
freelist = 0x0,
{
s_mem = 0x0,
counters = 0x0,
{
inuse = 0x0,
objects = 0x0,
frozen = 0x0
}
}
},
{
compound_head = 0x37203dec008,
compound_dtor = 0x0,
compound_order = 0x0,
compound_mapcount = {
counter = 0x3dec008
},
compound_nr = 0x0
},
{
_compound_pad_1 = 0x37203dec008,
hpage_pinned_refcount = {
counter = 0x372
},
deferred_list = {
next = 0x0,
prev = 0x0
}
},
{
_pt_pad_1 = 0x37203dec008,
pmd_huge_pte = 0x37203dec008,
_pt_pad_2 = 0x0,
{
pt_mm = 0x0,
pt_frag_refcount = {
counter = 0x0
}
},
ptl = {
{
rlock = {
raw_lock = {
lock = 0x0
}
}
}
}
},
{
pgmap = 0x37203dec008,
zone_device_data = 0x37203dec008
},
callback_head = {
next = 0x37203dec008,
func = 0x37203dec008
}
},
{
_mapcount = {
counter = 0xffffffff
},
page_type = 0xffffffff,
active = 0xffffffff,
units = 0xffffffff
},
_refcount = {
counter = 0x0
},
memcg_data = 0x0
}
crash> struct -x page 0000037203dec040
struct page {
flags = 0x3ffff00000000000,
{
{
lru = {
next = 0x37203dec001,
prev = 0x2080372ffffffff
},
mapping = 0x10000000400,
index = 0x2,
private = 0x0
},
{
dma_addr = 0x37203dec001
},
{
{
slab_list = {
next = 0x37203dec001,
prev = 0x2080372ffffffff
},
{
next = 0x37203dec001,
pages = 0x2080372,
pobjects = 0xffffffff
}
},
slab_cache = 0x10000000400,
freelist = 0x2,
{
s_mem = 0x0,
counters = 0x0,
{
inuse = 0x0,
objects = 0x0,
frozen = 0x0
}
}
},
{
compound_head = 0x37203dec001,
compound_dtor = 0x2,
compound_order = 0x8,
compound_mapcount = {
counter = 0xffffffff
},
compound_nr = 0x100
},
{
_compound_pad_1 = 0x37203dec001,
hpage_pinned_refcount = {
counter = 0x2080372
},
deferred_list = {
next = 0x10000000400,
prev = 0x2
}
},
{
_pt_pad_1 = 0x37203dec001,
pmd_huge_pte = 0x2080372ffffffff,
_pt_pad_2 = 0x10000000400,
{
pt_mm = 0x2,
pt_frag_refcount = {
counter = 0x0
}
},
ptl = {
{
rlock = {
raw_lock = {
lock = 0x0
}
}
}
}
},
{
pgmap = 0x37203dec001,
zone_device_data = 0x2080372ffffffff
},
callback_head = {
next = 0x37203dec001,
func = 0x2080372ffffffff
}
},
{
_mapcount = {
counter = 0xffffffff
},
page_type = 0xffffffff,
active = 0xffffffff,
units = 0xffffffff
},
_refcount = {
counter = 0x0
},
memcg_data = 0x0
}
Powered by blists - more mailing lists