[azure:x][PATCH v3 2/4] Revert "UBUNTU: SAUCE: vmbus: simplify packet iterator"
Marcelo Henrique Cerri
marcelo.cerri at canonical.com
Wed Mar 7 15:38:46 UTC 2018
BugLink: http://bugs.launchpad.net/bugs/1748662
This reverts commit 6e76d0d699a8effd941fa7732e18edf4173a6db0.
Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri at canonical.com>
---
drivers/hv/ring_buffer.c | 42 ++++++++++++++++--------------------------
include/linux/hyperv.h | 2 +-
2 files changed, 17 insertions(+), 27 deletions(-)
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;
};
/*
--
2.7.4
More information about the kernel-team
mailing list