Index: head/sys/dev/hyperv/vmbus/hv_channel.c =================================================================== --- head/sys/dev/hyperv/vmbus/hv_channel.c +++ head/sys/dev/hyperv/vmbus/hv_channel.c @@ -202,7 +202,8 @@ vmbus_on_channel_open(new_channel); - new_channel->rxq = hv_vmbus_g_context.hv_event_queue[new_channel->target_cpu]; + new_channel->rxq = VMBUS_PCPU_GET(vmbus_get_softc(), event_tq, + new_channel->target_cpu); TASK_INIT(&new_channel->channel_task, 0, VmbusProcessChannelEvent, new_channel); /* Allocate the ring buffer */ Index: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c =================================================================== --- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c +++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c @@ -177,8 +177,8 @@ msg = msg_base + HV_VMBUS_MESSAGE_SINT; if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) { - taskqueue_enqueue(hv_vmbus_g_context.hv_msg_tq[cpu], - &hv_vmbus_g_context.hv_msg_task[cpu]); + taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu), + VMBUS_PCPU_PTR(sc, message_task, cpu)); } return (FILTER_HANDLED); @@ -389,26 +389,25 @@ * Setup taskqueue to handle events. Task will be per- * channel. */ - hv_vmbus_g_context.hv_event_queue[cpu] = - taskqueue_create_fast("hyperv event", M_WAITOK, - taskqueue_thread_enqueue, - &hv_vmbus_g_context.hv_event_queue[cpu]); + VMBUS_PCPU_GET(sc, event_tq, cpu) = taskqueue_create_fast( + "hyperv event", M_WAITOK, taskqueue_thread_enqueue, + VMBUS_PCPU_PTR(sc, event_tq, cpu)); CPU_SETOF(cpu, &cpu_mask); taskqueue_start_threads_cpuset( - &hv_vmbus_g_context.hv_event_queue[cpu], 1, PI_NET, - &cpu_mask, "hvevent%d", cpu); + VMBUS_PCPU_PTR(sc, event_tq, cpu), 1, PI_NET, &cpu_mask, + "hvevent%d", cpu); /* * Setup tasks and taskqueues to handle messages. */ - hv_vmbus_g_context.hv_msg_tq[cpu] = taskqueue_create_fast( + VMBUS_PCPU_GET(sc, message_tq, cpu) = taskqueue_create_fast( "hyperv msg", M_WAITOK, taskqueue_thread_enqueue, - &hv_vmbus_g_context.hv_msg_tq[cpu]); + VMBUS_PCPU_PTR(sc, message_tq, cpu)); CPU_SETOF(cpu, &cpu_mask); taskqueue_start_threads_cpuset( - &hv_vmbus_g_context.hv_msg_tq[cpu], 1, PI_NET, - &cpu_mask, "hvmsg%d", cpu); - TASK_INIT(&hv_vmbus_g_context.hv_msg_task[cpu], 0, + VMBUS_PCPU_PTR(sc, message_tq, cpu), 1, PI_NET, &cpu_mask, + "hvmsg%d", cpu); + TASK_INIT(VMBUS_PCPU_PTR(sc, message_task, cpu), 0, vmbus_msg_task, sc); } @@ -439,15 +438,15 @@ } CPU_FOREACH(cpu) { - if (hv_vmbus_g_context.hv_event_queue[cpu] != NULL) { - taskqueue_free(hv_vmbus_g_context.hv_event_queue[cpu]); - hv_vmbus_g_context.hv_event_queue[cpu] = NULL; + if (VMBUS_PCPU_GET(sc, event_tq, cpu) != NULL) { + taskqueue_free(VMBUS_PCPU_GET(sc, event_tq, cpu)); + VMBUS_PCPU_GET(sc, event_tq, 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; + if (VMBUS_PCPU_GET(sc, message_tq, cpu) != NULL) { + taskqueue_drain(VMBUS_PCPU_GET(sc, message_tq, cpu), + VMBUS_PCPU_PTR(sc, message_task, cpu)); + taskqueue_free(VMBUS_PCPU_GET(sc, message_tq, cpu)); + VMBUS_PCPU_GET(sc, message_tq, cpu) = NULL; } } } Index: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h =================================================================== --- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h +++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h @@ -207,13 +207,6 @@ * For FreeBSD cpuid to Hyper-V vcpuid mapping. */ uint32_t hv_vcpu_index[MAXCPU]; - /* - * Each cpu has its own software interrupt handler for channel - * event and msg handling. - */ - struct taskqueue *hv_event_queue[MAXCPU]; - struct taskqueue *hv_msg_tq[MAXCPU]; - struct task hv_msg_task[MAXCPU]; } hv_vmbus_context; /* Index: head/sys/dev/hyperv/vmbus/vmbus_var.h =================================================================== --- head/sys/dev/hyperv/vmbus/vmbus_var.h +++ head/sys/dev/hyperv/vmbus/vmbus_var.h @@ -42,11 +42,16 @@ /* Rarely used fields */ struct hyperv_dma message_dma; /* busdma glue */ struct hyperv_dma event_flag_dma; /* busdma glue */ + struct taskqueue *event_tq; /* event taskq */ + struct taskqueue *message_tq; /* message taskq */ + struct task message_task; /* message task */ } __aligned(CACHE_LINE_SIZE); struct vmbus_softc { void (*vmbus_event_proc)(struct vmbus_softc *, int); struct vmbus_pcpu_data vmbus_pcpu[MAXCPU]; + + /* Rarely used fields */ device_t vmbus_dev; int vmbus_idtvec; };