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>
This commit is contained in:
parent
7ae3e03519
commit
f878f3d59e
1 changed files with 25 additions and 3 deletions
|
@ -212,6 +212,9 @@ static void process_chn_event(u32 relid)
|
||||||
{
|
{
|
||||||
struct vmbus_channel *channel;
|
struct vmbus_channel *channel;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
void *arg;
|
||||||
|
bool read_state;
|
||||||
|
u32 bytes_to_read;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the channel based on this relid and invokes the
|
* 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);
|
spin_lock_irqsave(&channel->inbound_lock, flags);
|
||||||
if (channel->onchannel_callback != NULL)
|
if (channel->onchannel_callback != NULL) {
|
||||||
channel->onchannel_callback(channel->channel_callback_context);
|
arg = channel->channel_callback_context;
|
||||||
else
|
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);
|
pr_err("no channel callback for relid - %u\n", relid);
|
||||||
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue