Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

zram: remove chained recompression

Chained recompression has unpredictable behavior and is not useful in
practice.

First, systems usually configure just one alternative recompression
algorithm, which has slower compression/decompression but better
compression ratio. A single alternative algorithm doesn't need chaining.

Second, even with multiple recompression algorithms, chained recompression
is suboptimal. If a lower priority algorithm succeeds, the page is never
attempted with a higher priority algorithm, leading to worse memory
savings. If a lower priority algorithm fails, the page is still attempted
with a higher priority algorithm, wasting resources on the failed lower
priority attempt.

In either case, the system would be better off targeting a specific
priority directly.

Chained recompression also significantly complicates the code. Remove it.

Link: https://lkml.kernel.org/r/20260311084312.1766036-6-senozhatsky@chromium.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Cc: Brian Geffon <bgeffon@google.com>
Cc: gao xu <gaoxu2@honor.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Minchan Kim <minchan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Sergey Senozhatsky and committed by
Andrew Morton
cedfa028 be5f13d9

+24 -69
-9
Documentation/admin-guide/blockdev/zram.rst
··· 533 533 priorities (e.g. different parameters). `priority` is the only way to 534 534 guarantee that the expected algorithm will be used. 535 535 536 - During re-compression for every page, that matches re-compression criteria, 537 - ZRAM iterates the list of registered alternative compression algorithms in 538 - order of their priorities. ZRAM stops either when re-compression was 539 - successful (re-compressed object is smaller in size than the original one) 540 - and matches re-compression criteria (e.g. size threshold) or when there are 541 - no secondary algorithms left to try. If none of the secondary algorithms can 542 - successfully re-compressed the page such a page is marked as incompressible, 543 - so ZRAM will not attempt to re-compress it in the future. 544 - 545 536 memory tracking 546 537 =============== 547 538
+24 -60
drivers/block/zram/zram_drv.c
··· 2336 2336 return true; 2337 2337 } 2338 2338 2339 - static int scan_slots_for_recompress(struct zram *zram, u32 mode, u32 prio_max, 2339 + static int scan_slots_for_recompress(struct zram *zram, u32 mode, u32 prio, 2340 2340 struct zram_pp_ctl *ctl) 2341 2341 { 2342 2342 unsigned long nr_pages = zram->disksize >> PAGE_SHIFT; ··· 2362 2362 test_slot_flag(zram, index, ZRAM_INCOMPRESSIBLE)) 2363 2363 goto next; 2364 2364 2365 - /* Already compressed with same of higher priority */ 2366 - if (get_slot_comp_priority(zram, index) + 1 >= prio_max) 2365 + /* Already compressed with same or higher priority */ 2366 + if (get_slot_comp_priority(zram, index) >= prio) 2367 2367 goto next; 2368 2368 2369 2369 ok = place_pp_slot(zram, ctl, index); ··· 2384 2384 * Corresponding ZRAM slot should be locked. 2385 2385 */ 2386 2386 static int recompress_slot(struct zram *zram, u32 index, struct page *page, 2387 - u64 *num_recomp_pages, u32 threshold, u32 prio, 2388 - u32 prio_max) 2387 + u64 *num_recomp_pages, u32 threshold, u32 prio) 2389 2388 { 2390 2389 struct zcomp_strm *zstrm = NULL; 2391 2390 unsigned long handle_old; ··· 2395 2396 unsigned int class_index_new; 2396 2397 void *src; 2397 2398 int ret = 0; 2399 + 2400 + if (!zram->comps[prio]) 2401 + return -EINVAL; 2398 2402 2399 2403 handle_old = get_slot_handle(zram, index); 2400 2404 if (!handle_old) ··· 2421 2419 */ 2422 2420 clear_slot_flag(zram, index, ZRAM_IDLE); 2423 2421 2424 - class_index_old = zs_lookup_class_index(zram->mem_pool, comp_len_old); 2425 - 2426 - prio = max(prio, get_slot_comp_priority(zram, index) + 1); 2427 - /* 2428 - * Recompression slots scan should not select slots that are 2429 - * already compressed with a higher priority algorithm, but 2430 - * just in case 2431 - */ 2432 - if (prio >= prio_max) 2433 - return 0; 2434 - 2435 - /* 2436 - * Iterate the secondary comp algorithms list (in order of priority) 2437 - * and try to recompress the page. 2438 - */ 2439 - for (; prio < prio_max; prio++) { 2440 - if (!zram->comps[prio]) 2441 - continue; 2442 - 2443 - zstrm = zcomp_stream_get(zram->comps[prio]); 2444 - src = kmap_local_page(page); 2445 - ret = zcomp_compress(zram->comps[prio], zstrm, 2446 - src, &comp_len_new); 2447 - kunmap_local(src); 2448 - 2449 - if (ret) { 2450 - zcomp_stream_put(zstrm); 2451 - zstrm = NULL; 2452 - break; 2453 - } 2454 - 2455 - class_index_new = zs_lookup_class_index(zram->mem_pool, 2456 - comp_len_new); 2457 - 2458 - /* Continue until we make progress */ 2459 - if (class_index_new >= class_index_old || 2460 - (threshold && comp_len_new >= threshold)) { 2461 - zcomp_stream_put(zstrm); 2462 - zstrm = NULL; 2463 - continue; 2464 - } 2465 - 2466 - /* Recompression was successful so break out */ 2467 - break; 2468 - } 2422 + zstrm = zcomp_stream_get(zram->comps[prio]); 2423 + src = kmap_local_page(page); 2424 + ret = zcomp_compress(zram->comps[prio], zstrm, src, &comp_len_new); 2425 + kunmap_local(src); 2469 2426 2470 2427 /* 2471 2428 * Decrement the limit (if set) on pages we can recompress, even ··· 2435 2474 if (*num_recomp_pages) 2436 2475 *num_recomp_pages -= 1; 2437 2476 2438 - /* Compression error */ 2439 - if (ret) 2477 + if (ret) { 2478 + zcomp_stream_put(zstrm); 2440 2479 return ret; 2480 + } 2441 2481 2442 - if (!zstrm) { 2482 + class_index_old = zs_lookup_class_index(zram->mem_pool, comp_len_old); 2483 + class_index_new = zs_lookup_class_index(zram->mem_pool, comp_len_new); 2484 + 2485 + if (class_index_new >= class_index_old || 2486 + (threshold && comp_len_new >= threshold)) { 2487 + zcomp_stream_put(zstrm); 2488 + 2443 2489 /* 2444 2490 * Secondary algorithms failed to re-compress the page 2445 2491 * in a way that would save memory. ··· 2496 2528 struct device_attribute *attr, 2497 2529 const char *buf, size_t len) 2498 2530 { 2499 - u32 prio = ZRAM_SECONDARY_COMP, prio_max = ZRAM_MAX_COMPS; 2500 2531 struct zram *zram = dev_to_zram(dev); 2501 2532 char *args, *param, *val, *algo = NULL; 2502 2533 u64 num_recomp_pages = ULLONG_MAX; 2503 2534 struct zram_pp_ctl *ctl = NULL; 2535 + u32 prio = ZRAM_SECONDARY_COMP; 2504 2536 struct zram_pp_slot *pps; 2505 2537 u32 mode = 0, threshold = 0; 2506 2538 struct page *page = NULL; ··· 2554 2586 ret = kstrtouint(val, 10, &prio); 2555 2587 if (ret) 2556 2588 return ret; 2557 - 2558 - prio_max = min(prio + 1, ZRAM_MAX_COMPS); 2559 2589 continue; 2560 2590 } 2561 2591 } ··· 2573 2607 continue; 2574 2608 2575 2609 if (!strcmp(zram->comp_algs[prio], algo)) { 2576 - prio_max = min(prio + 1, ZRAM_MAX_COMPS); 2577 2610 found = true; 2578 2611 break; 2579 2612 } ··· 2601 2636 goto out; 2602 2637 } 2603 2638 2604 - scan_slots_for_recompress(zram, mode, prio_max, ctl); 2639 + scan_slots_for_recompress(zram, mode, prio, ctl); 2605 2640 2606 2641 ret = len; 2607 2642 while ((pps = select_pp_slot(ctl))) { ··· 2615 2650 goto next; 2616 2651 2617 2652 err = recompress_slot(zram, pps->index, page, 2618 - &num_recomp_pages, threshold, 2619 - prio, prio_max); 2653 + &num_recomp_pages, threshold, prio); 2620 2654 next: 2621 2655 slot_unlock(zram, pps->index); 2622 2656 release_pp_slot(zram, pps);