svn commit: r302815 - head/sys/dev/hyperv/vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Thu Jul 14 07:31:44 UTC 2016
Author: sephe
Date: Thu Jul 14 07:31:43 2016
New Revision: 302815
URL: https://svnweb.freebsd.org/changeset/base/302815
Log:
hyperv/vmbus: Only add primary channels to vmbus channel list
- Make the vmbus_chan_add more straightforward.
- Partially fix the hv_vmbus_release_unattached_channels().
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D7109
Modified:
head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
Modified: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Thu Jul 14 07:24:03 2016 (r302814)
+++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Thu Jul 14 07:31:43 2016 (r302815)
@@ -142,52 +142,55 @@ vmbus_chan_add(struct hv_vmbus_channel *
sizeof(struct hyperv_guid)) == 0)
break;
}
- if (prichan == NULL) {
- /* Install the new primary channel */
- TAILQ_INSERT_TAIL(&sc->vmbus_chlist, newchan, ch_link);
- }
- mtx_unlock(&sc->vmbus_chlist_lock);
-
- if (prichan != NULL) {
- if (newchan->ch_subidx == 0) {
+ if (VMBUS_CHAN_ISPRIMARY(newchan)) {
+ if (prichan == NULL) {
+ /* Install the new primary channel */
+ TAILQ_INSERT_TAIL(&sc->vmbus_chlist, newchan, ch_link);
+ mtx_unlock(&sc->vmbus_chlist_lock);
+ return 0;
+ } else {
+ mtx_unlock(&sc->vmbus_chlist_lock);
device_printf(sc->vmbus_dev, "duplicated primary "
"chan%u\n", newchan->ch_id);
return EINVAL;
}
-
- /*
- * This is a sub-channel.
- */
- newchan->primary_channel = prichan;
- newchan->ch_dev = prichan->ch_dev;
- mtx_lock(&prichan->sc_lock);
- TAILQ_INSERT_TAIL(&prichan->sc_list_anchor, newchan,
- sc_list_entry);
- mtx_unlock(&prichan->sc_lock);
-
+ } else { /* Sub-channel */
+ if (prichan == NULL) {
+ mtx_unlock(&sc->vmbus_chlist_lock);
+ device_printf(sc->vmbus_dev, "no primary chan for "
+ "chan%u\n", newchan->ch_id);
+ return EINVAL;
+ }
/*
- * Insert the new channel to the end of the global
- * channel list.
+ * Found the primary channel for this sub-channel and
+ * move on.
*
- * 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, newchan, ch_link);
- mtx_unlock(&sc->vmbus_chlist_lock);
-
- /*
- * Bump up sub-channel count and notify anyone that is
- * interested in this sub-channel, after this sub-channel
- * is setup.
+ * XXX refcnt prichan
*/
- mtx_lock(&prichan->sc_lock);
- prichan->subchan_cnt++;
- mtx_unlock(&prichan->sc_lock);
- wakeup(prichan);
}
+ mtx_unlock(&sc->vmbus_chlist_lock);
+
+ /*
+ * This is a sub-channel; link it with the primary channel.
+ */
+ KASSERT(!VMBUS_CHAN_ISPRIMARY(newchan),
+ ("new channel is not sub-channel"));
+ KASSERT(prichan != NULL, ("no primary channel"));
+
+ newchan->primary_channel = prichan;
+ newchan->ch_dev = prichan->ch_dev;
+
+ mtx_lock(&prichan->sc_lock);
+ TAILQ_INSERT_TAIL(&prichan->sc_list_anchor, newchan, sc_list_entry);
+ /*
+ * Bump up sub-channel count and notify anyone that is
+ * interested in this sub-channel, after this sub-channel
+ * is setup.
+ */
+ prichan->subchan_cnt++;
+ mtx_unlock(&prichan->sc_lock);
+ wakeup(prichan);
+
return 0;
}
@@ -370,10 +373,6 @@ vmbus_chan_detach_task(void *xchan, int
}
}
remove:
- mtx_lock(&sc->vmbus_chlist_lock);
- TAILQ_REMOVE(&sc->vmbus_chlist, chan, ch_link);
- mtx_unlock(&sc->vmbus_chlist_lock);
-
mtx_lock(&pri_chan->sc_lock);
TAILQ_REMOVE(&pri_chan->sc_list_anchor, chan, sc_list_entry);
KASSERT(pri_chan->subchan_cnt > 0,
@@ -411,12 +410,10 @@ hv_vmbus_release_unattached_channels(str
while (!TAILQ_EMPTY(&sc->vmbus_chlist)) {
channel = TAILQ_FIRST(&sc->vmbus_chlist);
+ KASSERT(VMBUS_CHAN_ISPRIMARY(channel), ("not primary channel"));
TAILQ_REMOVE(&sc->vmbus_chlist, channel, ch_link);
- if (VMBUS_CHAN_ISPRIMARY(channel)) {
- /* Only primary channel owns the device */
- hv_vmbus_child_device_unregister(channel);
- }
+ hv_vmbus_child_device_unregister(channel);
vmbus_chan_free(channel);
}
bzero(sc->vmbus_chmap,
More information about the svn-src-all
mailing list