The additional abstraction is unneeded. This also fixes a sleeping while atomic issue as osd_schedule_callback can sleep which is not allowed for VmbusOnMsgDPC running in a tasklet. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=16701 Cc: Haiyang Zhang <haiyangz@xxxxxxxxxxxxx> Cc: Hank Janssen <hjanssen@xxxxxxxxxxxxx> Signed-off-by: Timo TerÃs <timo.teras@xxxxxx> --- drivers/staging/hv/channel_mgmt.c | 4 ---- drivers/staging/hv/vmbus.c | 27 +++++++++++++++++++++------ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 45dbe30..07806a3 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -753,7 +753,6 @@ void vmbus_onmessage(void *context) hdr->MessageType, size); print_hex_dump_bytes("", DUMP_PREFIX_NONE, (unsigned char *)msg->u.Payload, size); - kfree(msg); return; } @@ -762,9 +761,6 @@ void vmbus_onmessage(void *context) else DPRINT_ERR(VMBUS, "Unhandled channel message type %d", hdr->MessageType); - - /* Free the msg that was allocated in VmbusOnMsgDPC() */ - kfree(msg); } /* diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index d449daf..8607046 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -141,6 +141,21 @@ static void VmbusOnCleanup(struct hv_driver *drv) HvCleanup(); } +struct onmessage_work_context { + struct work_struct work; + struct hv_message msg; +}; + +static void vmbus_onmessage_work(struct work_struct *work) +{ + struct onmessage_work_context *ctx; + + ctx = container_of(work, struct onmessage_work_context, + work); + vmbus_onmessage(&ctx->msg); + kfree(ctx); +} + /* * VmbusOnMsgDPC - DPC routine to handle messages from the hypervisior */ @@ -150,20 +165,20 @@ static void VmbusOnMsgDPC(struct hv_driver *drv) void *page_addr = gHvContext.synICMessagePage[cpu]; struct hv_message *msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; - struct hv_message *copied; + struct onmessage_work_context *ctx; while (1) { if (msg->Header.MessageType == HvMessageTypeNone) { /* no msg */ break; } else { - copied = kmemdup(msg, sizeof(*copied), GFP_ATOMIC); - if (copied == NULL) + ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC); + if (ctx == NULL) continue; - osd_schedule_callback(gVmbusConnection.WorkQueue, - vmbus_onmessage, - (void *)copied); + INIT_WORK(&ctx->work, vmbus_onmessage_work); + memcpy(&ctx->msg, msg, sizeof(*msg)); + queue_work(gVmbusConnection.WorkQueue, &ctx->work); } msg->Header.MessageType = HvMessageTypeNone; -- 1.7.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel