From f878f3d59ed26f489add852ed6d5c8e5f3bbb1aa Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Sat, 1 Dec 2012 06:46:35 -0800 Subject: [PATCH] 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 Reviewed-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/connection.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 650c9f0..d1019a7 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -212,6 +212,9 @@ static void process_chn_event(u32 relid) { struct vmbus_channel *channel; unsigned long flags; + void *arg; + bool read_state; + u32 bytes_to_read; /* * Find the channel based on this relid and invokes the @@ -234,10 +237,29 @@ static void process_chn_event(u32 relid) */ spin_lock_irqsave(&channel->inbound_lock, flags); - if (channel->onchannel_callback != NULL) - channel->onchannel_callback(channel->channel_callback_context); - else + if (channel->onchannel_callback != NULL) { + arg = channel->channel_callback_context; + read_state = channel->batched_reading; + /* + * This callback reads the messages sent by the host. + * We can optimize host to guest signaling by ensuring: + * 1. While reading the channel, we disable interrupts from + * host. + * 2. Ensure that we process all posted messages from the host + * before returning from this callback. + * 3. Once we return, enable signaling from the host. Once this + * state is set we check to see if additional packets are + * available to read. In this case we repeat the process. + */ + + do { + hv_begin_read(&channel->inbound); + channel->onchannel_callback(arg); + bytes_to_read = hv_end_read(&channel->inbound); + } while (read_state && (bytes_to_read != 0)); + } else { pr_err("no channel callback for relid - %u\n", relid); + } spin_unlock_irqrestore(&channel->inbound_lock, flags); } -- 2.7.4