summaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorStephen Hemminger <stephen@networkplumber.org>2017-02-12 01:02:21 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-14 13:20:35 -0500
commitb71e328297a3a578c482fb4814e737a0ec185839 (patch)
treef18a93257c4d74332dafe953ef28da9809bf2bc8 /drivers/hv
parent631e63a9f346cb657761ae22138f294718696501 (diff)
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')
-rw-r--r--drivers/hv/channel_mgmt.c7
-rw-r--r--drivers/hv/connection.c27
-rw-r--r--drivers/hv/hv_util.c3
-rw-r--r--drivers/hv/vmbus_drv.c26
4 files changed, 37 insertions, 26 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 2f6270d76b79..b2bb5aafaa2f 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -820,13 +820,6 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
820 } 820 }
821 821
822 /* 822 /*
823 * By default we setup state to enable batched
824 * reading. A specific service can choose to
825 * disable this prior to opening the channel.
826 */
827 newchannel->batched_reading = true;
828
829 /*
830 * Setup state for signalling the host. 823 * Setup state for signalling the host.
831 */ 824 */
832 newchannel->sig_event = (struct hv_input_signal_event *) 825 newchannel->sig_event = (struct hv_input_signal_event *)
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)
300void vmbus_on_event(unsigned long data) 300void vmbus_on_event(unsigned long data)
301{ 301{
302 struct vmbus_channel *channel = (void *) data; 302 struct vmbus_channel *channel = (void *) data;
303 void *arg; 303 void (*callback_fn)(void *);
304 bool read_state;
305 u32 bytes_to_read;
306 304
307 /* 305 /*
308 * A channel once created is persistent even when there 306 * A channel once created is persistent even when there
@@ -312,9 +310,13 @@ void vmbus_on_event(unsigned long data)
312 * Thus, checking and invoking the driver specific callback takes 310 * Thus, checking and invoking the driver specific callback takes
313 * care of orderly unloading of the driver. 311 * care of orderly unloading of the driver.
314 */ 312 */
315 if (channel->onchannel_callback != NULL) { 313 callback_fn = READ_ONCE(channel->onchannel_callback);
316 arg = channel->channel_callback_context; 314 if (unlikely(callback_fn == NULL))
317 read_state = channel->batched_reading; 315 return;
316
317 (*callback_fn)(channel->channel_callback_context);
318
319 if (channel->callback_mode == HV_CALL_BATCHED) {
318 /* 320 /*
319 * This callback reads the messages sent by the host. 321 * This callback reads the messages sent by the host.
320 * We can optimize host to guest signaling by ensuring: 322 * We can optimize host to guest signaling by ensuring:
@@ -326,16 +328,11 @@ void vmbus_on_event(unsigned long data)
326 * state is set we check to see if additional packets are 328 * state is set we check to see if additional packets are
327 * available to read. In this case we repeat the process. 329 * available to read. In this case we repeat the process.
328 */ 330 */
331 if (hv_end_read(&channel->inbound) != 0) {
332 hv_begin_read(&channel->inbound);
329 333
330 do { 334 tasklet_schedule(&channel->callback_event);
331 if (read_state) 335 }
332 hv_begin_read(&channel->inbound);
333 channel->onchannel_callback(arg);
334 if (read_state)
335 bytes_to_read = hv_end_read(&channel->inbound);
336 else
337 bytes_to_read = 0;
338 } while (read_state && (bytes_to_read != 0));
339 } 336 }
340} 337}
341 338
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 098cd3dc7db2..3042eaa13062 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -435,8 +435,7 @@ static int util_probe(struct hv_device *dev,
435 * Turn off batched reading for all util drivers before we open the 435 * Turn off batched reading for all util drivers before we open the
436 * channel. 436 * channel.
437 */ 437 */
438 438 set_channel_read_mode(dev->channel, HV_CALL_DIRECT);
439 set_channel_read_state(dev->channel, false);
440 439
441 hv_set_drvdata(dev, srv); 440 hv_set_drvdata(dev, srv);
442 441
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index eaf1a10b0245..f7f6b9144b07 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -887,6 +887,18 @@ msg_handled:
887 887
888 888
889/* 889/*
890 * Direct callback for channels using other deferred processing
891 */
892static void vmbus_channel_isr(struct vmbus_channel *channel)
893{
894 void (*callback_fn)(void *);
895
896 callback_fn = READ_ONCE(channel->onchannel_callback);
897 if (likely(callback_fn != NULL))
898 (*callback_fn)(channel->channel_callback_context);
899}
900
901/*
890 * Schedule all channels with events pending 902 * Schedule all channels with events pending
891 */ 903 */
892static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu) 904static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
@@ -927,9 +939,19 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
927 939
928 /* Find channel based on relid */ 940 /* Find channel based on relid */
929 list_for_each_entry(channel, &hv_cpu->chan_list, percpu_list) { 941 list_for_each_entry(channel, &hv_cpu->chan_list, percpu_list) {
930 if (channel->offermsg.child_relid == relid) { 942 if (channel->offermsg.child_relid != relid)
931 tasklet_schedule(&channel->callback_event); 943 continue;
944
945 switch (channel->callback_mode) {
946 case HV_CALL_ISR:
947 vmbus_channel_isr(channel);
932 break; 948 break;
949
950 case HV_CALL_BATCHED:
951 hv_begin_read(&channel->inbound);
952 /* fallthrough */
953 case HV_CALL_DIRECT:
954 tasklet_schedule(&channel->callback_event);
933 } 955 }
934 } 956 }
935 } 957 }