Skip to content

Commit 66e0ea5

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 e5e8a22 commit 66e0ea5

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

mm/zswap.c

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,9 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
564564
return NULL;
565565
}
566566

567-
static __init struct zswap_pool *__zswap_pool_create_fallback(void)
567+
static bool zswap_try_pool_create(void)
568568
{
569+
struct zswap_pool *pool;
569570
bool has_comp, has_zpool;
570571

571572
has_comp = crypto_has_comp(zswap_compressor, 0, 0);
@@ -599,9 +600,21 @@ static __init struct zswap_pool *__zswap_pool_create_fallback(void)
599600
}
600601

601602
if (!has_comp || !has_zpool)
602-
return NULL;
603+
return false;
604+
605+
pool = zswap_pool_create(zswap_zpool_type, zswap_compressor);
606+
607+
if (pool) {
608+
pr_info("loaded using pool %s/%s\n", pool->tfm_name,
609+
zpool_get_type(pool->zpool));
610+
list_add(&pool->list, &zswap_pools);
611+
zswap_has_pool = true;
612+
} else {
613+
pr_err("pool creation failed\n");
614+
zswap_enabled = false;
615+
}
603616

604-
return zswap_pool_create(zswap_zpool_type, zswap_compressor);
617+
return zswap_enabled;
605618
}
606619

607620
static void zswap_pool_destroy(struct zswap_pool *pool)
@@ -773,16 +786,19 @@ static int zswap_zpool_param_set(const char *val,
773786
static int zswap_enabled_param_set(const char *val,
774787
const struct kernel_param *kp)
775788
{
789+
int ret;
790+
776791
if (zswap_init_failed) {
777792
pr_err("can't enable, initialization failed\n");
778793
return -ENODEV;
779794
}
780-
if (!zswap_has_pool && zswap_init_started) {
781-
pr_err("can't enable, no pool configured\n");
782-
return -ENODEV;
783-
}
784795

785-
return param_set_bool(val, kp);
796+
ret = param_set_bool(val, kp);
797+
if (!ret && zswap_enabled && zswap_init_started && !zswap_has_pool)
798+
if (!zswap_try_pool_create())
799+
ret = -ENODEV;
800+
801+
return ret;
786802
}
787803

788804
/*********************************
@@ -1297,7 +1313,6 @@ static void __exit zswap_debugfs_exit(void) { }
12971313
**********************************/
12981314
static int __init init_zswap(void)
12991315
{
1300-
struct zswap_pool *pool;
13011316
int ret;
13021317

13031318
zswap_init_started = true;
@@ -1321,20 +1336,13 @@ static int __init init_zswap(void)
13211336
if (ret)
13221337
goto hp_fail;
13231338

1324-
pool = __zswap_pool_create_fallback();
1325-
if (pool) {
1326-
pr_info("loaded using pool %s/%s\n", pool->tfm_name,
1327-
zpool_get_type(pool->zpool));
1328-
list_add(&pool->list, &zswap_pools);
1329-
zswap_has_pool = true;
1330-
} else {
1331-
pr_err("pool creation failed\n");
1332-
zswap_enabled = false;
1333-
}
1334-
13351339
frontswap_register_ops(&zswap_frontswap_ops);
13361340
if (zswap_debugfs_init())
13371341
pr_warn("debugfs initialization failed\n");
1342+
1343+
if (zswap_enabled)
1344+
zswap_try_pool_create();
1345+
13381346
return 0;
13391347

13401348
hp_fail:

0 commit comments

Comments
 (0)