diff options
-rw-r--r-- | drivers/block/drbd/drbd_actlog.c | 18 |
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) { |