diff options
author | Kimberly Brown <kimbrownkd@gmail.com> | 2019-03-14 21:05:15 +0100 |
---|---|---|
committer | Sasha Levin <sashal@kernel.org> | 2019-04-11 00:58:56 +0200 |
commit | 14948e39445db674516ccabdf01090586ecfdc9b (patch) | |
tree | c7dde66befabf1f3d78652672c73ff0f1ec5ea62 /drivers/hv/channel_mgmt.c | |
parent | Drivers: hv: vmbus: Set ring_info field to 0 and remove memset (diff) | |
download | linux-14948e39445db674516ccabdf01090586ecfdc9b.tar.xz linux-14948e39445db674516ccabdf01090586ecfdc9b.zip |
Drivers: hv: vmbus: Fix race condition with new ring_buffer_info mutex
Fix a race condition that can result in a ring buffer pointer being set
to null while a "_show" function is reading the ring buffer's data. This
problem was discussed here: https://lkml.org/lkml/2018/10/18/779
To fix the race condition, add a new mutex lock to the
"hv_ring_buffer_info" struct. Add a new function,
"hv_ringbuffer_pre_init()", where a channel's inbound and outbound
ring_buffer_info mutex locks are initialized.
Acquire/release the locks in the "hv_ringbuffer_cleanup()" function,
which is where the ring buffer pointers are set to null.
Acquire/release the locks in the four channel-level "_show" functions
that access ring buffer data. Remove the "const" qualifier from the
"vmbus_channel" parameter and the "rbi" variable of the channel-level
"_show" functions so that the locks can be acquired/released in these
functions.
Acquire/release the locks in hv_ringbuffer_get_debuginfo(). Remove the
"const" qualifier from the "hv_ring_buffer_info" parameter so that the
locks can be acquired/released in this function.
Signed-off-by: Kimberly Brown <kimbrownkd@gmail.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/hv/channel_mgmt.c')
-rw-r--r-- | drivers/hv/channel_mgmt.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index d32cac501fc7..3fc0b247a807 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -336,6 +336,8 @@ static struct vmbus_channel *alloc_channel(void) tasklet_init(&channel->callback_event, vmbus_on_event, (unsigned long)channel); + hv_ringbuffer_pre_init(channel); + return channel; } |