Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions drivers/block/drbd/drbd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -886,8 +886,6 @@ struct drbd_device {
atomic_t rs_sect_in; /* for incoming resync data rate, SyncTarget */
atomic_t rs_sect_ev; /* for submitted resync data rate, both */
int rs_last_sect_ev; /* counter to compare with */
int rs_last_events; /* counter of read or write "events" (unit sectors)
* on the lower level device when we last looked. */
int c_sync_rate; /* current resync rate after syncer throttle magic */
struct fifo_buffer *rs_plan_s; /* correction values of resync planer (RCU, connection->conn_update) */
int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */
Expand Down
1 change: 0 additions & 1 deletion drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2018,7 +2018,6 @@ void drbd_device_cleanup(struct drbd_device *device)
device->rs_start =
device->rs_total =
device->rs_failed = 0;
device->rs_last_events = 0;
device->rs_last_sect_ev = 0;
for (i = 0; i < DRBD_SYNC_MARKS; i++) {
device->rs_mark_left[i] = 0;
Expand Down
62 changes: 34 additions & 28 deletions drivers/block/drbd/drbd_receiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -2569,50 +2569,56 @@ bool drbd_rs_should_slow_down(struct drbd_peer_device *peer_device, sector_t sec
return throttle;
}

/*
* Throttle resync when application I/O is in flight on the backing
* device and the resync is running faster than c-min-rate.
*
* The previous heuristic compared the backing device's part_stat
* sectors counter against our own rs_sect_ev counter (similar to
* MD RAID is_mddev_idle()) and fired on a delta > 64 sectors. That
* comparison is racy: rs_sect_ev is bumped at submission while
* part_stat is updated on bio completion (and is per-cpu), and the
* receiver path bumps rs_sect_ev *after* the throttle check. On
* fast hardware the transient skew routinely exceeds 64 sectors
* even with no application I/O, capping resync throughput at
* c-min-rate.
*
* ap_bio_cnt is incremented unconditionally for every application
* request in drbd_make_request(), so it is the authoritative
* "is application I/O in flight" signal.
*/
bool drbd_rs_c_min_rate_throttle(struct drbd_device *device)
{
struct gendisk *disk = device->ldev->backing_bdev->bd_disk;
unsigned long db, dt, dbdt;
unsigned int c_min_rate;
int curr_events;
unsigned long rs_left;
int i;

rcu_read_lock();
c_min_rate = rcu_dereference(device->ldev->disk_conf)->c_min_rate;
rcu_read_unlock();

/* feature disabled? */
if (c_min_rate == 0)
return false;

curr_events = (int)part_stat_read_accum(disk->part0, sectors) -
atomic_read(&device->rs_sect_ev);

if (atomic_read(&device->ap_actlog_cnt)
|| curr_events - device->rs_last_events > 64) {
unsigned long rs_left;
int i;

device->rs_last_events = curr_events;
if (!atomic_read(&device->ap_bio_cnt))
return false;

/* sync speed average over the last 2*DRBD_SYNC_MARK_STEP,
* approx. */
i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
/* sync speed average over the last 2*DRBD_SYNC_MARK_STEP, approx. */
i = (device->rs_last_mark + DRBD_SYNC_MARKS - 1) % DRBD_SYNC_MARKS;

if (device->state.conn == C_VERIFY_S || device->state.conn == C_VERIFY_T)
rs_left = device->ov_left;
else
rs_left = drbd_bm_total_weight(device) - device->rs_failed;
if (device->state.conn == C_VERIFY_S || device->state.conn == C_VERIFY_T)
rs_left = device->ov_left;
else
rs_left = drbd_bm_total_weight(device) - device->rs_failed;

dt = ((long)jiffies - (long)device->rs_mark_time[i]) / HZ;
if (!dt)
dt++;
db = device->rs_mark_left[i] - rs_left;
dbdt = Bit2KB(db/dt);
dt = ((long)jiffies - (long)device->rs_mark_time[i]) / HZ;
if (!dt)
dt++;
db = device->rs_mark_left[i] - rs_left;
dbdt = Bit2KB(db / dt);

if (dbdt > c_min_rate)
return true;
}
return false;
return dbdt > c_min_rate;
}

static int receive_DataRequest(struct drbd_connection *connection, struct packet_info *pi)
Expand Down
3 changes: 0 additions & 3 deletions drivers/block/drbd/drbd_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -1657,14 +1657,11 @@ void drbd_resync_after_changed(struct drbd_device *device)
void drbd_rs_controller_reset(struct drbd_peer_device *peer_device)
{
struct drbd_device *device = peer_device->device;
struct gendisk *disk = device->ldev->backing_bdev->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_accum(disk->part0, sectors);

/* Updating the RCU protected object in place is necessary since
this function gets called from atomic context.
Expand Down