Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133162933
D4920.id12384.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D4920.id12384.diff
View Options
Index: sys/dev/hyperv/include/hyperv.h
===================================================================
--- sys/dev/hyperv/include/hyperv.h
+++ sys/dev/hyperv/include/hyperv.h
@@ -755,6 +755,8 @@
struct mtx inbound_lock;
+ struct taskqueue * rxq;
+ struct task channel_task;
hv_vmbus_pfn_channel_callback on_channel_callback;
void* channel_callback_context;
Index: sys/dev/hyperv/vmbus/hv_channel.c
===================================================================
--- sys/dev/hyperv/vmbus/hv_channel.c
+++ sys/dev/hyperv/vmbus/hv_channel.c
@@ -114,6 +114,9 @@
new_channel->on_channel_callback = pfn_on_channel_callback;
new_channel->channel_callback_context = context;
+ new_channel->rxq = hv_vmbus_g_context.hv_event_queue[new_channel->target_cpu];
+ TASK_INIT(&new_channel->channel_task, 0, VmbusProcessChannelEvent, new_channel);
+
/* Allocate the ring buffer */
out = contigmalloc((send_ring_buffer_size + recv_ring_buffer_size),
M_DEVBUF, M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
@@ -517,6 +520,7 @@
hv_vmbus_channel_close_internal(hv_vmbus_channel *channel)
{
int ret = 0;
+ struct taskqueue *rxq = channel->rxq;
hv_vmbus_channel_close_channel* msg;
hv_vmbus_channel_msg_info* info;
@@ -524,6 +528,11 @@
channel->sc_creation_callback = NULL;
/*
+ * set rxq to NULL to avoid more requests be scheduled
+ */
+ channel->rxq = NULL;
+ taskqueue_drain(rxq, &channel->channel_task);
+ /*
* Grab the lock to prevent race condition when a packet received
* and unloading driver is in the process.
*/
Index: sys/dev/hyperv/vmbus/hv_connection.c
===================================================================
--- sys/dev/hyperv/vmbus/hv_connection.c
+++ sys/dev/hyperv/vmbus/hv_connection.c
@@ -345,12 +345,12 @@
/**
* Process a channel event notification
*/
-static void
-VmbusProcessChannelEvent(uint32_t relid)
+void
+VmbusProcessChannelEvent(void* context, int pending)
{
void* arg;
uint32_t bytes_to_read;
- hv_vmbus_channel* channel;
+ hv_vmbus_channel* channel = (hv_vmbus_channel*)context;
boolean_t is_batched_reading;
/**
@@ -358,8 +358,6 @@
* the channel callback to process the event
*/
- channel = hv_vmbus_g_connection.channels[relid];
-
if (channel == NULL) {
return;
}
@@ -411,10 +409,9 @@
* Handler for events
*/
void
-hv_vmbus_on_events(void *arg)
+hv_vmbus_on_events(int cpu)
{
int bit;
- int cpu;
int dword;
void *page_addr;
uint32_t* recv_interrupt_page = NULL;
@@ -423,7 +420,6 @@
hv_vmbus_synic_event_flags *event;
/* int maxdword = PAGE_SIZE >> 3; */
- cpu = (int)(long)arg;
KASSERT(cpu <= mp_maxid, ("VMBUS: hv_vmbus_on_events: "
"cpu out of range!"));
@@ -465,8 +461,14 @@
*/
continue;
} else {
- VmbusProcessChannelEvent(rel_id);
-
+ hv_vmbus_channel * channel = hv_vmbus_g_connection.channels[rel_id];
+ /* if channel is closed or closing */
+ if (channel == NULL || channel->rxq == NULL)
+ continue;
+
+ if (channel->batched_reading)
+ hv_ring_buffer_read_begin(&channel->inbound);
+ taskqueue_enqueue_fast(channel->rxq, &channel->channel_task);
}
}
}
Index: sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
===================================================================
--- sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
+++ sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
@@ -177,7 +177,7 @@
(hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) {
/* Since we are a child, we only need to check bit 0 */
if (synch_test_and_clear_bit(0, &event->flags32[0])) {
- swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0);
+ hv_vmbus_on_events(cpu);
}
} else {
/*
@@ -187,7 +187,7 @@
* Directly schedule the event software interrupt on
* current cpu.
*/
- swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0);
+ hv_vmbus_on_events(cpu);
}
/* Check if there are actual msgs to be process */
@@ -472,6 +472,7 @@
{
int i, j, n, ret;
char buf[MAXCOMLEN + 1];
+ cpuset_t cpu_mask;
if (vmbus_inited)
return (0);
@@ -508,9 +509,7 @@
setup_args.vector = hv_vmbus_g_context.hv_cb_vector;
CPU_FOREACH(j) {
- hv_vmbus_g_context.hv_event_intr_event[j] = NULL;
hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
- hv_vmbus_g_context.event_swintr[j] = NULL;
hv_vmbus_g_context.msg_swintr[j] = NULL;
snprintf(buf, sizeof(buf), "cpu%d:hyperv", j);
@@ -525,6 +524,20 @@
*/
CPU_FOREACH(j) {
/*
+ * Setup taskqueue to handle events
+ */
+ hv_vmbus_g_context.hv_event_queue[j] = taskqueue_create_fast("hyperv event", M_WAITOK,
+ taskqueue_thread_enqueue, &hv_vmbus_g_context.hv_event_queue[j]);
+ if (hv_vmbus_g_context.hv_event_queue[j] == NULL) {
+ if (bootverbose)
+ printf("VMBUS: failed to setup taskqueue\n");
+ goto cleanup1;
+ }
+ CPU_SETOF(j, &cpu_mask);
+ taskqueue_start_threads_cpuset(&hv_vmbus_g_context.hv_event_queue[j], 1, PI_NET, &cpu_mask,
+ "hvevent%d", j);
+
+ /*
* Setup software interrupt thread and handler for msg handling.
*/
ret = swi_add(&hv_vmbus_g_context.hv_msg_intr_event[j],
@@ -542,7 +555,7 @@
*/
ret = intr_event_bind(hv_vmbus_g_context.hv_msg_intr_event[j],
j);
- if (ret) {
+ if (ret) {
if(bootverbose)
printf("VMBUS: failed to bind msg swi thread "
"to cpu %d\n", j);
@@ -550,20 +563,6 @@
}
/*
- * Setup software interrupt thread and handler for
- * event handling.
- */
- ret = swi_add(&hv_vmbus_g_context.hv_event_intr_event[j],
- "hv_event", hv_vmbus_on_events, (void *)(long)j,
- SWI_CLOCK, 0, &hv_vmbus_g_context.event_swintr[j]);
- if (ret) {
- if(bootverbose)
- printf("VMBUS: failed to setup event swi for "
- "cpu %d\n", j);
- goto cleanup1;
- }
-
- /*
* Prepare the per cpu msg and event pages to be called on each cpu.
*/
for(i = 0; i < 2; i++) {
@@ -606,12 +605,11 @@
* remove swi and vmbus callback vector;
*/
CPU_FOREACH(j) {
+ if (hv_vmbus_g_context.hv_event_queue[j] != NULL)
+ taskqueue_free(hv_vmbus_g_context.hv_event_queue[j]);
if (hv_vmbus_g_context.msg_swintr[j] != NULL)
swi_remove(hv_vmbus_g_context.msg_swintr[j]);
- if (hv_vmbus_g_context.event_swintr[j] != NULL)
- swi_remove(hv_vmbus_g_context.event_swintr[j]);
hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
- hv_vmbus_g_context.hv_event_intr_event[j] = NULL;
}
vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
@@ -676,12 +674,11 @@
/* remove swi */
CPU_FOREACH(i) {
+ if (hv_vmbus_g_context.hv_event_queue[i] != NULL)
+ taskqueue_free(hv_vmbus_g_context.hv_event_queue[i]);
if (hv_vmbus_g_context.msg_swintr[i] != NULL)
swi_remove(hv_vmbus_g_context.msg_swintr[i]);
- if (hv_vmbus_g_context.event_swintr[i] != NULL)
- swi_remove(hv_vmbus_g_context.event_swintr[i]);
hv_vmbus_g_context.hv_msg_intr_event[i] = NULL;
- hv_vmbus_g_context.hv_event_intr_event[i] = NULL;
}
vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
Index: sys/dev/hyperv/vmbus/hv_vmbus_priv.h
===================================================================
--- sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -202,9 +202,8 @@
* Each cpu has its own software interrupt handler for channel
* event and msg handling.
*/
- struct intr_event *hv_event_intr_event[MAXCPU];
+ struct taskqueue *hv_event_queue[MAXCPU];
struct intr_event *hv_msg_intr_event[MAXCPU];
- void *event_swintr[MAXCPU];
void *msg_swintr[MAXCPU];
/*
* Host use this vector to intrrupt guest for vmbus channel
@@ -717,7 +716,8 @@
int hv_vmbus_disconnect(void);
int hv_vmbus_post_message(void *buffer, size_t buf_size);
int hv_vmbus_set_event(hv_vmbus_channel *channel);
-void hv_vmbus_on_events(void *);
+void hv_vmbus_on_events(int cpu);
+void VmbusProcessChannelEvent(void* channel, int pending);
/**
* Event Timer interfaces
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 24, 1:28 PM (12 h, 57 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24114160
Default Alt Text
D4920.id12384.diff (7 KB)
Attached To
Mode
D4920: Hyperv: Event handling code refactor.
Attached
Detach File
Event Timeline
Log In to Comment