staging: hv: convert channel_mgmt.c to not call osd_schedule_callback
authorTimo Teräs <timo.teras@iki.fi>
Wed, 15 Dec 2010 18:48:09 +0000 (20:48 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 16 Dec 2010 20:35:15 +0000 (12:35 -0800)
The additional abstraction is unneeded.

The three calls are assumed to not be pending simultaneously:
 - vmbus_onoffer queues work exactly once when a new channel is
   created, the channel is not attached to lists until the work
   is executed
 - vmbus_onoffer_rescind is received only when the channel is
   active it is enough to process the work once
 - free_channel is called exactly once when the channel is getting
   destroyed; I assumed that vmbus_process_rescind_offer cannot be
   pending while free_channel is called

Reviewed-By: Hank Janssen <hjanssen@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/hv/channel_mgmt.c
drivers/staging/hv/channel_mgmt.h

index 6f393e7d8e25cd31bd33d060e29dd3177149db4b..d44d5c39f68bddf4c71364c80e904889a42d3c1e 100644 (file)
@@ -263,9 +263,11 @@ static struct vmbus_channel *alloc_channel(void)
 /*
  * release_hannel - Release the vmbus channel object itself
  */
-static inline void release_channel(void *context)
+static void release_channel(struct work_struct *work)
 {
-       struct vmbus_channel *channel = context;
+       struct vmbus_channel *channel = container_of(work,
+                                                    struct vmbus_channel,
+                                                    work);
 
        DPRINT_DBG(VMBUS, "releasing channel (%p)", channel);
        destroy_workqueue(channel->controlwq);
@@ -286,8 +288,8 @@ void free_channel(struct vmbus_channel *channel)
         * workqueue/thread context
         * ie we can't destroy ourselves.
         */
-       osd_schedule_callback(gVmbusConnection.WorkQueue, release_channel,
-                             channel);
+       INIT_WORK(&channel->work, release_channel);
+       queue_work(gVmbusConnection.WorkQueue, &channel->work);
 }
 
 
@@ -308,20 +310,37 @@ static void count_hv_channel(void)
        spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
 }
 
+/*
+ * vmbus_process_rescind_offer -
+ * Rescind the offer by initiating a device removal
+ */
+static void vmbus_process_rescind_offer(struct work_struct *work)
+{
+       struct vmbus_channel *channel = container_of(work,
+                                                    struct vmbus_channel,
+                                                    work);
+
+       vmbus_child_device_unregister(channel->device_obj);
+}
 
 /*
  * vmbus_process_offer - Process the offer by creating a channel/device
  * associated with this offer
  */
-static void vmbus_process_offer(void *context)
+static void vmbus_process_offer(struct work_struct *work)
 {
-       struct vmbus_channel *newchannel = context;
+       struct vmbus_channel *newchannel = container_of(work,
+                                                       struct vmbus_channel,
+                                                       work);
        struct vmbus_channel *channel;
        bool fnew = true;
        int ret;
        int cnt;
        unsigned long flags;
 
+       /* The next possible work is rescind handling */
+       INIT_WORK(&newchannel->work, vmbus_process_rescind_offer);
+
        /* Make sure this is a new offer */
        spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
 
@@ -405,17 +424,6 @@ static void vmbus_process_offer(void *context)
        }
 }
 
-/*
- * vmbus_process_rescind_offer -
- * Rescind the offer by initiating a device removal
- */
-static void vmbus_process_rescind_offer(void *context)
-{
-       struct vmbus_channel *channel = context;
-
-       vmbus_child_device_unregister(channel->device_obj);
-}
-
 /*
  * vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
  *
@@ -490,8 +498,8 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
        newchannel->monitor_bit = (u8)offer->monitorid % 32;
 
        /* TODO: Make sure the offer comes from our parent partition */
-       osd_schedule_callback(newchannel->controlwq, vmbus_process_offer,
-                             newchannel);
+       INIT_WORK(&newchannel->work, vmbus_process_offer);
+       queue_work(newchannel->controlwq, &newchannel->work);
 }
 
 /*
@@ -512,9 +520,9 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
                return;
        }
 
-       osd_schedule_callback(channel->controlwq,
-                             vmbus_process_rescind_offer,
-                             channel);
+       /* work is initialized for vmbus_process_rescind_offer() from
+        * vmbus_process_offer() where the channel got created */
+       queue_work(channel->controlwq, &channel->work);
 }
 
 /*
index 12f30aff152d89069f6bda64e2390bf799b03026..de6b2a0ebf701d8bf26bcaaa94a554ac397e4f93 100644 (file)
@@ -231,6 +231,7 @@ struct vmbus_channel {
        struct hv_device *device_obj;
 
        struct timer_list poll_timer; /* SA-111 workaround */
+       struct work_struct work;
 
        enum vmbus_channel_state state;