Btrfs: Throttle for async bio submits higher up the chain
authorChris Mason <chris.mason@oracle.com>
Thu, 28 Aug 2008 10:15:24 +0000 (06:15 -0400)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:04:07 +0000 (11:04 -0400)
The current code waits for the count of async bio submits to get below
a given threshold if it is too high right after adding the latest bio
to the work queue.  This isn't optimal because the caller may have
sequential adjacent bios pending they are waiting to send down the pipe.

This changeset requires the caller to wait on the async bio count,
and changes the async checksumming submits to wait for async bios any
time they self throttle.

The end result is much higher sequential throughput.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/disk-io.c
fs/btrfs/volumes.c

index bbba14b629d217d2f96e19707bb6e9f3eb82c6f1..6a218f792e597273d136a42c8ad3e7682caa804e 100644 (file)
@@ -487,9 +487,15 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
        atomic_inc(&fs_info->nr_async_submits);
        btrfs_queue_worker(&fs_info->workers, &async->work);
 
-       wait_event_timeout(fs_info->async_submit_wait,
+       if (atomic_read(&fs_info->nr_async_submits) > limit) {
+               wait_event_timeout(fs_info->async_submit_wait,
                           (atomic_read(&fs_info->nr_async_submits) < limit),
                           HZ/10);
+
+               wait_event_timeout(fs_info->async_submit_wait,
+                          (atomic_read(&fs_info->nr_async_bios) < limit),
+                          HZ/10);
+       }
        return 0;
 }
 
index 2652660e6079be6b8da1424989636d13518a27c7..5b1b60839d21d10c23b032ef95939be5b806dcac 100644 (file)
@@ -2145,7 +2145,6 @@ int schedule_bio(struct btrfs_root *root, struct btrfs_device *device,
                 int rw, struct bio *bio)
 {
        int should_queue = 1;
-       unsigned long limit;
 
        /* don't bother with additional async steps for reads, right now */
        if (!(rw & (1 << BIO_RW))) {
@@ -2182,11 +2181,6 @@ int schedule_bio(struct btrfs_root *root, struct btrfs_device *device,
        if (should_queue)
                btrfs_queue_worker(&root->fs_info->submit_workers,
                                   &device->work);
-
-       limit = btrfs_async_submit_limit(root->fs_info);
-       wait_event_timeout(root->fs_info->async_submit_wait,
-                          (atomic_read(&root->fs_info->nr_async_bios) < limit),
-                          HZ/10);
        return 0;
 }