|
@@ -601,6 +601,32 @@ static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int raid1_congested(void *data, int bits)
|
|
|
+{
|
|
|
+ mddev_t *mddev = data;
|
|
|
+ conf_t *conf = mddev_to_conf(mddev);
|
|
|
+ int i, ret = 0;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ for (i = 0; i < mddev->raid_disks; i++) {
|
|
|
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
|
|
|
+ if (rdev && !test_bit(Faulty, &rdev->flags)) {
|
|
|
+ request_queue_t *q = bdev_get_queue(rdev->bdev);
|
|
|
+
|
|
|
+ /* Note the '|| 1' - when read_balance prefers
|
|
|
+ * non-congested targets, it can be removed
|
|
|
+ */
|
|
|
+ if ((bits & (1<<BDI_write_congested)) || 1)
|
|
|
+ ret |= bdi_congested(&q->backing_dev_info, bits);
|
|
|
+ else
|
|
|
+ ret &= bdi_congested(&q->backing_dev_info, bits);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rcu_read_unlock();
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
/* Barriers....
|
|
|
* Sometimes we need to suspend IO while we do something else,
|
|
|
* either some resync/recovery, or reconfigure the array.
|
|
@@ -1965,6 +1991,8 @@ static int run(mddev_t *mddev)
|
|
|
|
|
|
mddev->queue->unplug_fn = raid1_unplug;
|
|
|
mddev->queue->issue_flush_fn = raid1_issue_flush;
|
|
|
+ mddev->queue->backing_dev_info.congested_fn = raid1_congested;
|
|
|
+ mddev->queue->backing_dev_info.congested_data = mddev;
|
|
|
|
|
|
return 0;
|
|
|
|