diff options
author | Timo Teräs <timo.teras@iki.fi> | 2010-12-15 13:48:08 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-12-16 15:35:14 -0500 |
commit | bf6506f60c46c8a709df534408cc6d470df657ff (patch) | |
tree | b870adf16c465d746796cda01def14d7a8d97046 | |
parent | f4528696d803749892eac27422a6fd7748cffee1 (diff) |
staging: hv: convert vmbus_on_msg_dpc to not call osd_schedule_callback
The additional abstraction is unneeded. This also fixes a sleeping
while atomic issue as osd_schedule_callback can sleep which is
not allowed for vmbus_on_msg_dpc running in a tasklet.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=16701
Reviewed-By: Hank Janssen <hjanssen@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/hv/channel_mgmt.c | 4 | ||||
-rw-r--r-- | drivers/staging/hv/vmbus_drv.c | 28 |
2 files changed, 21 insertions, 11 deletions
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 0f4d6093f674..6f393e7d8e25 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c | |||
@@ -753,7 +753,6 @@ void vmbus_onmessage(void *context) | |||
753 | hdr->msgtype, size); | 753 | hdr->msgtype, size); |
754 | print_hex_dump_bytes("", DUMP_PREFIX_NONE, | 754 | print_hex_dump_bytes("", DUMP_PREFIX_NONE, |
755 | (unsigned char *)msg->u.payload, size); | 755 | (unsigned char *)msg->u.payload, size); |
756 | kfree(msg); | ||
757 | return; | 756 | return; |
758 | } | 757 | } |
759 | 758 | ||
@@ -762,9 +761,6 @@ void vmbus_onmessage(void *context) | |||
762 | else | 761 | else |
763 | DPRINT_ERR(VMBUS, "Unhandled channel message type %d", | 762 | DPRINT_ERR(VMBUS, "Unhandled channel message type %d", |
764 | hdr->msgtype); | 763 | hdr->msgtype); |
765 | |||
766 | /* Free the msg that was allocated in VmbusOnMsgDPC() */ | ||
767 | kfree(msg); | ||
768 | } | 764 | } |
769 | 765 | ||
770 | /* | 766 | /* |
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index d794b603bf17..84fdb64d3ceb 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c | |||
@@ -203,6 +203,21 @@ static void VmbusOnCleanup(struct hv_driver *drv) | |||
203 | hv_cleanup(); | 203 | hv_cleanup(); |
204 | } | 204 | } |
205 | 205 | ||
206 | struct onmessage_work_context { | ||
207 | struct work_struct work; | ||
208 | struct hv_message msg; | ||
209 | }; | ||
210 | |||
211 | static void vmbus_onmessage_work(struct work_struct *work) | ||
212 | { | ||
213 | struct onmessage_work_context *ctx; | ||
214 | |||
215 | ctx = container_of(work, struct onmessage_work_context, | ||
216 | work); | ||
217 | vmbus_onmessage(&ctx->msg); | ||
218 | kfree(ctx); | ||
219 | } | ||
220 | |||
206 | /* | 221 | /* |
207 | * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior | 222 | * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior |
208 | */ | 223 | */ |
@@ -212,20 +227,19 @@ static void vmbus_on_msg_dpc(struct hv_driver *drv) | |||
212 | void *page_addr = hv_context.synic_message_page[cpu]; | 227 | void *page_addr = hv_context.synic_message_page[cpu]; |
213 | struct hv_message *msg = (struct hv_message *)page_addr + | 228 | struct hv_message *msg = (struct hv_message *)page_addr + |
214 | VMBUS_MESSAGE_SINT; | 229 | VMBUS_MESSAGE_SINT; |
215 | struct hv_message *copied; | 230 | struct onmessage_work_context *ctx; |
216 | 231 | ||
217 | while (1) { | 232 | while (1) { |
218 | if (msg->header.message_type == HVMSG_NONE) { | 233 | if (msg->header.message_type == HVMSG_NONE) { |
219 | /* no msg */ | 234 | /* no msg */ |
220 | break; | 235 | break; |
221 | } else { | 236 | } else { |
222 | copied = kmemdup(msg, sizeof(*copied), GFP_ATOMIC); | 237 | ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC); |
223 | if (copied == NULL) | 238 | if (ctx == NULL) |
224 | continue; | 239 | continue; |
225 | 240 | INIT_WORK(&ctx->work, vmbus_onmessage_work); | |
226 | osd_schedule_callback(gVmbusConnection.WorkQueue, | 241 | memcpy(&ctx->msg, msg, sizeof(*msg)); |
227 | vmbus_onmessage, | 242 | queue_work(gVmbusConnection.WorkQueue, &ctx->work); |
228 | (void *)copied); | ||
229 | } | 243 | } |
230 | 244 | ||
231 | msg->header.message_type = HVMSG_NONE; | 245 | msg->header.message_type = HVMSG_NONE; |