diff options
author | Stephen Hemminger <stephen@networkplumber.org> | 2017-06-25 12:30:28 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-21 17:55:07 +0200 |
commit | 77b446aa2ba607b6c25d730236b57592aa80166b (patch) | |
tree | 1045d7d72d400b7a2d7cd38b7795d8e6efd233aa | |
parent | 27ba39f28808d6e983ad028da15952f29918a6c4 (diff) |
vmbus: more host signalling avoidance
commit 03bad714a1619c0074eb44d6f217c505fe27030f upstream.
Don't signal host if it has disabled interrupts for that
ring buffer. Check the feature bit to see if host supports
pending send size flag.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/hv/ring_buffer.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index b0f79526b86a..741daa6e2fc7 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -396,7 +396,6 @@ void hv_pkt_iter_close(struct vmbus_channel *channel) { struct hv_ring_buffer_info *rbi = &channel->inbound; u32 orig_write_sz = hv_get_bytes_to_write(rbi); - u32 pending_sz; /* * Make sure all reads are done before we update the read index since @@ -419,15 +418,27 @@ void hv_pkt_iter_close(struct vmbus_channel *channel) */ virt_mb(); - pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz); - /* If the other end is not blocked on write don't bother. */ - if (pending_sz == 0) + /* If host has disabled notifications then skip */ + if (rbi->ring_buffer->interrupt_mask) return; - if (hv_get_bytes_to_write(rbi) < pending_sz) - return; + if (rbi->ring_buffer->feature_bits.feat_pending_send_sz) { + u32 pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz); - if (orig_write_sz < pending_sz) - vmbus_setevent(channel); + /* + * 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; + + /* If pending write will not fit, don't give false hope. */ + if (hv_get_bytes_to_write(rbi) < pending_sz) + return; + } + + vmbus_setevent(channel); } EXPORT_SYMBOL_GPL(hv_pkt_iter_close); |