hyperv/vmbus: Move channel list to vmbus_softc

MFC after:	1 week
Sponsored by:	Microsoft OSTC
Differential Revision:	https://reviews.freebsd.org/D6956
This commit is contained in:
Sepherosa Ziehau 2016-07-12 08:11:16 +00:00
parent ee7e313f03
commit 7fbf073008
6 changed files with 36 additions and 34 deletions

View File

@ -533,7 +533,6 @@ typedef union {
} __packed hv_vmbus_connection_id; } __packed hv_vmbus_connection_id;
typedef struct hv_vmbus_channel { typedef struct hv_vmbus_channel {
TAILQ_ENTRY(hv_vmbus_channel) list_entry;
struct hv_device* device; struct hv_device* device;
struct vmbus_softc *vmbus_sc; struct vmbus_softc *vmbus_sc;
hv_vmbus_channel_state state; hv_vmbus_channel_state state;
@ -627,6 +626,7 @@ typedef struct hv_vmbus_channel {
void *hv_chan_priv3; void *hv_chan_priv3;
struct task ch_detach_task; struct task ch_detach_task;
TAILQ_ENTRY(hv_vmbus_channel) ch_link;
} hv_vmbus_channel; } hv_vmbus_channel;
#define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL) #define HV_VMBUS_CHAN_ISPRIMARY(chan) ((chan)->primary_channel == NULL)

View File

@ -108,6 +108,7 @@ hv_vmbus_free_vmbus_channel(hv_vmbus_channel* channel)
static void static void
vmbus_channel_process_offer(hv_vmbus_channel *new_channel) vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
{ {
struct vmbus_softc *sc = new_channel->vmbus_sc;
hv_vmbus_channel* channel; hv_vmbus_channel* channel;
uint32_t relid; uint32_t relid;
@ -115,7 +116,7 @@ vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
/* /*
* Make sure this is a new offer * Make sure this is a new offer
*/ */
mtx_lock(&hv_vmbus_g_connection.channel_lock); mtx_lock(&sc->vmbus_chlist_lock);
if (relid == 0) { if (relid == 0) {
/* /*
* XXX channel0 will not be processed; skip it. * XXX channel0 will not be processed; skip it.
@ -125,8 +126,7 @@ vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
hv_vmbus_g_connection.channels[relid] = new_channel; hv_vmbus_g_connection.channels[relid] = new_channel;
} }
TAILQ_FOREACH(channel, &hv_vmbus_g_connection.channel_anchor, TAILQ_FOREACH(channel, &sc->vmbus_chlist, ch_link) {
list_entry) {
if (memcmp(&channel->offer_msg.offer.interface_type, if (memcmp(&channel->offer_msg.offer.interface_type,
&new_channel->offer_msg.offer.interface_type, &new_channel->offer_msg.offer.interface_type,
sizeof(hv_guid)) == 0 && sizeof(hv_guid)) == 0 &&
@ -138,10 +138,9 @@ vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
if (channel == NULL) { if (channel == NULL) {
/* Install the new primary channel */ /* Install the new primary channel */
TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor, TAILQ_INSERT_TAIL(&sc->vmbus_chlist, new_channel, ch_link);
new_channel, list_entry);
} }
mtx_unlock(&hv_vmbus_g_connection.channel_lock); mtx_unlock(&sc->vmbus_chlist_lock);
if (channel != NULL) { if (channel != NULL) {
/* /*
@ -165,11 +164,19 @@ vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
new_channel->offer_msg.offer.sub_channel_index); new_channel->offer_msg.offer.sub_channel_index);
} }
/* Insert new channel into channel_anchor. */ /*
mtx_lock(&hv_vmbus_g_connection.channel_lock); * Insert the new channel to the end of the global
TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor, * channel list.
new_channel, list_entry); *
mtx_unlock(&hv_vmbus_g_connection.channel_lock); * 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) if(bootverbose)
printf("VMBUS: new multi-channel offer <%p>, " printf("VMBUS: new multi-channel offer <%p>, "
@ -375,16 +382,15 @@ vmbus_channel_on_offers_delivered(struct vmbus_softc *sc,
* @brief Release channels that are unattached/unconnected (i.e., no drivers associated) * @brief Release channels that are unattached/unconnected (i.e., no drivers associated)
*/ */
void void
hv_vmbus_release_unattached_channels(void) hv_vmbus_release_unattached_channels(struct vmbus_softc *sc)
{ {
hv_vmbus_channel *channel; 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)) { while (!TAILQ_EMPTY(&sc->vmbus_chlist)) {
channel = TAILQ_FIRST(&hv_vmbus_g_connection.channel_anchor); channel = TAILQ_FIRST(&sc->vmbus_chlist);
TAILQ_REMOVE(&hv_vmbus_g_connection.channel_anchor, TAILQ_REMOVE(&sc->vmbus_chlist, channel, ch_link);
channel, list_entry);
if (HV_VMBUS_CHAN_ISPRIMARY(channel)) { if (HV_VMBUS_CHAN_ISPRIMARY(channel)) {
/* Only primary channel owns the hv_device */ /* Only primary channel owns the hv_device */
@ -394,7 +400,8 @@ hv_vmbus_release_unattached_channels(void)
} }
bzero(hv_vmbus_g_connection.channels, bzero(hv_vmbus_g_connection.channels,
sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX); sizeof(hv_vmbus_channel*) * VMBUS_CHAN_MAX);
mtx_unlock(&hv_vmbus_g_connection.channel_lock);
mtx_unlock(&sc->vmbus_chlist_lock);
} }
/** /**

View File

@ -67,10 +67,6 @@ hv_vmbus_connect(struct vmbus_softc *sc)
*/ */
hv_vmbus_g_connection.connect_state = HV_CONNECTING; 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*) * hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) *
VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO); VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO);

