drbd: fix resync throttling initialization
authorLars Ellenberg <lars.ellenberg@linbit.com>
Mon, 10 Nov 2014 16:21:12 +0000 (17:21 +0100)
committerJens Axboe <axboe@fb.com>
Mon, 10 Nov 2014 16:27:37 +0000 (09:27 -0700)
If for some reason DRBD resync was the only activity on a backend
device, drbd_rs_c_min_rate_throttle() would mistakenly decide that it is
still initialization time, and keep throttling the resync.

This patch explicitly initializes ->rs_last_events to the current
backend event counters, and drops the rs_last_events == 0 from the
throttle condition.

Reported-by: Mikhail Sugakov <msugakov@amazon.de>
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_receiver.c
drivers/block/drbd/drbd_state.c
drivers/block/drbd/drbd_worker.c

index 6960fb064731075ee86297082fc0a1cf4fcdcd2d..d169b4a7926700187cc643f1ef29a6cd22aeaed3 100644 (file)
@@ -2482,7 +2482,7 @@ bool drbd_rs_c_min_rate_throttle(struct drbd_device *device)
                        atomic_read(&device->rs_sect_ev);
 
        if (atomic_read(&device->ap_actlog_cnt)
-           || !device->rs_last_events || curr_events - device->rs_last_events > 64) {
+           || curr_events - device->rs_last_events > 64) {
                unsigned long rs_left;
                int i;
 
index 4529d9282cef6dd6d73593bc73cbea5c8247f8dc..2d7dd269b6a82a41f94ce044f4baf4c87c92d473 100644 (file)
@@ -1099,7 +1099,6 @@ __drbd_set_state(struct drbd_device *device, union drbd_state ns,
 
                set_ov_position(device, ns.conn);
                device->rs_start = now;
-               device->rs_last_events = 0;
                device->rs_last_sect_ev = 0;
                device->ov_last_oos_size = 0;
                device->ov_last_oos_start = 0;
index d2d1f97511bd1fe03496834dea3503f2aacdb617..d0fae55d871d699a67f0a9ad3036f71d2265131c 100644 (file)
@@ -1592,11 +1592,15 @@ void drbd_resync_after_changed(struct drbd_device *device)
 
 void drbd_rs_controller_reset(struct drbd_device *device)
 {
+       struct gendisk *disk = device->ldev->backing_bdev->bd_contains->bd_disk;
        struct fifo_buffer *plan;
 
        atomic_set(&device->rs_sect_in, 0);
        atomic_set(&device->rs_sect_ev, 0);
        device->rs_in_flight = 0;
+       device->rs_last_events =
+               (int)part_stat_read(&disk->part0, sectors[0]) +
+               (int)part_stat_read(&disk->part0, sectors[1]);
 
        /* Updating the RCU protected object in place is necessary since
           this function gets called from atomic context.
@@ -1743,7 +1747,6 @@ void drbd_start_resync(struct drbd_device *device, enum drbd_conns side)
                device->rs_failed    = 0;
                device->rs_paused    = 0;
                device->rs_same_csum = 0;
-               device->rs_last_events = 0;
                device->rs_last_sect_ev = 0;
                device->rs_total     = tw;
                device->rs_start     = now;