drbd: don't let application IO pre-empt resync too often
authorLars Ellenberg <lars.ellenberg@linbit.com>
Mon, 28 Apr 2014 16:43:19 +0000 (18:43 +0200)
committerJens Axboe <axboe@fb.com>
Wed, 30 Apr 2014 19:46:54 +0000 (13:46 -0600)
Before, application IO could pre-empt resync activity
for up to hardcoded 20 seconds per resync request.
A very busy server could throttle the effective resync bandwidth
down to one request per 20 seconds.

Now, we only let application IO pre-empt resync traffic
while the current resync rate estimate is above c-min-rate.

If you disable the c-min-rate throttle feature (set c-min-rate = 0),
application IO will no longer pre-empt resync traffic at all.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/block/drbd/drbd_actlog.c
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_receiver.c

index 7e7b0e1..8dd09a7 100644 (file)
@@ -1022,8 +1022,7 @@ int drbd_rs_begin_io(struct drbd_device *device, sector_t sector)
        unsigned int enr = BM_SECT_TO_EXT(sector);
        struct bm_extent *bm_ext;
        int i, sig;
-       int sa = 200; /* Step aside 200 times, then grab the extent and let app-IO wait.
-                        200 times -> 20 seconds. */
+       bool sa;
 
 retry:
        sig = wait_event_interruptible(device->al_wait,
@@ -1034,12 +1033,15 @@ retry:
        if (test_bit(BME_LOCKED, &bm_ext->flags))
                return 0;
 
+       /* step aside only while we are above c-min-rate; unless disabled. */
+       sa = drbd_rs_c_min_rate_throttle(device);
+
        for (i = 0; i < AL_EXT_PER_BM_SECT; i++) {
                sig = wait_event_interruptible(device->al_wait,
                                               !_is_in_al(device, enr * AL_EXT_PER_BM_SECT + i) ||
-                                              test_bit(BME_PRIORITY, &bm_ext->flags));
+                                              (sa && test_bit(BME_PRIORITY, &bm_ext->flags)));
 
-               if (sig || (test_bit(BME_PRIORITY, &bm_ext->flags) && sa)) {
+               if (sig || (sa && test_bit(BME_PRIORITY, &bm_ext->flags))) {
                        spin_lock_irq(&device->al_lock);
                        if (lc_put(device->resync, &bm_ext->lce) == 0) {
                                bm_ext->flags = 0; /* clears BME_NO_WRITES and eventually BME_PRIORITY */
@@ -1051,9 +1053,6 @@ retry:
                                return -EINTR;
                        if (schedule_timeout_interruptible(HZ/10))
                                return -EINTR;
-                       if (sa && --sa == 0)
-                               drbd_warn(device, "drbd_rs_begin_io() stepped aside for 20sec."
-                                        "Resync stalled?\n");
                        goto retry;
                }
        }
Simple merge
Simple merge