Skip to content

Commit 21923a9

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 a90c8a9 commit 21923a9

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
/*********************************
@@ -1476,7 +1492,6 @@ static int __init zswap_debugfs_init(void)
14761492
**********************************/
14771493
static int __init init_zswap(void)
14781494
{
1479-
struct zswap_pool *pool;
14801495
int ret;
14811496

14821497
zswap_init_started = true;
@@ -1500,33 +1515,23 @@ static int __init init_zswap(void)
15001515
if (ret)
15011516
goto hp_fail;
15021517

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

15181522
ret = frontswap_register_ops(&zswap_frontswap_ops);
15191523
if (ret)
15201524
goto destroy_wq;
15211525
if (zswap_debugfs_init())
15221526
pr_warn("debugfs initialization failed\n");
1527+
1528+
if (zswap_enabled)
1529+
zswap_try_pool_create();
1530+
15231531
return 0;
15241532

15251533
destroy_wq:
15261534
destroy_workqueue(shrink_wq);
1527-
fallback_fail:
1528-
if (pool)
1529-
zswap_pool_destroy(pool);
15301535
hp_fail:
15311536
cpuhp_remove_state(CPUHP_MM_ZSWP_MEM_PREPARE);
15321537
dstmem_fail:

0 commit comments

Comments
 (0)