]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
zsmalloc: fix obj_to_head use page_private(page) as value but not pointer
authorHui Zhu <zhuhui@xiaomi.com>
Sat, 7 Nov 2015 00:29:26 +0000 (16:29 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 7 Nov 2015 01:50:42 +0000 (17:50 -0800)
In obj_malloc():

if (!class->huge)
/* record handle in the header of allocated chunk */
link->handle = handle;
else
/* record handle in first_page->private */
set_page_private(first_page, handle);

In the hugepage we save handle to private directly.

But in obj_to_head():

if (class->huge) {
VM_BUG_ON(!is_first_page(page));
return *(unsigned long *)page_private(page);
} else
return *(unsigned long *)obj;

It is used as a pointer.

The reason why there is no problem until now is huge-class page is born
with ZS_FULL so it can't be migrated.  However, we need this patch for
future work: "VM-aware zsmalloced page migration" to reduce external
fragmentation.

Signed-off-by: Hui Zhu <zhuhui@xiaomi.com>
Acked-by: Minchan Kim <minchan@kernel.org>
Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/zsmalloc.c

index 4396b82fabafeaad74a65149073de9298037ce57..1fe9928d0ff111a23e04bfd5cda6237a7026dd01 100644 (file)
@@ -825,7 +825,7 @@ static unsigned long obj_to_head(struct size_class *class, struct page *page,
 {
        if (class->huge) {
                VM_BUG_ON(!is_first_page(page));
-               return *(unsigned long *)page_private(page);
+               return page_private(page);
        } else
                return *(unsigned long *)obj;
 }