If the balloon_probe() function fails, we do some cleanup and similar functions are called again when after this a balloon_remove() call is made. This fix makes sure that the cleanup is not called twice. Also made sure if dm_state is DM_INIT_ERROR, the clean up is already done properly. Signed-off-by: Shradha Gupta <shradhagupta@xxxxxxxxxxxxx> --- drivers/hv/hv_balloon.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index eee7402cfc02..7c62c1c3ffc7 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -1841,8 +1841,13 @@ static int balloon_probe(struct hv_device *dev, hv_set_drvdata(dev, &dm_device); ret = balloon_connect_vsp(dev); - if (ret != 0) + if (ret != 0) { +#ifdef CONFIG_MEMORY_HOTPLUG + unregister_memory_notifier(&hv_memory_nb); + restore_online_page_callback(&hv_online_page); +#endif return ret; + } enable_page_reporting(); dm_device.state = DM_INITIALIZED; @@ -1882,12 +1887,14 @@ static int balloon_remove(struct hv_device *dev) cancel_work_sync(&dm->ha_wrk.wrk); kthread_stop(dm->thread); - disable_page_reporting(); - vmbus_close(dev->channel); + if (dm_device.state != DM_INIT_ERROR) { + disable_page_reporting(); + vmbus_close(dev->channel); #ifdef CONFIG_MEMORY_HOTPLUG - unregister_memory_notifier(&hv_memory_nb); - restore_online_page_callback(&hv_online_page); + unregister_memory_notifier(&hv_memory_nb); + restore_online_page_callback(&hv_online_page); #endif + } spin_lock_irqsave(&dm_device.ha_lock, flags); list_for_each_entry_safe(has, tmp, &dm->ha_region_list, list) { list_for_each_entry_safe(gap, tmp_gap, &has->gap_list, list) { -- 2.17.1