svn commit: r298260 - head/sys/dev/hyperv/vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Tue Apr 19 09:42:49 UTC 2016
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
More information about the svn-src-head
mailing list