Skip to content

Commit 1f33ba4

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 d846db6 commit 1f33ba4

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
/*********************************
@@ -1492,7 +1508,6 @@ static int __init zswap_debugfs_init(void)
14921508
**********************************/
14931509
static int __init init_zswap(void)
14941510
{
1495-
struct zswap_pool *pool;
14961511
int ret;
14971512

14981513
zswap_init_started = true;
@@ -1516,33 +1531,23 @@ static int __init init_zswap(void)
15161531
if (ret)
15171532
goto hp_fail;
15181533

1519-
pool = __zswap_pool_create_fallback();
1520-
if (pool) {
1521-
pr_info("loaded using pool %s/%s\n", pool->tfm_name,
1522-
zpool_get_type(pool->zpool));
1523-
list_add(&pool->list, &zswap_pools);
1524-
zswap_has_pool = true;
1525-
} else {
1526-
pr_err("pool creation failed\n");
1527-
zswap_enabled = false;
1528-
}
1529-
15301534
shrink_wq = create_workqueue("zswap-shrink");
15311535
if (!shrink_wq)
1532-
goto fallback_fail;
1536+
goto hp_fail;
15331537

15341538
ret = frontswap_register_ops(&zswap_frontswap_ops);
15351539
if (ret)
15361540
goto destroy_wq;
15371541
if (zswap_debugfs_init())
15381542
pr_warn("debugfs initialization failed\n");
1543+
1544+
if (zswap_enabled)
1545+
zswap_try_pool_create();
1546+
15391547
return 0;
15401548

15411549
destroy_wq:
15421550
destroy_workqueue(shrink_wq);
1543-
fallback_fail:
1544-
if (pool)
1545-
zswap_pool_destroy(pool);
15461551
hp_fail:
15471552
cpuhp_remove_state(CPUHP_MM_ZSWP_MEM_PREPARE);
15481553
dstmem_fail:

0 commit comments

Comments
 (0)