Skip to content

Commit 8418a46

Browse files
committed
mm: 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 __init functions have to remain in memory after the init phase, just in case they are needed later, but the total size is negligible. See: #3432 Signed-off-by: Phil Elwell <[email protected]>
1 parent 9da67d7 commit 8418a46

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

mm/zswap.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ static bool zswap_has_pool;
212212
static int zswap_writeback_entry(struct zpool *pool, unsigned long handle);
213213
static int zswap_pool_get(struct zswap_pool *pool);
214214
static void zswap_pool_put(struct zswap_pool *pool);
215+
static int init_zswap(void);
215216

216217
static const struct zpool_ops zswap_zpool_ops = {
217218
.evict = zswap_writeback_entry
@@ -243,13 +244,13 @@ static void zswap_update_total_size(void)
243244
**********************************/
244245
static struct kmem_cache *zswap_entry_cache;
245246

246-
static int __init zswap_entry_cache_create(void)
247+
static int zswap_entry_cache_create(void)
247248
{
248249
zswap_entry_cache = KMEM_CACHE(zswap_entry, 0);
249250
return zswap_entry_cache == NULL;
250251
}
251252

252-
static void __init zswap_entry_cache_destroy(void)
253+
static void zswap_entry_cache_destroy(void)
253254
{
254255
kmem_cache_destroy(zswap_entry_cache);
255256
}
@@ -573,7 +574,7 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
573574
return NULL;
574575
}
575576

576-
static __init struct zswap_pool *__zswap_pool_create_fallback(void)
577+
static struct zswap_pool *__zswap_pool_create_fallback(void)
577578
{
578579
bool has_comp, has_zpool;
579580

@@ -770,28 +771,30 @@ static int __zswap_param_set(const char *val, const struct kernel_param *kp,
770771
static int zswap_compressor_param_set(const char *val,
771772
const struct kernel_param *kp)
772773
{
773-
return __zswap_param_set(val, kp, zswap_zpool_type, NULL);
774+
return __zswap_param_set(val, kp, NULL, zswap_compressor);
774775
}
775776

776777
static int zswap_zpool_param_set(const char *val,
777778
const struct kernel_param *kp)
778779
{
779-
return __zswap_param_set(val, kp, NULL, zswap_compressor);
780+
return __zswap_param_set(val, kp, zswap_zpool_type, NULL);
780781
}
781782

782783
static int zswap_enabled_param_set(const char *val,
783784
const struct kernel_param *kp)
784785
{
786+
int ret;
787+
785788
if (zswap_init_failed) {
786789
pr_err("can't enable, initialization failed\n");
787790
return -ENODEV;
788791
}
789-
if (!zswap_has_pool && zswap_init_started) {
790-
pr_err("can't enable, no pool configured\n");
791-
return -ENODEV;
792-
}
793792

794-
return param_set_bool(val, kp);
793+
ret = param_set_bool(val, kp);
794+
if (!ret && zswap_enabled && zswap_init_started && !zswap_has_pool)
795+
ret = init_zswap();
796+
797+
return ret;
795798
}
796799

797800
/*********************************
@@ -1256,7 +1259,7 @@ static struct frontswap_ops zswap_frontswap_ops = {
12561259

12571260
static struct dentry *zswap_debugfs_root;
12581261

1259-
static int __init zswap_debugfs_init(void)
1262+
static int zswap_debugfs_init(void)
12601263
{
12611264
if (!debugfs_initialized())
12621265
return -ENODEV;
@@ -1294,7 +1297,7 @@ static void __exit zswap_debugfs_exit(void)
12941297
debugfs_remove_recursive(zswap_debugfs_root);
12951298
}
12961299
#else
1297-
static int __init zswap_debugfs_init(void)
1300+
static int zswap_debugfs_init(void)
12981301
{
12991302
return 0;
13001303
}
@@ -1305,13 +1308,16 @@ static void __exit zswap_debugfs_exit(void) { }
13051308
/*********************************
13061309
* module init and exit
13071310
**********************************/
1308-
static int __init init_zswap(void)
1311+
static int init_zswap(void)
13091312
{
13101313
struct zswap_pool *pool;
13111314
int ret;
13121315

13131316
zswap_init_started = true;
13141317

1318+
if (!zswap_enabled)
1319+
return 0;
1320+
13151321
if (zswap_entry_cache_create()) {
13161322
pr_err("entry cache creation failed\n");
13171323
goto cache_fail;
@@ -1340,6 +1346,7 @@ static int __init init_zswap(void)
13401346
} else {
13411347
pr_err("pool creation failed\n");
13421348
zswap_enabled = false;
1349+
zswap_init_failed = true;
13431350
}
13441351

13451352
frontswap_register_ops(&zswap_frontswap_ops);

0 commit comments

Comments
 (0)