drbd: drbd_al_being_io: short circuit to reduce latency
authorLars Ellenberg <lars.ellenberg@linbit.com>
Tue, 19 Mar 2013 17:16:49 +0000 (18:16 +0100)
committerJens Axboe <axboe@kernel.dk>
Sat, 23 Mar 2013 00:14:00 +0000 (18:14 -0600)
A request hitting an already "hot" extent should proceed right away,
even if some other requests need to wait for pending transactions.

Without that short-circuit, several simultaneous make_request contexts
race for committing the transaction, possibly penalizing the innocent.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/drbd/drbd_actlog.c

index 82199d9a9a61fed987661d7b7cbae8bac7510156..1d7244d2a910ef02e6d375f3bde28a2939894246 100644 (file)
@@ -256,6 +256,7 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool dele
        unsigned first = i->sector >> (AL_EXTENT_SHIFT-9);
        unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9);
        unsigned enr;
+       bool need_transaction = false;
        bool locked = false;
 
        /* When called through generic_make_request(), we must delegate
@@ -273,8 +274,17 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool dele
        D_ASSERT(first <= last);
        D_ASSERT(atomic_read(&mdev->local_cnt) > 0);
 
-       for (enr = first; enr <= last; enr++)
-               wait_event(mdev->al_wait, _al_get(mdev, enr) != NULL);
+       for (enr = first; enr <= last; enr++) {
+               struct lc_element *al_ext;
+               wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)) != NULL);
+               if (al_ext->lc_number != enr)
+                       need_transaction = true;
+       }
+
+       /* If *this* request was to an already active extent,
+        * we're done, even if there are pending changes. */
+       if (!need_transaction)
+               return;
 
        /* Serialize multiple transactions.
         * This uses test_and_set_bit, memory barrier is implicit.