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 <jthumshirn@suse.de> Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Родитель
c4bf665a31
Коммит
1e4eb74654
|
@ -86,6 +86,70 @@ bool btrfs_compress_is_valid_type(const char *str, size_t len)
|
||||||
return false;
|
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 int btrfs_decompress_bio(struct compressed_bio *cb);
|
||||||
|
|
||||||
static inline int compressed_bio_size(struct btrfs_fs_info *fs_info,
|
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);
|
level = btrfs_compress_set_level(type, level);
|
||||||
workspace = get_workspace(type, level);
|
workspace = get_workspace(type, level);
|
||||||
ret = btrfs_compress_op[type]->compress_pages(workspace, mapping,
|
ret = compression_compress_pages(type, workspace, mapping, start, pages,
|
||||||
start, pages,
|
out_pages, total_in, total_out);
|
||||||
out_pages,
|
|
||||||
total_in, total_out);
|
|
||||||
put_workspace(type, workspace);
|
put_workspace(type, workspace);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1103,7 +1165,7 @@ static int btrfs_decompress_bio(struct compressed_bio *cb)
|
||||||
int type = cb->compress_type;
|
int type = cb->compress_type;
|
||||||
|
|
||||||
workspace = get_workspace(type, 0);
|
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);
|
put_workspace(type, workspace);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1121,9 +1183,8 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
workspace = get_workspace(type, 0);
|
workspace = get_workspace(type, 0);
|
||||||
ret = btrfs_compress_op[type]->decompress(workspace, data_in,
|
ret = compression_decompress(type, workspace, data_in, dest_page,
|
||||||
dest_page, start_byte,
|
start_byte, srclen, destlen);
|
||||||
srclen, destlen);
|
|
||||||
put_workspace(type, workspace);
|
put_workspace(type, workspace);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -140,23 +140,6 @@ struct btrfs_compress_op {
|
||||||
|
|
||||||
void (*free_workspace)(struct list_head *workspace);
|
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 */
|
/* Maximum level supported by the compression algorithm */
|
||||||
unsigned int max_level;
|
unsigned int max_level;
|
||||||
unsigned int default_level;
|
unsigned int default_level;
|
||||||
|
|
|
@ -509,9 +509,6 @@ const struct btrfs_compress_op btrfs_lzo_compress = {
|
||||||
.put_workspace = lzo_put_workspace,
|
.put_workspace = lzo_put_workspace,
|
||||||
.alloc_workspace = lzo_alloc_workspace,
|
.alloc_workspace = lzo_alloc_workspace,
|
||||||
.free_workspace = lzo_free_workspace,
|
.free_workspace = lzo_free_workspace,
|
||||||
.compress_pages = lzo_compress_pages,
|
|
||||||
.decompress_bio = lzo_decompress_bio,
|
|
||||||
.decompress = lzo_decompress,
|
|
||||||
.max_level = 1,
|
.max_level = 1,
|
||||||
.default_level = 1,
|
.default_level = 1,
|
||||||
};
|
};
|
||||||
|
|
|
@ -420,9 +420,6 @@ const struct btrfs_compress_op btrfs_zlib_compress = {
|
||||||
.put_workspace = zlib_put_workspace,
|
.put_workspace = zlib_put_workspace,
|
||||||
.alloc_workspace = zlib_alloc_workspace,
|
.alloc_workspace = zlib_alloc_workspace,
|
||||||
.free_workspace = zlib_free_workspace,
|
.free_workspace = zlib_free_workspace,
|
||||||
.compress_pages = zlib_compress_pages,
|
|
||||||
.decompress_bio = zlib_decompress_bio,
|
|
||||||
.decompress = zlib_decompress,
|
|
||||||
.max_level = 9,
|
.max_level = 9,
|
||||||
.default_level = BTRFS_ZLIB_DEFAULT_LEVEL,
|
.default_level = BTRFS_ZLIB_DEFAULT_LEVEL,
|
||||||
};
|
};
|
||||||
|
|
|
@ -713,9 +713,6 @@ const struct btrfs_compress_op btrfs_zstd_compress = {
|
||||||
.put_workspace = zstd_put_workspace,
|
.put_workspace = zstd_put_workspace,
|
||||||
.alloc_workspace = zstd_alloc_workspace,
|
.alloc_workspace = zstd_alloc_workspace,
|
||||||
.free_workspace = zstd_free_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,
|
.max_level = ZSTD_BTRFS_MAX_LEVEL,
|
||||||
.default_level = ZSTD_BTRFS_DEFAULT_LEVEL,
|
.default_level = ZSTD_BTRFS_DEFAULT_LEVEL,
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче