PM: hibernate: Support to select compression algorithm

Message ID 3776355f920c1af44490e076072f93bafdf128cc.1707740870.git.quic_nprakash@quicinc.com
State New
Headers
Series PM: hibernate: Support to select compression algorithm |

Commit Message

Nikhil V Feb. 12, 2024, 12:32 p.m. UTC
  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>
---
This patch is dependent on the patch series, [1] (patches 1/4 to 3/4).
This is picked in linux-next, [2].
 [1] https://lore.kernel.org/all/cover.1705927916.git.quic_nprakash@quicinc.com/
 [2] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/log/kernel/power?h=next-20240212

 .../admin-guide/kernel-parameters.txt         | 10 ++++
 kernel/power/hibernate.c                      | 57 ++++++++++++++++++-
 2 files changed, 64 insertions(+), 3 deletions(-)
  

Comments

Randy Dunlap Feb. 12, 2024, 7:04 p.m. UTC | #1
On 2/12/24 04:32, Nikhil V wrote:
> 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>
> ---
> This patch is dependent on the patch series, [1] (patches 1/4 to 3/4).
> This is picked in linux-next, [2].
>  [1] https://lore.kernel.org/all/cover.1705927916.git.quic_nprakash@quicinc.com/
>  [2] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/log/kernel/power?h=next-20240212
> 
>  .../admin-guide/kernel-parameters.txt         | 10 ++++
>  kernel/power/hibernate.c                      | 57 ++++++++++++++++++-
>  2 files changed, 64 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 31b3a25680d0..522155056645 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1748,6 +1748,16 @@
>  				(that will set all pages holding image data
>  				during restoration read-only).
>  

Hi,
Please add something like:


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


thanks.
  
Nikhil V Feb. 14, 2024, 7:03 a.m. UTC | #2
On 2/13/2024 12:34 AM, Randy Dunlap wrote:
> 
> 
> On 2/12/24 04:32, Nikhil V wrote:
>> 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>
>> ---
>> This patch is dependent on the patch series, [1] (patches 1/4 to 3/4).
>> This is picked in linux-next, [2].
>>   [1] https://lore.kernel.org/all/cover.1705927916.git.quic_nprakash@quicinc.com/
>>   [2] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/log/kernel/power?h=next-20240212
>>
>>   .../admin-guide/kernel-parameters.txt         | 10 ++++
>>   kernel/power/hibernate.c                      | 57 ++++++++++++++++++-
>>   2 files changed, 64 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
>> index 31b3a25680d0..522155056645 100644
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -1748,6 +1748,16 @@
>>   				(that will set all pages holding image data
>>   				during restoration read-only).
>>   
> 
> Hi,
> Please add something like:
> 
> 
>> +	hibernate.compressor= 	[HIBERNATION] Compression algorithm to be
>> +				used with hibernation.
>> +				Format: { lzo | lz4 }
> 				Default: lzo
>> +
>> +				lzo: Select LZO compression algorithm to
>> +				compress/decompress hibernation image.
>> +
>> +				lz4: Select LZ4 compression algorithm to
>> +				compress/decompress hibernation image.
>> +
>>   	highmem=nn[KMG]	[KNL,BOOT] forces the highmem zone to have an exact
>>   			size of <nn>. This works even on boxes that have no
>>   			highmem otherwise. This also works to reduce highmem
> 
> 
> thanks.

Hi @Randy,

Will update the documentation as mentioned and send the patch for review.

Thanks,
Nikhil V
  

Patch

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 31b3a25680d0..522155056645 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1748,6 +1748,16 @@ 
 				(that will set all pages holding image data
 				during restoration read-only).
 
