aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-06-09 15:59:22 -0400
committerChris Mason <chris.mason@oracle.com>2009-06-10 11:29:49 -0400
commitd644d8a1e30b88a93bcfb63cada2ae628462ddba (patch)
tree0037b0282390f5bced029d0a2973e5a03777ca12
parentd84275c938e1a5e2dc5b89eb9b878e0ddb2c55e0 (diff)
Btrfs: avoid IO stalls behind congested devices in a multi-device FS
The btrfs IO submission threads try to service a bunch of devices with a small number of threads. They do a congestion check to try and avoid waiting on requests for a busy device. The checks make sure we've sent a few requests down to a given device just so that we aren't bouncing between busy devices without actually sending down any IO. The counter used to decide if we can switch to the next device is somewhat overloaded. It is also being used to decide if we've done a good batch of requests between the WRITE_SYNC or regular priority lists. It may get reset to zero often, leaving us hammering on a busy device instead of moving on to another disk. This commit adds a new counter for the number of bios sent while servicing a device. It doesn't get reset or fiddled with. On multi-device filesystems, this fixes IO stalls in streaming write workloads. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/volumes.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 9d3618192009..27d5f37b845f 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -161,6 +161,7 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
161 int again = 0; 161 int again = 0;
162 unsigned long num_run; 162 unsigned long num_run;
163 unsigned long num_sync_run; 163 unsigned long num_sync_run;
164 unsigned long batch_run = 0;
164 unsigned long limit; 165 unsigned long limit;
165 unsigned long last_waited = 0; 166 unsigned long last_waited = 0;
166 int force_reg = 0; 167 int force_reg = 0;
@@ -257,6 +258,8 @@ loop_lock:
257 BUG_ON(atomic_read(&cur->bi_cnt) == 0); 258 BUG_ON(atomic_read(&cur->bi_cnt) == 0);
258 submit_bio(cur->bi_rw, cur); 259 submit_bio(cur->bi_rw, cur);
259 num_run++; 260 num_run++;
261 batch_run++;
262
260 if (bio_sync(cur)) 263 if (bio_sync(cur))
261 num_sync_run++; 264 num_sync_run++;
262 265
@@ -273,7 +276,7 @@ loop_lock:
273 * is now congested. Back off and let other work structs 276 * is now congested. Back off and let other work structs
274 * run instead 277 * run instead
275 */ 278 */
276 if (pending && bdi_write_congested(bdi) && num_run > 16 && 279 if (pending && bdi_write_congested(bdi) && batch_run > 32 &&
277 fs_info->fs_devices->open_devices > 1) { 280 fs_info->fs_devices->open_devices > 1) {
278 struct io_context *ioc; 281 struct io_context *ioc;
279 282