summaryrefslogtreecommitdiffstats
path: root/drivers/hv/channel.c
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2017-11-14 08:53:33 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-11-28 10:56:26 -0500
commit7fa32e5ec28b1609abc0b797b58267f725fc3964 (patch)
tree71055aa21cc5ab790e6386adac62e9a60af93348 /drivers/hv/channel.c
parentfb2c445277e7b0b4ffe10de8114bad4eccaca948 (diff)
Drivers: hv: vmbus: Fix a rescind issue
The current rescind processing code will not correctly handle the case where the host immediately rescinds a channel that has been offerred. In this case, we could be blocked in the open call and since the channel is rescinded, the host will not respond and we could be blocked forever in the vmbus open call.i Fix this problem. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/channel.c')
-rw-r--r--drivers/hv/channel.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 19f0cf37e0ed..ba0a092ae085 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -659,22 +659,28 @@ void vmbus_close(struct vmbus_channel *channel)
659 */ 659 */
660 return; 660 return;
661 } 661 }
662 mutex_lock(&vmbus_connection.channel_mutex);
663 /* 662 /*
664 * Close all the sub-channels first and then close the 663 * Close all the sub-channels first and then close the
665 * primary channel. 664 * primary channel.
666 */ 665 */
667 list_for_each_safe(cur, tmp, &channel->sc_list) { 666 list_for_each_safe(cur, tmp, &channel->sc_list) {
668 cur_channel = list_entry(cur, struct vmbus_channel, sc_list); 667 cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
669 vmbus_close_internal(cur_channel);
670 if (cur_channel->rescind) { 668 if (cur_channel->rescind) {
669 wait_for_completion(&cur_channel->rescind_event);
670 mutex_lock(&vmbus_connection.channel_mutex);
671 vmbus_close_internal(cur_channel);
671 hv_process_channel_removal( 672 hv_process_channel_removal(
672 cur_channel->offermsg.child_relid); 673 cur_channel->offermsg.child_relid);
674 } else {
675 mutex_lock(&vmbus_connection.channel_mutex);
676 vmbus_close_internal(cur_channel);
673 } 677 }
678 mutex_unlock(&vmbus_connection.channel_mutex);
674 } 679 }
675 /* 680 /*
676 * Now close the primary. 681 * Now close the primary.
677 */ 682 */
683 mutex_lock(&vmbus_connection.channel_mutex);
678 vmbus_close_internal(channel); 684 vmbus_close_internal(channel);
679 mutex_unlock(&vmbus_connection.channel_mutex); 685 mutex_unlock(&vmbus_connection.channel_mutex);
680} 686}