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>
This commit is contained in:
Родитель
56392d2f40
Коммит
ebfd5d8f71
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче