aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/drbd/drbd_req.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index d72f2fef1cba..9f7ff1cb46ff 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -1226,6 +1226,37 @@ void do_submit(struct work_struct *ws)
1226 break; 1226 break;
1227 1227
1228 wait_event(mdev->al_wait, prepare_al_transaction_nonblock(mdev, &incoming, &pending)); 1228 wait_event(mdev->al_wait, prepare_al_transaction_nonblock(mdev, &incoming, &pending));
1229 /* Maybe more was queued, while we prepared the transaction?
1230 * Try to stuff them into this transaction as well.
1231 * Be strictly non-blocking here, no wait_event, we already
1232 * have something to commit.
1233 * Stop if we don't make any more progres.
1234 */
1235 for (;;) {
1236 LIST_HEAD(more_pending);
1237 LIST_HEAD(more_incoming);
1238 bool made_progress;
1239
1240 /* It is ok to look outside the lock,
1241 * it's only an optimization anyways */
1242 if (list_empty(&mdev->submit.writes))
1243 break;
1244
1245 spin_lock(&mdev->submit.lock);
1246 list_splice_tail_init(&mdev->submit.writes, &more_incoming);
1247 spin_unlock(&mdev->submit.lock);
1248
1249 if (list_empty(&more_incoming))
1250 break;
1251
1252 made_progress = prepare_al_transaction_nonblock(mdev, &more_incoming, &more_pending);
1253
1254 list_splice_tail_init(&more_pending, &pending);
1255 list_splice_tail_init(&more_incoming, &incoming);
1256
1257 if (!made_progress)
1258 break;
1259 }
1229 drbd_al_begin_io_commit(mdev, false); 1260 drbd_al_begin_io_commit(mdev, false);
1230 1261
1231 list_for_each_entry_safe(req, tmp, &pending, tl_requests) { 1262 list_for_each_entry_safe(req, tmp, &pending, tl_requests) {