diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2014-04-08 18:45:53 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-03 19:24:26 -0400 |
commit | d3ba720dd58cdf6630fee4b89482c465d5ad0d0f (patch) | |
tree | 03ea0aba6f0509bf7c501dee9ae6e931634f3c4b /drivers/hv/channel.c | |
parent | e4d8270e604c3202131bac607969605ac397b893 (diff) | |
download | op-kernel-dev-d3ba720dd58cdf6630fee4b89482c465d5ad0d0f.zip op-kernel-dev-d3ba720dd58cdf6630fee4b89482c465d5ad0d0f.tar.gz |
Drivers: hv: Eliminate the channel spinlock in the callback path
By ensuring that we set the callback handler to NULL in the channel close
path on the same CPU that the channel is bound to, we can eliminate this lock
acquisition and release in a performance critical path.
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/channel.c')
-rw-r--r-- | drivers/hv/channel.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 602ca86..740edec 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -471,18 +471,26 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) } EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl); +static void reset_channel_cb(void *arg) +{ + struct vmbus_channel *channel = arg; + + channel->onchannel_callback = NULL; +} + static void vmbus_close_internal(struct vmbus_channel *channel) { struct vmbus_channel_close_channel *msg; int ret; - unsigned long flags; channel->state = CHANNEL_OPEN_STATE; channel->sc_creation_callback = NULL; /* Stop callback and cancel the timer asap */ - spin_lock_irqsave(&channel->inbound_lock, flags); - channel->onchannel_callback = NULL; - spin_unlock_irqrestore(&channel->inbound_lock, flags); + if (channel->target_cpu != smp_processor_id()) + smp_call_function_single(channel->target_cpu, reset_channel_cb, + channel, true); + else + reset_channel_cb(channel); /* Send a closing message */ |