From ec39f7696ccfac85b3eea41eba7d6f747ee4ce8d Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 10 Jul 2019 12:28:17 -0700 Subject: Btrfs: use REQ_CGROUP_PUNT for worker thread submitted bios Async CRCs and compression submit IO through helper threads, which means they have IO priority inversions when cgroup IO controllers are in use. This flags all of the writes submitted by btrfs helper threads as REQ_CGROUP_PUNT. submit_bio() will punt these to dedicated per-blkcg work items to avoid the priority inversion. For the compression code, we take a reference on the wbc's blkg css and pass it down to the async workers. For the async CRCs, the bio already has the correct css, we just need to tell the block layer to use REQ_CGROUP_PUNT. Reviewed-by: Josef Bacik Signed-off-by: Chris Mason Modified-and-reviewed-by: Tejun Heo Signed-off-by: David Sterba --- fs/btrfs/compression.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 4cb8be9ff88b..dd392278ab3f 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -93,7 +93,8 @@ blk_status_t btrfs_submit_compressed_write(struct inode *inode, u64 start, unsigned long compressed_len, struct page **compressed_pages, unsigned long nr_pages, - unsigned int write_flags); + unsigned int write_flags, + struct cgroup_subsys_state *blkcg_css); blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, int mirror_num, unsigned long bio_flags); -- cgit v1.2.3 From ce96b7ffd11e261ef2ecd6817b7572a77750170d Mon Sep 17 00:00:00 2001 From: Chengguang Xu Date: Thu, 10 Oct 2019 15:59:57 +0800 Subject: btrfs: use better definition of number of compression type The compression type upper limit constant is the same as the last value and this is confusing. In order to keep coding style consistent, use BTRFS_NR_COMPRESS_TYPES as the total number that follows the idom of 'NR' being one more than the last value. Signed-off-by: Chengguang Xu Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/compression.c | 2 ++ fs/btrfs/compression.h | 4 ++-- fs/btrfs/ioctl.c | 2 +- fs/btrfs/tree-checker.c | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index d70c46407420..93deaf0cc2b8 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -39,6 +39,8 @@ const char* btrfs_compress_type2str(enum btrfs_compression_type type) case BTRFS_COMPRESS_ZSTD: case BTRFS_COMPRESS_NONE: return btrfs_compress_types[type]; + default: + break; } return NULL; diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index dd392278ab3f..52dce1176f89 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -105,7 +105,7 @@ enum btrfs_compression_type { BTRFS_COMPRESS_ZLIB = 1, BTRFS_COMPRESS_LZO = 2, BTRFS_COMPRESS_ZSTD = 3, - BTRFS_COMPRESS_TYPES = 3, + BTRFS_NR_COMPRESS_TYPES = 4, }; struct workspace_manager { @@ -163,7 +163,7 @@ struct btrfs_compress_op { }; /* The heuristic workspaces are managed via the 0th workspace manager */ -#define BTRFS_NR_WORKSPACE_MANAGERS (BTRFS_COMPRESS_TYPES + 1) +#define BTRFS_NR_WORKSPACE_MANAGERS BTRFS_NR_COMPRESS_TYPES extern const struct btrfs_compress_op btrfs_heuristic_compress; extern const struct btrfs_compress_op btrfs_zlib_compress; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index d7a1bd74bb71..5892fa9398c3 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1409,7 +1409,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, return -EINVAL; if (do_compress) { - if (range->compress_type > BTRFS_COMPRESS_TYPES) + if (range->compress_type >= BTRFS_NR_COMPRESS_TYPES) return -EINVAL; if (range->compress_type) compress_type = range->compress_type; diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 9699c91c958e..f4751615a189 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -233,11 +233,11 @@ static int check_extent_data_item(struct extent_buffer *leaf, * Support for new compression/encryption must introduce incompat flag, * and must be caught in open_ctree(). */ - if (btrfs_file_extent_compression(leaf, fi) > BTRFS_COMPRESS_TYPES) { + if (btrfs_file_extent_compression(leaf, fi) >= BTRFS_NR_COMPRESS_TYPES) { file_extent_err(leaf, slot, "invalid compression for file extent, have %u expect range [0, %u]", btrfs_file_extent_compression(leaf, fi), - BTRFS_COMPRESS_TYPES); + BTRFS_NR_COMPRESS_TYPES - 1); return -EUCLEAN; } if (btrfs_file_extent_encryption(leaf, fi)) { -- cgit v1.2.3 From 1e4eb7465438e47cc3718a02d4326dd034f3c0da Mon Sep 17 00:00:00 2001 From: David Sterba Date: Wed, 2 Oct 2019 00:06:15 +0200 Subject: btrfs: switch compression callbacks to direct calls The indirect calls bring some overhead due to spectre vulnerability mitigations. The number of cases is small and below the threshold (10-20) where indirect call would be better. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 77 ++++++++++++++++++++++++++++++++++++++++++++------ fs/btrfs/compression.h | 17 ----------- fs/btrfs/lzo.c | 3 -- fs/btrfs/zlib.c | 3 -- fs/btrfs/zstd.c | 3 -- 5 files changed, 69 insertions(+), 34 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 8611a8b3321a..87bac8f73a99 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -86,6 +86,70 @@ bool btrfs_compress_is_valid_type(const char *str, size_t len) return false; } +static int compression_compress_pages(int type, struct list_head *ws, + struct address_space *mapping, u64 start, struct page **pages, + unsigned long *out_pages, unsigned long *total_in, + unsigned long *total_out) +{ + switch (type) { + case BTRFS_COMPRESS_ZLIB: + return zlib_compress_pages(ws, mapping, start, pages, + out_pages, total_in, total_out); + case BTRFS_COMPRESS_LZO: + return lzo_compress_pages(ws, mapping, start, pages, + out_pages, total_in, total_out); + case BTRFS_COMPRESS_ZSTD: + return zstd_compress_pages(ws, mapping, start, pages, + out_pages, total_in, total_out); + case BTRFS_COMPRESS_NONE: + default: + /* + * This can't happen, the type is validated several times + * before we get here. As a sane fallback, return what the + * callers will understand as 'no compression happened'. + */ + return -E2BIG; + } +} + +static int compression_decompress_bio(int type, struct list_head *ws, + struct compressed_bio *cb) +{ + switch (type) { + case BTRFS_COMPRESS_ZLIB: return zlib_decompress_bio(ws, cb); + case BTRFS_COMPRESS_LZO: return lzo_decompress_bio(ws, cb); + case BTRFS_COMPRESS_ZSTD: return zstd_decompress_bio(ws, cb); + case BTRFS_COMPRESS_NONE: + default: + /* + * This can't happen, the type is validated several times + * before we get here. + */ + BUG(); + } +} + +static int compression_decompress(int type, struct list_head *ws, + unsigned char *data_in, struct page *dest_page, + unsigned long start_byte, size_t srclen, size_t destlen) +{ + switch (type) { + case BTRFS_COMPRESS_ZLIB: return zlib_decompress(ws, data_in, dest_page, + start_byte, srclen, destlen); + case BTRFS_COMPRESS_LZO: return lzo_decompress(ws, data_in, dest_page, + start_byte, srclen, destlen); + case BTRFS_COMPRESS_ZSTD: return zstd_decompress(ws, data_in, dest_page, + start_byte, srclen, destlen); + case BTRFS_COMPRESS_NONE: + default: + /* + * This can't happen, the type is validated several times + * before we get here. + */ + BUG(); + } +} + static int btrfs_decompress_bio(struct compressed_bio *cb); static inline int compressed_bio_size(struct btrfs_fs_info *fs_info, @@ -1074,10 +1138,8 @@ int btrfs_compress_pages(unsigned int type_level, struct address_space *mapping, level = btrfs_compress_set_level(type, level); workspace = get_workspace(type, level); - ret = btrfs_compress_op[type]->compress_pages(workspace, mapping, - start, pages, - out_pages, - total_in, total_out); + ret = compression_compress_pages(type, workspace, mapping, start, pages, + out_pages, total_in, total_out); put_workspace(type, workspace); return ret; } @@ -1103,7 +1165,7 @@ static int btrfs_decompress_bio(struct compressed_bio *cb) int type = cb->compress_type; workspace = get_workspace(type, 0); - ret = btrfs_compress_op[type]->decompress_bio(workspace, cb); + ret = compression_decompress_bio(type, workspace, cb); put_workspace(type, workspace); return ret; @@ -1121,9 +1183,8 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page, int ret; workspace = get_workspace(type, 0); - ret = btrfs_compress_op[type]->decompress(workspace, data_in, - dest_page, start_byte, - srclen, destlen); + ret = compression_decompress(type, workspace, data_in, dest_page, + start_byte, srclen, destlen); put_workspace(type, workspace); return ret; diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 52dce1176f89..7db14d3166b5 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -140,23 +140,6 @@ struct btrfs_compress_op { void (*free_workspace)(struct list_head *workspace); - int (*compress_pages)(struct list_head *workspace, - struct address_space *mapping, - u64 start, - struct page **pages, - unsigned long *out_pages, - unsigned long *total_in, - unsigned long *total_out); - - int (*decompress_bio)(struct list_head *workspace, - struct compressed_bio *cb); - - int (*decompress)(struct list_head *workspace, - unsigned char *data_in, - struct page *dest_page, - unsigned long start_byte, - size_t srclen, size_t destlen); - /* Maximum level supported by the compression algorithm */ unsigned int max_level; unsigned int default_level; diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 04a6815ea9cb..9417944ec829 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -509,9 +509,6 @@ const struct btrfs_compress_op btrfs_lzo_compress = { .put_workspace = lzo_put_workspace, .alloc_workspace = lzo_alloc_workspace, .free_workspace = lzo_free_workspace, - .compress_pages = lzo_compress_pages, - .decompress_bio = lzo_decompress_bio, - .decompress = lzo_decompress, .max_level = 1, .default_level = 1, }; diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 4091f94ba378..8bb6f19ab369 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -420,9 +420,6 @@ const struct btrfs_compress_op btrfs_zlib_compress = { .put_workspace = zlib_put_workspace, .alloc_workspace = zlib_alloc_workspace, .free_workspace = zlib_free_workspace, - .compress_pages = zlib_compress_pages, - .decompress_bio = zlib_decompress_bio, - .decompress = zlib_decompress, .max_level = 9, .default_level = BTRFS_ZLIB_DEFAULT_LEVEL, }; diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index b3728220c329..5f17c741d167 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -713,9 +713,6 @@ const struct btrfs_compress_op btrfs_zstd_compress = { .put_workspace = zstd_put_workspace, .alloc_workspace = zstd_alloc_workspace, .free_workspace = zstd_free_workspace, - .compress_pages = zstd_compress_pages, - .decompress_bio = zstd_decompress_bio, - .decompress = zstd_decompress, .max_level = ZSTD_BTRFS_MAX_LEVEL, .default_level = ZSTD_BTRFS_DEFAULT_LEVEL, }; -- cgit v1.2.3 From be951045312d963ffeacd6a566a0de87e4784af1 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Wed, 2 Oct 2019 00:53:31 +0200 Subject: btrfs: compression: attach workspace manager to the ops There's a lot of indirection when the generic code calls into algo-specific callbacks to reach the private workspace manager structure and back to the generic code. To simplify that, export the workspace manager for heuristic, LZO and ZLIB, while ZSTD is going to use it's own manager. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 1 + fs/btrfs/compression.h | 1 + fs/btrfs/lzo.c | 1 + fs/btrfs/zlib.c | 1 + fs/btrfs/zstd.c | 2 ++ 5 files changed, 6 insertions(+) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 87bac8f73a99..e650125b1d2b 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -920,6 +920,7 @@ fail: } const struct btrfs_compress_op btrfs_heuristic_compress = { + .workspace_manager = &heuristic_wsm, .init_workspace_manager = heuristic_init_workspace_manager, .cleanup_workspace_manager = heuristic_cleanup_workspace_manager, .get_workspace = heuristic_get_workspace, diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 7db14d3166b5..7091eae063e5 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -140,6 +140,7 @@ struct btrfs_compress_op { void (*free_workspace)(struct list_head *workspace); + struct workspace_manager *workspace_manager; /* Maximum level supported by the compression algorithm */ unsigned int max_level; unsigned int default_level; diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 9417944ec829..aff105cc80e7 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -503,6 +503,7 @@ out: } const struct btrfs_compress_op btrfs_lzo_compress = { + .workspace_manager = &wsm, .init_workspace_manager = lzo_init_workspace_manager, .cleanup_workspace_manager = lzo_cleanup_workspace_manager, .get_workspace = lzo_get_workspace, diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 8bb6f19ab369..a5e8f0207473 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -414,6 +414,7 @@ next: } const struct btrfs_compress_op btrfs_zlib_compress = { + .workspace_manager = &wsm, .init_workspace_manager = zlib_init_workspace_manager, .cleanup_workspace_manager = zlib_cleanup_workspace_manager, .get_workspace = zlib_get_workspace, diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index 5f17c741d167..4791e89e43e3 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -707,6 +707,8 @@ finish: } const struct btrfs_compress_op btrfs_zstd_compress = { + /* ZSTD uses own workspace manager */ + .workspace_manager = NULL, .init_workspace_manager = zstd_init_workspace_manager, .cleanup_workspace_manager = zstd_cleanup_workspace_manager, .get_workspace = zstd_get_workspace, -- cgit v1.2.3 From 975db48330c492a84d8b29b10ae55a30a03dfe0f Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 4 Oct 2019 01:40:58 +0200 Subject: btrfs: compression: let workspace manager init take only the type With the access to the workspace structures, we can look it up together with the compression ops inside the workspace manager init helper. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 7 ++++--- fs/btrfs/compression.h | 3 +-- fs/btrfs/lzo.c | 2 +- fs/btrfs/zlib.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index e650125b1d2b..6adc7f6857d7 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -862,7 +862,7 @@ static struct workspace_manager heuristic_wsm; static void heuristic_init_workspace_manager(void) { - btrfs_init_workspace_manager(&heuristic_wsm, &btrfs_heuristic_compress); + btrfs_init_workspace_manager(BTRFS_COMPRESS_NONE); } static void heuristic_cleanup_workspace_manager(void) @@ -937,9 +937,10 @@ static const struct btrfs_compress_op * const btrfs_compress_op[] = { &btrfs_zstd_compress, }; -void btrfs_init_workspace_manager(struct workspace_manager *wsm, - const struct btrfs_compress_op *ops) +void btrfs_init_workspace_manager(int type) { + const struct btrfs_compress_op *ops = btrfs_compress_op[type]; + struct workspace_manager *wsm = ops->workspace_manager; struct list_head *workspace; wsm->ops = ops; diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 7091eae063e5..10f82e791769 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -120,8 +120,7 @@ struct workspace_manager { wait_queue_head_t ws_wait; }; -void btrfs_init_workspace_manager(struct workspace_manager *wsm, - const struct btrfs_compress_op *ops); +void btrfs_init_workspace_manager(int type); struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, unsigned int level); void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws); diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index aff105cc80e7..5b8470041bf6 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -65,7 +65,7 @@ static struct workspace_manager wsm; static void lzo_init_workspace_manager(void) { - btrfs_init_workspace_manager(&wsm, &btrfs_lzo_compress); + btrfs_init_workspace_manager(BTRFS_COMPRESS_LZO); } static void lzo_cleanup_workspace_manager(void) diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index a5e8f0207473..be964128dba3 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -31,7 +31,7 @@ static struct workspace_manager wsm; static void zlib_init_workspace_manager(void) { - btrfs_init_workspace_manager(&wsm, &btrfs_zlib_compress); + btrfs_init_workspace_manager(BTRFS_COMPRESS_ZLIB); } static void zlib_cleanup_workspace_manager(void) -- cgit v1.2.3 From d551703347263b7f79168e51c2f999cb883b8d65 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Wed, 2 Oct 2019 01:08:03 +0200 Subject: btrfs: compression: inline init_workspace_manager Replace loop calling to all algos with a list of direct calls to the init manager callback. When that becomes trivial it is replaced by direct call to the helper. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 17 ++++++----------- fs/btrfs/compression.h | 3 --- fs/btrfs/lzo.c | 6 ------ fs/btrfs/zlib.c | 6 ------ fs/btrfs/zstd.c | 3 +-- 5 files changed, 7 insertions(+), 28 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 6adc7f6857d7..61b9cf095ee5 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -52,6 +52,7 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb); int zstd_decompress(struct list_head *ws, unsigned char *data_in, struct page *dest_page, unsigned long start_byte, size_t srclen, size_t destlen); +void zstd_init_workspace_manager(void); static const char* const btrfs_compress_types[] = { "", "zlib", "lzo", "zstd" }; @@ -860,11 +861,6 @@ struct heuristic_ws { static struct workspace_manager heuristic_wsm; -static void heuristic_init_workspace_manager(void) -{ - btrfs_init_workspace_manager(BTRFS_COMPRESS_NONE); -} - static void heuristic_cleanup_workspace_manager(void) { btrfs_cleanup_workspace_manager(&heuristic_wsm); @@ -921,7 +917,6 @@ fail: const struct btrfs_compress_op btrfs_heuristic_compress = { .workspace_manager = &heuristic_wsm, - .init_workspace_manager = heuristic_init_workspace_manager, .cleanup_workspace_manager = heuristic_cleanup_workspace_manager, .get_workspace = heuristic_get_workspace, .put_workspace = heuristic_put_workspace, @@ -937,7 +932,7 @@ static const struct btrfs_compress_op * const btrfs_compress_op[] = { &btrfs_zstd_compress, }; -void btrfs_init_workspace_manager(int type) +static void btrfs_init_workspace_manager(int type) { const struct btrfs_compress_op *ops = btrfs_compress_op[type]; struct workspace_manager *wsm = ops->workspace_manager; @@ -1194,10 +1189,10 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page, void __init btrfs_init_compress(void) { - int i; - - for (i = 0; i < BTRFS_NR_WORKSPACE_MANAGERS; i++) - btrfs_compress_op[i]->init_workspace_manager(); + btrfs_init_workspace_manager(BTRFS_COMPRESS_NONE); + btrfs_init_workspace_manager(BTRFS_COMPRESS_ZLIB); + btrfs_init_workspace_manager(BTRFS_COMPRESS_LZO); + zstd_init_workspace_manager(); } void __cold btrfs_exit_compress(void) diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 10f82e791769..12a46139c389 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -120,15 +120,12 @@ struct workspace_manager { wait_queue_head_t ws_wait; }; -void btrfs_init_workspace_manager(int type); struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, unsigned int level); void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws); void btrfs_cleanup_workspace_manager(struct workspace_manager *wsm); struct btrfs_compress_op { - void (*init_workspace_manager)(void); - void (*cleanup_workspace_manager)(void); struct list_head *(*get_workspace)(unsigned int level); diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 5b8470041bf6..a55079477edf 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -63,11 +63,6 @@ struct workspace { static struct workspace_manager wsm; -static void lzo_init_workspace_manager(void) -{ - btrfs_init_workspace_manager(BTRFS_COMPRESS_LZO); -} - static void lzo_cleanup_workspace_manager(void) { btrfs_cleanup_workspace_manager(&wsm); @@ -504,7 +499,6 @@ out: const struct btrfs_compress_op btrfs_lzo_compress = { .workspace_manager = &wsm, - .init_workspace_manager = lzo_init_workspace_manager, .cleanup_workspace_manager = lzo_cleanup_workspace_manager, .get_workspace = lzo_get_workspace, .put_workspace = lzo_put_workspace, diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index be964128dba3..39f1d0f1b286 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -29,11 +29,6 @@ struct workspace { static struct workspace_manager wsm; -static void zlib_init_workspace_manager(void) -{ - btrfs_init_workspace_manager(BTRFS_COMPRESS_ZLIB); -} - static void zlib_cleanup_workspace_manager(void) { btrfs_cleanup_workspace_manager(&wsm); @@ -415,7 +410,6 @@ next: const struct btrfs_compress_op btrfs_zlib_compress = { .workspace_manager = &wsm, - .init_workspace_manager = zlib_init_workspace_manager, .cleanup_workspace_manager = zlib_cleanup_workspace_manager, .get_workspace = zlib_get_workspace, .put_workspace = zlib_put_workspace, diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index 4791e89e43e3..8e7a804b05ee 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -168,7 +168,7 @@ static void zstd_calc_ws_mem_sizes(void) } } -static void zstd_init_workspace_manager(void) +void zstd_init_workspace_manager(void) { struct list_head *ws; int i; @@ -709,7 +709,6 @@ finish: const struct btrfs_compress_op btrfs_zstd_compress = { /* ZSTD uses own workspace manager */ .workspace_manager = NULL, - .init_workspace_manager = zstd_init_workspace_manager, .cleanup_workspace_manager = zstd_cleanup_workspace_manager, .get_workspace = zstd_get_workspace, .put_workspace = zstd_put_workspace, -- cgit v1.2.3 From 2dba714390f1ff7a8a37cc8c3b374d71d3e84af7 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 4 Oct 2019 01:40:58 +0200 Subject: btrfs: compression: let workspace manager cleanup take only the type With the access to the workspace structures, we can look it up together with the compression ops inside the workspace manager cleanup helper. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 6 ++++-- fs/btrfs/compression.h | 2 +- fs/btrfs/lzo.c | 2 +- fs/btrfs/zlib.c | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 61b9cf095ee5..6c4dc62b9ab0 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -863,7 +863,7 @@ static struct workspace_manager heuristic_wsm; static void heuristic_cleanup_workspace_manager(void) { - btrfs_cleanup_workspace_manager(&heuristic_wsm); + btrfs_cleanup_workspace_manager(BTRFS_COMPRESS_NONE); } static struct list_head *heuristic_get_workspace(unsigned int level) @@ -960,10 +960,12 @@ static void btrfs_init_workspace_manager(int type) } } -void btrfs_cleanup_workspace_manager(struct workspace_manager *wsman) +void btrfs_cleanup_workspace_manager(int type) { + struct workspace_manager *wsman; struct list_head *ws; + wsman = btrfs_compress_op[type]->workspace_manager; while (!list_empty(&wsman->idle_ws)) { ws = wsman->idle_ws.next; list_del(ws); diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 12a46139c389..0deaa8e03836 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -123,7 +123,7 @@ struct workspace_manager { struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, unsigned int level); void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws); -void btrfs_cleanup_workspace_manager(struct workspace_manager *wsm); +void btrfs_cleanup_workspace_manager(int type); struct btrfs_compress_op { void (*cleanup_workspace_manager)(void); diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index a55079477edf..6aa602040506 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -65,7 +65,7 @@ static struct workspace_manager wsm; static void lzo_cleanup_workspace_manager(void) { - btrfs_cleanup_workspace_manager(&wsm); + btrfs_cleanup_workspace_manager(BTRFS_COMPRESS_LZO); } static struct list_head *lzo_get_workspace(unsigned int level) diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 39f1d0f1b286..7319e9f3d484 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -31,7 +31,7 @@ static struct workspace_manager wsm; static void zlib_cleanup_workspace_manager(void) { - btrfs_cleanup_workspace_manager(&wsm); + btrfs_cleanup_workspace_manager(BTRFS_COMPRESS_ZLIB); } static struct list_head *zlib_get_workspace(unsigned int level) -- cgit v1.2.3 From 2510307e6c78d1d9a59c85164cbff66f8a9f3fed Mon Sep 17 00:00:00 2001 From: David Sterba Date: Wed, 2 Oct 2019 01:08:03 +0200 Subject: btrfs: compression: inline cleanup_workspace_manager Replace loop calling to all algos with a list of direct calls to the cleanup manager callback. When that becomes trivial it is replaced by direct call to the helper. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 17 ++++++----------- fs/btrfs/compression.h | 3 --- fs/btrfs/lzo.c | 6 ------ fs/btrfs/zlib.c | 6 ------ fs/btrfs/zstd.c | 3 +-- 5 files changed, 7 insertions(+), 28 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 6c4dc62b9ab0..34921a120829 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -53,6 +53,7 @@ int zstd_decompress(struct list_head *ws, unsigned char *data_in, struct page *dest_page, unsigned long start_byte, size_t srclen, size_t destlen); void zstd_init_workspace_manager(void); +void zstd_cleanup_workspace_manager(void); static const char* const btrfs_compress_types[] = { "", "zlib", "lzo", "zstd" }; @@ -861,11 +862,6 @@ struct heuristic_ws { static struct workspace_manager heuristic_wsm; -static void heuristic_cleanup_workspace_manager(void) -{ - btrfs_cleanup_workspace_manager(BTRFS_COMPRESS_NONE); -} - static struct list_head *heuristic_get_workspace(unsigned int level) { return btrfs_get_workspace(&heuristic_wsm, level); @@ -917,7 +913,6 @@ fail: const struct btrfs_compress_op btrfs_heuristic_compress = { .workspace_manager = &heuristic_wsm, - .cleanup_workspace_manager = heuristic_cleanup_workspace_manager, .get_workspace = heuristic_get_workspace, .put_workspace = heuristic_put_workspace, .alloc_workspace = alloc_heuristic_ws, @@ -960,7 +955,7 @@ static void btrfs_init_workspace_manager(int type) } } -void btrfs_cleanup_workspace_manager(int type) +static void btrfs_cleanup_workspace_manager(int type) { struct workspace_manager *wsman; struct list_head *ws; @@ -1199,10 +1194,10 @@ void __init btrfs_init_compress(void) void __cold btrfs_exit_compress(void) { - int i; - - for (i = 0; i < BTRFS_NR_WORKSPACE_MANAGERS; i++) - btrfs_compress_op[i]->cleanup_workspace_manager(); + btrfs_cleanup_workspace_manager(BTRFS_COMPRESS_NONE); + btrfs_cleanup_workspace_manager(BTRFS_COMPRESS_ZLIB); + btrfs_cleanup_workspace_manager(BTRFS_COMPRESS_LZO); + zstd_cleanup_workspace_manager(); } /* diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 0deaa8e03836..cf667e599b70 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -123,11 +123,8 @@ struct workspace_manager { struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, unsigned int level); void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws); -void btrfs_cleanup_workspace_manager(int type); struct btrfs_compress_op { - void (*cleanup_workspace_manager)(void); - struct list_head *(*get_workspace)(unsigned int level); void (*put_workspace)(struct list_head *ws); diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 6aa602040506..6f4619e76c11 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -63,11 +63,6 @@ struct workspace { static struct workspace_manager wsm; -static void lzo_cleanup_workspace_manager(void) -{ - btrfs_cleanup_workspace_manager(BTRFS_COMPRESS_LZO); -} - static struct list_head *lzo_get_workspace(unsigned int level) { return btrfs_get_workspace(&wsm, level); @@ -499,7 +494,6 @@ out: const struct btrfs_compress_op btrfs_lzo_compress = { .workspace_manager = &wsm, - .cleanup_workspace_manager = lzo_cleanup_workspace_manager, .get_workspace = lzo_get_workspace, .put_workspace = lzo_put_workspace, .alloc_workspace = lzo_alloc_workspace, diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 7319e9f3d484..03c632c7deac 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -29,11 +29,6 @@ struct workspace { static struct workspace_manager wsm; -static void zlib_cleanup_workspace_manager(void) -{ - btrfs_cleanup_workspace_manager(BTRFS_COMPRESS_ZLIB); -} - static struct list_head *zlib_get_workspace(unsigned int level) { struct list_head *ws = btrfs_get_workspace(&wsm, level); @@ -410,7 +405,6 @@ next: const struct btrfs_compress_op btrfs_zlib_compress = { .workspace_manager = &wsm, - .cleanup_workspace_manager = zlib_cleanup_workspace_manager, .get_workspace = zlib_get_workspace, .put_workspace = zlib_put_workspace, .alloc_workspace = zlib_alloc_workspace, diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index 8e7a804b05ee..f575ce77ea3d 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -194,7 +194,7 @@ void zstd_init_workspace_manager(void) } } -static void zstd_cleanup_workspace_manager(void) +void zstd_cleanup_workspace_manager(void) { struct workspace *workspace; int i; @@ -709,7 +709,6 @@ finish: const struct btrfs_compress_op btrfs_zstd_compress = { /* ZSTD uses own workspace manager */ .workspace_manager = NULL, - .cleanup_workspace_manager = zstd_cleanup_workspace_manager, .get_workspace = zstd_get_workspace, .put_workspace = zstd_put_workspace, .alloc_workspace = zstd_alloc_workspace, -- cgit v1.2.3 From 6a0d12724bd2dd1c766769578e221ce1d10a4656 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 4 Oct 2019 02:36:16 +0200 Subject: btrfs: compression: inline get_workspace Majority of the callbacks is trivial, we don't gain anything by the indirection, so replace them by a switch function. ZLIB needs to adjust level in the callback and ZSTD workspace management is complex, the rest is call to the helper. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 23 +++++++++++++++-------- fs/btrfs/compression.h | 2 -- fs/btrfs/lzo.c | 6 ------ fs/btrfs/zlib.c | 1 - fs/btrfs/zstd.c | 1 - 5 files changed, 15 insertions(+), 18 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index f707db4a9a53..de9b06574f42 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -50,7 +50,6 @@ int lzo_decompress(struct list_head *ws, unsigned char *data_in, size_t destlen); struct list_head *lzo_alloc_workspace(unsigned int level); void lzo_free_workspace(struct list_head *ws); -struct list_head *lzo_get_workspace(unsigned int level); void lzo_put_workspace(struct list_head *ws); int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, @@ -874,11 +873,6 @@ struct heuristic_ws { static struct workspace_manager heuristic_wsm; -static struct list_head *heuristic_get_workspace(unsigned int level) -{ - return btrfs_get_workspace(&heuristic_wsm, level); -} - static void heuristic_put_workspace(struct list_head *ws) { btrfs_put_workspace(&heuristic_wsm, ws); @@ -925,7 +919,6 @@ fail: const struct btrfs_compress_op btrfs_heuristic_compress = { .workspace_manager = &heuristic_wsm, - .get_workspace = heuristic_get_workspace, .put_workspace = heuristic_put_workspace, .alloc_workspace = alloc_heuristic_ws, .free_workspace = free_heuristic_ws, @@ -1067,7 +1060,21 @@ again: static struct list_head *get_workspace(int type, int level) { - return btrfs_compress_op[type]->get_workspace(level); + struct workspace_manager *wsm; + + wsm = btrfs_compress_op[type]->workspace_manager; + switch (type) { + case BTRFS_COMPRESS_NONE: return btrfs_get_workspace(wsm, level); + case BTRFS_COMPRESS_ZLIB: return zlib_get_workspace(level); + case BTRFS_COMPRESS_LZO: return btrfs_get_workspace(wsm, level); + case BTRFS_COMPRESS_ZSTD: return zstd_get_workspace(level); + default: + /* + * This can't happen, the type is validated several times + * before we get here. + */ + BUG(); + } } /* diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index cf667e599b70..df7274c1a5d8 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -125,8 +125,6 @@ struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws); struct btrfs_compress_op { - struct list_head *(*get_workspace)(unsigned int level); - void (*put_workspace)(struct list_head *ws); struct list_head *(*alloc_workspace)(unsigned int level); diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 18018619c019..821e5c137971 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -63,11 +63,6 @@ struct workspace { static struct workspace_manager wsm; -struct list_head *lzo_get_workspace(unsigned int level) -{ - return btrfs_get_workspace(&wsm, level); -} - void lzo_put_workspace(struct list_head *ws) { btrfs_put_workspace(&wsm, ws); @@ -494,7 +489,6 @@ out: const struct btrfs_compress_op btrfs_lzo_compress = { .workspace_manager = &wsm, - .get_workspace = lzo_get_workspace, .put_workspace = lzo_put_workspace, .alloc_workspace = lzo_alloc_workspace, .free_workspace = lzo_free_workspace, diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index f2a56e999e5f..7caa468efe94 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -405,7 +405,6 @@ next: const struct btrfs_compress_op btrfs_zlib_compress = { .workspace_manager = &wsm, - .get_workspace = zlib_get_workspace, .put_workspace = zlib_put_workspace, .alloc_workspace = zlib_alloc_workspace, .free_workspace = zlib_free_workspace, diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index 2caf08e06e2f..c9fe0e2bd107 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -708,7 +708,6 @@ finish: const struct btrfs_compress_op btrfs_zstd_compress = { /* ZSTD uses own workspace manager */ .workspace_manager = NULL, - .get_workspace = zstd_get_workspace, .put_workspace = zstd_put_workspace, .alloc_workspace = zstd_alloc_workspace, .free_workspace = zstd_free_workspace, -- cgit v1.2.3 From bd3a5287cc20e37f1e365be1f742b6c574e3f83c Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 4 Oct 2019 02:42:03 +0200 Subject: btrfs: compression: inline put_workspace Similar to get_workspace, majority of the callbacks is trivial, we don't gain anything by the indirection, so replace them by a switch function. Trivial callback implementations use the helper. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 24 +++++++++++++++--------- fs/btrfs/compression.h | 2 -- fs/btrfs/lzo.c | 6 ------ fs/btrfs/zlib.c | 6 ------ fs/btrfs/zstd.c | 1 - 5 files changed, 15 insertions(+), 24 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index de9b06574f42..9b9638557e19 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -39,7 +39,6 @@ int zlib_decompress(struct list_head *ws, unsigned char *data_in, struct list_head *zlib_alloc_workspace(unsigned int level); void zlib_free_workspace(struct list_head *ws); struct list_head *zlib_get_workspace(unsigned int level); -void zlib_put_workspace(struct list_head *ws); int lzo_compress_pages(struct list_head *ws, struct address_space *mapping, u64 start, struct page **pages, unsigned long *out_pages, @@ -50,7 +49,6 @@ int lzo_decompress(struct list_head *ws, unsigned char *data_in, size_t destlen); struct list_head *lzo_alloc_workspace(unsigned int level); void lzo_free_workspace(struct list_head *ws); -void lzo_put_workspace(struct list_head *ws); int zstd_compress_pages(struct list_head *ws, struct address_space *mapping, u64 start, struct page **pages, unsigned long *out_pages, @@ -873,11 +871,6 @@ struct heuristic_ws { static struct workspace_manager heuristic_wsm; -static void heuristic_put_workspace(struct list_head *ws) -{ - btrfs_put_workspace(&heuristic_wsm, ws); -} - static void free_heuristic_ws(struct list_head *ws) { struct heuristic_ws *workspace; @@ -919,7 +912,6 @@ fail: const struct btrfs_compress_op btrfs_heuristic_compress = { .workspace_manager = &heuristic_wsm, - .put_workspace = heuristic_put_workspace, .alloc_workspace = alloc_heuristic_ws, .free_workspace = free_heuristic_ws, }; @@ -1112,7 +1104,21 @@ wake: static void put_workspace(int type, struct list_head *ws) { - return btrfs_compress_op[type]->put_workspace(ws); + struct workspace_manager *wsm; + + wsm = btrfs_compress_op[type]->workspace_manager; + switch (type) { + case BTRFS_COMPRESS_NONE: return btrfs_put_workspace(wsm, ws); + case BTRFS_COMPRESS_ZLIB: return btrfs_put_workspace(wsm, ws); + case BTRFS_COMPRESS_LZO: return btrfs_put_workspace(wsm, ws); + case BTRFS_COMPRESS_ZSTD: return zstd_put_workspace(ws); + default: + /* + * This can't happen, the type is validated several times + * before we get here. + */ + BUG(); + } } /* diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index df7274c1a5d8..b8ed97fc6db4 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -125,8 +125,6 @@ struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws); struct btrfs_compress_op { - void (*put_workspace)(struct list_head *ws); - struct list_head *(*alloc_workspace)(unsigned int level); void (*free_workspace)(struct list_head *workspace); diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 821e5c137971..bbf917c5ff2d 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -63,11 +63,6 @@ struct workspace { static struct workspace_manager wsm; -void lzo_put_workspace(struct list_head *ws) -{ - btrfs_put_workspace(&wsm, ws); -} - void lzo_free_workspace(struct list_head *ws) { struct workspace *workspace = list_entry(ws, struct workspace, list); @@ -489,7 +484,6 @@ out: const struct btrfs_compress_op btrfs_lzo_compress = { .workspace_manager = &wsm, - .put_workspace = lzo_put_workspace, .alloc_workspace = lzo_alloc_workspace, .free_workspace = lzo_free_workspace, .max_level = 1, diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 7caa468efe94..610765640c8e 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -39,11 +39,6 @@ struct list_head *zlib_get_workspace(unsigned int level) return ws; } -void zlib_put_workspace(struct list_head *ws) -{ - btrfs_put_workspace(&wsm, ws); -} - void zlib_free_workspace(struct list_head *ws) { struct workspace *workspace = list_entry(ws, struct workspace, list); @@ -405,7 +400,6 @@ next: const struct btrfs_compress_op btrfs_zlib_compress = { .workspace_manager = &wsm, - .put_workspace = zlib_put_workspace, .alloc_workspace = zlib_alloc_workspace, .free_workspace = zlib_free_workspace, .max_level = 9, diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index c9fe0e2bd107..a346f1187fae 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -708,7 +708,6 @@ finish: const struct btrfs_compress_op btrfs_zstd_compress = { /* ZSTD uses own workspace manager */ .workspace_manager = NULL, - .put_workspace = zstd_put_workspace, .alloc_workspace = zstd_alloc_workspace, .free_workspace = zstd_free_workspace, .max_level = ZSTD_BTRFS_MAX_LEVEL, -- cgit v1.2.3 From 5907a9bb13cea3bbf0c54d6a9a1ccf5edebedeed Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 4 Oct 2019 02:50:28 +0200 Subject: btrfs: compression: pass type to btrfs_get_workspace We can infer the workspace_manager from type and the type will be used in the following patch to call a common helper for alloc_workspace. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 12 +++++------- fs/btrfs/compression.h | 3 +-- fs/btrfs/zlib.c | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 9b9638557e19..ffc94e15d86e 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -972,9 +972,9 @@ static void btrfs_cleanup_workspace_manager(int type) * Preallocation makes a forward progress guarantees and we do not return * errors. */ -struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, - unsigned int level) +struct list_head *btrfs_get_workspace(int type, unsigned int level) { + struct workspace_manager *wsm; struct list_head *workspace; int cpus = num_online_cpus(); unsigned nofs_flag; @@ -984,6 +984,7 @@ struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, wait_queue_head_t *ws_wait; int *free_ws; + wsm = btrfs_compress_op[type]->workspace_manager; idle_ws = &wsm->idle_ws; ws_lock = &wsm->ws_lock; total_ws = &wsm->total_ws; @@ -1052,13 +1053,10 @@ again: static struct list_head *get_workspace(int type, int level) { - struct workspace_manager *wsm; - - wsm = btrfs_compress_op[type]->workspace_manager; switch (type) { - case BTRFS_COMPRESS_NONE: return btrfs_get_workspace(wsm, level); + case BTRFS_COMPRESS_NONE: return btrfs_get_workspace(type, level); case BTRFS_COMPRESS_ZLIB: return zlib_get_workspace(level); - case BTRFS_COMPRESS_LZO: return btrfs_get_workspace(wsm, level); + case BTRFS_COMPRESS_LZO: return btrfs_get_workspace(type, level); case BTRFS_COMPRESS_ZSTD: return zstd_get_workspace(level); default: /* diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index b8ed97fc6db4..accb1d61df87 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -120,8 +120,7 @@ struct workspace_manager { wait_queue_head_t ws_wait; }; -struct list_head *btrfs_get_workspace(struct workspace_manager *wsm, - unsigned int level); +struct list_head *btrfs_get_workspace(int type, unsigned int level); void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws); struct btrfs_compress_op { diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 610765640c8e..5679a2e41a52 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -31,7 +31,7 @@ static struct workspace_manager wsm; struct list_head *zlib_get_workspace(unsigned int level) { - struct list_head *ws = btrfs_get_workspace(&wsm, level); + struct list_head *ws = btrfs_get_workspace(BTRFS_COMPRESS_ZLIB, level); struct workspace *workspace = list_entry(ws, struct workspace, list); workspace->level = level; -- cgit v1.2.3 From c778df140644142fb7e12b7e468b137721d85890 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 4 Oct 2019 02:47:39 +0200 Subject: btrfs: compression: inline alloc_workspace Replace indirect calls to alloc_workspace by switch and calls to the specific callbacks. This is mainly to get rid of the indirection due to spectre vulnerability mitigations. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 21 ++++++++++++++++++--- fs/btrfs/compression.h | 2 -- fs/btrfs/lzo.c | 1 - fs/btrfs/zlib.c | 1 - fs/btrfs/zstd.c | 1 - 5 files changed, 18 insertions(+), 8 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index ffc94e15d86e..4a8dab961f88 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -912,7 +912,6 @@ fail: const struct btrfs_compress_op btrfs_heuristic_compress = { .workspace_manager = &heuristic_wsm, - .alloc_workspace = alloc_heuristic_ws, .free_workspace = free_heuristic_ws, }; @@ -924,6 +923,22 @@ static const struct btrfs_compress_op * const btrfs_compress_op[] = { &btrfs_zstd_compress, }; +static struct list_head *alloc_workspace(int type, unsigned int level) +{ + switch (type) { + case BTRFS_COMPRESS_NONE: return alloc_heuristic_ws(level); + case BTRFS_COMPRESS_ZLIB: return zlib_alloc_workspace(level); + case BTRFS_COMPRESS_LZO: return lzo_alloc_workspace(level); + case BTRFS_COMPRESS_ZSTD: return zstd_alloc_workspace(level); + default: + /* + * This can't happen, the type is validated several times + * before we get here. + */ + BUG(); + } +} + static void btrfs_init_workspace_manager(int type) { const struct btrfs_compress_op *ops = btrfs_compress_op[type]; @@ -941,7 +956,7 @@ static void btrfs_init_workspace_manager(int type) * Preallocate one workspace for each compression type so we can * guarantee forward progress in the worst case */ - workspace = wsm->ops->alloc_workspace(0); + workspace = alloc_workspace(type, 0); if (IS_ERR(workspace)) { pr_warn( "BTRFS: cannot preallocate compression workspace, will try later\n"); @@ -1020,7 +1035,7 @@ again: * context of btrfs_compress_bio/btrfs_compress_pages */ nofs_flag = memalloc_nofs_save(); - workspace = wsm->ops->alloc_workspace(level); + workspace = alloc_workspace(type, level); memalloc_nofs_restore(nofs_flag); if (IS_ERR(workspace)) { diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index accb1d61df87..8336c2ef6b5a 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -124,8 +124,6 @@ struct list_head *btrfs_get_workspace(int type, unsigned int level); void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws); struct btrfs_compress_op { - struct list_head *(*alloc_workspace)(unsigned int level); - void (*free_workspace)(struct list_head *workspace); struct workspace_manager *workspace_manager; diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index bbf917c5ff2d..39b2cf80f77c 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -484,7 +484,6 @@ out: const struct btrfs_compress_op btrfs_lzo_compress = { .workspace_manager = &wsm, - .alloc_workspace = lzo_alloc_workspace, .free_workspace = lzo_free_workspace, .max_level = 1, .default_level = 1, diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 5679a2e41a52..c5dfab3ab082 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -400,7 +400,6 @@ next: const struct btrfs_compress_op btrfs_zlib_compress = { .workspace_manager = &wsm, - .alloc_workspace = zlib_alloc_workspace, .free_workspace = zlib_free_workspace, .max_level = 9, .default_level = BTRFS_ZLIB_DEFAULT_LEVEL, diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index a346f1187fae..9413f741c2f6 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -708,7 +708,6 @@ finish: const struct btrfs_compress_op btrfs_zstd_compress = { /* ZSTD uses own workspace manager */ .workspace_manager = NULL, - .alloc_workspace = zstd_alloc_workspace, .free_workspace = zstd_free_workspace, .max_level = ZSTD_BTRFS_MAX_LEVEL, .default_level = ZSTD_BTRFS_DEFAULT_LEVEL, -- cgit v1.2.3 From a3bbd2a9ee3c08b60b3127843866bdc76757c24f Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 4 Oct 2019 02:50:28 +0200 Subject: btrfs: compression: pass type to btrfs_put_workspace We can infer the workspace_manager from type and the type will be used in the following patch to call a common helper for free_workspace. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 13 ++++++------- fs/btrfs/compression.h | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 4a8dab961f88..2a77c91c194b 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -1086,14 +1086,16 @@ static struct list_head *get_workspace(int type, int level) * put a workspace struct back on the list or free it if we have enough * idle ones sitting around */ -void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws) +void btrfs_put_workspace(int type, struct list_head *ws) { + struct workspace_manager *wsm; struct list_head *idle_ws; spinlock_t *ws_lock; atomic_t *total_ws; wait_queue_head_t *ws_wait; int *free_ws; + wsm = btrfs_compress_op[type]->workspace_manager; idle_ws = &wsm->idle_ws; ws_lock = &wsm->ws_lock; total_ws = &wsm->total_ws; @@ -1117,13 +1119,10 @@ wake: static void put_workspace(int type, struct list_head *ws) { - struct workspace_manager *wsm; - - wsm = btrfs_compress_op[type]->workspace_manager; switch (type) { - case BTRFS_COMPRESS_NONE: return btrfs_put_workspace(wsm, ws); - case BTRFS_COMPRESS_ZLIB: return btrfs_put_workspace(wsm, ws); - case BTRFS_COMPRESS_LZO: return btrfs_put_workspace(wsm, ws); + case BTRFS_COMPRESS_NONE: return btrfs_put_workspace(type, ws); + case BTRFS_COMPRESS_ZLIB: return btrfs_put_workspace(type, ws); + case BTRFS_COMPRESS_LZO: return btrfs_put_workspace(type, ws); case BTRFS_COMPRESS_ZSTD: return zstd_put_workspace(ws); default: /* diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 8336c2ef6b5a..664b029cd5e4 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -121,7 +121,7 @@ struct workspace_manager { }; struct list_head *btrfs_get_workspace(int type, unsigned int level); -void btrfs_put_workspace(struct workspace_manager *wsm, struct list_head *ws); +void btrfs_put_workspace(int type, struct list_head *ws); struct btrfs_compress_op { void (*free_workspace)(struct list_head *workspace); -- cgit v1.2.3 From 1e002351605db4f2fc4114cbb973d5aead72d006 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 4 Oct 2019 02:57:22 +0200 Subject: btrfs: compression: inline free_workspace Replace indirect calls to free_workspace by switch and calls to the specific callbacks. This is mainly to get rid of the indirection due to spectre vulnerability mitigations. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 21 ++++++++++++++++++--- fs/btrfs/compression.h | 2 -- fs/btrfs/lzo.c | 1 - fs/btrfs/zlib.c | 1 - fs/btrfs/zstd.c | 1 - 5 files changed, 18 insertions(+), 8 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 2a77c91c194b..b2342f99b093 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -912,7 +912,6 @@ fail: const struct btrfs_compress_op btrfs_heuristic_compress = { .workspace_manager = &heuristic_wsm, - .free_workspace = free_heuristic_ws, }; static const struct btrfs_compress_op * const btrfs_compress_op[] = { @@ -939,6 +938,22 @@ static struct list_head *alloc_workspace(int type, unsigned int level) } } +static void free_workspace(int type, struct list_head *ws) +{ + switch (type) { + case BTRFS_COMPRESS_NONE: return free_heuristic_ws(ws); + case BTRFS_COMPRESS_ZLIB: return zlib_free_workspace(ws); + case BTRFS_COMPRESS_LZO: return lzo_free_workspace(ws); + case BTRFS_COMPRESS_ZSTD: return zstd_free_workspace(ws); + default: + /* + * This can't happen, the type is validated several times + * before we get here. + */ + BUG(); + } +} + static void btrfs_init_workspace_manager(int type) { const struct btrfs_compress_op *ops = btrfs_compress_op[type]; @@ -976,7 +991,7 @@ static void btrfs_cleanup_workspace_manager(int type) while (!list_empty(&wsman->idle_ws)) { ws = wsman->idle_ws.next; list_del(ws); - wsman->ops->free_workspace(ws); + free_workspace(type, ws); atomic_dec(&wsman->total_ws); } } @@ -1111,7 +1126,7 @@ void btrfs_put_workspace(int type, struct list_head *ws) } spin_unlock(ws_lock); - wsm->ops->free_workspace(ws); + free_workspace(type, ws); atomic_dec(total_ws); wake: cond_wake_up(ws_wait); diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 664b029cd5e4..14057498dcbb 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -124,8 +124,6 @@ struct list_head *btrfs_get_workspace(int type, unsigned int level); void btrfs_put_workspace(int type, struct list_head *ws); struct btrfs_compress_op { - void (*free_workspace)(struct list_head *workspace); - struct workspace_manager *workspace_manager; /* Maximum level supported by the compression algorithm */ unsigned int max_level; diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 39b2cf80f77c..aa9cd11f4b78 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -484,7 +484,6 @@ out: const struct btrfs_compress_op btrfs_lzo_compress = { .workspace_manager = &wsm, - .free_workspace = lzo_free_workspace, .max_level = 1, .default_level = 1, }; diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index c5dfab3ab082..a6c90a003c12 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -400,7 +400,6 @@ next: const struct btrfs_compress_op btrfs_zlib_compress = { .workspace_manager = &wsm, - .free_workspace = zlib_free_workspace, .max_level = 9, .default_level = BTRFS_ZLIB_DEFAULT_LEVEL, }; diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index 9413f741c2f6..9a4871636c6c 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -708,7 +708,6 @@ finish: const struct btrfs_compress_op btrfs_zstd_compress = { /* ZSTD uses own workspace manager */ .workspace_manager = NULL, - .free_workspace = zstd_free_workspace, .max_level = ZSTD_BTRFS_MAX_LEVEL, .default_level = ZSTD_BTRFS_DEFAULT_LEVEL, }; -- cgit v1.2.3 From 0cf252131361cdeebb7dfc88dd8ec825fff0956a Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 4 Oct 2019 03:09:55 +0200 Subject: btrfs: compression: remove ops pointer from workspace_manager We can infer the ops from the type that is now passed to all functions that would need it, this makes workspace_manager::ops redundant and can be removed. Reviewed-by: Johannes Thumshirn Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- fs/btrfs/compression.c | 6 ++---- fs/btrfs/compression.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'fs/btrfs/compression.h') diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index b2342f99b093..53aee0db9d71 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -956,12 +956,10 @@ static void free_workspace(int type, struct list_head *ws) static void btrfs_init_workspace_manager(int type) { - const struct btrfs_compress_op *ops = btrfs_compress_op[type]; - struct workspace_manager *wsm = ops->workspace_manager; + struct workspace_manager *wsm; struct list_head *workspace; - wsm->ops = ops; - + wsm = btrfs_compress_op[type]->workspace_manager; INIT_LIST_HEAD(&wsm->idle_ws); spin_lock_init(&wsm->ws_lock); atomic_set(&wsm->total_ws, 0); diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 14057498dcbb..d253f7aa8ed5 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -109,7 +109,6 @@ enum btrfs_compression_type { }; struct workspace_manager { - const struct btrfs_compress_op *ops; struct list_head idle_ws; spinlock_t ws_lock; /* Number of free workspaces */ -- cgit v1.2.3