diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2014-08-28 18:29:53 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-09-23 23:31:21 -0700 |
commit | 2115b5617adf2eecca49e78f3810f359ddc5c396 (patch) | |
tree | 78deae37a3debee67b4cd30b54d948ad3cc1c8ab /drivers/hv | |
parent | b29ef3546aecb253a5552b198cef23750d56e1e4 (diff) |
Drivers: hv: vmbus: Properly protect calls to smp_processor_id()
Disable preemption when sampling current processor ID when preemption
is otherwise possible.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Sitsofe Wheeler <sitsofe@yahoo.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r-- | drivers/hv/channel.c | 7 | ||||
-rw-r--r-- | drivers/hv/channel_mgmt.c | 21 |
2 files changed, 20 insertions, 8 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 19bad59073e6..433f72a1c006 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -486,11 +486,14 @@ static int vmbus_close_internal(struct vmbus_channel *channel) channel->state = CHANNEL_OPEN_STATE; channel->sc_creation_callback = NULL; /* Stop callback and cancel the timer asap */ - if (channel->target_cpu != smp_processor_id()) + if (channel->target_cpu != get_cpu()) { + put_cpu(); smp_call_function_single(channel->target_cpu, reset_channel_cb, channel, true); - else + } else { reset_channel_cb(channel); + put_cpu(); + } /* Send a closing message */ diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index ed9350d42764..a2d1a9612c86 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -224,11 +224,14 @@ static void vmbus_process_rescind_offer(struct work_struct *work) msg.header.msgtype = CHANNELMSG_RELID_RELEASED; vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released)); - if (channel->target_cpu != smp_processor_id()) + if (channel->target_cpu != get_cpu()) { + put_cpu(); smp_call_function_single(channel->target_cpu, percpu_channel_deq, channel, true); - else + } else { percpu_channel_deq(channel); + put_cpu(); + } if (channel->primary_channel == NULL) { spin_lock_irqsave(&vmbus_connection.channel_lock, flags); @@ -294,12 +297,15 @@ static void vmbus_process_offer(struct work_struct *work) spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); if (enq) { - if (newchannel->target_cpu != smp_processor_id()) + if (newchannel->target_cpu != get_cpu()) { + put_cpu(); smp_call_function_single(newchannel->target_cpu, percpu_channel_enq, newchannel, true); - else + } else { percpu_channel_enq(newchannel); + put_cpu(); + } } if (!fnew) { /* @@ -314,12 +320,15 @@ static void vmbus_process_offer(struct work_struct *work) list_add_tail(&newchannel->sc_list, &channel->sc_list); spin_unlock_irqrestore(&channel->sc_lock, flags); - if (newchannel->target_cpu != smp_processor_id()) + if (newchannel->target_cpu != get_cpu()) { + put_cpu(); smp_call_function_single(newchannel->target_cpu, percpu_channel_enq, newchannel, true); - else + } else { percpu_channel_enq(newchannel); + put_cpu(); + } newchannel->state = CHANNEL_OPEN_STATE; if (channel->sc_creation_callback != NULL) |