svn commit: r302606 - head/sys/dev/hyperv/vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Tue Jul 12 03:03:19 UTC 2016
Author: sephe
Date: Tue Jul 12 03:03:17 2016
New Revision: 302606
URL: https://svnweb.freebsd.org/changeset/base/302606
Log:
hyperv/vmbus: Reorganize vmbus scan process.
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D6875
Modified:
head/sys/dev/hyperv/vmbus/hv_channel_mgmt.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/vmbus/hv_channel_mgmt.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Jul 12 02:57:13 2016 (r302605)
+++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Jul 12 03:03:17 2016 (r302606)
@@ -80,14 +80,6 @@ vmbus_chanmsg_process[HV_CHANNEL_MESSAGE
vmbus_channel_on_version_response
};
-static struct mtx vmbus_chwait_lock;
-MTX_SYSINIT(vmbus_chwait_lk, &vmbus_chwait_lock, "vmbus primarych wait lock",
- MTX_DEF);
-static uint32_t vmbus_chancnt;
-static uint32_t vmbus_devcnt;
-
-#define VMBUS_CHANCNT_DONE 0x80000000
-
/**
* @brief Allocate and initialize a vmbus channel object
*/
@@ -124,7 +116,6 @@ static void
vmbus_channel_process_offer(hv_vmbus_channel *new_channel)
{
hv_vmbus_channel* channel;
- int ret;
uint32_t relid;
relid = new_channel->offer_msg.child_rel_id;
@@ -229,19 +220,8 @@ vmbus_channel_process_offer(hv_vmbus_cha
* binding which eventually invokes the device driver's AddDevice()
* method.
*/
- ret = hv_vmbus_child_device_register(new_channel->device);
- if (ret != 0) {
- mtx_lock(&hv_vmbus_g_connection.channel_lock);
- TAILQ_REMOVE(&hv_vmbus_g_connection.channel_anchor,
- new_channel, list_entry);
- mtx_unlock(&hv_vmbus_g_connection.channel_lock);
- hv_vmbus_free_vmbus_channel(new_channel);
- }
-
- mtx_lock(&vmbus_chwait_lock);
- vmbus_devcnt++;
- mtx_unlock(&vmbus_chwait_lock);
- wakeup(&vmbus_devcnt);
+ hv_vmbus_child_device_register(new_channel->vmbus_sc,
+ new_channel->device);
}
void
@@ -332,10 +312,8 @@ vmbus_channel_on_offer(struct vmbus_soft
{
const hv_vmbus_channel_offer_channel *offer;
- mtx_lock(&vmbus_chwait_lock);
- if ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0)
- vmbus_chancnt++;
- mtx_unlock(&vmbus_chwait_lock);
+ /* New channel is offered by vmbus */
+ vmbus_scan_newchan(sc);
offer = (const hv_vmbus_channel_offer_channel *)msg->msg_data;
vmbus_channel_on_offer_internal(sc, offer);
@@ -428,14 +406,12 @@ vmbus_chan_detach_task(void *xchan, int
* @brief Invoked when all offers have been delivered.
*/
static void
-vmbus_channel_on_offers_delivered(struct vmbus_softc *sc __unused,
+vmbus_channel_on_offers_delivered(struct vmbus_softc *sc,
const struct vmbus_message *msg __unused)
{
- mtx_lock(&vmbus_chwait_lock);
- vmbus_chancnt |= VMBUS_CHANCNT_DONE;
- mtx_unlock(&vmbus_chwait_lock);
- wakeup(&vmbus_chancnt);
+ /* No more new channels for the channel request. */
+ vmbus_scan_done(sc);
}
/**
@@ -668,21 +644,6 @@ vmbus_select_outgoing_channel(struct hv_
return(outgoing_channel);
}
-void
-vmbus_scan(void)
-{
- uint32_t chancnt;
-
- mtx_lock(&vmbus_chwait_lock);
- while ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0)
- mtx_sleep(&vmbus_chancnt, &vmbus_chwait_lock, 0, "waitch", 0);
- chancnt = vmbus_chancnt & ~VMBUS_CHANCNT_DONE;
-
- while (vmbus_devcnt != chancnt)
- mtx_sleep(&vmbus_devcnt, &vmbus_chwait_lock, 0, "waitdev", 0);
- mtx_unlock(&vmbus_chwait_lock);
-}
-
struct hv_vmbus_channel **
vmbus_get_subchan(struct hv_vmbus_channel *pri_chan, int subchan_cnt)
{
Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Jul 12 02:57:13 2016 (r302605)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Tue Jul 12 03:03:17 2016 (r302606)
@@ -411,7 +411,9 @@ struct hv_device* hv_vmbus_child_device_
hv_guid device_instance,
hv_vmbus_channel *channel);
-int hv_vmbus_child_device_register(
+struct vmbus_softc;
+
+void hv_vmbus_child_device_register(struct vmbus_softc *,
struct hv_device *child_dev);
int hv_vmbus_child_device_unregister(
struct hv_device *child_dev);
@@ -419,13 +421,9 @@ int hv_vmbus_child_device_unregister(
/**
* Connection interfaces
*/
-struct vmbus_softc;
int hv_vmbus_connect(struct vmbus_softc *);
int hv_vmbus_disconnect(void);
int hv_vmbus_post_message(void *buffer, size_t buf_size);
int hv_vmbus_set_event(hv_vmbus_channel *channel);
-/* Wait for device creation */
-void vmbus_scan(void);
-
#endif /* __HYPERV_PRIV_H__ */
Modified: head/sys/dev/hyperv/vmbus/vmbus.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus.c Tue Jul 12 02:57:13 2016 (r302605)
+++ head/sys/dev/hyperv/vmbus/vmbus.c Tue Jul 12 03:03:17 2016 (r302606)
@@ -100,6 +100,9 @@ static int vmbus_init_contact(struct v
uint32_t);
static int vmbus_req_channels(struct vmbus_softc *sc);
static void vmbus_uninit(struct vmbus_softc *);
+static int vmbus_scan(struct vmbus_softc *);
+static void vmbus_scan_wait(struct vmbus_softc *);
+static void vmbus_scan_newdev(struct vmbus_softc *);
static int vmbus_sysctl_version(SYSCTL_HANDLER_ARGS);
@@ -467,6 +470,85 @@ vmbus_req_channels(struct vmbus_softc *s
return error;
}
+void
+vmbus_scan_newchan(struct vmbus_softc *sc)
+{
+ mtx_lock(&sc->vmbus_scan_lock);
+ if ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0)
+ sc->vmbus_scan_chcnt++;
+ mtx_unlock(&sc->vmbus_scan_lock);
+}
+
+void
+vmbus_scan_done(struct vmbus_softc *sc)
+{
+ mtx_lock(&sc->vmbus_scan_lock);
+ sc->vmbus_scan_chcnt |= VMBUS_SCAN_CHCNT_DONE;
+ mtx_unlock(&sc->vmbus_scan_lock);
+ wakeup(&sc->vmbus_scan_chcnt);
+}
+
+static void
+vmbus_scan_newdev(struct vmbus_softc *sc)
+{
+ mtx_lock(&sc->vmbus_scan_lock);
+ sc->vmbus_scan_devcnt++;
+ mtx_unlock(&sc->vmbus_scan_lock);
+ wakeup(&sc->vmbus_scan_devcnt);
+}
+
+static void
+vmbus_scan_wait(struct vmbus_softc *sc)
+{
+ uint32_t chancnt;
+
+ mtx_lock(&sc->vmbus_scan_lock);
+ while ((sc->vmbus_scan_chcnt & VMBUS_SCAN_CHCNT_DONE) == 0) {
+ mtx_sleep(&sc->vmbus_scan_chcnt, &sc->vmbus_scan_lock, 0,
+ "waitch", 0);
+ }
+ chancnt = sc->vmbus_scan_chcnt & ~VMBUS_SCAN_CHCNT_DONE;
+
+ while (sc->vmbus_scan_devcnt != chancnt) {
+ mtx_sleep(&sc->vmbus_scan_devcnt, &sc->vmbus_scan_lock, 0,
+ "waitdev", 0);
+ }
+ mtx_unlock(&sc->vmbus_scan_lock);
+}
+
+static int
+vmbus_scan(struct vmbus_softc *sc)
+{
+ int error;
+
+ /*
+ * Start vmbus scanning.
+ */
+ error = vmbus_req_channels(sc);
+ if (error) {
+ device_printf(sc->vmbus_dev, "channel request failed: %d\n",
+ error);
+ return error;
+ }
+
+ /*
+ * Wait for all devices are added to vmbus.
+ */
+ vmbus_scan_wait(sc);
+
+ /*
+ * Identify, probe and attach.
+ */
+ bus_generic_probe(sc->vmbus_dev);
+ bus_generic_attach(sc->vmbus_dev);
+
+ if (bootverbose) {
+ device_printf(sc->vmbus_dev, "device scan, probe and attach "
+ "done\n");
+ }
+ return 0;
+}
+
static void
vmbus_msg_task(void *xsc, int pending __unused)
{
@@ -942,12 +1024,13 @@ hv_vmbus_child_device_create(hv_guid typ
return (child_dev);
}
-int
-hv_vmbus_child_device_register(struct hv_device *child_dev)
+void
+hv_vmbus_child_device_register(struct vmbus_softc *sc,
+ struct hv_device *child_dev)
{
device_t child, parent;
- parent = vmbus_get_device();
+ parent = sc->vmbus_dev;
if (bootverbose) {
char name[HYPERV_GUID_STRLEN];
@@ -959,7 +1042,8 @@ hv_vmbus_child_device_register(struct hv
child_dev->device = child;
device_set_ivars(child, child_dev);
- return (0);
+ /* New device was added to vmbus */
+ vmbus_scan_newdev(sc);
}
int
@@ -1025,6 +1109,8 @@ vmbus_doattach(struct vmbus_softc *sc)
return (0);
sc->vmbus_flags |= VMBUS_FLAG_ATTACHED;
+ mtx_init(&sc->vmbus_scan_lock, "vmbus scan", NULL, MTX_DEF);
+
/*
* Create context for "post message" Hypercalls
*/
@@ -1074,14 +1160,10 @@ vmbus_doattach(struct vmbus_softc *sc)
else
sc->vmbus_event_proc = vmbus_event_proc;
- ret = vmbus_req_channels(sc);
+ ret = vmbus_scan(sc);
if (ret != 0)
goto cleanup;
- vmbus_scan();
- bus_generic_attach(sc->vmbus_dev);
- device_printf(sc->vmbus_dev, "device scan, probe and attach done\n");
-
ctx = device_get_sysctl_ctx(sc->vmbus_dev);
child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->vmbus_dev));
SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "version",
@@ -1097,6 +1179,7 @@ cleanup:
vmbus_msghc_ctx_destroy(sc->vmbus_msg_hc);
sc->vmbus_msg_hc = NULL;
}
+ mtx_destroy(&sc->vmbus_scan_lock);
return (ret);
}
@@ -1131,7 +1214,6 @@ vmbus_attach(device_t dev)
#endif
vmbus_doattach(vmbus_sc);
- bus_generic_probe(dev);
return (0);
}
@@ -1178,6 +1260,7 @@ vmbus_detach(device_t dev)
sc->vmbus_msg_hc = NULL;
}
+ mtx_destroy(&sc->vmbus_scan_lock);
return (0);
}
Modified: head/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_var.h Tue Jul 12 02:57:13 2016 (r302605)
+++ head/sys/dev/hyperv/vmbus/vmbus_var.h Tue Jul 12 03:03:17 2016 (r302606)
@@ -84,6 +84,11 @@ struct vmbus_softc {
void *vmbus_mnf1; /* monitored by VM, unused */
struct hyperv_dma vmbus_mnf1_dma;
struct hyperv_dma vmbus_mnf2_dma;
+
+ struct mtx vmbus_scan_lock;
+ uint32_t vmbus_scan_chcnt;
+#define VMBUS_SCAN_CHCNT_DONE 0x80000000
+ uint32_t vmbus_scan_devcnt;
};
#define VMBUS_FLAG_ATTACHED 0x0001 /* vmbus was attached */
@@ -129,4 +134,7 @@ const struct vmbus_message *vmbus_msghc_
struct vmbus_msghc *);
void vmbus_msghc_wakeup(struct vmbus_softc *, const struct vmbus_message *);
+void vmbus_scan_done(struct vmbus_softc *);
+void vmbus_scan_newchan(struct vmbus_softc *);
+
#endif /* !_VMBUS_VAR_H_ */
More information about the svn-src-head
mailing list