[SRU,Yakkety,1/1] Drivers: hv: util: move waiting for release to hv_utils_transport itself

Message ID 0f464ea85db1f8d468000011f3877ad33b27cf88.1492111731.git.joseph.salisbury@canonical.com
State New
Headers show

Commit Message

Joseph Salisbury April 13, 2017, 9:09 p.m.
From: Vitaly Kuznetsov <vkuznets@redhat.com>

BugLink: http://bugs.launchpad.net/bugs/1682561

Waiting for release_event in all three drivers introduced issues on release
as on_reset() hook is not always called. E.g. if the device was never
opened we will never get the completion.

Move the waiting code to hvutil_transport_destroy() and make sure it is
only called when the device is open. hvt->lock serialization should
guarantee the absence of races.

Fixes: 5a66fecbf6aa ("Drivers: hv: util: kvp: Fix a rescind processing issue")
Fixes: 20951c7535b5 ("Drivers: hv: util: Fcopy: Fix a rescind processing issue")
Fixes: d77044d142e9 ("Drivers: hv: util: Backup: Fix a rescind processing issue")

Reported-by: Dexuan Cui <decui@microsoft.com>
Tested-by: Dexuan Cui <decui@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>
(cherry picked from commit e9c18ae6eb2b312f16c63e34b43ea23926daa398)
Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com>
---
 drivers/hv/hv_utils_transport.c | 12 ++++++++----
 drivers/hv/hv_utils_transport.h |  1 +
 2 files changed, 9 insertions(+), 4 deletions(-)

Comments

Stefan Bader April 18, 2017, 9:05 a.m. | #1
Looks reasonable, though the breakage was (at least for Xenial) introduced by
patches which came via upstream stable. So I would personally maybe wait a
little to make efforts of getting this into the current cycle.

-Stefan
Joshua R. Poulson April 18, 2017, 12:48 p.m. | #2
We are pursuing getting the fixes into stable, but we missed a cycle.
We're trying not to miss the cycle for the kernel in proposed as well.

On Tue, Apr 18, 2017 at 2:05 AM, Stefan Bader
<stefan.bader@canonical.com> wrote:
> Looks reasonable, though the breakage was (at least for Xenial) introduced by
> patches which came via upstream stable. So I would personally maybe wait a
> little to make efforts of getting this into the current cycle.
>
> -Stefan
>
>
> --
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
>
Stefan Bader April 20, 2017, 8 a.m. | #3
Applied to Yakkety when re-spinning

Patch

diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c
index c235a95..4402a71 100644
--- a/drivers/hv/hv_utils_transport.c
+++ b/drivers/hv/hv_utils_transport.c
@@ -182,10 +182,11 @@  static int hvt_op_release(struct inode *inode, struct file *file)
 	 * connects back.
 	 */
 	hvt_reset(hvt);
-	mutex_unlock(&hvt->lock);
 
 	if (mode_old == HVUTIL_TRANSPORT_DESTROY)
-		hvt_transport_free(hvt);
+		complete(&hvt->release);
+
+	mutex_unlock(&hvt->lock);
 
 	return 0;
 }
@@ -304,6 +305,7 @@  struct hvutil_transport *hvutil_transport_init(const char *name,
 
 	init_waitqueue_head(&hvt->outmsg_q);
 	mutex_init(&hvt->lock);
+	init_completion(&hvt->release);
 
 	spin_lock(&hvt_list_lock);
 	list_add(&hvt->list, &hvt_list);
@@ -351,6 +353,8 @@  void hvutil_transport_destroy(struct hvutil_transport *hvt)
 	if (hvt->cn_id.idx > 0 && hvt->cn_id.val > 0)
 		cn_del_callback(&hvt->cn_id);
 
-	if (mode_old != HVUTIL_TRANSPORT_CHARDEV)
-		hvt_transport_free(hvt);
+	if (mode_old == HVUTIL_TRANSPORT_CHARDEV)
+		wait_for_completion(&hvt->release);
+
+	hvt_transport_free(hvt);
 }
diff --git a/drivers/hv/hv_utils_transport.h b/drivers/hv/hv_utils_transport.h
index d98f522..79afb62 100644
--- a/drivers/hv/hv_utils_transport.h
+++ b/drivers/hv/hv_utils_transport.h
@@ -41,6 +41,7 @@  struct hvutil_transport {
 	int outmsg_len;                     /* its length */
 	wait_queue_head_t outmsg_q;         /* poll/read wait queue */
 	struct mutex lock;                  /* protects struct members */
+	struct completion release;          /* synchronize with fd release */
 };
 
 struct hvutil_transport *hvutil_transport_init(const char *name,