aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_actlog.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2013-03-19 13:16:49 -0400
committerJens Axboe <axboe@kernel.dk>2013-03-22 20:14:00 -0400
commitebfd5d8f715167b886c9401e6b123847187f137b (patch)
tree33da96fa4f1949af33492299930491f2ee797c9a /drivers/block/drbd/drbd_actlog.c
parent56392d2f40aac4b520fc50bc356f40e07f7e1c7d (diff)
drbd: drbd_al_being_io: short circuit to reduce latency
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>
Diffstat (limited to 'drivers/block/drbd/drbd_actlog.c')
-rw-r--r--drivers/block/drbd/drbd_actlog.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 82199d9a9a61..1d7244d2a910 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -256,6 +256,7 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i, bool dele
256 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); 256 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9);
257 unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); 257 unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9);
258 unsigned enr; 258 unsigned enr;
259 bool need_transaction = false;
259 bool locked = false; 260 bool locked = false;
260 261
261 /* When called through generic_make_request(), we must delegate 262 /* 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
273 D_ASSERT(first <= last); 274 D_ASSERT(first <= last);
274 D_ASSERT(atomic_read(&mdev->local_cnt) > 0); 275 D_ASSERT(atomic_read(&mdev->local_cnt) > 0);
275 276
276 for (enr = first; enr <= last; enr++) 277 for (enr = first; enr <= last; enr++) {
277 wait_event(mdev->al_wait, _al_get(mdev, enr) != NULL); 278 struct lc_element *al_ext;
279 wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)) != NULL);
280 if (al_ext->lc_number != enr)
281 need_transaction = true;
282 }
283
284 /* If *this* request was to an already active extent,
285 * we're done, even if there are pending changes. */
286 if (!need_transaction)
287 return;
278 288
279 /* Serialize multiple transactions. 289 /* Serialize multiple transactions.
280 * This uses test_and_set_bit, memory barrier is implicit. 290 * This uses test_and_set_bit, memory barrier is implicit.