Date: Tue, 12 Jul 2016 03:03:17 +0000 (UTC) From: Sepherosa Ziehau <sephe@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r302606 - head/sys/dev/hyperv/vmbus Message-ID: <201607120303.u6C33H3q009886@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607120303.u6C33H3q009886>