Author: sephe
Date: Tue Apr 19 09:42:48 2016
New Revision: 298260
URL: https://svnweb.freebsd.org/changeset/base/298260

Log:
  hyperv/vmbus: Make device probe/attach synchronous w/ vmbus attach/SYSINIT
  
  Discussed with:       Jun Su <junsu microsoft com>, Dexuan Cui <decui 
microsoft com>
  MFC after:    1 week
  Sponsored by: Microsoft OSTC

Modified:
  head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h

Modified: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Apr 19 09:25:56 2016        
(r298259)
+++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Apr 19 09:42:48 2016        
(r298260)
@@ -27,7 +27,10 @@
  */
 
 #include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/mbuf.h>
+#include <sys/mutex.h>
 
 #include "hv_vmbus_priv.h"
 
@@ -92,6 +95,14 @@ typedef struct hv_work_item {
        void*           context;
 } hv_work_item;
 
+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
+
 /**
  * Implementation of the work abstraction.
  */
@@ -276,6 +287,11 @@ vmbus_channel_process_offer(hv_vmbus_cha
                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);
 }
 
 void
@@ -377,6 +393,11 @@ vmbus_channel_on_offer(hv_vmbus_channel_
 
        memcpy(copied, hdr, sizeof(*copied));
        hv_queue_work_item(vmbus_channel_on_offer_internal, copied);
+
+       mtx_lock(&vmbus_chwait_lock);
+       if ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0)
+               vmbus_chancnt++;
+       mtx_unlock(&vmbus_chwait_lock);
 }
 
 static void
@@ -468,6 +489,11 @@ vmbus_channel_on_offer_rescind_internal(
 static void
 vmbus_channel_on_offers_delivered(hv_vmbus_channel_msg_header* hdr)
 {
+
+       mtx_lock(&vmbus_chwait_lock);
+       vmbus_chancnt |= VMBUS_CHANCNT_DONE;
+       mtx_unlock(&vmbus_chwait_lock);
+       wakeup(&vmbus_chancnt);
 }
 
 /**
@@ -745,3 +771,18 @@ 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);
+}

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c    Tue Apr 19 09:25:56 
2016        (r298259)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c    Tue Apr 19 09:42:48 
2016        (r298260)
@@ -326,7 +326,6 @@ int
 hv_vmbus_child_device_register(struct hv_device *child_dev)
 {
        device_t child;
-       int ret = 0;
 
        if (bootverbose) {
                char name[40];
@@ -338,10 +337,6 @@ hv_vmbus_child_device_register(struct hv
        child_dev->device = child;
        device_set_ivars(child, child_dev);
 
-       mtx_lock(&Giant);
-       ret = device_probe_and_attach(child);
-       mtx_unlock(&Giant);
-
        return (0);
 }
 
@@ -481,6 +476,11 @@ vmbus_bus_init(void)
                goto cleanup1;
 
        hv_vmbus_request_channel_offers();
+
+       vmbus_scan();
+       bus_generic_attach(vmbus_devp);
+       device_printf(vmbus_devp, "device scan, probe and attach done\n");
+
        return (ret);
 
        cleanup1:

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h   Tue Apr 19 09:25:56 2016        
(r298259)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h   Tue Apr 19 09:42:48 2016        
(r298260)
@@ -751,6 +751,9 @@ void                        hv_vmbus_on_events(int cpu);
 void                   hv_et_init(void);
 void                   hv_et_intr(struct trapframe*);
 
+/* Wait for device creation */
+void                   vmbus_scan(void);
+
 /*
  * The guest OS needs to register the guest ID with the hypervisor.
  * The guest ID is a 64 bit entity and the structure of this ID is
_______________________________________________
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