vmbus.c (293874) | vmbus.c (294886) |
---|---|
1/*- 2 * Copyright (c) 2009-2012 Microsoft Corp. 3 * Copyright (c) 2012 NetApp Inc. 4 * Copyright (c) 2012 Citrix Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 16 unchanged lines hidden (view full) --- 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * VM Bus Driver Implementation 31 */ 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009-2012 Microsoft Corp. 3 * Copyright (c) 2012 NetApp Inc. 4 * Copyright (c) 2012 Citrix Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 16 unchanged lines hidden (view full) --- 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * VM Bus Driver Implementation 31 */ 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c 293874 2016-01-14 03:11:35Z sephe $"); | 33__FBSDID("$FreeBSD: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c 294886 2016-01-27 03:53:30Z sephe $"); |
34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/kernel.h> 38#include <sys/lock.h> 39#include <sys/malloc.h> 40#include <sys/module.h> 41#include <sys/proc.h> --- 130 unchanged lines hidden (view full) --- 172 page_addr = hv_vmbus_g_context.syn_ic_event_page[cpu]; 173 event = (hv_vmbus_synic_event_flags*) 174 page_addr + HV_VMBUS_MESSAGE_SINT; 175 176 if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) || 177 (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) { 178 /* Since we are a child, we only need to check bit 0 */ 179 if (synch_test_and_clear_bit(0, &event->flags32[0])) { | 34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/kernel.h> 38#include <sys/lock.h> 39#include <sys/malloc.h> 40#include <sys/module.h> 41#include <sys/proc.h> --- 130 unchanged lines hidden (view full) --- 172 page_addr = hv_vmbus_g_context.syn_ic_event_page[cpu]; 173 event = (hv_vmbus_synic_event_flags*) 174 page_addr + HV_VMBUS_MESSAGE_SINT; 175 176 if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) || 177 (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) { 178 /* Since we are a child, we only need to check bit 0 */ 179 if (synch_test_and_clear_bit(0, &event->flags32[0])) { |
180 swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0); | 180 hv_vmbus_on_events(cpu); |
181 } 182 } else { 183 /* 184 * On host with Win8 or above, we can directly look at 185 * the event page. If bit n is set, we have an interrupt 186 * on the channel with id n. 187 * Directly schedule the event software interrupt on 188 * current cpu. 189 */ | 181 } 182 } else { 183 /* 184 * On host with Win8 or above, we can directly look at 185 * the event page. If bit n is set, we have an interrupt 186 * on the channel with id n. 187 * Directly schedule the event software interrupt on 188 * current cpu. 189 */ |
190 swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0); | 190 hv_vmbus_on_events(cpu); |
191 } 192 193 /* Check if there are actual msgs to be process */ 194 page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu]; 195 msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT; 196 197 /* we call eventtimer process the message */ 198 if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) { --- 21 unchanged lines hidden (view full) --- 220 221 if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) { 222 swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0); 223 } 224 225 return (FILTER_HANDLED); 226} 227 | 191 } 192 193 /* Check if there are actual msgs to be process */ 194 page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu]; 195 msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT; 196 197 /* we call eventtimer process the message */ 198 if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) { --- 21 unchanged lines hidden (view full) --- 220 221 if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) { 222 swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0); 223 } 224 225 return (FILTER_HANDLED); 226} 227 |
228uint32_t hv_vmbus_swintr_event_cpu[MAXCPU]; | |
229u_long *hv_vmbus_intr_cpu[MAXCPU]; 230 231void 232hv_vector_handler(struct trapframe *trap_frame) 233{ 234 int cpu; 235 236 /* --- 230 unchanged lines hidden (view full) --- 467 * - setup the vmbus root device 468 * - retrieve the channel offers 469 */ 470static int 471vmbus_bus_init(void) 472{ 473 int i, j, n, ret; 474 char buf[MAXCOMLEN + 1]; | 228u_long *hv_vmbus_intr_cpu[MAXCPU]; 229 230void 231hv_vector_handler(struct trapframe *trap_frame) 232{ 233 int cpu; 234 235 /* --- 230 unchanged lines hidden (view full) --- 466 * - setup the vmbus root device 467 * - retrieve the channel offers 468 */ 469static int 470vmbus_bus_init(void) 471{ 472 int i, j, n, ret; 473 char buf[MAXCOMLEN + 1]; |
474 cpuset_t cpu_mask; |
|
475 476 if (vmbus_inited) 477 return (0); 478 479 vmbus_inited = 1; 480 481 ret = hv_vmbus_init(); 482 --- 20 unchanged lines hidden (view full) --- 503 hv_vmbus_g_context.hv_cb_vector); 504 505 /* 506 * Notify the hypervisor of our vector. 507 */ 508 setup_args.vector = hv_vmbus_g_context.hv_cb_vector; 509 510 CPU_FOREACH(j) { | 475 476 if (vmbus_inited) 477 return (0); 478 479 vmbus_inited = 1; 480 481 ret = hv_vmbus_init(); 482 --- 20 unchanged lines hidden (view full) --- 503 hv_vmbus_g_context.hv_cb_vector); 504 505 /* 506 * Notify the hypervisor of our vector. 507 */ 508 setup_args.vector = hv_vmbus_g_context.hv_cb_vector; 509 510 CPU_FOREACH(j) { |
511 hv_vmbus_swintr_event_cpu[j] = 0; 512 hv_vmbus_g_context.hv_event_intr_event[j] = NULL; | |
513 hv_vmbus_g_context.hv_msg_intr_event[j] = NULL; | 511 hv_vmbus_g_context.hv_msg_intr_event[j] = NULL; |
514 hv_vmbus_g_context.event_swintr[j] = NULL; | |
515 hv_vmbus_g_context.msg_swintr[j] = NULL; 516 517 snprintf(buf, sizeof(buf), "cpu%d:hyperv", j); 518 intrcnt_add(buf, &hv_vmbus_intr_cpu[j]); 519 520 for (i = 0; i < 2; i++) 521 setup_args.page_buffers[2 * j + i] = NULL; 522 } 523 524 /* 525 * Per cpu setup. 526 */ 527 CPU_FOREACH(j) { 528 /* | 512 hv_vmbus_g_context.msg_swintr[j] = NULL; 513 514 snprintf(buf, sizeof(buf), "cpu%d:hyperv", j); 515 intrcnt_add(buf, &hv_vmbus_intr_cpu[j]); 516 517 for (i = 0; i < 2; i++) 518 setup_args.page_buffers[2 * j + i] = NULL; 519 } 520 521 /* 522 * Per cpu setup. 523 */ 524 CPU_FOREACH(j) { 525 /* |
526 * Setup taskqueue to handle events 527 */ 528 hv_vmbus_g_context.hv_event_queue[j] = taskqueue_create_fast("hyperv event", M_WAITOK, 529 taskqueue_thread_enqueue, &hv_vmbus_g_context.hv_event_queue[j]); 530 if (hv_vmbus_g_context.hv_event_queue[j] == NULL) { 531 if (bootverbose) 532 printf("VMBUS: failed to setup taskqueue\n"); 533 goto cleanup1; 534 } 535 CPU_SETOF(j, &cpu_mask); 536 taskqueue_start_threads_cpuset(&hv_vmbus_g_context.hv_event_queue[j], 1, PI_NET, &cpu_mask, 537 "hvevent%d", j); 538 539 /* |
|
529 * Setup software interrupt thread and handler for msg handling. 530 */ 531 ret = swi_add(&hv_vmbus_g_context.hv_msg_intr_event[j], 532 "hv_msg", vmbus_msg_swintr, (void *)(long)j, SWI_CLOCK, 0, 533 &hv_vmbus_g_context.msg_swintr[j]); 534 if (ret) { 535 if(bootverbose) 536 printf("VMBUS: failed to setup msg swi for " 537 "cpu %d\n", j); 538 goto cleanup1; 539 } 540 541 /* 542 * Bind the swi thread to the cpu. 543 */ 544 ret = intr_event_bind(hv_vmbus_g_context.hv_msg_intr_event[j], 545 j); | 540 * Setup software interrupt thread and handler for msg handling. 541 */ 542 ret = swi_add(&hv_vmbus_g_context.hv_msg_intr_event[j], 543 "hv_msg", vmbus_msg_swintr, (void *)(long)j, SWI_CLOCK, 0, 544 &hv_vmbus_g_context.msg_swintr[j]); 545 if (ret) { 546 if(bootverbose) 547 printf("VMBUS: failed to setup msg swi for " 548 "cpu %d\n", j); 549 goto cleanup1; 550 } 551 552 /* 553 * Bind the swi thread to the cpu. 554 */ 555 ret = intr_event_bind(hv_vmbus_g_context.hv_msg_intr_event[j], 556 j); |
546 if (ret) { | 557 if (ret) { |
547 if(bootverbose) 548 printf("VMBUS: failed to bind msg swi thread " 549 "to cpu %d\n", j); 550 goto cleanup1; 551 } 552 553 /* | 558 if(bootverbose) 559 printf("VMBUS: failed to bind msg swi thread " 560 "to cpu %d\n", j); 561 goto cleanup1; 562 } 563 564 /* |
554 * Setup software interrupt thread and handler for 555 * event handling. 556 */ 557 ret = swi_add(&hv_vmbus_g_context.hv_event_intr_event[j], 558 "hv_event", hv_vmbus_on_events, (void *)(long)j, 559 SWI_CLOCK, 0, &hv_vmbus_g_context.event_swintr[j]); 560 if (ret) { 561 if(bootverbose) 562 printf("VMBUS: failed to setup event swi for " 563 "cpu %d\n", j); 564 goto cleanup1; 565 } 566 567 /* | |
568 * Prepare the per cpu msg and event pages to be called on each cpu. 569 */ 570 for(i = 0; i < 2; i++) { 571 setup_args.page_buffers[2 * j + i] = 572 malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO); 573 if (setup_args.page_buffers[2 * j + i] == NULL) { 574 KASSERT(setup_args.page_buffers[2 * j + i] != NULL, 575 ("Error VMBUS: malloc failed!")); --- 26 unchanged lines hidden (view full) --- 602 for (n = 0; n < 2 * MAXCPU; n++) 603 if (setup_args.page_buffers[n] != NULL) 604 free(setup_args.page_buffers[n], M_DEVBUF); 605 606 /* 607 * remove swi and vmbus callback vector; 608 */ 609 CPU_FOREACH(j) { | 565 * Prepare the per cpu msg and event pages to be called on each cpu. 566 */ 567 for(i = 0; i < 2; i++) { 568 setup_args.page_buffers[2 * j + i] = 569 malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO); 570 if (setup_args.page_buffers[2 * j + i] == NULL) { 571 KASSERT(setup_args.page_buffers[2 * j + i] != NULL, 572 ("Error VMBUS: malloc failed!")); --- 26 unchanged lines hidden (view full) --- 599 for (n = 0; n < 2 * MAXCPU; n++) 600 if (setup_args.page_buffers[n] != NULL) 601 free(setup_args.page_buffers[n], M_DEVBUF); 602 603 /* 604 * remove swi and vmbus callback vector; 605 */ 606 CPU_FOREACH(j) { |
607 if (hv_vmbus_g_context.hv_event_queue[j] != NULL) 608 taskqueue_free(hv_vmbus_g_context.hv_event_queue[j]); |
|
610 if (hv_vmbus_g_context.msg_swintr[j] != NULL) 611 swi_remove(hv_vmbus_g_context.msg_swintr[j]); | 609 if (hv_vmbus_g_context.msg_swintr[j] != NULL) 610 swi_remove(hv_vmbus_g_context.msg_swintr[j]); |
612 if (hv_vmbus_g_context.event_swintr[j] != NULL) 613 swi_remove(hv_vmbus_g_context.event_swintr[j]); | |
614 hv_vmbus_g_context.hv_msg_intr_event[j] = NULL; | 611 hv_vmbus_g_context.hv_msg_intr_event[j] = NULL; |
615 hv_vmbus_g_context.hv_event_intr_event[j] = NULL; | |
616 } 617 618 vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector); 619 620 cleanup: 621 hv_vmbus_cleanup(); 622 623 return (ret); --- 48 unchanged lines hidden (view full) --- 672 if (setup_args.page_buffers[i] != 0) 673 free(setup_args.page_buffers[i], M_DEVBUF); 674 } 675 676 hv_vmbus_cleanup(); 677 678 /* remove swi */ 679 CPU_FOREACH(i) { | 612 } 613 614 vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector); 615 616 cleanup: 617 hv_vmbus_cleanup(); 618 619 return (ret); --- 48 unchanged lines hidden (view full) --- 668 if (setup_args.page_buffers[i] != 0) 669 free(setup_args.page_buffers[i], M_DEVBUF); 670 } 671 672 hv_vmbus_cleanup(); 673 674 /* remove swi */ 675 CPU_FOREACH(i) { |
676 if (hv_vmbus_g_context.hv_event_queue[i] != NULL) 677 taskqueue_free(hv_vmbus_g_context.hv_event_queue[i]); |
|
680 if (hv_vmbus_g_context.msg_swintr[i] != NULL) 681 swi_remove(hv_vmbus_g_context.msg_swintr[i]); | 678 if (hv_vmbus_g_context.msg_swintr[i] != NULL) 679 swi_remove(hv_vmbus_g_context.msg_swintr[i]); |
682 if (hv_vmbus_g_context.event_swintr[i] != NULL) 683 swi_remove(hv_vmbus_g_context.event_swintr[i]); | |
684 hv_vmbus_g_context.hv_msg_intr_event[i] = NULL; | 680 hv_vmbus_g_context.hv_msg_intr_event[i] = NULL; |
685 hv_vmbus_g_context.hv_event_intr_event[i] = NULL; | |
686 } 687 688 vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector); 689 690 return; 691} 692 693static void --- 72 unchanged lines hidden --- | 681 } 682 683 vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector); 684 685 return; 686} 687 688static void --- 72 unchanged lines hidden --- |