diff options
| -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; |
