Skip to content

Commit 61596d4

Browse files
committed
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 9497552 commit 61596d4

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
@@ -594,8 +594,9 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
594594
return NULL;
595595
}
596596

597-
static __init struct zswap_pool *__zswap_pool_create_fallback(void)
597+
static bool zswap_try_pool_create(void)
598598
{
599+
struct zswap_pool *pool;
599600
bool has_comp, has_zpool;
600601

601602
has_comp = crypto_has_comp(zswap_compressor, 0, 0);
@@ -629,9 +630,21 @@ static __init struct zswap_pool *__zswap_pool_create_fallback(void)
629630
}
630631

631632
if (!has_comp || !has_zpool)
632-
return NULL;
633+
return false;
634+
635+
pool = zswap_pool_create(zswap_zpool_type, zswap_compressor);
633636

634-
return zswap_pool_create(zswap_zpool_type, zswap_compressor);
637+
if (pool) {
638+
pr_info("loaded using pool %s/%s\n", pool->tfm_name,
639+
zpool_get_type(pool->zpool));
640+
list_add(&pool->list, &zswap_pools);
641+
zswap_has_pool = true;
642+
} else {
643+
pr_err("pool creation failed\n");
644+
zswap_enabled = false;
645+
}
646+
647+
return zswap_enabled;
635648
}
636649

637650
static void zswap_pool_destroy(struct zswap_pool *pool)
@@ -804,16 +817,19 @@ static int zswap_zpool_param_set(const char *val,
804817
static int zswap_enabled_param_set(const char *val,
805818
const struct kernel_param *kp)
806819
{
820+
int ret;
821+
807822
if (zswap_init_failed) {
808823
pr_err("can't enable, initialization failed\n");
809824
return -ENODEV;
810825
}
811-
if (!zswap_has_pool && zswap_init_started) {
812-
pr_err("can't enable, no pool configured\n");
813-
return -ENODEV;
814-
}
815826

816-
return param_set_bool(val, kp);
827+
ret = param_set_bool(val, kp);
828+
if (!ret && zswap_enabled && zswap_init_started && !zswap_has_pool)
829+
if (!zswap_try_pool_create())
830+
ret = -ENODEV;
831+
832+
return ret;
817833
}
818834

819835
/*********************************
@@ -1314,7 +1330,6 @@ static void __exit zswap_debugfs_exit(void) { }
13141330
**********************************/
13151331
static int __init init_zswap(void)
13161332
{
1317-
struct zswap_pool *pool;
13181333
int ret;
13191334

13201335
zswap_init_started = true;
@@ -1338,29 +1353,19 @@ static int __init init_zswap(void)
13381353
if (ret)
13391354
goto hp_fail;
13401355

1341-
pool = __zswap_pool_create_fallback();
1342-
if (pool) {
1343-
pr_info("loaded using pool %s/%s\n", pool->tfm_name,
1344-
zpool_get_type(pool->zpool));
1345-
list_add(&pool->list, &zswap_pools);
1346-
zswap_has_pool = true;
1347-
} else {
1348-
pr_err("pool creation failed\n");
1349-
zswap_enabled = false;
1350-
}
1351-
13521356
shrink_wq = create_workqueue("zswap-shrink");
13531357
if (!shrink_wq)
1354-
goto fallback_fail;
1358+
goto hp_fail;
13551359

13561360
frontswap_register_ops(&zswap_frontswap_ops);
13571361
if (zswap_debugfs_init())
13581362
pr_warn("debugfs initialization failed\n");
1363+
1364+
if (zswap_enabled)
1365+
zswap_try_pool_create();
1366+
13591367
return 0;
13601368

1361-
fallback_fail:
1362-
if (pool)
1363-
zswap_pool_destroy(pool);
13641369
hp_fail:
13651370
cpuhp_remove_state(CPUHP_MM_ZSWP_MEM_PREPARE);
13661371
dstmem_fail:

0 commit comments

Comments
 (0)