Re: [PATCH 1/2] mm/zsmalloc: don't hold locks of all pages when free_zspage()

From: Chengming Zhou
Date: Wed Feb 28 2024 - 00:15:19 EST


On 2024/2/28 12:33, Sergey Senozhatsky wrote:
> On (24/02/27 03:02), Chengming Zhou wrote:
> [..]
>> @@ -978,10 +974,11 @@ static struct zspage *alloc_zspage(struct zs_pool *pool,
>> pages[i] = page;
>> }
>>
>> - create_page_chain(class, zspage, pages);
>> init_zspage(class, zspage);
>> zspage->pool = pool;
>> zspage->class = class->index;
>> + /* RCU set_zspage() after zspage initialized. */
>> + create_page_chain(class, zspage, pages);
>
> So this hasn't been tested, has it?
I have tested it in my test vm, but it hasn't KASAN enabled. I tested the
kernel build in tmpfs with zswap enabled using zsmalloc pool, not sure
why the kernel didn't crash then...

>
> init_zspage() does not like to be invoked before create_page_chain(),
> because we haven't setup required pointers yet.

You're right, I can reproduce the problem with KASAN enabled this time,
create_page_chain() should be put before init_zspage(), which will iterate
over the pages to create free objects list.

>
> So when init_zspage() calls get_first_page() it gets NULL zspage->first_page
> which we then use in is_first_page(first_page)->PagePrivate(page). As far as
> I can tell.

Thanks! I will fix it and test throughly before send an update.