Skip to content

Commit c42aa77

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 0cfd902 commit c42aa77

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
/*********************************
@@ -1499,7 +1515,6 @@ static int __init zswap_debugfs_init(void)
14991515
**********************************/
15001516
static int __init init_zswap(void)
15011517
{
1502-
struct zswap_pool *pool;
15031518
int ret;
15041519

15051520
zswap_init_started = true;
@@ -1523,33 +1538,23 @@ static int __init init_zswap(void)
15231538
if (ret)
15241539
goto hp_fail;
15251540

1526-
pool = __zswap_pool_create_fallback();
1527-
if (pool) {
1528-
pr_info("loaded using pool %s/%s\n", pool->tfm_name,
1529-
zpool_get_type(pool->zpool));
1530-
list_add(&pool->list, &zswap_pools);
1531-
zswap_has_pool = true;
1532-
} else {
1533-
pr_err("pool creation failed\n");
1534-
zswap_enabled = false;
1535-
}
1536-
15371541
shrink_wq = create_workqueue("zswap-shrink");
15381542
if (!shrink_wq)
1539-
goto fallback_fail;
1543+
goto hp_fail;
15401544

15411545
ret = frontswap_register_ops(&zswap_frontswap_ops);
15421546
if (ret)
15431547
goto destroy_wq;
15441548
if (zswap_debugfs_init())
15451549
pr_warn("debugfs initialization failed\n");
1550+
1551+
if (zswap_enabled)
1552+
zswap_try_pool_create();
1553+
15461554
return 0;
15471555

15481556
destroy_wq:
15491557
destroy_workqueue(shrink_wq);
1550-
fallback_fail:
1551-
if (pool)
1552-
zswap_pool_destroy(pool);
15531558
hp_fail:
15541559
cpuhp_remove_state(CPUHP_MM_ZSWP_MEM_PREPARE);
15551560
dstmem_fail:

0 commit comments

Comments
 (0)