]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Drivers: hv: vmbus: Properly protect calls to smp_processor_id()
authorK. Y. Srinivasan <kys@microsoft.com>
Fri, 29 Aug 2014 01:29:53 +0000 (18:29 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Sep 2014 06:31:21 +0000 (23:31 -0700)
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>
drivers/hv/channel.c
drivers/hv/channel_mgmt.c

index 19bad59073e642ea8a92a8e9f85a9db33d8f4318..433f72a1c0062be9b13dff78b6885d37a80a8738 100644 (file)
@@ -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 */
 
index ed9350d42764e06bb38eacfdf8756ae8ac43b2ba..a2d1a9612c86c4730c6aa2f0ce038ca06da4f9c5 100644 (file)
@@ -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)