summaryrefslogtreecommitdiffstats
path: root/drivers/hv/channel.c
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2015-12-14 19:01:54 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-12-14 22:15:05 -0500
commit8599846d73997cdbccf63f23394d871cfad1e5e6 (patch)
tree71b9d87febd70d4f439c29ac0b88a3a749f1c4f4 /drivers/hv/channel.c
parent40f26f3168bf7a4da490db308dc0bd9f9923f41f (diff)
Drivers: hv: vmbus: Fix a Host signaling bug
Currently we have two policies for deciding when to signal the host: One based on the ring buffer state and the other based on what the VMBUS client driver wants to do. Consider the case when the client wants to explicitly control when to signal the host. In this case, if the client were to defer signaling, we will not be able to signal the host subsequently when the client does want to signal since the ring buffer state will prevent the signaling. Implement logic to have only one signaling policy in force for a given channel. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com> Tested-by: Haiyang Zhang <haiyangz@microsoft.com> Cc: <stable@vger.kernel.org> # v4.2+ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/channel.c')
-rw-r--r--drivers/hv/channel.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 77d2579d6124..2889d97c03b1 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -653,10 +653,19 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
653 * on the ring. We will not signal if more data is 653 * on the ring. We will not signal if more data is
654 * to be placed. 654 * to be placed.
655 * 655 *
656 * Based on the channel signal state, we will decide
657 * which signaling policy will be applied.
658 *
656 * If we cannot write to the ring-buffer; signal the host 659 * If we cannot write to the ring-buffer; signal the host
657 * even if we may not have written anything. This is a rare 660 * even if we may not have written anything. This is a rare
658 * enough condition that it should not matter. 661 * enough condition that it should not matter.
659 */ 662 */
663
664 if (channel->signal_policy)
665 signal = true;
666 else
667 kick_q = true;
668
660 if (((ret == 0) && kick_q && signal) || (ret)) 669 if (((ret == 0) && kick_q && signal) || (ret))
661 vmbus_setevent(channel); 670 vmbus_setevent(channel);
662 671
@@ -756,10 +765,19 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
756 * on the ring. We will not signal if more data is 765 * on the ring. We will not signal if more data is
757 * to be placed. 766 * to be placed.
758 * 767 *
768 * Based on the channel signal state, we will decide
769 * which signaling policy will be applied.
770 *
759 * If we cannot write to the ring-buffer; signal the host 771 * If we cannot write to the ring-buffer; signal the host
760 * even if we may not have written anything. This is a rare 772 * even if we may not have written anything. This is a rare
761 * enough condition that it should not matter. 773 * enough condition that it should not matter.
762 */ 774 */
775
776 if (channel->signal_policy)
777 signal = true;
778 else
779 kick_q = true;
780
763 if (((ret == 0) && kick_q && signal) || (ret)) 781 if (((ret == 0) && kick_q && signal) || (ret))
764 vmbus_setevent(channel); 782 vmbus_setevent(channel);
765 783