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_ */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to