Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Jul 2016 03:03:17 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r302606 - head/sys/dev/hyperv/vmbus
Message-ID:  <201607120303.u6C33H3q009886@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Tue Jul 12 03:03:17 2016
New Revision: 302606
URL: https://svnweb.freebsd.org/changeset/base/302606

Log:
  hyperv/vmbus: Reorganize vmbus scan process.
  
  MFC after:	1 week
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D6875

Modified:
  head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
  head/sys/dev/hyperv/vmbus/vmbus.c
  head/sys/dev/hyperv/vmbus/vmbus_var.h

Modified: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Tue Jul 12 02:57:13 2016	(r302605)
+++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Tue Jul 12 03:03:17 2016	(r302606)
@@ -80,14 +80,6 @@ vmbus_chanmsg_process[HV_CHANNEL_MESSAGE
 		vmbus_channel_on_version_response
 };
 
-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
-
 /**
  * @brief Allocate and initialize a vmbus channel object
  */
@@ -124,7 +116,6 @@ static void
 vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
 {
 	hv_vmbus_channel*	channel;
-	int			ret;
 	uint32_t                relid;
 
 	relid = new_channel->offer_msg.child_rel_id;
@@ -229,19 +220,8 @@ vmbus_channel_process_offer(hv_vmbus_cha
 	 * binding which eventually invokes the device driver's AddDevice()
 	 * method.
 	 */
-	ret = hv_vmbus_child_device_register(new_channel->device);
-	if (ret != 0) {
-		mtx_lock(&hv_vmbus_g_connection.channel_lock);
-		TAILQ_REMOVE(&hv_vmbus_g_connection.channel_anchor,
-		    new_channel, list_entry);
-		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);
+	hv_vmbus_child_device_register(new_channel->vmbus_sc,
+	    new_channel->device);
 }
 
 void
@@ -332,10 +312,8 @@ vmbus_channel_on_offer(struct vmbus_soft
 {
 	const hv_vmbus_channel_offer_channel *offer;
 
-	mtx_lock(&vmbus_chwait_lock);
-	if ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0)
-		vmbus_chancnt++;
-	mtx_unlock(&vmbus_chwait_lock);
+	/* New channel is offered by vmbus */
+	vmbus_scan_newchan(sc);
 
 	offer = (const hv_vmbus_channel_offer_channel *)msg->msg_data;
 	vmbus_channel_on_offer_internal(sc, offer);
@@ -428,14 +406,12 @@ vmbus_chan_detach_task(void *xchan, int 
  * @brief Invoked when all offers have been delivered.
  */
 static void
-vmbus_channel_on_offers_delivered(struct vmbus_softc *sc __unused,
+vmbus_channel_on_offers_delivered(struct vmbus_softc *sc,
     const struct vmbus_message *msg __unused)
 {
 
-	mtx_lock(&vmbus_chwait_lock);
-	vmbus_chancnt |= VMBUS_CHANCNT_DONE;
-	mtx_unlock(&vmbus_chwait_lock);
-	wakeup(&vmbus_chancnt);
+	/* No more new channels for the channel request. */
+	vmbus_scan_done(sc);
 }
 
 /**
@@ -668,21 +644,6 @@ 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);
-}
-
 struct hv_vmbus_channel **
 vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt)
 {

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue Jul 12 02:57:13 2016	(r302605)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue Jul 12 03:03:17 2016	(r302606)
@@ -411,7 +411,9 @@ struct hv_device*	hv_vmbus_child_device_
 				hv_guid			device_instance,
 				hv_vmbus_channel	*channel);
 
-int			hv_vmbus_child_device_register(
+struct vmbus_softc;
+
+void			hv_vmbus_child_device_register(struct vmbus_softc *,
 					struct hv_device *child_dev);
 int			hv_vmbus_child_device_unregister(
 					struct hv_device *child_dev);
@@ -419,13 +421,9 @@ int			hv_vmbus_child_device_unregister(
 /**
  * Connection interfaces
  */
-struct vmbus_softc;
 int			hv_vmbus_connect(struct vmbus_softc *);
 int			hv_vmbus_disconnect(void);
 int			hv_vmbus_post_message(void *buffer, size_t buf_size);
 int			hv_vmbus_set_event(hv_vmbus_channel *channel);
 
-/* Wait for device creation */
-void			vmbus_scan(void);
-
 #endif  /* __HYPERV_PRIV_H__ */

Modified: head/sys/dev/hyperv/vmbus/vmbus.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus.c	Tue Jul 12 02:57:13 2016	(r302605)
+++ head/sys/dev/hyperv/vmbus/vmbus.c	Tue Jul 12 03:03:17 2016	(r302606)
@@ -100,6 +100,9 @@ static int			vmbus_init_contact(struct v
 				    uint32_t);
 static int			vmbus_req_channels(struct vmbus_softc *sc);
 static void			vmbus_uninit(struct vmbus_softc *);
+static int			vmbus_scan(struct vmbus_softc *);
+static void			vmbus_scan_wait(struct vmbus_softc *);
+static void			vmbus_scan_newdev(struct vmbus_softc *);
 
 static int			vmbus_sysctl_version(SYSCTL_HANDLER_ARGS);
 
@@ -467,6 +470,85 @@ vmbus_req_channels(struct vmbus_softc *s
 	return error;
 }
 
+void
+vmbus_scan_newchan(struct vmbus_softc *sc)
+{
+	mtx_lock(&sc->vmbus_scan_lock);
+	if ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0)
+		sc->vmbus_scan_chcnt++;
+	mtx_unlock(&sc->vmbus_scan_lock);
+}
+
+void
+vmbus_scan_done(struct vmbus_softc *sc)
+{
+	mtx_lock(&sc->vmbus_scan_lock);
+	sc->vmbus_scan_chcnt |= VMBUS_SCAN_CHCNT_DONE;
+	mtx_unlock(&sc->vmbus_scan_lock);
+	wakeup(&sc->vmbus_scan_chcnt);
+}
+
+static void
+vmbus_scan_newdev(struct vmbus_softc *sc)
+{
+	mtx_lock(&sc->vmbus_scan_lock);
+	sc->vmbus_scan_devcnt++;
+	mtx_unlock(&sc->vmbus_scan_lock);
+	wakeup(&sc->vmbus_scan_devcnt);
+}
+
+static void
+vmbus_scan_wait(struct vmbus_softc *sc)
+{
+	uint32_t chancnt;
+
+	mtx_lock(&sc->vmbus_scan_lock);
+	while ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0) {
+		mtx_sleep(&sc->vmbus_scan_chcnt, &sc->vmbus_scan_lock, 0,
+		    "waitch", 0);
+	}
+	chancnt = sc->vmbus_scan_chcnt & ~VMBUS_SCAN_CHCNT_DONE;
+
+	while (sc->vmbus_scan_devcnt != chancnt) {
+		mtx_sleep(&sc->vmbus_scan_devcnt, &sc->vmbus_scan_lock, 0,
+		    "waitdev", 0);
+	}
+	mtx_unlock(&sc->vmbus_scan_lock);
+}
+
+static int
+vmbus_scan(struct vmbus_softc *sc)
+{
+	int error;
+
+	/*
+	 * Start vmbus scanning.
+	 */
+	error = vmbus_req_channels(sc);
+	if (error) {
+		device_printf(sc->vmbus_dev, "channel request failed: %d\n",
+		    error);
+		return error;
+	}
+
+	/*
+	 * Wait for all devices are added to vmbus.
+	 */
+	vmbus_scan_wait(sc);
+
+	/*
+	 * Identify, probe and attach.
+	 */
+	bus_generic_probe(sc->vmbus_dev);
+	bus_generic_attach(sc->vmbus_dev);
+
+	if (bootverbose) {
+		device_printf(sc->vmbus_dev, "device scan, probe and attach "
+		    "done\n");
+	}
+	return 0;
+}
+
 static void
 vmbus_msg_task(void *xsc, int pending __unused)
 {
@@ -942,12 +1024,13 @@ hv_vmbus_child_device_create(hv_guid typ
 	return (child_dev);
 }
 
-int
-hv_vmbus_child_device_register(struct hv_device *child_dev)
+void
+hv_vmbus_child_device_register(struct vmbus_softc *sc,
+    struct hv_device *child_dev)
 {
 	device_t child, parent;
 
-	parent = vmbus_get_device();
+	parent = sc->vmbus_dev;
 	if (bootverbose) {
 		char name[HYPERV_GUID_STRLEN];
 
@@ -959,7 +1042,8 @@ hv_vmbus_child_device_register(struct hv
 	child_dev->device = child;
 	device_set_ivars(child, child_dev);
 
-	return (0);
+	/* New device was added to vmbus */
+	vmbus_scan_newdev(sc);
 }
 
 int
@@ -1025,6 +1109,8 @@ vmbus_doattach(struct vmbus_softc *sc)
 		return (0);
 	sc->vmbus_flags |= VMBUS_FLAG_ATTACHED;
 
+	mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF);
+
 	/*
 	 * Create context for "post message" Hypercalls
 	 */
@@ -1074,14 +1160,10 @@ vmbus_doattach(struct vmbus_softc *sc)
 	else
 		sc->vmbus_event_proc = vmbus_event_proc;
 
-	ret = vmbus_req_channels(sc);
+	ret = vmbus_scan(sc);
 	if (ret != 0)
 		goto cleanup;
 
-	vmbus_scan();
-	bus_generic_attach(sc->vmbus_dev);
-	device_printf(sc->vmbus_dev, "device scan, probe and attach done\n");
-
 	ctx = device_get_sysctl_ctx(sc->vmbus_dev);
 	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev));
 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version",
@@ -1097,6 +1179,7 @@ cleanup:
 		vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc);
 		sc->vmbus_msg_hc = NULL;
 	}
