]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/block/drbd/drbd_actlog.c
drbd: skip spurious wait_event in drbd_al_begin_io
[mirror_ubuntu-artful-kernel.git] / drivers / block / drbd / drbd_actlog.c
index 933404e6ba2818c060dea80bc31acd9b16974b39..aeb483daea067fe805a47556ab7c66f4029b3a80 100644 (file)
@@ -212,13 +212,22 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i)
        unsigned first = i->sector >> (AL_EXTENT_SHIFT-9);
        unsigned last = (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9);
        unsigned enr;
+       bool locked = false;
+
 
        D_ASSERT(atomic_read(&mdev->local_cnt) > 0);
 
        for (enr = first; enr <= last; enr++)
                wait_event(mdev->al_wait, _al_get(mdev, enr) != NULL);
 
-       if (mdev->act_log->pending_changes) {
+       /* Serialize multiple transactions.
+        * This uses test_and_set_bit, memory barrier is implicit.
+        */
+       wait_event(mdev->al_wait,
+                       mdev->act_log->pending_changes == 0 ||
+                       (locked = lc_try_lock_for_transaction(mdev->act_log)));
+
+       if (locked) {
                /* drbd_al_write_transaction(mdev,al_ext,enr);
                 * recurses into generic_make_request(), which
                 * disallows recursion, bios being serialized on the
@@ -226,13 +235,6 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i)
                 * we have to delegate updates to the activity log
                 * to the worker thread. */
 
-               /* Serialize multiple transactions.
-                * This uses test_and_set_bit, memory barrier is implicit.
-                * Optimization potential:
-                * first check for transaction number > old transaction number,
-                * so not all waiters have to lock/unlock.  */
-               wait_event(mdev->al_wait, lc_try_lock_for_transaction(mdev->act_log));
-
                /* Double check: it may have been committed by someone else,
                 * while we have been waiting for the lock. */
                if (mdev->act_log->pending_changes) {