diff options
author | sephe <sephe@FreeBSD.org> | 2016-06-23 06:27:41 +0000 |
---|---|---|
committer | sephe <sephe@FreeBSD.org> | 2016-06-23 06:27:41 +0000 |
commit | 158b68ec4ae4e27cc63062f6822daefe4e21f31d (patch) | |
tree | bf4657b1b9c8283864f9385b33c9c79802de4bed | |
parent | 64ff0fd8364005e63beb54c0a7df8238b75a2fef (diff) | |
download | FreeBSD-src-158b68ec4ae4e27cc63062f6822daefe4e21f31d.zip FreeBSD-src-158b68ec4ae4e27cc63062f6822daefe4e21f31d.tar.gz |
MFC 300576,300644
300576
hyperv/vmbus: Free message taskqueue during interrupt teardown
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D6506
300644
hyperv/vmbus: Check hyperv_dmamem_alloc return value
Though it is highly unlikely this function would fail w/ BUS_DMA_WAITOK,
we had better to check its return value; better safe then sorry here.
MFC after: 1 week
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D6518
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c index 9e8b204..fd1adc3 100644 --- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c +++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c @@ -321,24 +321,34 @@ vmbus_synic_teardown(void *arg) wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t); } -static void +static int vmbus_dma_alloc(struct vmbus_softc *sc) { int cpu; CPU_FOREACH(cpu) { + void *ptr; + /* * Per-cpu messages and event flags. */ - VMBUS_PCPU_GET(sc, message, cpu) = hyperv_dmamem_alloc( - bus_get_dma_tag(sc->vmbus_dev), PAGE_SIZE, 0, PAGE_SIZE, + ptr = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), + PAGE_SIZE, 0, PAGE_SIZE, VMBUS_PCPU_PTR(sc, message_dma, cpu), BUS_DMA_WAITOK | BUS_DMA_ZERO); - VMBUS_PCPU_GET(sc, event_flag, cpu) = hyperv_dmamem_alloc( - bus_get_dma_tag(sc->vmbus_dev), PAGE_SIZE, 0, PAGE_SIZE, + if (ptr == NULL) + return ENOMEM; + VMBUS_PCPU_GET(sc, message, cpu) = ptr; + + ptr = hyperv_dmamem_alloc(bus_get_dma_tag(sc->vmbus_dev), + PAGE_SIZE, 0, PAGE_SIZE, VMBUS_PCPU_PTR(sc, event_flag_dma, cpu), BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (ptr == NULL) + return ENOMEM; + VMBUS_PCPU_GET(sc, event_flag, cpu) = ptr; } + return 0; } static void @@ -517,6 +527,12 @@ vmbus_intr_teardown(struct vmbus_softc *sc) taskqueue_free(hv_vmbus_g_context.hv_event_queue[cpu]); hv_vmbus_g_context.hv_event_queue[cpu] = NULL; } + if (hv_vmbus_g_context.hv_msg_tq[cpu] != NULL) { + taskqueue_drain(hv_vmbus_g_context.hv_msg_tq[cpu], + &hv_vmbus_g_context.hv_msg_task[cpu]); + taskqueue_free(hv_vmbus_g_context.hv_msg_tq[cpu]); + hv_vmbus_g_context.hv_msg_tq[cpu] = NULL; + } } vmbus_vector_free(sc->vmbus_idtvec); } @@ -699,7 +715,9 @@ vmbus_bus_init(void) /* * Allocate DMA stuffs. */ - vmbus_dma_alloc(sc); + ret = vmbus_dma_alloc(sc); + if (ret != 0) + goto cleanup; if (bootverbose) printf("VMBUS: Calling smp_rendezvous, smp_started = %d\n", |