summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_main.c
diff options
context:
space:
mode:
authorLars Ellenberg2012-07-30 09:08:25 +0200
committerPhilipp Reisner2012-11-08 16:58:39 +0100
commit6f3465ed82b10922effe364676103cbd4f2bcd81 (patch)
tree9dc3f63d3faffecd49cac56a3affc55b1df08ae8 /drivers/block/drbd/drbd_main.c
parentdrbd: differentiate between normal and forced detach (diff)
downloadkernel-qcow2-linux-6f3465ed82b10922effe364676103cbd4f2bcd81.tar.gz
kernel-qcow2-linux-6f3465ed82b10922effe364676103cbd4f2bcd81.tar.xz
kernel-qcow2-linux-6f3465ed82b10922effe364676103cbd4f2bcd81.zip
drbd: report congestion if we are waiting for some userland callback
If the drbd worker thread is synchronously waiting for some userland callback, we don't want some casual pageout to block on us. Have drbd_congested() report congestion in that case. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_main.c')
-rw-r--r--drivers/block/drbd/drbd_main.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 849e5de9ea8f..f2af74d06860 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2338,6 +2338,22 @@ static int drbd_congested(void *congested_data, int bdi_bits)
goto out;
}
+ if (test_bit(CALLBACK_PENDING, &mdev->tconn->flags)) {
+ r |= (1 << BDI_async_congested);
+ /* Without good local data, we would need to read from remote,
+ * and that would need the worker thread as well, which is
+ * currently blocked waiting for that usermode helper to
+ * finish.
+ */
+ if (!get_ldev_if_state(mdev, D_UP_TO_DATE))
+ r |= (1 << BDI_sync_congested);
+ else
+ put_ldev(mdev);
+ r &= bdi_bits;
+ reason = 'c';
+ goto out;
+ }
+
if (get_ldev(mdev)) {
q = bdev_get_queue(mdev->ldev->backing_bdev);
r = bdi_congested(&q->backing_dev_info, bdi_bits);