summaryrefslogtreecommitdiffstats
path: root/drivers/hv/connection.c
diff options
context:
space:
mode:
authorStephen Hemminger <stephen@networkplumber.org>2017-02-11 23:02:21 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-14 10:20:35 -0800
commitb71e328297a3a578c482fb4814e737a0ec185839 (patch)
treef18a93257c4d74332dafe953ef28da9809bf2bc8 /drivers/hv/connection.c
parent631e63a9f346cb657761ae22138f294718696501 (diff)
downloadlinux-b71e328297a3a578c482fb4814e737a0ec185839.tar.gz
linux-b71e328297a3a578c482fb4814e737a0ec185839.tar.bz2
linux-b71e328297a3a578c482fb4814e737a0ec185839.zip
vmbus: add direct isr callback mode
Change the simple boolean batched_reading into a tri-value. For future NAPI support in netvsc driver, the callback needs to occur directly in interrupt handler. Batched mode is also changed to disable host interrupts immediately in interrupt routine (to avoid unnecessary host signals), and the tasklet is rescheduled if more data is detected. Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/connection.c')
-rw-r--r--drivers/hv/connection.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 27e72dc07e12..a8366fec1458 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -300,9 +300,7 @@ struct vmbus_channel *relid2channel(u32 relid)
void vmbus_on_event(unsigned long data)
{
struct vmbus_channel *channel = (void *) data;
- void *arg;
- bool read_state;
- u32 bytes_to_read;
+ void (*callback_fn)(void *);
/*
* A channel once created is persistent even when there
@@ -312,9 +310,13 @@ void vmbus_on_event(unsigned long data)
* Thus, checking and invoking the driver specific callback takes
* care of orderly unloading of the driver.
*/
- if (channel->onchannel_callback != NULL) {
- arg = channel->channel_callback_context;
- read_state = channel->batched_reading;
+ callback_fn = READ_ONCE(channel->onchannel_callback);
+ if (unlikely(callback_fn == NULL))
+ return;
+
+ (*callback_fn)(channel->channel_callback_context);
+
+ if (channel->callback_mode == HV_CALL_BATCHED) {
/*
* This callback reads the messages sent by the host.
* We can optimize host to guest signaling by ensuring:
@@ -326,16 +328,11 @@ void vmbus_on_event(unsigned long data)
* state is set we check to see if additional packets are
* available to read. In this case we repeat the process.
*/
+ if (hv_end_read(&channel->inbound) != 0) {
+ hv_begin_read(&channel->inbound);
- do {
- if (read_state)
- hv_begin_read(&channel->inbound);
- channel->onchannel_callback(arg);
- if (read_state)
- bytes_to_read = hv_end_read(&channel->inbound);
- else
- bytes_to_read = 0;
- } while (read_state && (bytes_to_read != 0));
+ tasklet_schedule(&channel->callback_event);
+ }
}
}