diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2012-12-01 15:46:49 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-17 20:39:15 +0100 |
commit | 6552ecd70cc6f31f4bb9d63f36a7dd023db3e519 (patch) | |
tree | c049853ac72d2720afcac4f896752657499a7aac /drivers/hv/vmbus_drv.c | |
parent | Drivers: hv: Add state to manage incoming channel interrupt load (diff) | |
download | linux-6552ecd70cc6f31f4bb9d63f36a7dd023db3e519.tar.xz linux-6552ecd70cc6f31f4bb9d63f36a7dd023db3e519.zip |
Drivers: hv: Modify the interrupt handling code to support win8 and beyond
Starting with Win8 (WS2012), the event page can be used to directly get the
channel ID that needs servicing. Modify the channel event handling code
to take advantage of this feature.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/vmbus_drv.c')
-rw-r--r-- | drivers/hv/vmbus_drv.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 8e1a9ec53003..c583a0403c53 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -460,15 +460,32 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) * Hyper-V, and the Windows team suggested we do the same. */ - page_addr = hv_context.synic_event_page[cpu]; - event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; + if ((vmbus_proto_version == VERSION_WS2008) || + (vmbus_proto_version == VERSION_WIN7)) { - /* Since we are a child, we only need to check bit 0 */ - if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) { + page_addr = hv_context.synic_event_page[cpu]; + event = (union hv_synic_event_flags *)page_addr + + VMBUS_MESSAGE_SINT; + + /* Since we are a child, we only need to check bit 0 */ + if (sync_test_and_clear_bit(0, + (unsigned long *) &event->flags32[0])) { + handled = true; + } + } else { + /* + * Our host is win8 or above. The signaling mechanism + * has changed and we can directly look at the event page. + * If bit n is set then we have an interrup on the channel + * whose id is n. + */ handled = true; - tasklet_schedule(&event_dpc); } + if (handled) + tasklet_schedule(&event_dpc); + + page_addr = hv_context.synic_message_page[cpu]; msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; |