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>
This commit is contained in:
Bill Pemberton 2009-07-29 17:00:09 -04:00 committed by Greg Kroah-Hartman
parent 949cadaa05
commit de65a38406
5 changed files with 45 additions and 62 deletions

View File

@ -149,7 +149,7 @@ static VMBUS_CHANNEL* AllocVmbusChannel(void)
} }
/* channel->dataWorkQueue = WorkQueueCreate("data"); */ /* channel->dataWorkQueue = WorkQueueCreate("data"); */
channel->ControlWQ = WorkQueueCreate("control"); channel->ControlWQ = create_workqueue("hv_vmbus_ctl");
if (!channel->ControlWQ) if (!channel->ControlWQ)
{ {
TimerClose(channel->PollTimer); TimerClose(channel->PollTimer);
@ -176,7 +176,7 @@ static inline void ReleaseVmbusChannel(void* Context)
DPRINT_ENTER(VMBUS); DPRINT_ENTER(VMBUS);
DPRINT_DBG(VMBUS, "releasing channel (%p)", channel); DPRINT_DBG(VMBUS, "releasing channel (%p)", channel);
WorkQueueClose(channel->ControlWQ); destroy_workqueue(channel->ControlWQ);
DPRINT_DBG(VMBUS, "channel released (%p)", channel); DPRINT_DBG(VMBUS, "channel released (%p)", channel);
kfree(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 */ /* We have to release the channel's workqueue/thread in the vmbus's workqueue/thread context */
/* ie we can't destroy ourselves. */ /* 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; newChannel->MonitorBit = (u8)offer->MonitorId % 32;
/* TODO: Make sure the offer comes from our parent partition */ /* 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); DPRINT_EXIT(VMBUS);
} }
@ -422,7 +424,9 @@ VmbusChannelOnOfferRescind(
return; return;
} }
WorkQueueQueueWorkItem(channel->ControlWQ, VmbusChannelProcessRescindOffer, channel); osd_schedule_callback(channel->ControlWQ,
VmbusChannelProcessRescindOffer,
channel);
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
} }

View File

@ -60,7 +60,12 @@ VmbusConnect(void)
/* Initialize the vmbus connection */ /* Initialize the vmbus connection */
gVmbusConnection.ConnectState = Connecting; 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); INITIALIZE_LIST_HEAD(&gVmbusConnection.ChannelMsgList);
spin_lock_init(&gVmbusConnection.channelmsg_lock); spin_lock_init(&gVmbusConnection.channelmsg_lock);
@ -160,7 +165,8 @@ Cleanup:
gVmbusConnection.ConnectState = Disconnected; gVmbusConnection.ConnectState = Disconnected;
WorkQueueClose(gVmbusConnection.WorkQueue); if (gVmbusConnection.WorkQueue)
destroy_workqueue(gVmbusConnection.WorkQueue);
if (gVmbusConnection.InterruptPage) if (gVmbusConnection.InterruptPage)
{ {
@ -226,7 +232,7 @@ VmbusDisconnect(
/* TODO: iterate thru the msg list and free up */ /* TODO: iterate thru the msg list and free up */
WorkQueueClose(gVmbusConnection.WorkQueue); destroy_workqueue(gVmbusConnection.WorkQueue);
gVmbusConnection.ConnectState = Disconnected; gVmbusConnection.ConnectState = Disconnected;

View File

@ -423,7 +423,9 @@ VmbusOnMsgDPC(
} }
memcpy(copied, msg, sizeof(HV_MESSAGE)); memcpy(copied, msg, sizeof(HV_MESSAGE));
WorkQueueQueueWorkItem(gVmbusConnection.WorkQueue, VmbusOnChannelMessage, (void*)copied); osd_schedule_callback(gVmbusConnection.WorkQueue,
VmbusOnChannelMessage,
(void *)copied);
} }
msg->Header.MessageType = HvMessageTypeNone; msg->Header.MessageType = HvMessageTypeNone;

View File

@ -47,7 +47,6 @@ typedef struct _DLIST_ENTRY {
/* typedef unsigned char GUID[16]; */ /* typedef unsigned char GUID[16]; */
typedef void (*PFN_WORKITEM_CALLBACK)(void* context);
typedef void (*PFN_TIMER_CALLBACK)(void* context); typedef void (*PFN_TIMER_CALLBACK)(void* context);
@ -155,12 +154,8 @@ void* PageMapVirtualAddress(unsigned long Pfn);
void PageUnmapVirtualAddress(void* VirtAddr); void PageUnmapVirtualAddress(void* VirtAddr);
extern struct workqueue_struct *WorkQueueCreate(char* name); int osd_schedule_callback(struct workqueue_struct *wq,
extern void WorkQueueClose(struct workqueue_struct *hWorkQueue); void (*func)(void *),
extern int WorkQueueQueueWorkItem(struct workqueue_struct *hWorkQueue, void *data);
PFN_WORKITEM_CALLBACK workItem,
void *context);
extern void QueueWorkItem(PFN_WORKITEM_CALLBACK workItem, void* context);
#endif /* _OSD_H_ */ #endif /* _OSD_H_ */

View File

@ -50,11 +50,11 @@
/* Data types */ /* Data types */
typedef struct _WORKITEM { struct osd_callback_struct {
struct work_struct work; struct work_struct work;
PFN_WORKITEM_CALLBACK callback; void (*callback)(void *);
void* context; void *data;
} WORKITEM; };
void BitSet(unsigned int* addr, int bit) void BitSet(unsigned int* addr, int bit)
@ -269,56 +269,32 @@ unsigned long Virtual2Physical(void * VirtAddr)
return pfn << PAGE_SHIFT; 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(cb);
kfree(w);
} }
struct workqueue_struct *WorkQueueCreate(char *name) int osd_schedule_callback(struct workqueue_struct *wq,
void (*func)(void *),
void *data)
{ {
struct workqueue_struct *wq; struct osd_callback_struct *cb;
wq = create_workqueue(name);
if (unlikely(!wq))
return NULL;
return wq;
}
void WorkQueueClose(struct workqueue_struct *hWorkQueue) cb = kmalloc(sizeof(*cb), GFP_KERNEL);
{ if (!cb)
destroy_workqueue(hWorkQueue);
return;
}
int WorkQueueQueueWorkItem(struct workqueue_struct *hWorkQueue,
PFN_WORKITEM_CALLBACK workItem,
void* context)
{
WORKITEM* w = kmalloc(sizeof(WORKITEM), GFP_ATOMIC);
if (!w)
{ {
printk(KERN_ERR "unable to allocate memory in osd_schedule_callback");
return -1; return -1;
} }
w->callback = workItem, cb->callback = func;
w->context = context; cb->data = data;
INIT_WORK(&w->work, WorkItemCallback); INIT_WORK(&cb->work, osd_callback_work);
return queue_work(hWorkQueue, &w->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);
}