hv_balloon: Reorganize the probe function
authorDexuan Cui <decui@microsoft.com>
Fri, 14 Jun 2019 18:42:30 +0000 (18:42 +0000)
committerSasha Levin <sashal@kernel.org>
Tue, 30 Jul 2019 22:35:56 +0000 (18:35 -0400)
Move the code that negotiates with the host to a new function
balloon_connect_vsp() and improve the error handling.

This makes the code more readable and paves the way for the
support of hibernation in future.

Makes no real logic change here.

Signed-off-by: Dexuan Cui <decui@microsoft.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/hv/hv_balloon.c

index 4b06f07..34bd735 100644 (file)
@@ -1564,50 +1564,18 @@ static void balloon_onchannelcallback(void *context)
 
 }
 
-static int balloon_probe(struct hv_device *dev,
-                       const struct hv_vmbus_device_id *dev_id)
+static int balloon_connect_vsp(struct hv_device *dev)
 {
-       int ret;
-       unsigned long t;
        struct dm_version_request version_req;
        struct dm_capabilities cap_msg;
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-       do_hot_add = hot_add;
-#else
-       do_hot_add = false;
-#endif
+       unsigned long t;
+       int ret;
 
        ret = vmbus_open(dev->channel, dm_ring_size, dm_ring_size, NULL, 0,
-                       balloon_onchannelcallback, dev);
-
+                        balloon_onchannelcallback, dev);
        if (ret)
                return ret;
 
-       dm_device.dev = dev;
-       dm_device.state = DM_INITIALIZING;
-       dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN8;
-       init_completion(&dm_device.host_event);
-       init_completion(&dm_device.config_event);
-       INIT_LIST_HEAD(&dm_device.ha_region_list);
-       spin_lock_init(&dm_device.ha_lock);
-       INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up);
-       INIT_WORK(&dm_device.ha_wrk.wrk, hot_add_req);
-       dm_device.host_specified_ha_region = false;
-
-       dm_device.thread =
-                kthread_run(dm_thread_func, &dm_device, "hv_balloon");
-       if (IS_ERR(dm_device.thread)) {
-               ret = PTR_ERR(dm_device.thread);
-               goto probe_error1;
-       }
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-       set_online_page_callback(&hv_online_page);
-       register_memory_notifier(&hv_memory_nb);
-#endif
-
-       hv_set_drvdata(dev, &dm_device);
        /*
         * Initiate the hand shake with the host and negotiate
         * a version that the host can support. We start with the
@@ -1623,16 +1591,15 @@ static int balloon_probe(struct hv_device *dev,
        dm_device.version = version_req.version.version;
 
        ret = vmbus_sendpacket(dev->channel, &version_req,
-                               sizeof(struct dm_version_request),
-                               (unsigned long)NULL,
-                               VM_PKT_DATA_INBAND, 0);
+                              sizeof(struct dm_version_request),
+                              (unsigned long)NULL, VM_PKT_DATA_INBAND, 0);
        if (ret)
-               goto probe_error2;
+               goto out;
 
        t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ);
        if (t == 0) {
                ret = -ETIMEDOUT;
-               goto probe_error2;
+               goto out;
        }
 
        /*
@@ -1640,8 +1607,8 @@ static int balloon_probe(struct hv_device *dev,
         * fail the probe function.
         */
        if (dm_device.state == DM_INIT_ERROR) {
-               ret = -ETIMEDOUT;
-               goto probe_error2;
+               ret = -EPROTO;
+               goto out;
        }
 
        pr_info("Using Dynamic Memory protocol version %u.%u\n",
@@ -1674,16 +1641,15 @@ static int balloon_probe(struct hv_device *dev,
        cap_msg.max_page_number = -1;
 
        ret = vmbus_sendpacket(dev->channel, &cap_msg,
-                               sizeof(struct dm_capabilities),
-                               (unsigned long)NULL,
-                               VM_PKT_DATA_INBAND, 0);
+                              sizeof(struct dm_capabilities),
+                              (unsigned long)NULL, VM_PKT_DATA_INBAND, 0);
        if (ret)
-               goto probe_error2;
+               goto out;
 
        t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ);
        if (t == 0) {
                ret = -ETIMEDOUT;
-               goto probe_error2;
+               goto out;
        }
 
        /*
@@ -1691,23 +1657,65 @@ static int balloon_probe(struct hv_device *dev,
         * fail the probe function.
         */
        if (dm_device.state == DM_INIT_ERROR) {
-               ret = -ETIMEDOUT;
-               goto probe_error2;
+               ret = -EPROTO;
+               goto out;
        }
 
+       return 0;
+out:
+       vmbus_close(dev->channel);
+       return ret;
+}
+
+static int balloon_probe(struct hv_device *dev,
+                        const struct hv_vmbus_device_id *dev_id)
+{
+       int ret;
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+       do_hot_add = hot_add;
+#else
+       do_hot_add = false;
+#endif
+       dm_device.dev = dev;
+       dm_device.state = DM_INITIALIZING;
+       dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN8;
+       init_completion(&dm_device.host_event);
+       init_completion(&dm_device.config_event);
+       INIT_LIST_HEAD(&dm_device.ha_region_list);
+       spin_lock_init(&dm_device.ha_lock);
+       INIT_WORK(&dm_device.balloon_wrk.wrk, balloon_up);
+       INIT_WORK(&dm_device.ha_wrk.wrk, hot_add_req);
+       dm_device.host_specified_ha_region = false;
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+       set_online_page_callback(&hv_online_page);
+       register_memory_notifier(&hv_memory_nb);
+#endif
+
+       hv_set_drvdata(dev, &dm_device);
+
+       ret = balloon_connect_vsp(dev);
+       if (ret != 0)
+               return ret;
+
        dm_device.state = DM_INITIALIZED;
-       last_post_time = jiffies;
+
+       dm_device.thread =
+                kthread_run(dm_thread_func, &dm_device, "hv_balloon");
+       if (IS_ERR(dm_device.thread)) {
+               ret = PTR_ERR(dm_device.thread);
+               goto probe_error;
+       }
 
        return 0;
 
-probe_error2:
+probe_error:
+       vmbus_close(dev->channel);
 #ifdef CONFIG_MEMORY_HOTPLUG
+       unregister_memory_notifier(&hv_memory_nb);
        restore_online_page_callback(&hv_online_page);
 #endif
-       kthread_stop(dm_device.thread);
-
-probe_error1:
-       vmbus_close(dev->channel);
        return ret;
 }
 
@@ -1724,11 +1732,11 @@ static int balloon_remove(struct hv_device *dev)
        cancel_work_sync(&dm->balloon_wrk.wrk);
        cancel_work_sync(&dm->ha_wrk.wrk);
 
-       vmbus_close(dev->channel);
        kthread_stop(dm->thread);
+       vmbus_close(dev->channel);
 #ifdef CONFIG_MEMORY_HOTPLUG
-       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) {