diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2012-12-01 09:46:35 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-17 13:46:39 -0500 |
commit | f878f3d59ed26f489add852ed6d5c8e5f3bbb1aa (patch) | |
tree | a43fb3ee6c95abb34660921dad31b80a59d9cde6 /drivers/hv | |
parent | 7ae3e035195735f9b6ce3308b6240af877a41ea0 (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.c | 28 |
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 | } |