drbd: Control the actual resync rate based on the queuing delay of data packets
authorPhilipp Reisner <philipp.reisner@linbit.com>
Tue, 4 May 2010 14:57:18 +0000 (16:57 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Mon, 17 May 2010 23:25:47 +0000 (01:25 +0200)
In a setup with a high bandwidth and high latency network, eventually
involving deep queues in routers, it is beneficial to only fill those
queues up to an limited extend with resync data.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_worker.c

index 44bf6d11197e7bbad72f511ba36fba23747be68e..0bbecf45b485f183b41558480924fc62e9223630 100644 (file)
@@ -414,6 +414,18 @@ void resync_timer_fn(unsigned long data)
                drbd_queue_work(&mdev->data.work, &mdev->resync_work);
 }
 
+static int calc_resync_rate(struct drbd_conf *mdev)
+{
+       int d = mdev->data_delay / 1000; /* us -> ms */
+       int td = mdev->sync_conf.throttle_th * 100;  /* 0.1s -> ms */
+       int hd = mdev->sync_conf.hold_off_th * 100;  /* 0.1s -> ms */
+       int cr = mdev->sync_conf.rate;
+
+       return d <= td ? cr :
+               d >= hd ? 0 :
+               cr + (cr * (td - d) / (hd - td));
+}
+
 int w_make_resync_request(struct drbd_conf *mdev,
                struct drbd_work *w, int cancel)
 {
@@ -446,7 +458,8 @@ int w_make_resync_request(struct drbd_conf *mdev,
                return 1;
        }
 
-       number = SLEEP_TIME * mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ);
+       mdev->c_sync_rate = calc_resync_rate(mdev);
+       number = SLEEP_TIME * mdev->c_sync_rate  / ((BM_BLOCK_SIZE / 1024) * HZ);
        pe = atomic_read(&mdev->rs_pending_cnt);
 
        mutex_lock(&mdev->data.mutex);