Page MenuHomeFreeBSD

D6956.diff
No OneTemporary

D6956.diff

Index: head/sys/dev/hyperv/include/hyperv.h
===================================================================
--- head/sys/dev/hyperv/include/hyperv.h
+++ head/sys/dev/hyperv/include/hyperv.h
@@ -533,7 +533,6 @@
} __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 @@
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)
Index: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
===================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
+++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
@@ -108,6 +108,7 @@
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 @@
/*
* 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 @@
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 @@
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 @@
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 @@
* @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 @@
}
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);
}
/**
Index: head/sys/dev/hyperv/vmbus/hv_connection.c
===================================================================
--- head/sys/dev/hyperv/vmbus/hv_connection.c
+++ head/sys/dev/hyperv/vmbus/hv_connection.c
@@ -67,10 +67,6 @@
*/
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);
Index: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
===================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -38,6 +38,8 @@
#include <dev/hyperv/include/hyperv.h>
+struct vmbus_softc;
+
typedef struct {
void* data;
uint32_t length;
@@ -109,13 +111,6 @@
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 @@
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(
Index: head/sys/dev/hyperv/vmbus/vmbus.c
===================================================================
--- head/sys/dev/hyperv/vmbus/vmbus.c
+++ head/sys/dev/hyperv/vmbus/vmbus.c
@@ -1130,6 +1130,8 @@
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 @@
{
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();
Index: head/sys/dev/hyperv/vmbus/vmbus_var.h
===================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_var.h
+++ head/sys/dev/hyperv/vmbus/vmbus_var.h
@@ -100,6 +100,9 @@
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 */

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 5, 2:21 PM (20 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16994194
Default Alt Text
D6956.diff (6 KB)

Event Timeline