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;
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)

View File

@ -108,6 +108,7 @@ hv_vmbus_free_vmbus_channel(hv_vmbus_channel* channel)
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_channel *new_channel)
/*
* 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_channel *new_channel)
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_channel *new_channel)
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_channel *new_channel)
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 vmbus_softc *sc,
* @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(void)
}
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);
}
/**

View File

@ -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);

View File

@ -38,6 +38,8 @@
#include <dev/hyperv/include/hyperv.h>
struct vmbus_softc;
typedef struct {
void* data;
uint32_t length;
@ -108,13 +110,6 @@ typedef enum {
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.
*/
@ -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(

View File

@ -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();

View File

@ -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 */