Skip to content

Commit

Permalink
squashfs: allows users to configure the number of decompression threads
Browse files Browse the repository at this point in the history
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/[email protected]
Signed-off-by: Xiaoming Ni <[email protected]>
Reviewed-by: Phillip Lougher <[email protected]>
Cc: Jianguo Chen <[email protected]>
Cc: Jubin Zhong <[email protected]>
Cc: Zhang Yi <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
nixiaoming authored and akpm00 committed Nov 18, 2022
1 parent 80f7840 commit fb40fe0
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 10 deletions.
16 changes: 14 additions & 2 deletions fs/squashfs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions fs/squashfs/decompressor_multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions fs/squashfs/squashfs_fs_sb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
55 changes: 49 additions & 6 deletions fs/squashfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand All @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down

0 comments on commit fb40fe0

Please sign in to comment.