tree: git://git.cmpxchg.org/linux-mmotm.git master head: f50a6baf25034cdc74a3c2a919c455076f776944 commit: 5e656681183d9045de7815921012f5731c16eae3 [14/264] mm/zsmalloc.c: fix race condition in zs_destroy_pool config: i386-randconfig-c003-201934 (attached as .config) compiler: gcc-7 (Debian 7.4.0-10) 7.4.0 reproduce: git checkout 5e656681183d9045de7815921012f5731c16eae3 # save the attached .config to linux build tree make ARCH=i386 If you fix the issue, kindly add following tag Reported-by: kbuild test robot <lkp@xxxxxxxxx> All errors (new ones prefixed by >>): In file included from include/linux/mmzone.h:10:0, from include/linux/gfp.h:6, from include/linux/umh.h:4, from include/linux/kmod.h:9, from include/linux/module.h:13, from mm/zsmalloc.c:33: mm/zsmalloc.c: In function 'zs_create_pool': >> mm/zsmalloc.c:2415:27: error: 'struct zs_pool' has no member named 'migration_wait' init_waitqueue_head(&pool->migration_wait); ^ include/linux/wait.h:67:26: note: in definition of macro 'init_waitqueue_head' __init_waitqueue_head((wq_head), #wq_head, &__key); \ ^~~~~~~ vim +2415 mm/zsmalloc.c 2388 2389 /** 2390 * zs_create_pool - Creates an allocation pool to work from. 2391 * @name: pool name to be created 2392 * 2393 * This function must be called before anything when using 2394 * the zsmalloc allocator. 2395 * 2396 * On success, a pointer to the newly created pool is returned, 2397 * otherwise NULL. 2398 */ 2399 struct zs_pool *zs_create_pool(const char *name) 2400 { 2401 int i; 2402 struct zs_pool *pool; 2403 struct size_class *prev_class = NULL; 2404 2405 pool = kzalloc(sizeof(*pool), GFP_KERNEL); 2406 if (!pool) 2407 return NULL; 2408 2409 init_deferred_free(pool); 2410 2411 pool->name = kstrdup(name, GFP_KERNEL); 2412 if (!pool->name) 2413 goto err; 2414 > 2415 init_waitqueue_head(&pool->migration_wait); 2416 2417 if (create_cache(pool)) 2418 goto err; 2419 2420 /* 2421 * Iterate reversely, because, size of size_class that we want to use 2422 * for merging should be larger or equal to current size. 2423 */ 2424 for (i = ZS_SIZE_CLASSES - 1; i >= 0; i--) { 2425 int size; 2426 int pages_per_zspage; 2427 int objs_per_zspage; 2428 struct size_class *class; 2429 int fullness = 0; 2430 2431 size = ZS_MIN_ALLOC_SIZE + i * ZS_SIZE_CLASS_DELTA; 2432 if (size > ZS_MAX_ALLOC_SIZE) 2433 size = ZS_MAX_ALLOC_SIZE; 2434 pages_per_zspage = get_pages_per_zspage(size); 2435 objs_per_zspage = pages_per_zspage * PAGE_SIZE / size; 2436 2437 /* 2438 * We iterate from biggest down to smallest classes, 2439 * so huge_class_size holds the size of the first huge 2440 * class. Any object bigger than or equal to that will 2441 * endup in the huge class. 2442 */ 2443 if (pages_per_zspage != 1 && objs_per_zspage != 1 && 2444 !huge_class_size) { 2445 huge_class_size = size; 2446 /* 2447 * The object uses ZS_HANDLE_SIZE bytes to store the 2448 * handle. We need to subtract it, because zs_malloc() 2449 * unconditionally adds handle size before it performs 2450 * size class search - so object may be smaller than 2451 * huge class size, yet it still can end up in the huge 2452 * class because it grows by ZS_HANDLE_SIZE extra bytes 2453 * right before class lookup. 2454 */ 2455 huge_class_size -= (ZS_HANDLE_SIZE - 1); 2456 } 2457 2458 /* 2459 * size_class is used for normal zsmalloc operation such 2460 * as alloc/free for that size. Although it is natural that we 2461 * have one size_class for each size, there is a chance that we 2462 * can get more memory utilization if we use one size_class for 2463 * many different sizes whose size_class have same 2464 * characteristics. So, we makes size_class point to 2465 * previous size_class if possible. 2466 */ 2467 if (prev_class) { 2468 if (can_merge(prev_class, pages_per_zspage, objs_per_zspage)) { 2469 pool->size_class[i] = prev_class; 2470 continue; 2471 } 2472 } 2473 2474 class = kzalloc(sizeof(struct size_class), GFP_KERNEL); 2475 if (!class) 2476 goto err; 2477 2478 class->size = size; 2479 class->index = i; 2480 class->pages_per_zspage = pages_per_zspage; 2481 class->objs_per_zspage = objs_per_zspage; 2482 spin_lock_init(&class->lock); 2483 pool->size_class[i] = class; 2484 for (fullness = ZS_EMPTY; fullness < NR_ZS_FULLNESS; 2485 fullness++) 2486 INIT_LIST_HEAD(&class->fullness_list[fullness]); 2487 2488 prev_class = class; 2489 } 2490 2491 /* debug only, don't abort if it fails */ 2492 zs_pool_stat_create(pool, name); 2493 2494 if (zs_register_migration(pool)) 2495 goto err; 2496 2497 /* 2498 * Not critical since shrinker is only used to trigger internal 2499 * defragmentation of the pool which is pretty optional thing. If 2500 * registration fails we still can use the pool normally and user can 2501 * trigger compaction manually. Thus, ignore return code. 2502 */ 2503 zs_register_shrinker(pool); 2504 2505 return pool; 2506 2507 err: 2508 zs_destroy_pool(pool); 2509 return NULL; 2510 } 2511 EXPORT_SYMBOL_GPL(zs_create_pool); 2512 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Attachment:
.config.gz
Description: application/gzip