drbd: conflicting writes: make wake_up of waiting peer_requests explicit

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 938a57b..c0326f5 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -212,6 +212,16 @@
 		wake_up(&mdev->misc_wait);
 }
 
+static void maybe_wakeup_conflicting_requests(struct drbd_request *req)
+{
+	const unsigned long s = req->rq_state;
+	if (s & RQ_LOCAL_PENDING && !(s & RQ_LOCAL_ABORTED))
+		return;
+	if (req->i.waiting)
+		/* Retry all conflicting peer requests.  */
+		wake_up(&req->w.mdev->misc_wait);
+}
+
 /* Helper for __req_mod().
  * Set m->bio to the master bio, if it is fit to be completed,
  * or leave it alone (it is initialized to NULL in __req_mod),
@@ -235,10 +245,6 @@
 	 */
 	if (s & RQ_LOCAL_PENDING && !(s & RQ_LOCAL_ABORTED))
 		return;
-	if (req->i.waiting) {
-		/* Retry all conflicting peer requests.  */
-		wake_up(&mdev->misc_wait);
-	}
 	if (s & RQ_NET_QUEUED)
 		return;
 	if (s & RQ_NET_PENDING)
@@ -388,6 +394,7 @@
 		req->rq_state |= (RQ_LOCAL_COMPLETED|RQ_LOCAL_OK);
 		req->rq_state &= ~RQ_LOCAL_PENDING;
 
+		maybe_wakeup_conflicting_requests(req);
 		_req_may_be_done_not_susp(req, m);
 		put_ldev(mdev);
 		break;
@@ -405,6 +412,7 @@
 		req->rq_state &= ~RQ_LOCAL_PENDING;
 
 		__drbd_chk_io_error(mdev, false);
+		maybe_wakeup_conflicting_requests(req);
 		_req_may_be_done_not_susp(req, m);
 		put_ldev(mdev);
 		break;
@@ -615,6 +623,7 @@
 		dec_ap_pending(mdev);
 		atomic_sub(req->i.size >> 9, &mdev->ap_in_flight);
 		req->rq_state &= ~RQ_NET_PENDING;
+		maybe_wakeup_conflicting_requests(req);
 		_req_may_be_done_not_susp(req, m);
 		break;
 
@@ -626,6 +635,7 @@
 		 */
 		D_ASSERT(req->rq_state & RQ_NET_PENDING);
 		req->rq_state |= RQ_POSTPONED;
+		maybe_wakeup_conflicting_requests(req);
 		_req_may_be_done_not_susp(req, m);
 		break;
 
@@ -643,6 +653,7 @@
 		if (!(req->rq_state & RQ_WRITE))
 			goto goto_read_retry_local;
 
+		maybe_wakeup_conflicting_requests(req);
 		_req_may_be_done_not_susp(req, m);
 		/* else: done by HANDED_OVER_TO_NETWORK */
 		break;