diff options
author | Vitaly Kuznetsov <vkuznets@redhat.com> | 2015-08-01 16:08:09 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-08-04 22:28:38 -0700 |
commit | b4370df2b1f5158de028e167974263c5757b34a6 (patch) | |
tree | 4a8733a8b1ae446e1b1a3df70f7c180f8bc15ecf /drivers | |
parent | d7646eaa7678fe5adc42247b4bdfbe9d9db8c253 (diff) |
Drivers: hv: vmbus: add special crash handler
Full kernel hang is observed when kdump kernel starts after a crash. This
hang happens in vmbus_negotiate_version() function on
wait_for_completion() as Hyper-V host (Win2012R2 in my testing) never
responds to CHANNELMSG_INITIATE_CONTACT as it thinks the connection is
already established. We need to perform some mandatory minimalistic
cleanup before we start new kernel.
Reported-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hv/vmbus_drv.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 31748a21d8f9..1ed9b32853a1 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1071,6 +1071,18 @@ static void hv_kexec_handler(void) hv_cleanup(); }; +static void hv_crash_handler(struct pt_regs *regs) +{ + vmbus_initiate_unload(); + /* + * In crash handler we can't schedule synic cleanup for all CPUs, + * doing the cleanup for current CPU only. This should be sufficient + * for kdump. + */ + hv_synic_cleanup(NULL); + hv_cleanup(); +}; + static int __init hv_acpi_init(void) { int ret, t; @@ -1104,6 +1116,7 @@ static int __init hv_acpi_init(void) goto cleanup; hv_setup_kexec_handler(hv_kexec_handler); + hv_setup_crash_handler(hv_crash_handler); return 0; @@ -1118,6 +1131,7 @@ static void __exit vmbus_exit(void) int cpu; hv_remove_kexec_handler(); + hv_remove_crash_handler(); vmbus_connection.conn_state = DISCONNECTED; hv_synic_clockevents_cleanup(); vmbus_disconnect(); |