Re: [memcg BUG] unable to handle kernel NULL pointer derefence at 00000000

Li Zefan
2008-10-21T10:57:08Z

KAMEZAWA Hiroyuki wrote:
> On Tue, 21 Oct 2008 17:54:28 +0800
> Li Zefan <lizf@cn.fujitsu.com> wrote:
>
>> KAMEZAWA Hiroyuki wrote:
>>> On Tue, 21 Oct 2008 17:13:20 +0800
>>> Li Zefan <lizf@cn.fujitsu.com> wrote:
>>>
>>>> KAMEZAWA Hiroyuki wrote:
>>>>> On Tue, 21 Oct 2008 16:35:09 +0800
>>>>> Li Zefan <lizf@cn.fujitsu.com> wrote:
>>>>>
>>>>>> KAMEZAWA Hiroyuki wrote:
>>>>>>> On Tue, 21 Oct 2008 15:21:07 +0800
>>>>>>> Li Zefan <lizf@cn.fujitsu.com> wrote:
>>>>>>>> dmesg is attached.
>>>>>>>>
>>>>>>> Thanks....I think I caught some. (added Mel Gorman to CC:)
>>>>>>>
>>>>>>> NODE_DATA(nid)->spanned_pages just means sum of zone->spanned_pages in node.
>>>>>>>
>>>>>>> So, If there is a hole between zone, node->spanned_pages doesn't mean
>>>>>>> length of node's memmap....(then, some hole can be skipped.)
>>>>>>>
>>>>>>> OMG....Could you try this ?
>>>>>>>
>>>>>> No luck, the same bug still exists. :(
>>>>>>
>>>>> This is a little fixed one..
>>>>>
>>>> I tried the patch, but it doesn't solve the problem..
>>>>
>>> Hmm.. Can you catch "pfn" of troublesome page_cgroup ?
>>> By patch like this ?
>>>
>> I got what you want:
>>
>> pc c1d589dc pc->page 00000000 page c105f67c pfn 1d5b
>> ...
>> pc c1d589f0 pc->page 00000000 page c105f6b0 pfn 1d5c
>>
> Oh! thanks...but it seems pc->page is NULL in the middle of ZONE_NORMAL..
> ==
> Normal 0x00001000 -> 0x000373fe
> ==
> This is appearently in the range of page_cgroup initialization.
> (if pgdat->node_page_cgroup is initalized correctly...)
>
> I think write to page_cgroup->page happens only at initialization.
> Hmm ? not initilization failure but curruption ?
>

Yes, curruption. I didn't find informatation about initialization failure.

> What happens if replacing __alloc_bootmem() with vmalloc() in page_cgroup.c init ?
>

So I did this change, and the box booted up without any problem.

diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c
index 5d86550..82a30b1 100644
--- a/mm/page_cgroup.c
+++ b/mm/page_cgroup.c
@@ -48,8 +48,7 @@ static int __init alloc_node_page_cgroup(int nid)

table_size = sizeof(struct page_cgroup) * nr_pages;

- base = __alloc_bootmem_node_nopanic(NODE_DATA(nid),
- table_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
+ base = vmalloc_node(table_size, nid);
if (!base)
return -ENOMEM;
for (index = 0; index < nr_pages; index++) {