svn commit: r302118 - stable/10/sys/dev/hyperv/vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Thu Jun 23 05:51:59 UTC 2016
Author: sephe
Date: Thu Jun 23 05:51:57 2016
New Revision: 302118
URL: https://svnweb.freebsd.org/changeset/base/302118
Log:
MFC 300572
hyperv/vmbus: Use busdma(9) for messages and event flags
And
- Move message and event flags to vmbus_softc per-cpu data.
- Get rid of hv_setup_arg, which serves no purpose now.
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D6502
Modified:
stable/10/sys/dev/hyperv/vmbus/hv_connection.c
stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
stable/10/sys/dev/hyperv/vmbus/vmbus_var.h
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/hyperv/vmbus/hv_connection.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_connection.c Thu Jun 23 05:41:46 2016 (r302117)
+++ stable/10/sys/dev/hyperv/vmbus/hv_connection.c Thu Jun 23 05:51:57 2016 (r302118)
@@ -336,13 +336,11 @@ vmbus_event_proc(struct vmbus_softc *sc,
{
hv_vmbus_synic_event_flags *event;
- event = hv_vmbus_g_context.syn_ic_event_page[cpu] +
- HV_VMBUS_MESSAGE_SINT;
-
/*
* On Host with Win8 or above, the event page can be checked directly
* to get the id of the channel that has the pending interrupt.
*/
+ event = VMBUS_SC_PCPU_GET(sc, event_flag, cpu) + HV_VMBUS_MESSAGE_SINT;
vmbus_event_flags_proc(event->flagsul,
VMBUS_SC_PCPU_GET(sc, event_flag_cnt, cpu));
}
@@ -352,9 +350,7 @@ vmbus_event_proc_compat(struct vmbus_sof
{
hv_vmbus_synic_event_flags *event;
- event = hv_vmbus_g_context.syn_ic_event_page[cpu] +
- HV_VMBUS_MESSAGE_SINT;
-
+ event = VMBUS_SC_PCPU_GET(sc, event_flag, cpu) + HV_VMBUS_MESSAGE_SINT;
if (atomic_testandclear_int(&event->flags32[0], 0)) {
vmbus_event_flags_proc(
hv_vmbus_g_connection.recv_interrupt_page,
Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c Thu Jun 23 05:41:46 2016 (r302117)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c Thu Jun 23 05:51:57 2016 (r302118)
@@ -69,18 +69,16 @@ __FBSDID("$FreeBSD$");
struct vmbus_softc *vmbus_sc;
static int vmbus_inited;
-static hv_setup_args setup_args; /* only CPU 0 supported at this time */
static char *vmbus_ids[] = { "VMBUS", NULL };
static void
-vmbus_msg_task(void *arg __unused, int pending __unused)
+vmbus_msg_task(void *xsc, int pending __unused)
{
+ struct vmbus_softc *sc = xsc;
hv_vmbus_message *msg;
- msg = hv_vmbus_g_context.syn_ic_msg_page[curcpu] +
- HV_VMBUS_MESSAGE_SINT;
-
+ msg = VMBUS_SC_PCPU_GET(sc, message, curcpu) + HV_VMBUS_MESSAGE_SINT;
for (;;) {
const hv_vmbus_channel_msg_table_entry *entry;
hv_vmbus_channel_msg_header *hdr;
@@ -143,7 +141,7 @@ hv_vmbus_isr(struct vmbus_softc *sc, str
sc->vmbus_event_proc(sc, cpu);
/* Check if there are actual msgs to be process */
- msg_base = hv_vmbus_g_context.syn_ic_msg_page[cpu];
+ msg_base = VMBUS_SC_PCPU_GET(sc, message, cpu);
msg = msg_base + HV_VMBUS_TIMER_SINT;
/* we call eventtimer process the message */
@@ -209,7 +207,7 @@ hv_vector_handler(struct trapframe *trap
}
static void
-vmbus_synic_setup(void *arg)
+vmbus_synic_setup(void *arg __unused)
{
struct vmbus_softc *sc = vmbus_get_softc();
int cpu;
@@ -219,7 +217,6 @@ vmbus_synic_setup(void *arg)
hv_vmbus_synic_scontrol sctrl;
hv_vmbus_synic_sint shared_sint;
uint64_t version;
- hv_setup_args* setup_args = (hv_setup_args *)arg;
cpu = PCPU_GET(cpuid);
@@ -228,19 +225,13 @@ vmbus_synic_setup(void *arg)
*/
version = rdmsr(HV_X64_MSR_SVERSION);
- hv_vmbus_g_context.syn_ic_msg_page[cpu] =
- setup_args->page_buffers[2 * cpu];
- hv_vmbus_g_context.syn_ic_event_page[cpu] =
- setup_args->page_buffers[2 * cpu + 1];
-
/*
* Setup the Synic's message page
*/
-
simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
simp.u.simp_enabled = 1;
- simp.u.base_simp_gpa = ((hv_get_phys_addr(
- hv_vmbus_g_context.syn_ic_msg_page[cpu])) >> PAGE_SHIFT);
+ simp.u.base_simp_gpa =
+ VMBUS_SC_PCPU_GET(sc, message_dma.hv_paddr, cpu) >> PAGE_SHIFT;
wrmsr(HV_X64_MSR_SIMP, simp.as_uint64_t);
@@ -249,8 +240,8 @@ vmbus_synic_setup(void *arg)
*/
siefp.as_uint64_t = rdmsr(HV_X64_MSR_SIEFP);
siefp.u.siefp_enabled = 1;
- siefp.u.base_siefp_gpa = ((hv_get_phys_addr(
- hv_vmbus_g_context.syn_ic_event_page[cpu])) >> PAGE_SHIFT);
+ siefp.u.base_siefp_gpa =
+ VMBUS_SC_PCPU_GET(sc, event_flag_dma.hv_paddr, cpu) >> PAGE_SHIFT;
wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
@@ -328,6 +319,47 @@ vmbus_synic_teardown(void *arg)
wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
}
+static void
+vmbus_dma_alloc(struct vmbus_softc *sc)
+{
+ int cpu;
+
+ CPU_FOREACH(cpu) {
+ /*
+ * Per-cpu messages and event flags.
+ */
+ VMBUS_SC_PCPU_GET(sc, message, cpu) = hyperv_dmamem_alloc(
+ bus_get_dma_tag(sc->vmbus_dev), PAGE_SIZE, 0, PAGE_SIZE,
+ VMBUS_SC_PCPU_PTR(sc, message_dma, cpu),
+ BUS_DMA_WAITOK | BUS_DMA_ZERO);
+ VMBUS_SC_PCPU_GET(sc, event_flag, cpu) = hyperv_dmamem_alloc(
+ bus_get_dma_tag(sc->vmbus_dev), PAGE_SIZE, 0, PAGE_SIZE,
+ VMBUS_SC_PCPU_PTR(sc, event_flag_dma, cpu),
+ BUS_DMA_WAITOK | BUS_DMA_ZERO);
+ }
+}
+
+static void
+vmbus_dma_free(struct vmbus_softc *sc)
+{
+ int cpu;
+
+ CPU_FOREACH(cpu) {
+ if (VMBUS_SC_PCPU_GET(sc, message, cpu) != NULL) {
+ hyperv_dmamem_free(
+ VMBUS_SC_PCPU_PTR(sc, message_dma, cpu),
+ VMBUS_SC_PCPU_GET(sc, message, cpu));
+ VMBUS_SC_PCPU_GET(sc, message, cpu) = NULL;
+ }
+ if (VMBUS_SC_PCPU_GET(sc, event_flag, cpu) != NULL) {
+ hyperv_dmamem_free(
+ VMBUS_SC_PCPU_PTR(sc, event_flag_dma, cpu),
+ VMBUS_SC_PCPU_GET(sc, event_flag, cpu));
+ VMBUS_SC_PCPU_GET(sc, event_flag, cpu) = NULL;
+ }
+ }
+}
+
static int
vmbus_read_ivar(
device_t dev,
@@ -560,7 +592,7 @@ static int
vmbus_bus_init(void)
{
struct vmbus_softc *sc;
- int i, n, ret, cpu;
+ int ret, cpu;
char buf[MAXCOMLEN + 1];
cpuset_t cpu_mask;
@@ -587,9 +619,6 @@ vmbus_bus_init(void)
CPU_FOREACH(cpu) {
snprintf(buf, sizeof(buf), "cpu%d:hyperv", cpu);
intrcnt_add(buf, VMBUS_SC_PCPU_PTR(sc, intr_cnt, cpu));
-
- for (i = 0; i < 2; i++)
- setup_args.page_buffers[2 * cpu + i] = NULL;
}
/*
@@ -623,9 +652,9 @@ vmbus_bus_init(void)
"hyperv msg", M_WAITOK, taskqueue_thread_enqueue,
&hv_vmbus_g_context.hv_msg_tq[cpu]);
taskqueue_start_threads(&hv_vmbus_g_context.hv_msg_tq[cpu], 1,
- PI_NET, "hvmsg%d", cpu);
+ PI_NET, "hvmsg%d", cpu);
TASK_INIT(&hv_vmbus_g_context.hv_msg_task[cpu], 0,
- vmbus_msg_task, NULL);
+ vmbus_msg_task, sc);
CPU_SETOF(cpu, &cpu_mask);
TASK_INIT(&cpuset_task, 0, vmbus_cpuset_setthread_task,
@@ -634,22 +663,17 @@ vmbus_bus_init(void)
&cpuset_task);
taskqueue_drain(hv_vmbus_g_context.hv_msg_tq[cpu],
&cpuset_task);
-
- /*
- * Prepare the per cpu msg and event pages to be called on
- * each cpu.
- */
- for(i = 0; i < 2; i++) {
- setup_args.page_buffers[2 * cpu + i] =
- malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO);
- }
}
+ /*
+ * Allocate vmbus DMA stuffs.
+ */
+ vmbus_dma_alloc(sc);
+
if (bootverbose)
printf("VMBUS: Calling smp_rendezvous, smp_started = %d\n",
smp_started);
-
- smp_rendezvous(NULL, vmbus_synic_setup, NULL, &setup_args);
+ smp_rendezvous(NULL, vmbus_synic_setup, NULL, NULL);
/*
* Connect to VMBus in the root partition
@@ -673,13 +697,8 @@ vmbus_bus_init(void)
return (ret);
- cleanup1:
- /*
- * Free pages alloc'ed
- */
- for (n = 0; n < 2 * MAXCPU; n++)
- if (setup_args.page_buffers[n] != NULL)
- free(setup_args.page_buffers[n], M_DEVBUF);
+cleanup1:
+ vmbus_dma_free(sc);
/*
* remove swi and vmbus callback vector;
@@ -755,10 +774,7 @@ vmbus_detach(device_t dev)
smp_rendezvous(NULL, vmbus_synic_teardown, NULL, NULL);
- for(i = 0; i < 2 * MAXCPU; i++) {
- if (setup_args.page_buffers[i] != NULL)
- free(setup_args.page_buffers[i], M_DEVBUF);
- }
+ vmbus_dma_free(sc);
/* remove swi */
CPU_FOREACH(i) {
Modified: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Thu Jun 23 05:41:46 2016 (r302117)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h Thu Jun 23 05:51:57 2016 (r302118)
@@ -203,8 +203,6 @@ union vmbus_event_flags;
typedef struct {
hv_bool_uint8_t syn_ic_initialized;
- struct vmbus_message *syn_ic_msg_page[MAXCPU];
- union vmbus_event_flags *syn_ic_event_page[MAXCPU];
/*
* For FreeBSD cpuid to Hyper-V vcpuid mapping.
*/
@@ -755,8 +753,4 @@ void hv_et_intr(struct trapframe*);
/* Wait for device creation */
void vmbus_scan(void);
-typedef struct {
- void *page_buffers[2 * MAXCPU];
-} hv_setup_args;
-
#endif /* __HYPERV_PRIV_H__ */
Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Thu Jun 23 05:41:46 2016 (r302117)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h Thu Jun 23 05:51:57 2016 (r302118)
@@ -30,10 +30,18 @@
#define _VMBUS_VAR_H_
#include <sys/param.h>
+#include <sys/bus_dma.h>
+#include <dev/hyperv/include/hyperv_busdma.h>
struct vmbus_pcpu_data {
- int event_flag_cnt; /* # of event flags */
- u_long *intr_cnt;
+ u_long *intr_cnt; /* Hyper-V interrupt counter */
+ struct vmbus_message *message; /* shared messages */
+ int event_flag_cnt; /* # of event flags */
+ union vmbus_event_flags *event_flag; /* shared event flags */
+
+ /* Rarely used fields */
+ struct hyperv_dma message_dma; /* busdma glue */
+ struct hyperv_dma event_flag_dma; /* busdma glue */
} __aligned(CACHE_LINE_SIZE);
struct vmbus_softc {
More information about the svn-src-all
mailing list