Skip to content

Commit 3fec6e5

Browse files
vnikhilprakashrafaeljw
authored andcommitted
PM: hibernate: Support to select compression algorithm
Currently the default compression algorithm is selected based on compile time options. Introduce a module parameter "hibernate.compressor" to override this behaviour. Different compression algorithms have different characteristics and hibernation may benefit when it uses any of these algorithms, especially when a secondary algorithm(LZ4) offers better decompression speeds over a default algorithm(LZO), which in turn reduces hibernation image restore time. Users can override the default algorithm in two ways: 1) Passing "hibernate.compressor" as kernel command line parameter. Usage: LZO: hibernate.compressor=lzo LZ4: hibernate.compressor=lz4 2) Specifying the algorithm at runtime. Usage: LZO: echo lzo > /sys/module/hibernate/parameters/compressor LZ4: echo lz4 > /sys/module/hibernate/parameters/compressor Currently LZO and LZ4 are the supported algorithms. LZO is the default compression algorithm used with hibernation. Signed-off-by: Nikhil V <quic_nprakash@quicinc.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 9bb6c39 commit 3fec6e5

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,17 @@
17481748
(that will set all pages holding image data
17491749
during restoration read-only).
17501750

1751+
hibernate.compressor= [HIBERNATION] Compression algorithm to be
1752+
used with hibernation.
1753+
Format: { lzo | lz4 }
1754+
Default: lzo
1755+
1756+
lzo: Select LZO compression algorithm to
1757+
compress/decompress hibernation image.
1758+
1759+
lz4: Select LZ4 compression algorithm to
1760+
compress/decompress hibernation image.
1761+
17511762
highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact
17521763
size of <nn>. This works even on boxes that have no
17531764
highmem otherwise. This also works to reduce highmem

kernel/power/hibernate.c

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ dev_t swsusp_resume_device;
4747
sector_t swsusp_resume_block;
4848
__visible int in_suspend __nosavedata;
4949

50-
static const char *default_compressor = CONFIG_HIBERNATION_DEF_COMP;
50+
static char hibernate_compressor[CRYPTO_MAX_ALG_NAME] = CONFIG_HIBERNATION_DEF_COMP;
5151

5252
/*
5353
* Compression/decompression algorithm to be used while saving/loading
@@ -748,7 +748,7 @@ int hibernate(void)
748748
* Query for the compression algorithm support if compression is enabled.
749749
*/
750750
if (!nocompress) {
751-
strscpy(hib_comp_algo, default_compressor, sizeof(hib_comp_algo));
751+
strscpy(hib_comp_algo, hibernate_compressor, sizeof(hib_comp_algo));
752752
if (crypto_has_comp(hib_comp_algo, 0, 0) != 1) {
753753
pr_err("%s compression is not available\n", hib_comp_algo);
754754
return -EOPNOTSUPP;
@@ -999,7 +999,7 @@ static int software_resume(void)
999999
if (swsusp_header_flags & SF_COMPRESSION_ALG_LZ4)
10001000
strscpy(hib_comp_algo, COMPRESSION_ALGO_LZ4, sizeof(hib_comp_algo));
10011001
else
1002-
strscpy(hib_comp_algo, default_compressor, sizeof(hib_comp_algo));
1002+
strscpy(hib_comp_algo, COMPRESSION_ALGO_LZO, sizeof(hib_comp_algo));
10031003
if (crypto_has_comp(hib_comp_algo, 0, 0) != 1) {
10041004
pr_err("%s compression is not available\n", hib_comp_algo);
10051005
error = -EOPNOTSUPP;
@@ -1422,6 +1422,57 @@ static int __init nohibernate_setup(char *str)
14221422
return 1;
14231423
}
14241424

1425+
static const char * const comp_alg_enabled[] = {
1426+
#if IS_ENABLED(CONFIG_CRYPTO_LZO)
1427+
COMPRESSION_ALGO_LZO,
1428+
#endif
1429+
#if IS_ENABLED(CONFIG_CRYPTO_LZ4)
1430+
COMPRESSION_ALGO_LZ4,
1431+
#endif
1432+
};
1433+
1434+
static int hibernate_compressor_param_set(const char *compressor,
1435+
const struct kernel_param *kp)
1436+
{
1437+
unsigned int sleep_flags;
1438+
int index, ret;
1439+
1440+
sleep_flags = lock_system_sleep();
1441+
1442+
index = sysfs_match_string(comp_alg_enabled, compressor);
1443+
if (index >= 0) {
1444+
ret = param_set_copystring(comp_alg_enabled[index], kp);
1445+
if (!ret)
1446+
strscpy(hib_comp_algo, comp_alg_enabled[index],
1447+
sizeof(hib_comp_algo));
1448+
} else {
1449+
ret = index;
1450+
}
1451+
1452+
unlock_system_sleep(sleep_flags);
1453+
1454+
if (ret)
1455+
pr_debug("Cannot set specified compressor %s\n",
1456+
compressor);
1457+
1458+
return ret;
1459+
}
1460+
1461+
static const struct kernel_param_ops hibernate_compressor_param_ops = {
1462+
.set = hibernate_compressor_param_set,
1463+
.get = param_get_string,
1464+
};
1465+
1466+
static struct kparam_string hibernate_compressor_param_string = {
1467+
.maxlen = sizeof(hibernate_compressor),
1468+
.string = hibernate_compressor,
1469+
};
1470+
1471+
module_param_cb(compressor, &hibernate_compressor_param_ops,
1472+
&hibernate_compressor_param_string, 0644);
1473+
MODULE_PARM_DESC(compressor,
1474+
"Compression algorithm to be used with hibernation");
1475+
14251476
__setup("noresume", noresume_setup);
14261477
__setup("resume_offset=", resume_offset_setup);
14271478
__setup("resume=", resume_setup);

0 commit comments

Comments
 (0)