Drivers: hv: vmbus: On the read path cleanup the logic to interrupt the host
authorK. Y. Srinivasan <kys@microsoft.com>
Sun, 6 Nov 2016 21:14:18 +0000 (13:14 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Nov 2016 09:01:18 +0000 (10:01 +0100)
Signal the host when we determine the host is to be signaled -
on th read path. The currrent code determines the need to signal in the
ringbuffer code and actually issues the signal elsewhere. This can result
in the host viewing this interrupt as spurious since the host may also
poll the channel. Make the necessary adjustments.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hv/channel.c
drivers/hv/hyperv_vmbus.h
drivers/hv/ring_buffer.c
include/linux/hyperv.h

index 8a8148f7b8427853d29544dd27ba428d76e0c6aa..5fb4c6d9209b753a12dcddb4c441ff00c3e8746a 100644 (file)
@@ -879,16 +879,9 @@ __vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
                   u32 bufferlen, u32 *buffer_actual_len, u64 *requestid,
                   bool raw)
 {
-       int ret;
-       bool signal = false;
-
-       ret = hv_ringbuffer_read(&channel->inbound, buffer, bufferlen,
-                                buffer_actual_len, requestid, &signal, raw);
+       return hv_ringbuffer_read(channel, buffer, bufferlen,
+                                 buffer_actual_len, requestid, raw);
 
-       if (signal)
-               vmbus_setevent(channel);
-
-       return ret;
 }
 
 int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
index 2d42ebe2af6c0500d95b1eea80a1aa253dbac441..0675b395ce5c47f284dec3c86b02133086e86cf9 100644 (file)
@@ -532,9 +532,9 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
                    u32 kv_count, bool lock,
                    bool kick_q);
 
-int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
+int hv_ringbuffer_read(struct vmbus_channel *channel,
                       void *buffer, u32 buflen, u32 *buffer_actual_len,
-                      u64 *requestid, bool *signal, bool raw);
+                      u64 *requestid, bool raw);
 
 void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
                            struct hv_ring_buffer_debug_info *debug_info);
index 4af71306d0ffa391e436f4295b3b70db13b02d47..cd49cb17eb7fb385ddbf507ef14b2ea2be090159 100644 (file)
@@ -353,9 +353,9 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
        return 0;
 }
 
-int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
+int hv_ringbuffer_read(struct vmbus_channel *channel,
                       void *buffer, u32 buflen, u32 *buffer_actual_len,
-                      u64 *requestid, bool *signal, bool raw)
+                      u64 *requestid, bool raw)
 {
        u32 bytes_avail_toread;
        u32 next_read_location = 0;
@@ -364,6 +364,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
        u32 offset;
        u32 packetlen;
        int ret = 0;
+       struct hv_ring_buffer_info *inring_info = &channel->inbound;
 
        if (buflen <= 0)
                return -EINVAL;
@@ -421,7 +422,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info,
        /* Update the read index */
        hv_set_next_read_location(inring_info, next_read_location);
 
-       *signal = hv_need_to_signal_on_read(inring_info);
+       hv_signal_on_read(channel);
 
        return ret;
 }
index 8cf78ed96747d3a9a4ceea146f434e222b9b9652..fdb0a87323f351aab6b9ddd6ba3eaa7f4cedc697 100644 (file)
@@ -1487,10 +1487,11 @@ hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
  *    there is room for the producer to send the pending packet.
  */
 
-static inline  bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi)
+static inline  void hv_signal_on_read(struct vmbus_channel *channel)
 {
        u32 cur_write_sz;
        u32 pending_sz;
+       struct hv_ring_buffer_info *rbi = &channel->inbound;
 
        /*
         * Issue a full memory barrier before making the signaling decision.
@@ -1508,14 +1509,14 @@ static inline  bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi)
        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)
-               return false;
+               return;
 
        cur_write_sz = hv_get_bytes_to_write(rbi);
 
        if (cur_write_sz >= pending_sz)
-               return true;
+               vmbus_setevent(channel);
 
-       return false;
+       return;
 }
 
 /*
@@ -1587,8 +1588,7 @@ static inline void commit_rd_index(struct vmbus_channel *channel)
        virt_rmb();
        ring_info->ring_buffer->read_index = ring_info->priv_read_index;
 
-       if (hv_need_to_signal_on_read(ring_info))
-               vmbus_set_event(channel);
+       hv_signal_on_read(channel);
 }