Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ebfd5d8f authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Jens Axboe
Browse files

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: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 56392d2f
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -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.