aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/drbd/drbd_actlog.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 933404e6ba28..aeb483daea06 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -212,13 +212,22 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i)
212 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); 212 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9);
213 unsigned last = (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); 213 unsigned last = (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9);
214 unsigned enr; 214 unsigned enr;
215 bool locked = false;
216
215 217
216 D_ASSERT(atomic_read(&mdev->local_cnt) > 0); 218 D_ASSERT(atomic_read(&mdev->local_cnt) > 0);
217 219
218 for (enr = first; enr <= last; enr++) 220 for (enr = first; enr <= last; enr++)
219 wait_event(mdev->al_wait, _al_get(mdev, enr) != NULL); 221 wait_event(mdev->al_wait, _al_get(mdev, enr) != NULL);
220 222
221 if (mdev->act_log->pending_changes) { 223 /* Serialize multiple transactions.
224 * This uses test_and_set_bit, memory barrier is implicit.
225 */
226 wait_event(mdev->al_wait,
227 mdev->act_log->pending_changes == 0 ||
228 (locked = lc_try_lock_for_transaction(mdev->act_log)));
229
230 if (locked) {
222 /* drbd_al_write_transaction(mdev,al_ext,enr); 231 /* drbd_al_write_transaction(mdev,al_ext,enr);
223 * recurses into generic_make_request(), which 232 * recurses into generic_make_request(), which
224 * disallows recursion, bios being serialized on the 233 * disallows recursion, bios being serialized on the
@@ -226,13 +235,6 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i)
226 * we have to delegate updates to the activity log 235 * we have to delegate updates to the activity log
227 * to the worker thread. */ 236 * to the worker thread. */
228 237
229 /* Serialize multiple transactions.
230 * This uses test_and_set_bit, memory barrier is implicit.
231 * Optimization potential:
232 * first check for transaction number > old transaction number,
233 * so not all waiters have to lock/unlock. */
234 wait_event(mdev->al_wait, lc_try_lock_for_transaction(mdev->act_log));
235
236 /* Double check: it may have been committed by someone else, 238 /* Double check: it may have been committed by someone else,
237 * while we have been waiting for the lock. */ 239 * while we have been waiting for the lock. */
238 if (mdev->act_log->pending_changes) { 240 if (mdev->act_log->pending_changes) {