View File

@ -38,6 +38,8 @@
#include <dev/hyperv/include/hyperv.h> #include <dev/hyperv/include/hyperv.h>
struct vmbus_softc;
typedef struct { typedef struct {
void* data; void* data;
uint32_t length; uint32_t length;
@ -108,13 +110,6 @@ typedef enum {
typedef struct { typedef struct {
hv_vmbus_connect_state connect_state; 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. * channel table for fast lookup through id.
*/ */
@ -239,15 +234,14 @@ uint32_t hv_ring_buffer_read_end(
hv_vmbus_ring_buffer_info *ring_info); hv_vmbus_ring_buffer_info *ring_info);
void hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel); 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( struct hv_device* hv_vmbus_child_device_create(
hv_guid device_type, hv_guid device_type,
hv_guid device_instance, hv_guid device_instance,
hv_vmbus_channel *channel); hv_vmbus_channel *channel);
struct vmbus_softc;
void hv_vmbus_child_device_register(struct vmbus_softc *, void hv_vmbus_child_device_register(struct vmbus_softc *,
struct hv_device *child_dev); struct hv_device *child_dev);
int hv_vmbus_child_device_unregister( int hv_vmbus_child_device_unregister(

View File

@ -1130,6 +1130,8 @@ vmbus_doattach(struct vmbus_softc *sc)
mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF); mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF);
sc->vmbus_gpadl = VMBUS_GPADL_START; 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 * Create context for "post message" Hypercalls
@ -1262,7 +1264,7 @@ vmbus_detach(device_t dev)
{ {
struct vmbus_softc *sc = device_get_softc(dev); struct vmbus_softc *sc = device_get_softc(dev);
hv_vmbus_release_unattached_channels(); hv_vmbus_release_unattached_channels(sc);
vmbus_disconnect(sc); vmbus_disconnect(sc);
hv_vmbus_disconnect(); hv_vmbus_disconnect();

View File

@ -100,6 +100,9 @@ struct vmbus_softc {
uint32_t vmbus_scan_chcnt; uint32_t vmbus_scan_chcnt;
#define VMBUS_SCAN_CHCNT_DONE 0x80000000 #define VMBUS_SCAN_CHCNT_DONE 0x80000000
uint32_t vmbus_scan_devcnt; 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 */ #define VMBUS_FLAG_ATTACHED 0x0001 /* vmbus was attached */