diff options
author | Josef Bacik <josef@redhat.com> | 2011-04-06 14:41:34 -0400 |
---|---|---|
committer | Josef Bacik <josef@redhat.com> | 2011-04-08 13:00:39 -0400 |
commit | 1ae399382512b3e4d6c923e53da9e45935577040 (patch) | |
tree | 0c07663bf1b6bca8cb774b187f5bb85d36e372d5 /fs | |
parent | 02f57c7aedef1a537f4b16db7061cdd8efa3bb4e (diff) |
Btrfs: do not use async submit for small DIO io's
When looking at our DIO performance Chris said that for small IO's doing the
async submit stuff tends to be more overhead than it's worth. With this on top
of my other fixes I get about a 17-20% speedup doing a sequential dd with 4k
IO's. Basically if we don't have to split the bio for the map length it's small
enough to be directly submitted, otherwise go back to the async submit. Thanks,
Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/inode.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 149c77fd1eb5..2bb76c6157a4 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -5957,7 +5957,7 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, | |||
5957 | 5957 | ||
5958 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | 5958 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, |
5959 | int rw, u64 file_offset, int skip_sum, | 5959 | int rw, u64 file_offset, int skip_sum, |
5960 | u32 *csums) | 5960 | u32 *csums, int async_submit) |
5961 | { | 5961 | { |
5962 | int write = rw & REQ_WRITE; | 5962 | int write = rw & REQ_WRITE; |
5963 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5963 | struct btrfs_root *root = BTRFS_I(inode)->root; |
@@ -5968,13 +5968,24 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | |||
5968 | if (ret) | 5968 | if (ret) |
5969 | goto err; | 5969 | goto err; |
5970 | 5970 | ||
5971 | if (write && !skip_sum) { | 5971 | if (skip_sum) |
5972 | goto map; | ||
5973 | |||
5974 | if (write && async_submit) { | ||
5972 | ret = btrfs_wq_submit_bio(root->fs_info, | 5975 | ret = btrfs_wq_submit_bio(root->fs_info, |
5973 | inode, rw, bio, 0, 0, | 5976 | inode, rw, bio, 0, 0, |
5974 | file_offset, | 5977 | file_offset, |
5975 | __btrfs_submit_bio_start_direct_io, | 5978 | __btrfs_submit_bio_start_direct_io, |
5976 | __btrfs_submit_bio_done); | 5979 | __btrfs_submit_bio_done); |
5977 | goto err; | 5980 | goto err; |
5981 | } else if (write) { | ||
5982 | /* | ||
5983 | * If we aren't doing async submit, calculate the csum of the | ||
5984 | * bio now. | ||
5985 | */ | ||
5986 | ret = btrfs_csum_one_bio(root, inode, bio, file_offset, 1); | ||
5987 | if (ret) | ||
5988 | goto err; | ||
5978 | } else if (!skip_sum) { | 5989 | } else if (!skip_sum) { |
5979 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, | 5990 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, |
5980 | file_offset, csums); | 5991 | file_offset, csums); |
@@ -5982,7 +5993,8 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | |||
5982 | goto err; | 5993 | goto err; |
5983 | } | 5994 | } |
5984 | 5995 | ||
5985 | ret = btrfs_map_bio(root, rw, bio, 0, 1); | 5996 | map: |
5997 | ret = btrfs_map_bio(root, rw, bio, 0, async_submit); | ||
5986 | err: | 5998 | err: |
5987 | bio_put(bio); | 5999 | bio_put(bio); |
5988 | return ret; | 6000 | return ret; |
@@ -6004,6 +6016,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
6004 | int nr_pages = 0; | 6016 | int nr_pages = 0; |
6005 | u32 *csums = dip->csums; | 6017 | u32 *csums = dip->csums; |
6006 | int ret = 0; | 6018 | int ret = 0; |
6019 | int async_submit = 0; | ||
6007 | int write = rw & REQ_WRITE; | 6020 | int write = rw & REQ_WRITE; |
6008 | 6021 | ||
6009 | map_length = orig_bio->bi_size; | 6022 | map_length = orig_bio->bi_size; |
@@ -6019,6 +6032,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
6019 | goto submit; | 6032 | goto submit; |
6020 | } | 6033 | } |
6021 | 6034 | ||
6035 | async_submit = 1; | ||
6022 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); | 6036 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); |
6023 | if (!bio) | 6037 | if (!bio) |
6024 | return -ENOMEM; | 6038 | return -ENOMEM; |
@@ -6039,7 +6053,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
6039 | atomic_inc(&dip->pending_bios); | 6053 | atomic_inc(&dip->pending_bios); |
6040 | ret = __btrfs_submit_dio_bio(bio, inode, rw, | 6054 | ret = __btrfs_submit_dio_bio(bio, inode, rw, |
6041 | file_offset, skip_sum, | 6055 | file_offset, skip_sum, |
6042 | csums); | 6056 | csums, async_submit); |
6043 | if (ret) { | 6057 | if (ret) { |
6044 | bio_put(bio); | 6058 | bio_put(bio); |
6045 | atomic_dec(&dip->pending_bios); | 6059 | atomic_dec(&dip->pending_bios); |
@@ -6078,7 +6092,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
6078 | 6092 | ||
6079 | submit: | 6093 | submit: |
6080 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, | 6094 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, |
6081 | csums); | 6095 | csums, async_submit); |
6082 | if (!ret) | 6096 | if (!ret) |
6083 | return 0; | 6097 | return 0; |
6084 | 6098 | ||