summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv/vmbus/hv_connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/hyperv/vmbus/hv_connection.c')
-rw-r--r--sys/dev/hyperv/vmbus/hv_connection.c79
1 files changed, 9 insertions, 70 deletions
diff --git a/sys/dev/hyperv/vmbus/hv_connection.c b/sys/dev/hyperv/vmbus/hv_connection.c
index 97071cc..05b1612 100644
--- a/sys/dev/hyperv/vmbus/hv_connection.c
+++ b/sys/dev/hyperv/vmbus/hv_connection.c
@@ -335,78 +335,12 @@ hv_vmbus_disconnect(void) {
}
/**
- * Process a channel event notification
- */
-static void
-VmbusProcessChannelEvent(uint32_t relid)
-{
- void* arg;
- uint32_t bytes_to_read;
- hv_vmbus_channel* channel;
- boolean_t is_batched_reading;
-
- /**
- * Find the channel based on this relid and invokes
- * the channel callback to process the event
- */
-
- channel = hv_vmbus_g_connection.channels[relid];
-
- if (channel == NULL) {
- return;
- }
- /**
- * To deal with the race condition where we might
- * receive a packet while the relevant driver is
- * being unloaded, dispatch the callback while
- * holding the channel lock. The unloading driver
- * will acquire the same channel lock to set the
- * callback to NULL. This closes the window.
- */
-
- /*
- * Disable the lock due to newly added WITNESS check in r277723.
- * Will seek other way to avoid race condition.
- * -- whu
- */
- // mtx_lock(&channel->inbound_lock);
- if (channel->on_channel_callback != NULL) {
- arg = channel->channel_callback_context;
- is_batched_reading = channel->batched_reading;
- /*
- * Optimize host to guest signaling by ensuring:
- * 1. While reading the channel, we disable interrupts from
- * host.
- * 2. Ensure that we process all posted messages from the host
- * before returning from this callback.
- * 3. Once we return, enable signaling from the host. Once this
- * state is set we check to see if additional packets are
- * available to read. In this case we repeat the process.
- */
- do {
- if (is_batched_reading)
- hv_ring_buffer_read_begin(&channel->inbound);
-
- channel->on_channel_callback(arg);
-
- if (is_batched_reading)
- bytes_to_read =
- hv_ring_buffer_read_end(&channel->inbound);
- else
- bytes_to_read = 0;
- } while (is_batched_reading && (bytes_to_read != 0));
- }
- // mtx_unlock(&channel->inbound_lock);
-}
-
-/**
* 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;
@@ -415,7 +349,6 @@ hv_vmbus_on_events(void *arg)
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!"));
@@ -457,8 +390,14 @@ hv_vmbus_on_events(void *arg)
*/
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);
}
}
}
OpenPOWER on IntegriCloud