diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2015-04-23 00:31:32 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-05-24 15:18:24 -0400 |
commit | 2db84eff127e3f4b3635edc589cd6a56db8755a3 (patch) | |
tree | 2890e6494ebeb52bfdbaa182a9e58d3f2734d57e /drivers/hv | |
parent | db9ba2088f6507fee370904f02db1eb9b49bd088 (diff) |
Drivers: hv: vmbus: Implement the protocol for tearing down vmbus state
Implement the protocol for tearing down the monitor state established with
the host.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r-- | drivers/hv/channel_mgmt.c | 25 | ||||
-rw-r--r-- | drivers/hv/connection.c | 5 | ||||
-rw-r--r-- | drivers/hv/hyperv_vmbus.h | 2 | ||||
-rw-r--r-- | drivers/hv/vmbus_drv.c | 2 |
4 files changed, 33 insertions, 1 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 865a3afa1d86..4b9d89ab44d3 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c | |||
@@ -422,6 +422,30 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui | |||
422 | } | 422 | } |
423 | 423 | ||
424 | /* | 424 | /* |
425 | * vmbus_unload_response - Handler for the unload response. | ||
426 | */ | ||
427 | static void vmbus_unload_response(struct vmbus_channel_message_header *hdr) | ||
428 | { | ||
429 | /* | ||
430 | * This is a global event; just wakeup the waiting thread. | ||
431 | * Once we successfully unload, we can cleanup the monitor state. | ||
432 | */ | ||
433 | complete(&vmbus_connection.unload_event); | ||
434 | } | ||
435 | |||
436 | void vmbus_initiate_unload(void) | ||
437 | { | ||
438 | struct vmbus_channel_message_header hdr; | ||
439 | |||
440 | init_completion(&vmbus_connection.unload_event); | ||
441 | memset(&hdr, 0, sizeof(struct vmbus_channel_message_header)); | ||
442 | hdr.msgtype = CHANNELMSG_UNLOAD; | ||
443 | vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header)); | ||
444 | |||
445 | wait_for_completion(&vmbus_connection.unload_event); | ||
446 | } | ||
447 | |||
448 | /* | ||
425 | * vmbus_onoffer - Handler for channel offers from vmbus in parent partition. | 449 | * vmbus_onoffer - Handler for channel offers from vmbus in parent partition. |
426 | * | 450 | * |
427 | */ | 451 | */ |
@@ -717,6 +741,7 @@ struct vmbus_channel_message_table_entry | |||
717 | {CHANNELMSG_INITIATE_CONTACT, 0, NULL}, | 741 | {CHANNELMSG_INITIATE_CONTACT, 0, NULL}, |
718 | {CHANNELMSG_VERSION_RESPONSE, 1, vmbus_onversion_response}, | 742 | {CHANNELMSG_VERSION_RESPONSE, 1, vmbus_onversion_response}, |
719 | {CHANNELMSG_UNLOAD, 0, NULL}, | 743 | {CHANNELMSG_UNLOAD, 0, NULL}, |
744 | {CHANNELMSG_UNLOAD_RESPONSE, 1, vmbus_unload_response}, | ||
720 | }; | 745 | }; |
721 | 746 | ||
722 | /* | 747 | /* |
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index b27220a425f4..acd50e9d666a 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c | |||
@@ -227,6 +227,11 @@ cleanup: | |||
227 | 227 | ||
228 | void vmbus_disconnect(void) | 228 | void vmbus_disconnect(void) |
229 | { | 229 | { |
230 | /* | ||
231 | * First send the unload request to the host. | ||
232 | */ | ||
233 | vmbus_initiate_unload(); | ||
234 | |||
230 | if (vmbus_connection.work_queue) { | 235 | if (vmbus_connection.work_queue) { |
231 | drain_workqueue(vmbus_connection.work_queue); | 236 | drain_workqueue(vmbus_connection.work_queue); |
232 | destroy_workqueue(vmbus_connection.work_queue); | 237 | destroy_workqueue(vmbus_connection.work_queue); |
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 138d6634c79d..cddc0c9f6bf9 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h | |||
@@ -647,6 +647,7 @@ struct vmbus_connection { | |||
647 | 647 | ||
648 | atomic_t next_gpadl_handle; | 648 | atomic_t next_gpadl_handle; |
649 | 649 | ||
650 | struct completion unload_event; | ||
650 | /* | 651 | /* |
651 | * Represents channel interrupts. Each bit position represents a | 652 | * Represents channel interrupts. Each bit position represents a |
652 | * channel. When a channel sends an interrupt via VMBUS, it finds its | 653 | * channel. When a channel sends an interrupt via VMBUS, it finds its |
@@ -741,6 +742,7 @@ void hv_vss_onchannelcallback(void *); | |||
741 | int hv_fcopy_init(struct hv_util_service *); | 742 | int hv_fcopy_init(struct hv_util_service *); |
742 | void hv_fcopy_deinit(void); | 743 | void hv_fcopy_deinit(void); |
743 | void hv_fcopy_onchannelcallback(void *); | 744 | void hv_fcopy_onchannelcallback(void *); |
745 | void vmbus_initiate_unload(void); | ||
744 | 746 | ||
745 | static inline void hv_poll_channel(struct vmbus_channel *channel, | 747 | static inline void hv_poll_channel(struct vmbus_channel *channel, |
746 | void (*cb)(void *)) | 748 | void (*cb)(void *)) |
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 7870a906365e..2b56260b0eb4 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c | |||
@@ -1106,6 +1106,7 @@ static void __exit vmbus_exit(void) | |||
1106 | 1106 | ||
1107 | vmbus_connection.conn_state = DISCONNECTED; | 1107 | vmbus_connection.conn_state = DISCONNECTED; |
1108 | hv_synic_clockevents_cleanup(); | 1108 | hv_synic_clockevents_cleanup(); |
1109 | vmbus_disconnect(); | ||
1109 | hv_remove_vmbus_irq(); | 1110 | hv_remove_vmbus_irq(); |
1110 | vmbus_free_channels(); | 1111 | vmbus_free_channels(); |
1111 | if (ms_hyperv.features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { | 1112 | if (ms_hyperv.features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { |
@@ -1118,7 +1119,6 @@ static void __exit vmbus_exit(void) | |||
1118 | smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1); | 1119 | smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1); |
1119 | acpi_bus_unregister_driver(&vmbus_acpi_driver); | 1120 | acpi_bus_unregister_driver(&vmbus_acpi_driver); |
1120 | hv_cpu_hotplug_quirk(false); | 1121 | hv_cpu_hotplug_quirk(false); |
1121 | vmbus_disconnect(); | ||
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | 1124 | ||