Drivers: hv: vmbus: Fix a siganlling host signalling issue
authorK. Y. Srinivasan <kys@microsoft.com>
Wed, 18 Mar 2015 19:29:30 +0000 (12:29 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 25 Mar 2015 10:53:55 +0000 (11:53 +0100)
Handle the case when the write to the ringbuffer fails. In this case,
unconditionally signal the host. Since we may have deferred signalling
the host based on the kick_q parameter, signalling the host
unconditionally in this case deals with the issue.

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

index fddd3b5..54da66d 100644 (file)
@@ -611,7 +611,19 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
 
        ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
 
-       if ((ret == 0) && kick_q && signal)
+       /*
+        * Signalling the host is conditional on many factors:
+        * 1. The ring state changed from being empty to non-empty.
+        *    This is tracked by the variable "signal".
+        * 2. The variable kick_q tracks if more data will be placed
+        *    on the ring. We will not signal if more data is
+        *    to be placed.
+        *
+        * If we cannot write to the ring-buffer; signal the host
+        * even if we may not have written anything. This is a rare
+        * enough condition that it should not matter.
+        */
+       if (((ret == 0) && kick_q && signal) || (ret))
                vmbus_setevent(channel);
 
        return ret;
@@ -702,7 +714,19 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
 
        ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal);
 
-       if ((ret == 0) && kick_q && signal)
+       /*
+        * Signalling the host is conditional on many factors:
+        * 1. The ring state changed from being empty to non-empty.
+        *    This is tracked by the variable "signal".
+        * 2. The variable kick_q tracks if more data will be placed
+        *    on the ring. We will not signal if more data is
+        *    to be placed.
+        *
+        * If we cannot write to the ring-buffer; signal the host
+        * even if we may not have written anything. This is a rare
+        * enough condition that it should not matter.
+        */
+       if (((ret == 0) && kick_q && signal) || (ret))
                vmbus_setevent(channel);
 
        return ret;