Skip to content

Commit e91d8d7

Browse files
minchanktorvalds
authored andcommitted
mm/zsmalloc.c: drop ZSMALLOC_PGTABLE_MAPPING
While I was doing zram testing, I found sometimes decompression failed since the compression buffer was corrupted. With investigation, I found below commit calls cond_resched unconditionally so it could make a problem in atomic context if the task is reschedule. BUG: sleeping function called from invalid context at mm/vmalloc.c:108 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 946, name: memhog 3 locks held by memhog/946: #0: ffff9d01d4b193e8 (&mm->mmap_lock#2){++++}-{4:4}, at: __mm_populate+0x103/0x160 #1: ffffffffa3d53de0 (fs_reclaim){+.+.}-{0:0}, at: __alloc_pages_slowpath.constprop.0+0xa98/0x1160 #2: ffff9d01d56b8110 (&zspage->lock){.+.+}-{3:3}, at: zs_map_object+0x8e/0x1f0 CPU: 0 PID: 946 Comm: memhog Not tainted 5.9.3-00011-gc5bfc0287345-dirty #316 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014 Call Trace: unmap_kernel_range_noflush+0x2eb/0x350 unmap_kernel_range+0x14/0x30 zs_unmap_object+0xd5/0xe0 zram_bvec_rw.isra.0+0x38c/0x8e0 zram_rw_page+0x90/0x101 bdev_write_page+0x92/0xe0 __swap_writepage+0x94/0x4a0 pageout+0xe3/0x3a0 shrink_page_list+0xb94/0xd60 shrink_inactive_list+0x158/0x460 We can fix this by removing the ZSMALLOC_PGTABLE_MAPPING feature (which contains the offending calling code) from zsmalloc. Even though this option showed some amount improvement(e.g., 30%) in some arm32 platforms, it has been headache to maintain since it have abused APIs[1](e.g., unmap_kernel_range in atomic context). Since we are approaching to deprecate 32bit machines and already made the config option available for only builtin build since v5.8, lastly it has been not default option in zsmalloc, it's time to drop the option for better maintenance. [1] http://lore.kernel.org/linux-mm/[email protected] Fixes: e47110e ("mm/vunmap: add cond_resched() in vunmap_pmd_range") Signed-off-by: Minchan Kim <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Reviewed-by: Sergey Senozhatsky <[email protected]> Cc: Tony Lindgren <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Harish Sriram <[email protected]> Cc: Uladzislau Rezki <[email protected]> Cc: <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Linus Torvalds <[email protected]>
1 parent 8199be0 commit e91d8d7

File tree

4 files changed

+0
-69
lines changed

4 files changed

+0
-69
lines changed

arch/arm/configs/omap2plus_defconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ CONFIG_PARTITION_ADVANCED=y
8181
CONFIG_BINFMT_MISC=y
8282
CONFIG_CMA=y
8383
CONFIG_ZSMALLOC=m
84-
CONFIG_ZSMALLOC_PGTABLE_MAPPING=y
8584
CONFIG_NET=y
8685
CONFIG_PACKET=y
8786
CONFIG_UNIX=y

include/linux/zsmalloc.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
* zsmalloc mapping modes
2121
*
2222
* NOTE: These only make a difference when a mapped object spans pages.
23-
* They also have no effect when ZSMALLOC_PGTABLE_MAPPING is selected.
2423
*/
2524
enum zs_mapmode {
2625
ZS_MM_RW, /* normal read-write mapping */

mm/Kconfig

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -707,19 +707,6 @@ config ZSMALLOC
707707
returned by an alloc(). This handle must be mapped in order to
708708
access the allocated space.
709709

710-
config ZSMALLOC_PGTABLE_MAPPING
711-
bool "Use page table mapping to access object in zsmalloc"
712-
depends on ZSMALLOC=y
713-
help
714-
By default, zsmalloc uses a copy-based object mapping method to
715-
access allocations that span two pages. However, if a particular
716-
architecture (ex, ARM) performs VM mapping faster than copying,
717-
then you should select this. This causes zsmalloc to use page table
718-
mapping rather than copying for object mapping.
719-
720-
You can check speed with zsmalloc benchmark:
721-
https://github.com/spartacus06/zsmapbench
722-
723710
config ZSMALLOC_STAT
724711
bool "Export zsmalloc statistics"
725712
depends on ZSMALLOC

mm/zsmalloc.c

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,7 @@ struct zspage {
293293
};
294294

295295
struct mapping_area {
296-
#ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
297-
struct vm_struct *vm; /* vm area for mapping object that span pages */
298-
#else
299296
char *vm_buf; /* copy buffer for objects that span pages */
300-
#endif
301297
char *vm_addr; /* address of kmap_atomic()'ed pages */
302298
enum zs_mapmode vm_mm; /* mapping mode */
303299
};
@@ -1113,54 +1109,6 @@ static struct zspage *find_get_zspage(struct size_class *class)
11131109
return zspage;
11141110
}
11151111

1116-
#ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
1117-
static inline int __zs_cpu_up(struct mapping_area *area)
1118-
{
1119-
/*
1120-
* Make sure we don't leak memory if a cpu UP notification
1121-
* and zs_init() race and both call zs_cpu_up() on the same cpu
1122-
*/
1123-
if (area->vm)
1124-
return 0;
1125-
area->vm = get_vm_area(PAGE_SIZE * 2, 0);
1126-
if (!area->vm)
1127-
return -ENOMEM;
1128-
1129-
/*
1130-
* Populate ptes in advance to avoid pte allocation with GFP_KERNEL
1131-
* in non-preemtible context of zs_map_object.
1132-
*/
1133-
return apply_to_page_range(&init_mm, (unsigned long)area->vm->addr,
1134-
PAGE_SIZE * 2, NULL, NULL);
1135-
}
1136-
1137-
static inline void __zs_cpu_down(struct mapping_area *area)
1138-
{
1139-
if (area->vm)
1140-
free_vm_area(area->vm);
1141-
area->vm = NULL;
1142-
}
1143-
1144-
static inline void *__zs_map_object(struct mapping_area *area,
1145-
struct page *pages[2], int off, int size)
1146-
{
1147-
unsigned long addr = (unsigned long)area->vm->addr;
1148-
1149-
BUG_ON(map_kernel_range(addr, PAGE_SIZE * 2, PAGE_KERNEL, pages) < 0);
1150-
area->vm_addr = area->vm->addr;
1151-
return area->vm_addr + off;
1152-
}
1153-
1154-
static inline void __zs_unmap_object(struct mapping_area *area,
1155-
struct page *pages[2], int off, int size)
1156-
{
1157-
unsigned long addr = (unsigned long)area->vm_addr;
1158-
1159-
unmap_kernel_range(addr, PAGE_SIZE * 2);
1160-
}
1161-
1162-
#else /* CONFIG_ZSMALLOC_PGTABLE_MAPPING */
1163-
11641112
static inline int __zs_cpu_up(struct mapping_area *area)
11651113
{
11661114
/*
@@ -1241,8 +1189,6 @@ static void __zs_unmap_object(struct mapping_area *area,
12411189
pagefault_enable();
12421190
}
12431191

1244-
#endif /* CONFIG_ZSMALLOC_PGTABLE_MAPPING */
1245-
12461192
static int zs_cpu_prepare(unsigned int cpu)
12471193
{
12481194
struct mapping_area *area;

0 commit comments

Comments
 (0)