+	mtx_destroy(&sc->vmbus_scan_lock);
 
 	return (ret);
 }
@@ -1131,7 +1214,6 @@ vmbus_attach(device_t dev)
 #endif
 		vmbus_doattach(vmbus_sc);
 
-	bus_generic_probe(dev);
 	return (0);
 }
 
@@ -1178,6 +1260,7 @@ vmbus_detach(device_t dev)
 		sc->vmbus_msg_hc = NULL;
 	}
 
+	mtx_destroy(&sc->vmbus_scan_lock);
 	return (0);
 }
 

Modified: head/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_var.h	Tue Jul 12 02:57:13 2016	(r302605)
+++ head/sys/dev/hyperv/vmbus/vmbus_var.h	Tue Jul 12 03:03:17 2016	(r302606)
@@ -84,6 +84,11 @@ struct vmbus_softc {
 	void			*vmbus_mnf1;	/* monitored by VM, unused */
 	struct hyperv_dma	vmbus_mnf1_dma;
 	struct hyperv_dma	vmbus_mnf2_dma;
+
+	struct mtx		vmbus_scan_lock;
+	uint32_t		vmbus_scan_chcnt;
+#define VMBUS_SCAN_CHCNT_DONE	0x80000000
+	uint32_t		vmbus_scan_devcnt;
 };
 
 #define VMBUS_FLAG_ATTACHED	0x0001	/* vmbus was attached */
@@ -129,4 +134,7 @@ const struct vmbus_message *vmbus_msghc_
 	    struct vmbus_msghc *);
 void	vmbus_msghc_wakeup(struct vmbus_softc *, const struct vmbus_message *);
 
+void	vmbus_scan_done(struct vmbus_softc *);
+void	vmbus_scan_newchan(struct vmbus_softc *);
+
 #endif	/* !_VMBUS_VAR_H_ */



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