]> www.infradead.org Git - users/hch/configfs.git/commitdiff
squashfs: allows users to configure the number of decompression threads
authorXiaoming Ni <nixiaoming@huawei.com>
Wed, 19 Oct 2022 03:09:30 +0000 (11:09 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 18 Nov 2022 21:55:08 +0000 (13:55 -0800)
The maximum number of threads in the decompressor_multi.c file is fixed
and cannot be adjusted according to user needs.  Therefore, the mount
parameter needs to be added to allow users to configure the number of
threads as required.  The upper limit is num_online_cpus() * 2.

Link: https://lkml.kernel.org/r/20221019030930.130456-3-nixiaoming@huawei.com
Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
Reviewed-by: Phillip Lougher <phillip@squashfs.org.uk>
Cc: Jianguo Chen <chenjianguo3@huawei.com>
Cc: Jubin Zhong <zhongjubin@huawei.com>
Cc: Zhang Yi <yi.zhang@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/squashfs/Kconfig
fs/squashfs/decompressor_multi.c
fs/squashfs/squashfs_fs_sb.h
fs/squashfs/super.c

index 218bacdd4298fd8b6ba3460f469086e249abac6f..60fc98bdf421272c7c125e1fd6ba1d9ae3369f66 100644 (file)
@@ -73,11 +73,10 @@ config SQUASHFS_CHOICE_DECOMP_BY_MOUNT
        select SQUASHFS_DECOMP_SINGLE
        select SQUASHFS_DECOMP_MULTI
        select SQUASHFS_DECOMP_MULTI_PERCPU
+       select SQUASHFS_MOUNT_DECOMP_THREADS
        help
          Compile all parallel decompression modes and specify the
          decompression mode by setting "threads=" during mount.
-           threads=<single|multi|percpu>
-
          default Decompressor parallelisation is SQUASHFS_DECOMP_SINGLE
 
 choice
@@ -127,6 +126,19 @@ config SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU
          decompression is load-balanced across the cores.
 endchoice
 
+config SQUASHFS_MOUNT_DECOMP_THREADS
+       bool "Add the mount parameter 'threads=' for squashfs"
+       depends on SQUASHFS
+       depends on SQUASHFS_DECOMP_MULTI
+       default n
+       help
+         Use threads= to set the decompression parallel mode and the number of threads.
+         If SQUASHFS_CHOICE_DECOMP_BY_MOUNT=y
+             threads=<single|multi|percpu|1|2|3|...>
+         else
+             threads=<2|3|...>
+         The upper limit is num_online_cpus() * 2.
+
 config SQUASHFS_XATTR
        bool "Squashfs XATTR support"
        depends on SQUASHFS
index eb25432bd1494eecd3a4cfe3eb6ceb0b10b50b54..416c53eedbd1d39fc50204bf0070d56aabafdb99 100644 (file)
@@ -144,7 +144,7 @@ static struct decomp_stream *get_decomp_stream(struct squashfs_sb_info *msblk,
                 * If there is no available decomp and already full,
                 * let's wait for releasing decomp from other users.
                 */
-               if (stream->avail_decomp >= MAX_DECOMPRESSOR)
+               if (stream->avail_decomp >= msblk->max_thread_num)
                        goto wait;
 
                /* Let's allocate new decomp */
@@ -160,7 +160,7 @@ static struct decomp_stream *get_decomp_stream(struct squashfs_sb_info *msblk,
                }
 
                stream->avail_decomp++;
-               WARN_ON(stream->avail_decomp > MAX_DECOMPRESSOR);
+               WARN_ON(stream->avail_decomp > msblk->max_thread_num);
 
                mutex_unlock(&stream->mutex);
                break;
index f1e5dad8ae0afc8e785024a1e63c226713be10d0..659082e9e51d6f93175800faba8c765d6b1fae9e 100644 (file)
@@ -67,5 +67,6 @@ struct squashfs_sb_info {
        unsigned int                            ids;
        bool                                    panic_on_errors;
        const struct squashfs_decompressor_thread_ops *thread_ops;
+       int                                     max_thread_num;
 };
 #endif
index aac3ea72a9ba76ed98e542dba0714ef73d34480e..1e428ca9414e792c5604676e8b0c0f38a569b714 100644 (file)
@@ -53,6 +53,7 @@ enum squashfs_param {
 struct squashfs_mount_opts {
        enum Opt_errors errors;
        const struct squashfs_decompressor_thread_ops *thread_ops;
+       int thread_num;
 };
 
 static const struct constant_table squashfs_param_errors[] = {
@@ -67,7 +68,8 @@ static const struct fs_parameter_spec squashfs_fs_parameters[] = {
        {}
 };
 
-static int squashfs_parse_param_threads(const char *str, struct squashfs_mount_opts *opts)
+
+static int squashfs_parse_param_threads_str(const char *str, struct squashfs_mount_opts *opts)
 {
 #ifdef CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT
        if (strcmp(str, "single") == 0) {
@@ -86,6 +88,42 @@ static int squashfs_parse_param_threads(const char *str, struct squashfs_mount_o
        return -EINVAL;
 }
 
+static int squashfs_parse_param_threads_num(const char *str, struct squashfs_mount_opts *opts)
+{
+#ifdef CONFIG_SQUASHFS_MOUNT_DECOMP_THREADS
+       int ret;
+       unsigned long num;
+
+       ret = kstrtoul(str, 0, &num);
+       if (ret != 0)
+               return -EINVAL;
+       if (num > 1) {
+               opts->thread_ops = &squashfs_decompressor_multi;
+               if (num > opts->thread_ops->max_decompressors())
+                       return -EINVAL;
+               opts->thread_num = (int)num;
+               return 0;
+       }
+#ifdef CONFIG_SQUASHFS_DECOMP_SINGLE
+       if (num == 1) {
+               opts->thread_ops = &squashfs_decompressor_single;
+               opts->thread_num = 1;
+               return 0;
+       }
+#endif
+#endif /* !CONFIG_SQUASHFS_MOUNT_DECOMP_THREADS */
+       return -EINVAL;
+}
+
+static int squashfs_parse_param_threads(const char *str, struct squashfs_mount_opts *opts)
+{
+       int ret = squashfs_parse_param_threads_str(str, opts);
+
+       if (ret == 0)
+               return ret;
+       return squashfs_parse_param_threads_num(str, opts);
+}
+
 static int squashfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
        struct squashfs_mount_opts *opts = fc->fs_private;
@@ -194,6 +232,11 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)
                goto failed_mount;
        }
        msblk->thread_ops = opts->thread_ops;
+       if (opts->thread_num == 0) {
+               msblk->max_thread_num = msblk->thread_ops->max_decompressors();
+       } else {
+               msblk->max_thread_num = opts->thread_num;
+       }
 
        /* Check the MAJOR & MINOR versions and lookup compression type */
        msblk->decompressor = supported_squashfs_filesystem(
@@ -279,7 +322,7 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)
 
        /* Allocate read_page block */
        msblk->read_page = squashfs_cache_init("data",
-               msblk->thread_ops->max_decompressors(), msblk->block_size);
+               msblk->max_thread_num, msblk->block_size);
        if (msblk->read_page == NULL) {
                errorf(fc, "Failed to allocate read_page block");
                goto failed_mount;
@@ -467,14 +510,13 @@ static int squashfs_show_options(struct seq_file *s, struct dentry *root)
                seq_puts(s, ",threads=single");
                return 0;
        }
-       if (msblk->thread_ops == &squashfs_decompressor_multi) {
-               seq_puts(s, ",threads=multi");
-               return 0;
-       }
        if (msblk->thread_ops == &squashfs_decompressor_percpu) {
                seq_puts(s, ",threads=percpu");
                return 0;
        }
+#endif
+#ifdef CONFIG_SQUASHFS_MOUNT_DECOMP_THREADS
+       seq_printf(s, ",threads=%d", msblk->max_thread_num);
 #endif
        return 0;
 }
@@ -496,6 +538,7 @@ static int squashfs_init_fs_context(struct fs_context *fc)
 #else
 #error "fail: unknown squashfs decompression thread mode?"
 #endif
+       opts->thread_num = 0;
        fc->fs_private = opts;
        fc->ops = &squashfs_context_ops;
        return 0;