aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Pemberton <wfp5p@virginia.edu>2009-07-29 17:00:09 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-15 12:01:53 -0700
commitde65a38406bdf712abc2a845fe1f3db7d1a083ed (patch)
treecd4d9f38dd90c6bfc5a5667bc2c4fcc4481d2f8b
parent949cadaa054588db0c4a3a0cfc3ac93f08fda913 (diff)
Staging: hv: rework use of workqueues in osd
Change the usage of workqueues to be consistant with other parts of the kernel. Signed-off-by: Bill Pemberton <wfp5p@virginia.edu> Cc: Hank Janssen <hjanssen@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/hv/ChannelMgmt.c14
-rw-r--r--drivers/staging/hv/Connection.c12
-rw-r--r--drivers/staging/hv/Vmbus.c4
-rw-r--r--drivers/staging/hv/include/osd.h11
-rw-r--r--drivers/staging/hv/osd.c66
5 files changed, 45 insertions, 62 deletions
diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c
index c5efc6ec6c3..2c4f4c8e5e7 100644
--- a/drivers/staging/hv/ChannelMgmt.c
+++ b/drivers/staging/hv/ChannelMgmt.c
@@ -149,7 +149,7 @@ static VMBUS_CHANNEL* AllocVmbusChannel(void)
}
/* channel->dataWorkQueue = WorkQueueCreate("data"); */
- channel->ControlWQ = WorkQueueCreate("control");
+ channel->ControlWQ = create_workqueue("hv_vmbus_ctl");
if (!channel->ControlWQ)
{
TimerClose(channel->PollTimer);
@@ -176,7 +176,7 @@ static inline void ReleaseVmbusChannel(void* Context)
DPRINT_ENTER(VMBUS);
DPRINT_DBG(VMBUS, "releasing channel (%p)", channel);
- WorkQueueClose(channel->ControlWQ);
+ destroy_workqueue(channel->ControlWQ);
DPRINT_DBG(VMBUS, "channel released (%p)", channel);
kfree(channel);
@@ -199,7 +199,8 @@ static void FreeVmbusChannel(VMBUS_CHANNEL* Channel)
/* We have to release the channel's workqueue/thread in the vmbus's workqueue/thread context */
/* ie we can't destroy ourselves. */
- WorkQueueQueueWorkItem(gVmbusConnection.WorkQueue, ReleaseVmbusChannel, (void*)Channel);
+ osd_schedule_callback(gVmbusConnection.WorkQueue, ReleaseVmbusChannel,
+ (void *)Channel);
}
@@ -389,7 +390,8 @@ VmbusChannelOnOffer(
newChannel->MonitorBit = (u8)offer->MonitorId % 32;
/* TODO: Make sure the offer comes from our parent partition */
- WorkQueueQueueWorkItem(newChannel->ControlWQ, VmbusChannelProcessOffer, newChannel);
+ osd_schedule_callback(newChannel->ControlWQ, VmbusChannelProcessOffer,
+ newChannel);
DPRINT_EXIT(VMBUS);
}
@@ -422,7 +424,9 @@ VmbusChannelOnOfferRescind(
return;
}
- WorkQueueQueueWorkItem(channel->ControlWQ, VmbusChannelProcessRescindOffer, channel);
+ osd_schedule_callback(channel->ControlWQ,
+ VmbusChannelProcessRescindOffer,
+ channel);
DPRINT_EXIT(VMBUS);
}
diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c
index a2888cb4670..33e5628b88c 100644
--- a/drivers/staging/hv/Connection.c
+++ b/drivers/staging/hv/Connection.c
@@ -60,7 +60,12 @@ VmbusConnect(void)
/* Initialize the vmbus connection */
gVmbusConnection.ConnectState = Connecting;
- gVmbusConnection.WorkQueue = WorkQueueCreate("vmbusQ");
+ gVmbusConnection.WorkQueue = create_workqueue("hv_vmbus_con");
+ if (!gVmbusConnection.WorkQueue)
+ {
+ ret = -1;
+ goto Cleanup;
+ }
INITIALIZE_LIST_HEAD(&gVmbusConnection.ChannelMsgList);
spin_lock_init(&gVmbusConnection.channelmsg_lock);
@@ -160,7 +165,8 @@ Cleanup:
gVmbusConnection.ConnectState = Disconnected;
- WorkQueueClose(gVmbusConnection.WorkQueue);
+ if (gVmbusConnection.WorkQueue)
+ destroy_workqueue(gVmbusConnection.WorkQueue);
if (gVmbusConnection.InterruptPage)
{
@@ -226,7 +232,7 @@ VmbusDisconnect(
/* TODO: iterate thru the msg list and free up */
- WorkQueueClose(gVmbusConnection.WorkQueue);
+ destroy_workqueue(gVmbusConnection.WorkQueue);
gVmbusConnection.ConnectState = Disconnected;
diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c
index c8e0df6c480..13d7ac80d6b 100644
--- a/drivers/staging/hv/Vmbus.c
+++ b/drivers/staging/hv/Vmbus.c
@@ -423,7 +423,9 @@ VmbusOnMsgDPC(
}
memcpy(copied, msg, sizeof(HV_MESSAGE));
- WorkQueueQueueWorkItem(gVmbusConnection.WorkQueue, VmbusOnChannelMessage, (void*)copied);
+ osd_schedule_callback(gVmbusConnection.WorkQueue,
+ VmbusOnChannelMessage,
+ (void *)copied);
}
msg->Header.MessageType = HvMessageTypeNone;
diff --git a/drivers/staging/hv/include/osd.h b/drivers/staging/hv/include/osd.h
index 2a47d149b83..4147aba5d31 100644
--- a/drivers/staging/hv/include/osd.h
+++ b/drivers/staging/hv/include/osd.h
@@ -47,7 +47,6 @@ typedef struct _DLIST_ENTRY {
/* typedef unsigned char GUID[16]; */
-typedef void (*PFN_WORKITEM_CALLBACK)(void* context);
typedef void (*PFN_TIMER_CALLBACK)(void* context);
@@ -155,12 +154,8 @@ void* PageMapVirtualAddress(unsigned long Pfn);
void PageUnmapVirtualAddress(void* VirtAddr);
-extern struct workqueue_struct *WorkQueueCreate(char* name);
-extern void WorkQueueClose(struct workqueue_struct *hWorkQueue);
-extern int WorkQueueQueueWorkItem(struct workqueue_struct *hWorkQueue,
- PFN_WORKITEM_CALLBACK workItem,
- void *context);
-
-extern void QueueWorkItem(PFN_WORKITEM_CALLBACK workItem, void* context);
+int osd_schedule_callback(struct workqueue_struct *wq,
+ void (*func)(void *),
+ void *data);
#endif /* _OSD_H_ */
diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c
index ea3e226f178..46cdf88cf9d 100644
--- a/drivers/staging/hv/osd.c
+++ b/drivers/staging/hv/osd.c
@@ -50,11 +50,11 @@
/* Data types */
-typedef struct _WORKITEM {
+struct osd_callback_struct {
struct work_struct work;
- PFN_WORKITEM_CALLBACK callback;
- void* context;
-} WORKITEM;
+ void (*callback)(void *);
+ void *data;
+};
void BitSet(unsigned int* addr, int bit)
@@ -269,56 +269,32 @@ unsigned long Virtual2Physical(void * VirtAddr)
return pfn << PAGE_SHIFT;
}
-static void WorkItemCallback(struct work_struct *work)
+static void osd_callback_work(struct work_struct *work)
{
- WORKITEM* w = (WORKITEM*)work;
+ struct osd_callback_struct *cb = container_of(work,
+ struct osd_callback_struct,
+ work);
+ (cb->callback)(cb->data);
- w->callback(w->context);
-
- kfree(w);
-}
-
-struct workqueue_struct *WorkQueueCreate(char *name)
-{
- struct workqueue_struct *wq;
- wq = create_workqueue(name);
- if (unlikely(!wq))
- return NULL;
- return wq;
+ kfree(cb);
}
-void WorkQueueClose(struct workqueue_struct *hWorkQueue)
+int osd_schedule_callback(struct workqueue_struct *wq,
+ void (*func)(void *),
+ void *data)
{
- destroy_workqueue(hWorkQueue);
- return;
-}
+ struct osd_callback_struct *cb;
-int WorkQueueQueueWorkItem(struct workqueue_struct *hWorkQueue,
- PFN_WORKITEM_CALLBACK workItem,
- void* context)
-{
- WORKITEM* w = kmalloc(sizeof(WORKITEM), GFP_ATOMIC);
- if (!w)
+ cb = kmalloc(sizeof(*cb), GFP_KERNEL);
+ if (!cb)
{
+ printk(KERN_ERR "unable to allocate memory in osd_schedule_callback");
return -1;
}
- w->callback = workItem,
- w->context = context;
- INIT_WORK(&w->work, WorkItemCallback);
- return queue_work(hWorkQueue, &w->work);
+ cb->callback = func;
+ cb->data = data;
+ INIT_WORK(&cb->work, osd_callback_work);
+ return queue_work(wq, &cb->work);
}
-void QueueWorkItem(PFN_WORKITEM_CALLBACK workItem, void* context)
-{
- WORKITEM* w = kmalloc(sizeof(WORKITEM), GFP_ATOMIC);
- if (!w)
- {
- return;
- }
-
- w->callback = workItem,
- w->context = context;
- INIT_WORK(&w->work, WorkItemCallback);
- schedule_work(&w->work);
-}