提交 221f6df0 编写于 作者: D Dexuan Cui 提交者: Sasha Levin

hv_balloon: Reorganize the probe function

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: NDexuan Cui <decui@microsoft.com>
Reviewed-by: NMichael Kelley <mikelley@microsoft.com>
Signed-off-by: NSasha Levin <sashal@kernel.org>
上级 1fed17df
...@@ -1564,50 +1564,18 @@ static void balloon_onchannelcallback(void *context) ...@@ -1564,50 +1564,18 @@ static void balloon_onchannelcallback(void *context)
} }
static int balloon_probe(struct hv_device *dev, static int balloon_connect_vsp(struct hv_device *dev)
const struct hv_vmbus_device_id *dev_id)
{ {
int ret;
unsigned long t;
struct dm_version_request version_req; struct dm_version_request version_req;
struct dm_capabilities cap_msg; struct dm_capabilities cap_msg;
unsigned long t;
#ifdef CONFIG_MEMORY_HOTPLUG int ret;
do_hot_add = hot_add;
#else
do_hot_add = false;
#endif
ret = vmbus_open(dev->channel, dm_ring_size, dm_ring_size, NULL, 0, ret = vmbus_open(dev->channel, dm_ring_size, dm_ring_size, NULL, 0,
balloon_onchannelcallback, dev); balloon_onchannelcallback, dev);
if (ret) if (ret)
return 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 * Initiate the hand shake with the host and negotiate
* a version that the host can support. We start with the * a version that the host can support. We start with the
...@@ -1623,16 +1591,15 @@ static int balloon_probe(struct hv_device *dev, ...@@ -1623,16 +1591,15 @@ static int balloon_probe(struct hv_device *dev,
dm_device.version = version_req.version.version; dm_device.version = version_req.version.version;
ret = vmbus_sendpacket(dev->channel, &version_req, ret = vmbus_sendpacket(dev->channel, &version_req,
sizeof(struct dm_version_request), sizeof(struct dm_version_request),
(unsigned long)NULL, (unsigned long)NULL, VM_PKT_DATA_INBAND, 0);
VM_PKT_DATA_INBAND, 0);
if (ret) if (ret)
goto probe_error2; goto out;
t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ); t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ);
if (t == 0) { if (t == 0) {
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
goto probe_error2; goto out;
} }
/* /*
...@@ -1640,8 +1607,8 @@ static int balloon_probe(struct hv_device *dev, ...@@ -1640,8 +1607,8 @@ static int balloon_probe(struct hv_device *dev,
* fail the probe function. * fail the probe function.
*/ */
if (dm_device.state == DM_INIT_ERROR) { if (dm_device.state == DM_INIT_ERROR) {
ret = -ETIMEDOUT; ret = -EPROTO;
goto probe_error2; goto out;
} }
pr_info("Using Dynamic Memory protocol version %u.%u\n", pr_info("Using Dynamic Memory protocol version %u.%u\n",
...@@ -1674,16 +1641,15 @@ static int balloon_probe(struct hv_device *dev, ...@@ -1674,16 +1641,15 @@ static int balloon_probe(struct hv_device *dev,
cap_msg.max_page_number = -1; cap_msg.max_page_number = -1;
ret = vmbus_sendpacket(dev->channel, &cap_msg, ret = vmbus_sendpacket(dev->channel, &cap_msg,
sizeof(struct dm_capabilities), sizeof(struct dm_capabilities),
(unsigned long)NULL, (unsigned long)NULL, VM_PKT_DATA_INBAND, 0);
VM_PKT_DATA_INBAND, 0);
if (ret) if (ret)
goto probe_error2; goto out;
t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ); t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ);
if (t == 0) { if (t == 0) {
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
goto probe_error2; goto out;
} }
/* /*
...@@ -1691,23 +1657,65 @@ static int balloon_probe(struct hv_device *dev, ...@@ -1691,23 +1657,65 @@ static int balloon_probe(struct hv_device *dev,
* fail the probe function. * fail the probe function.
*/ */
if (dm_device.state == DM_INIT_ERROR) { if (dm_device.state == DM_INIT_ERROR) {
ret = -ETIMEDOUT; ret = -EPROTO;
goto probe_error2; 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; 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; return 0;
probe_error2: probe_error:
vmbus_close(dev->channel);
#ifdef CONFIG_MEMORY_HOTPLUG #ifdef CONFIG_MEMORY_HOTPLUG
unregister_memory_notifier(&hv_memory_nb);
restore_online_page_callback(&hv_online_page); restore_online_page_callback(&hv_online_page);
#endif #endif
kthread_stop(dm_device.thread);
probe_error1:
vmbus_close(dev->channel);
return ret; return ret;
} }
...@@ -1724,11 +1732,11 @@ static int balloon_remove(struct hv_device *dev) ...@@ -1724,11 +1732,11 @@ static int balloon_remove(struct hv_device *dev)
cancel_work_sync(&dm->balloon_wrk.wrk); cancel_work_sync(&dm->balloon_wrk.wrk);
cancel_work_sync(&dm->ha_wrk.wrk); cancel_work_sync(&dm->ha_wrk.wrk);
vmbus_close(dev->channel);
kthread_stop(dm->thread); kthread_stop(dm->thread);
vmbus_close(dev->channel);
#ifdef CONFIG_MEMORY_HOTPLUG #ifdef CONFIG_MEMORY_HOTPLUG
restore_online_page_callback(&hv_online_page);
unregister_memory_notifier(&hv_memory_nb); unregister_memory_notifier(&hv_memory_nb);
restore_online_page_callback(&hv_online_page);
#endif #endif
spin_lock_irqsave(&dm_device.ha_lock, flags); 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(has, tmp, &dm->ha_region_list, list) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册