Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Jul 2016 08:11:16 +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: r302631 - in head/sys/dev/hyperv: include vmbus
Message-ID:  <201607120811.u6C8BGfA018360@repo.freebsd.org>

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

Log:
  hyperv/vmbus: Move channel list to vmbus_softc
  
  MFC after:	1 week
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D6956

Modified:
  head/sys/dev/hyperv/include/hyperv.h
  head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
  head/sys/dev/hyperv/vmbus/hv_connection.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/include/hyperv.h
==============================================================================
--- head/sys/dev/hyperv/include/hyperv.h	Tue Jul 12 07:49:38 2016	(r302630)
+++ head/sys/dev/hyperv/include/hyperv.h	Tue Jul 12 08:11:16 2016	(r302631)
@@ -533,7 +533,6 @@ typedef union {
 } __packed hv_vmbus_connection_id;
 
 typedef struct hv_vmbus_channel {
-	TAILQ_ENTRY(hv_vmbus_channel)	list_entry;
 	struct hv_device*		device;
 	struct vmbus_softc		*vmbus_sc;
 	hv_vmbus_channel_state		state;
@@ -627,6 +626,7 @@ typedef struct hv_vmbus_channel {
 	void				*hv_chan_priv3;
 
 	struct task			ch_detach_task;
+	TAILQ_ENTRY(hv_vmbus_channel)	ch_link;
 } hv_vmbus_channel;
 
 #define HV_VMBUS_CHAN_ISPRIMARY(chan)	((chan)->primary_channel == NULL)

Modified: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Tue Jul 12 07:49:38 2016	(r302630)
+++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Tue Jul 12 08:11:16 2016	(r302631)
@@ -108,6 +108,7 @@ hv_vmbus_free_vmbus_channel(hv_vmbus_cha
 static void
 vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
 {
+	struct vmbus_softc *sc = new_channel->vmbus_sc;
 	hv_vmbus_channel*	channel;
 	uint32_t                relid;
 
@@ -115,7 +116,7 @@ vmbus_channel_process_offer(hv_vmbus_cha
 	/*
 	 * Make sure this is a new offer
 	 */
-	mtx_lock(&hv_vmbus_g_connection.channel_lock);
+	mtx_lock(&sc->vmbus_chlist_lock);
 	if (relid == 0) {
 		/*
 		 * XXX channel0 will not be processed; skip it.
@@ -125,8 +126,7 @@ vmbus_channel_process_offer(hv_vmbus_cha
 		hv_vmbus_g_connection.channels[relid] = new_channel;
 	}
 
-	TAILQ_FOREACH(channel, &hv_vmbus_g_connection.channel_anchor,
-	    list_entry) {
+	TAILQ_FOREACH(channel, &sc->vmbus_chlist, ch_link) {
 		if (memcmp(&channel->offer_msg.offer.interface_type,
 		    &new_channel->offer_msg.offer.interface_type,
 		    sizeof(hv_guid)) == 0 &&
@@ -138,10 +138,9 @@ vmbus_channel_process_offer(hv_vmbus_cha
 
 	if (channel == NULL) {
 		/* Install the new primary channel */
-		TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor,
-		    new_channel, list_entry);
+		TAILQ_INSERT_TAIL(&sc->vmbus_chlist, new_channel, ch_link);
 	}
-	mtx_unlock(&hv_vmbus_g_connection.channel_lock);
+	mtx_unlock(&sc->vmbus_chlist_lock);
 
 	if (channel != NULL) {
 		/*
@@ -165,11 +164,19 @@ vmbus_channel_process_offer(hv_vmbus_cha
 				    new_channel->offer_msg.offer.sub_channel_index);	
 			}
 
-			/* Insert new channel into channel_anchor. */
-			mtx_lock(&hv_vmbus_g_connection.channel_lock);
-			TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor,
-			    new_channel, list_entry);				
-			mtx_unlock(&hv_vmbus_g_connection.channel_lock);
+			/*
+			 * Insert the new channel to the end of the global
+			 * channel list.
+			 *
+			 * NOTE:
+			 * The new sub-channel MUST be inserted AFTER it's
+			 * primary channel, so that the primary channel will
+			 * be found in the above loop for its baby siblings.
+			 */
+			mtx_lock(&sc->vmbus_chlist_lock);
+			TAILQ_INSERT_TAIL(&sc->vmbus_chlist, new_channel,
+			    ch_link);
+			mtx_unlock(&sc->vmbus_chlist_lock);
 
 			if(bootverbose)
 				printf("VMBUS: new multi-channel offer <%p>, "
@@ -375,16 +382,15 @@ vmbus_channel_on_offers_delivered(struct
  * @brief Release channels that are unattached/unconnected (i.e., no drivers associated)
  */
 void
-hv_vmbus_release_unattached_channels(void) 
+hv_vmbus_release_unattached_channels(struct vmbus_softc *sc)
 {
 	hv_vmbus_channel *channel;
 
-	mtx_lock(&hv_vmbus_g_connection.channel_lock);
+	mtx_lock(&sc->vmbus_chlist_lock);
 
-	while (!TAILQ_EMPTY(&hv_vmbus_g_connection.channel_anchor)) {
-	    channel = TAILQ_FIRST(&hv_vmbus_g_connection.channel_anchor);
-	    TAILQ_REMOVE(&hv_vmbus_g_connection.channel_anchor,
-			    channel, list_entry);
+	while (!TAILQ_EMPTY(&sc->vmbus_chlist)) {
+	    channel = TAILQ_FIRST(&sc->vmbus_chlist);
+	    TAILQ_REMOVE(&sc->vmbus_chlist, channel, ch_link);
 
 	    if (HV_VMBUS_CHAN_ISPRIMARY(channel)) {
 		/* Only primary channel owns the hv_device */
@@ -394,7 +400,8 @@ hv_vmbus_release_unattached_channels(voi
 	}
 	bzero(hv_vmbus_g_connection.channels,
 	    sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX);
-	mtx_unlock(&hv_vmbus_g_connection.channel_lock);
+
+	mtx_unlock(&sc->vmbus_chlist_lock);
 }
 
 /**

Modified: head/sys/dev/hyperv/vmbus/hv_connection.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_connection.c	Tue Jul 12 07:49:38 2016	(r302630)
+++ head/sys/dev/hyperv/vmbus/hv_connection.c	Tue Jul 12 08:11:16 2016	(r302631)
@@ -67,10 +67,6 @@ hv_vmbus_connect(struct vmbus_softc *sc)
 	 */
 	hv_vmbus_g_connection.connect_state = HV_CONNECTING;
 
-	TAILQ_INIT(&hv_vmbus_g_connection.channel_anchor);
-	mtx_init(&hv_vmbus_g_connection.channel_lock, "vmbus channel",
-		NULL, MTX_DEF);
-
 	hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) *
 	    VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO);
 

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue Jul 12 07:49:38 2016	(r302630)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue Jul 12 08:11:16 2016	(r302631)
@@ -38,6 +38,8 @@
 
 #include <dev/hyperv/include/hyperv.h>
 
+struct vmbus_softc;
+
 typedef struct {
 	void*		data;
 	uint32_t	length;
@@ -109,13 +111,6 @@ typedef struct {
 	hv_vmbus_connect_state			connect_state;
 
 	/**
-	 * List of primary channels. Sub channels will be linked
-	 * under their primary channel.
-	 */
-	TAILQ_HEAD(, hv_vmbus_channel)		channel_anchor;
-	struct mtx				channel_lock;
-
-	/**
 	 * channel table for fast lookup through id.
 	*/
 	hv_vmbus_channel                        **channels;
@@ -239,15 +234,14 @@ uint32_t		hv_ring_buffer_read_end(
 				hv_vmbus_ring_buffer_info	*ring_info);
 
 void			hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel);
-void			hv_vmbus_release_unattached_channels(void);
+void			hv_vmbus_release_unattached_channels(
+			    struct vmbus_softc *);
 
 struct hv_device*	hv_vmbus_child_device_create(
 				hv_guid			device_type,
 				hv_guid			device_instance,
 				hv_vmbus_channel	*channel);
 
-struct vmbus_softc;
-
 void			hv_vmbus_child_device_register(struct vmbus_softc *,
 					struct hv_device *child_dev);
 int			hv_vmbus_child_device_unregister(

Modified: head/sys/dev/hyperv/vmbus/vmbus.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus.c	Tue Jul 12 07:49:38 2016	(r302630)
+++ head/sys/dev/hyperv/vmbus/vmbus.c	Tue Jul 12 08:11:16 2016	(r302631)
@@ -1130,6 +1130,8 @@ vmbus_doattach(struct vmbus_softc *sc)
 
 	mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF);
 	sc->vmbus_gpadl = VMBUS_GPADL_START;
+	mtx_init(&sc->vmbus_chlist_lock, "vmbus chlist", NULL, MTX_DEF);
+	TAILQ_INIT(&sc->vmbus_chlist);
 
 	/*
 	 * Create context for "post message" Hypercalls
@@ -1262,7 +1264,7 @@ vmbus_detach(device_t dev)
 {
 	struct vmbus_softc *sc = device_get_softc(dev);
 
-	hv_vmbus_release_unattached_channels();
+	hv_vmbus_release_unattached_channels(sc);
 
 	vmbus_disconnect(sc);
 	hv_vmbus_disconnect();

Modified: head/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_var.h	Tue Jul 12 07:49:38 2016	(r302630)
+++ head/sys/dev/hyperv/vmbus/vmbus_var.h	Tue Jul 12 08:11:16 2016	(r302631)
@@ -100,6 +100,9 @@ struct vmbus_softc {
 	uint32_t		vmbus_scan_chcnt;
 #define VMBUS_SCAN_CHCNT_DONE	0x80000000
 	uint32_t		vmbus_scan_devcnt;
+
+	struct mtx		vmbus_chlist_lock;
+	TAILQ_HEAD(, hv_vmbus_channel) vmbus_chlist;
 };
 
 #define VMBUS_FLAG_ATTACHED	0x0001	/* vmbus was attached */



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