+	hibernate.compressor= 	[HIBERNATION] Compression algorithm to be
+				used with hibernation.
+				Format: { lzo | lz4 }
+
+				lzo: Select LZO compression algorithm to
+				compress/decompress hibernation image.
+
+				lz4: Select LZ4 compression algorithm to
+				compress/decompress hibernation image.
+
 	highmem=nn[KMG]	[KNL,BOOT] forces the highmem zone to have an exact
 			size of <nn>. This works even on boxes that have no
 			highmem otherwise. This also works to reduce highmem
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 219191d6d0e8..43b1a82e800c 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -47,7 +47,7 @@  dev_t swsusp_resume_device;
 sector_t swsusp_resume_block;
 __visible int in_suspend __nosavedata;
 
-static const char *default_compressor = CONFIG_HIBERNATION_DEF_COMP;
+static char hibernate_compressor[CRYPTO_MAX_ALG_NAME] = CONFIG_HIBERNATION_DEF_COMP;
 
 /*
  * Compression/decompression algorithm to be used while saving/loading
@@ -748,7 +748,7 @@  int hibernate(void)
 	 * Query for the compression algorithm support if compression is enabled.
 	 */
 	if (!nocompress) {
-		strscpy(hib_comp_algo, default_compressor, sizeof(hib_comp_algo));
+		strscpy(hib_comp_algo, hibernate_compressor, sizeof(hib_comp_algo));
 		if (crypto_has_comp(hib_comp_algo, 0, 0) != 1) {
 			pr_err("%s compression is not available\n", hib_comp_algo);
 			return -EOPNOTSUPP;
@@ -999,7 +999,7 @@  static int software_resume(void)
 		if (swsusp_header_flags & SF_COMPRESSION_ALG_LZ4)
 			strscpy(hib_comp_algo, COMPRESSION_ALGO_LZ4, sizeof(hib_comp_algo));
 		else
-			strscpy(hib_comp_algo, default_compressor, sizeof(hib_comp_algo));
+			strscpy(hib_comp_algo, COMPRESSION_ALGO_LZO, sizeof(hib_comp_algo));
 		if (crypto_has_comp(hib_comp_algo, 0, 0) != 1) {
 			pr_err("%s compression is not available\n", hib_comp_algo);
 			error = -EOPNOTSUPP;
@@ -1422,6 +1422,57 @@  static int __init nohibernate_setup(char *str)
 	return 1;
 }
 
+static const char * const comp_alg_enabled[] = {
+#if IS_ENABLED(CONFIG_CRYPTO_LZO)
+	COMPRESSION_ALGO_LZO,
+#endif
+#if IS_ENABLED(CONFIG_CRYPTO_LZ4)
+	COMPRESSION_ALGO_LZ4,
+#endif
+};
+
+static int hibernate_compressor_param_set(const char *compressor,
+		const struct kernel_param *kp)
+{
+	unsigned int sleep_flags;
+	int index, ret;
+
+	sleep_flags = lock_system_sleep();
+
+	index = sysfs_match_string(comp_alg_enabled, compressor);
+	if (index >= 0) {
+		ret = param_set_copystring(comp_alg_enabled[index], kp);
+		if (!ret)
+			strscpy(hib_comp_algo, comp_alg_enabled[index],
+				sizeof(hib_comp_algo));
+	} else {
+		ret = index;
+	}
+
+	unlock_system_sleep(sleep_flags);
+
+	if (ret)
+		pr_debug("Cannot set specified compressor %s\n",
+			 compressor);
+
+	return ret;
+}
+
+static const struct kernel_param_ops hibernate_compressor_param_ops = {
+	.set    = hibernate_compressor_param_set,
+	.get    = param_get_string,
+};
+
+static struct kparam_string hibernate_compressor_param_string = {
+	.maxlen = sizeof(hibernate_compressor),
+	.string = hibernate_compressor,
+};
+
+module_param_cb(compressor, &hibernate_compressor_param_ops,
+		&hibernate_compressor_param_string, 0644);
+MODULE_PARM_DESC(compressor,
+		 "Compression algorithm to be used with hibernation");
+
 __setup("noresume", noresume_setup);
 __setup("resume_offset=", resume_offset_setup);
 __setup("resume=", resume_setup);