| From 5a66fecbf6aa528e375cbebccb1061cc58d80c84 Mon Sep 17 00:00:00 2001 |
| From: "K. Y. Srinivasan" <kys@microsoft.com> |
| Date: Thu, 22 Dec 2016 16:54:01 -0800 |
| Subject: Drivers: hv: util: kvp: Fix a rescind processing issue |
| |
| From: K. Y. Srinivasan <kys@microsoft.com> |
| |
| commit 5a66fecbf6aa528e375cbebccb1061cc58d80c84 upstream. |
| |
| KVP may use a char device to support the communication between |
| the user level daemon and the driver. When the KVP channel is rescinded |
| we need to make sure that the char device is fully cleaned up before |
| we can process a new KVP offer from the host. Implement this logic. |
| |
| Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/hv/hv_kvp.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| --- a/drivers/hv/hv_kvp.c |
| +++ b/drivers/hv/hv_kvp.c |
| @@ -88,6 +88,7 @@ static DECLARE_WORK(kvp_sendkey_work, kv |
| static const char kvp_devname[] = "vmbus/hv_kvp"; |
| static u8 *recv_buffer; |
| static struct hvutil_transport *hvt; |
| +static struct completion release_event; |
| /* |
| * Register the kernel component with the user-level daemon. |
| * As part of this registration, pass the LIC version number. |
| @@ -716,6 +717,7 @@ static void kvp_on_reset(void) |
| if (cancel_delayed_work_sync(&kvp_timeout_work)) |
| kvp_respond_to_host(NULL, HV_E_FAIL); |
| kvp_transaction.state = HVUTIL_DEVICE_INIT; |
| + complete(&release_event); |
| } |
| |
| int |
| @@ -724,6 +726,7 @@ hv_kvp_init(struct hv_util_service *srv) |
| recv_buffer = srv->recv_buffer; |
| kvp_transaction.recv_channel = srv->channel; |
| |
| + init_completion(&release_event); |
| /* |
| * When this driver loads, the user level daemon that |
| * processes the host requests may not yet be running. |
| @@ -747,4 +750,5 @@ void hv_kvp_deinit(void) |
| cancel_delayed_work_sync(&kvp_timeout_work); |
| cancel_work_sync(&kvp_sendkey_work); |
| hvutil_transport_destroy(hvt); |
| + wait_for_completion(&release_event); |
| } |