aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-04-06 14:41:34 -0400
committerJosef Bacik <josef@redhat.com>2011-04-08 13:00:39 -0400
commit1ae399382512b3e4d6c923e53da9e45935577040 (patch)
tree0c07663bf1b6bca8cb774b187f5bb85d36e372d5 /fs
parent02f57c7aedef1a537f4b16db7061cdd8efa3bb4e (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.c24
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
5958static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, 5958static 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); 5996map:
5997 ret = btrfs_map_bio(root, rw, bio, 0, async_submit);
5986err: 5998err:
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
6079submit: 6093submit:
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