aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2012-12-01 09:46:35 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-17 13:46:39 -0500
commitf878f3d59ed26f489add852ed6d5c8e5f3bbb1aa (patch)
treea43fb3ee6c95abb34660921dad31b80a59d9cde6 /drivers/hv
parent7ae3e035195735f9b6ce3308b6240af877a41ea0 (diff)
Drivers: hv: Optimize signaling in the read path
Now that we have the infratructure for correctly determining when we should signal the host; optimize the signaling on the read side - signaling the guest from the host. 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')
-rw-r--r--drivers/hv/connection.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 650c9f0b6642..d1019a770ad7 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -212,6 +212,9 @@ static void process_chn_event(u32 relid)
212{ 212{
213 struct vmbus_channel *channel; 213 struct vmbus_channel *channel;
214 unsigned long flags; 214 unsigned long flags;
215 void *arg;
216 bool read_state;
217 u32 bytes_to_read;
215 218
216 /* 219 /*
217 * Find the channel based on this relid and invokes the 220 * Find the channel based on this relid and invokes the
@@ -234,10 +237,29 @@ static void process_chn_event(u32 relid)
234 */ 237 */
235 238
236 spin_lock_irqsave(&channel->inbound_lock, flags); 239 spin_lock_irqsave(&channel->inbound_lock, flags);
237 if (channel->onchannel_callback != NULL) 240 if (channel->onchannel_callback != NULL) {
238 channel->onchannel_callback(channel->channel_callback_context); 241 arg = channel->channel_callback_context;
239 else 242 read_state = channel->batched_reading;
243 /*
244 * This callback reads the messages sent by the host.
245 * We can optimize host to guest signaling by ensuring:
246 * 1. While reading the channel, we disable interrupts from
247 * host.
248 * 2. Ensure that we process all posted messages from the host
249 * before returning from this callback.
250 * 3. Once we return, enable signaling from the host. Once this
251 * state is set we check to see if additional packets are
252 * available to read. In this case we repeat the process.
253 */
254
255 do {
256 hv_begin_read(&channel->inbound);
257 channel->onchannel_callback(arg);
258 bytes_to_read = hv_end_read(&channel->inbound);
259 } while (read_state && (bytes_to_read != 0));
260 } else {
240 pr_err("no channel callback for relid - %u\n", relid); 261 pr_err("no channel callback for relid - %u\n", relid);
262 }
241 263
242 spin_unlock_irqrestore(&channel->inbound_lock, flags); 264 spin_unlock_irqrestore(&channel->inbound_lock, flags);
243} 265}