Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Jun 2016 05:16:22 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r302044 - stable/10/sys/dev/hyperv/vmbus
Message-ID:  <201606210516.u5L5GMxa089753@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Tue Jun 21 05:16:21 2016
New Revision: 302044
URL: https://svnweb.freebsd.org/changeset/base/302044

Log:
  MFC 298260
  
      hyperv/vmbus: Make device probe/attach synchronous w/ vmbus attach/SYSINIT
  
      Discussed with:     Jun Su <junsu microsoft com>, Dexuan Cui <decui microsoft com>
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC

Modified:
  stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
  stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Tue Jun 21 05:11:19 2016	(r302043)
+++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Tue Jun 21 05:16:21 2016	(r302044)
@@ -30,7 +30,10 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/mbuf.h>
+#include <sys/mutex.h>
 
 #include "hv_vmbus_priv.h"
 
@@ -95,6 +98,14 @@ typedef struct hv_work_item {
 	void*		context;
 } hv_work_item;
 
+static struct mtx	vmbus_chwait_lock;
+MTX_SYSINIT(vmbus_chwait_lk, &vmbus_chwait_lock, "vmbus primarych wait lock",
+    MTX_DEF);
+static uint32_t		vmbus_chancnt;
+static uint32_t		vmbus_devcnt;
+
+#define VMBUS_CHANCNT_DONE	0x80000000
+
 /**
  * Implementation of the work abstraction.
  */
@@ -279,6 +290,11 @@ vmbus_channel_process_offer(hv_vmbus_cha
 		mtx_unlock(&hv_vmbus_g_connection.channel_lock);
 		hv_vmbus_free_vmbus_channel(new_channel);
 	}
+
+	mtx_lock(&vmbus_chwait_lock);
+	vmbus_devcnt++;
+	mtx_unlock(&vmbus_chwait_lock);
+	wakeup(&vmbus_devcnt);
 }
 
 void
@@ -384,6 +400,11 @@ vmbus_channel_on_offer(hv_vmbus_channel_
 
 	memcpy(copied, hdr, sizeof(*copied));
 	hv_queue_work_item(vmbus_channel_on_offer_internal, copied);
+
+	mtx_lock(&vmbus_chwait_lock);
+	if ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0)
+		vmbus_chancnt++;
+	mtx_unlock(&vmbus_chwait_lock);
 }
 
 static void
@@ -475,6 +496,11 @@ vmbus_channel_on_offer_rescind_internal(
 static void
 vmbus_channel_on_offers_delivered(hv_vmbus_channel_msg_header* hdr)
 {
+
+	mtx_lock(&vmbus_chwait_lock);
+	vmbus_chancnt |= VMBUS_CHANCNT_DONE;
+	mtx_unlock(&vmbus_chwait_lock);
+	wakeup(&vmbus_chancnt);
 }
 
 /**
@@ -752,3 +778,18 @@ vmbus_select_outgoing_channel(struct hv_
 
 	return(outgoing_channel);
 }
+
+void
+vmbus_scan(void)
+{
+	uint32_t chancnt;
+
+	mtx_lock(&vmbus_chwait_lock);
+	while ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0)
+		mtx_sleep(&vmbus_chancnt, &vmbus_chwait_lock, 0, "waitch", 0);
+	chancnt = vmbus_chancnt & ~VMBUS_CHANCNT_DONE;
+
+	while (vmbus_devcnt != chancnt)
+		mtx_sleep(&vmbus_devcnt, &vmbus_chwait_lock, 0, "waitdev", 0);
+	mtx_unlock(&vmbus_chwait_lock);
+}

Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Tue Jun 21 05:11:19 2016	(r302043)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Tue Jun 21 05:16:21 2016	(r302044)
@@ -326,7 +326,6 @@ int
 hv_vmbus_child_device_register(struct hv_device *child_dev)
 {
 	device_t child;
-	int ret = 0;
 
 	if (bootverbose) {
 		char name[40];
@@ -338,10 +337,6 @@ hv_vmbus_child_device_register(struct hv
 	child_dev->device = child;
 	device_set_ivars(child, child_dev);
 
-	mtx_lock(&Giant);
-	ret = device_probe_and_attach(child);
-	mtx_unlock(&Giant);
-
 	return (0);
 }
 
@@ -562,6 +557,11 @@ vmbus_bus_init(void)
 		goto cleanup1;
 
 	hv_vmbus_request_channel_offers();
+
+	vmbus_scan();
+	bus_generic_attach(vmbus_devp);
+	device_printf(vmbus_devp, "device scan, probe and attach done\n");
+
 	return (ret);
 
 	cleanup1:

Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue Jun 21 05:11:19 2016	(r302043)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue Jun 21 05:16:21 2016	(r302044)
@@ -751,6 +751,9 @@ void			hv_vmbus_on_events(int cpu);
 void			hv_et_init(void);
 void			hv_et_intr(struct trapframe*);
 
+/* Wait for device creation */
+void			vmbus_scan(void);
+
 /*
  * The guest OS needs to register the guest ID with the hypervisor.
  * The guest ID is a 64 bit entity and the structure of this ID is



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606210516.u5L5GMxa089753>