summaryrefslogtreecommitdiff
path: root/drivers/hv/hyperv_vmbus.h
diff options
context:
space:
mode:
authorOlaf Hering <olaf@aepfle.de>2015-12-14 16:01:33 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-09-15 08:27:40 +0200
commitb125fabf22d44f7c57e6df2a21d27add8385df0d (patch)
tree49268b93b6bde34ea8155ddec3d4a59cbfe4d3a7 /drivers/hv/hyperv_vmbus.h
parente31409cd1ae44450964fc29e2bb0519cc50f5923 (diff)
Drivers: hv: utils: run polling callback always in interrupt context
[ Upstream commit 3cace4a616108539e2730f8dc21a636474395e0f ] All channel interrupts are bound to specific VCPUs in the guest at the point channel is created. While currently, we invoke the polling function on the correct CPU (the CPU to which the channel is bound to) in some cases we may run the polling function in a non-interrupt context. This potentially can cause an issue as the polling function can be interrupted by the channel callback function. Fix the issue by running the polling function on the appropriate CPU at interrupt level. Additional details of the issue being addressed by this patch are given below: Currently hv_fcopy_onchannelcallback is called from interrupts and also via the ->write function of hv_utils. Since the used global variables to maintain state are not thread safe the state can get out of sync. This affects the variable state as well as the channel inbound buffer. As suggested by KY adjust hv_poll_channel to always run the given callback on the cpu which the channel is bound to. This avoids the need for locking because all the util services are single threaded and only one transaction is active at any given point in time. Additionally, remove the context variable, they will always be the same as recv_channel. Signed-off-by: Olaf Hering <olaf@aepfle.de> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/hyperv_vmbus.h')
-rw-r--r--drivers/hv/hyperv_vmbus.h6
1 files changed, 1 insertions, 5 deletions
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 225b96bcf7fe..12156db2e88e 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -764,11 +764,7 @@ static inline void hv_poll_channel(struct vmbus_channel *channel,
if (!channel)
return;
- if (channel->target_cpu != smp_processor_id())
- smp_call_function_single(channel->target_cpu,
- cb, channel, true);
- else
- cb(channel);
+ smp_call_function_single(channel->target_cpu, cb, channel, true);
}
enum hvutil_device_state {