Skip to content

Commit 2dca87d

Browse files
pelwellpopcornmix
authored andcommitted
zswap: Defer zswap initialisation
Enabling zswap support in the kernel configuration costs about 1.5MB of RAM, even when zswap is not enabled at runtime. This cost can be reduced significantly by deferring initialisation (including pool creation) until the "enabled" parameter is set to true. There is a small cost to this in that some initialisation code has to remain in memory after the init phase, just in case they are needed later, but the total size increase is negligible. See: #3432 Signed-off-by: Phil Elwell <[email protected]>
1 parent 2cd69c1 commit 2dca87d

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

mm/zswap.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -663,8 +663,9 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
663663
return NULL;
664664
}
665665

666-
static __init struct zswap_pool *__zswap_pool_create_fallback(void)
666+
static bool zswap_try_pool_create(void)
667667
{
668+
struct zswap_pool *pool;
668669
bool has_comp, has_zpool;
669670

670671
has_comp = crypto_has_acomp(zswap_compressor, 0, 0);
@@ -700,9 +701,21 @@ static __init struct zswap_pool *__zswap_pool_create_fallback(void)
700701
}
701702

702703
if (!has_comp || !has_zpool)
703-
return NULL;
704+
return false;
705+
706+
pool = zswap_pool_create(zswap_zpool_type, zswap_compressor);
704707

705-
return zswap_pool_create(zswap_zpool_type, zswap_compressor);
708+
if (pool) {
709+
pr_info("loaded using pool %s/%s\n", pool->tfm_name,
710+
zpool_get_type(pool->zpool));
711+
list_add(&pool->list, &zswap_pools);
712+
zswap_has_pool = true;
713+
} else {
714+
pr_err("pool creation failed\n");
715+
zswap_enabled = false;
716+
}
717+
718+
return zswap_enabled;
706719
}
707720

708721
static void zswap_pool_destroy(struct zswap_pool *pool)
@@ -875,16 +888,19 @@ static int zswap_zpool_param_set(const char *val,
875888
static int zswap_enabled_param_set(const char *val,
876889
const struct kernel_param *kp)
877890
{
891+
int ret;
892+
878893
if (zswap_init_failed) {
879894
pr_err("can't enable, initialization failed\n");
880895
return -ENODEV;
881896
}
882-
if (!zswap_has_pool && zswap_init_started) {
883-
pr_err("can't enable, no pool configured\n");
884-
return -ENODEV;
885-
}
886897

887-
return param_set_bool(val, kp);
898+
ret = param_set_bool(val, kp);
899+
if (!ret && zswap_enabled && zswap_init_started && !zswap_has_pool)
900+
if (!zswap_try_pool_create())
901+
ret = -ENODEV;
902+
903+
return ret;
888904
}
889905

890906
/*********************************
@@ -1473,7 +1489,6 @@ static int __init zswap_debugfs_init(void)
14731489
**********************************/
14741490
static int __init init_zswap(void)
14751491
{
1476-
struct zswap_pool *pool;
14771492
int ret;
14781493

14791494
zswap_init_started = true;
@@ -1497,33 +1512,23 @@ static int __init init_zswap(void)
14971512
if (ret)
14981513
goto hp_fail;
14991514

1500-
pool = __zswap_pool_create_fallback();
1501-
if (pool) {
1502-
pr_info("loaded using pool %s/%s\n", pool->tfm_name,
1503-
zpool_get_type(pool->zpool));
1504-
list_add(&pool->list, &zswap_pools);
1505-
zswap_has_pool = true;
1506-
} else {
1507-
pr_err("pool creation failed\n");
1508-
zswap_enabled = false;
1509-
}
1510-
15111515
shrink_wq = create_workqueue("zswap-shrink");
15121516
if (!shrink_wq)
1513-
goto fallback_fail;
1517+
goto hp_fail;
15141518

15151519
ret = frontswap_register_ops(&zswap_frontswap_ops);
15161520
if (ret)
15171521
goto destroy_wq;
15181522
if (zswap_debugfs_init())
15191523
pr_warn("debugfs initialization failed\n");
1524+
1525+
if (zswap_enabled)
1526+
zswap_try_pool_create();
1527+
15201528
return 0;
15211529

15221530
destroy_wq:
15231531
destroy_workqueue(shrink_wq);
1524-
fallback_fail:
1525-
if (pool)
1526-
zswap_pool_destroy(pool);
15271532
hp_fail:
15281533
cpuhp_remove_state(CPUHP_MM_ZSWP_MEM_PREPARE);
15291534
dstmem_fail:

0 commit comments

Comments
 (0)