[azure:x,v2,2/4] Revert "UBUNTU: SAUCE: vmbus: simplify packet iterator"
diff mbox series

Message ID 1520432911-4667-3-git-send-email-marcelo.cerri@canonical.com
State New
Headers show
Series
  • Drivers: hv: vmbus: Fix ring buffer signaling
Related show

Commit Message

Marcelo Henrique Cerri March 7, 2018, 2:28 p.m. UTC
BugLink: http://bugs.launchpad.net/bugs/1748662

This reverts commit 6e76d0d699a8effd941fa7732e18edf4173a6db0.

Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
---
 drivers/hv/ring_buffer.c | 42 ++++++++++++++++--------------------------
 include/linux/hyperv.h   |  2 +-
 2 files changed, 17 insertions(+), 27 deletions(-)

Patch
diff mbox series

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 8214042757cb..2f80666583c4 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -389,28 +389,18 @@  __hv_pkt_iter_next(struct vmbus_channel *channel,
 	if (rbi->priv_read_index >= dsize)
 		rbi->priv_read_index -= dsize;
 
+	/* more data? */
 	return hv_pkt_iter_first(channel);
 }
 EXPORT_SYMBOL_GPL(__hv_pkt_iter_next);
 
 /*
  * Update host ring buffer after iterating over packets.
- *
- * Avoid unnecessary signaling of the host by making sure that all
- * data is read, and the host has not masked off the interrupt.
- *
- * In addition, in Windows 8 or later there is an extension for the
- * host to indicate how much space needs to be available before
- * signaling. The hos sets pending_send_sz to the number of bytes
- * that it is waiting to send.
  */
 void hv_pkt_iter_close(struct vmbus_channel *channel)
 {
 	struct hv_ring_buffer_info *rbi = &channel->inbound;
-	u32 orig_write_sz;
-
-	/* Available space before read_index update */
-	orig_write_sz = hv_get_bytes_to_write(rbi);
+	u32 orig_write_sz = hv_get_bytes_to_write(rbi);
 
 	/*
 	 * Make sure all reads are done before we update the read index since
@@ -418,29 +408,29 @@  void hv_pkt_iter_close(struct vmbus_channel *channel)
 	 * is updated.
 	 */
 	virt_rmb();
-
-	/* Update the position where ring buffer has been read from */
 	rbi->ring_buffer->read_index = rbi->priv_read_index;
 
-	/* If more data is available then no need to signal */
-	if (hv_get_bytes_to_read(rbi))
-		return;
-
 	/*
-	 * If the reading of the pend_sz were to be reordered and read
-	 * before we commit the new read index.
-	 * Then we could have if the host were to set the pending_sz
-	 * after we have already sampled pending_sz.
+	 * Issue a full memory barrier before making the signaling decision.
+	 * Here is the reason for having this barrier:
+	 * If the reading of the pend_sz (in this function)
+	 * were to be reordered and read before we commit the new read
+	 * index (in the calling function)  we could
+	 * have a problem. If the host were to set the pending_sz after we
+	 * have sampled pending_sz and go to sleep before we commit the
+	 * read index, we could miss sending the interrupt. Issue a full
+	 * memory barrier to address this.
 	 */
-	virt_wmb();
+	virt_mb();
 
 	if (rbi->ring_buffer->feature_bits.feat_pending_send_sz) {
 		u32 pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
 
 		/*
-		 * If there was space before we began iteration, then
-		 * host was not blocked. Also handles the case where
-		 * pending_sz is zero because host has nothing pending.
+		 * If there was space before we began iteration,
+		 * then host was not blocked. Also handles case where
+		 * pending_sz is zero then host has nothing pending
+		 * and does not need to be signaled.
 		 */
 		if (orig_write_sz > pending_sz)
 			return;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 822c7a3a4efc..dd3e59116ace 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -126,7 +126,7 @@  struct hv_ring_buffer_info {
 	u32 ring_datasize;		/* < ring_size */
 	u32 ring_data_startoffset;
 	u32 priv_write_index;
-	u32 priv_read_index;		/* read cursor */
+	u32 priv_read_index;
 };
 
 /*