Skip to content

Commit

Permalink
btrfs: detect fast implementation of crc32c on all architectures
Browse files Browse the repository at this point in the history
Currently, there's only check for fast crc32c implementation on X86,
based on the CPU flags. This is used to decide if checksumming should be
offloaded to worker threads or can be calculated by the caller.

As there are more architectures that implement a faster version of
crc32c (ARM, SPARC, s390, MIPS, PowerPC), also there are specialized hw
cards.

The detection is based on driver name, all generic C implementations
contain 'generic', while the specialized versions do not. Alternatively
the priority could be used, but this is not currently provided by the
crypto API.

The flag is set per-filesystem at mount time and used for the offloading
decisions.

Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
David Sterba committed Jul 1, 2019
1 parent 7819244 commit 9b4e675
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 9 deletions.
6 changes: 6 additions & 0 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,12 @@ enum {

/* Indicate that the cleaner thread is awake and doing something. */
BTRFS_FS_CLEANER_RUNNING,

/*
* The checksumming has an optimized version and is considered fast,
* so we don't need to offload checksums to workqueues.
*/
BTRFS_FS_CSUM_IMPL_FAST,
};

struct btrfs_fs_info {
Expand Down
13 changes: 4 additions & 9 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@
#include "tree-checker.h"
#include "ref-verify.h"

#ifdef CONFIG_X86
#include <asm/cpufeature.h>
#endif

#define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN |\
BTRFS_HEADER_FLAG_RELOC |\
BTRFS_SUPER_FLAG_ERROR |\
Expand Down Expand Up @@ -873,14 +869,13 @@ static blk_status_t btree_submit_bio_start(void *private_data, struct bio *bio,
return btree_csum_one_bio(bio);
}

static int check_async_write(struct btrfs_inode *bi)
static int check_async_write(struct btrfs_fs_info *fs_info,
struct btrfs_inode *bi)
{
if (atomic_read(&bi->sync_writers))
return 0;
#ifdef CONFIG_X86
if (static_cpu_has(X86_FEATURE_XMM4_2))
if (test_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags))
return 0;
#endif
return 1;
}

Expand All @@ -889,7 +884,7 @@ static blk_status_t btree_submit_bio_hook(struct inode *inode, struct bio *bio,
unsigned long bio_flags)
{
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
int async = check_async_write(BTRFS_I(inode));
int async = check_async_write(fs_info, BTRFS_I(inode));
blk_status_t ret;

if (bio_op(bio) != REQ_OP_WRITE) {
Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,8 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
} else {
snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
btrfs_sb(s)->bdev_holder = fs_type;
if (!strstr(crc32c_impl(), "generic"))
set_bit(BTRFS_FS_CSUM_IMPL_FAST, &fs_info->flags);
error = btrfs_fill_super(s, fs_devices, data);
}
if (!error)
Expand Down

0 comments on commit 9b4e675

Please sign in to comment.