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)  			   hdr->msgtype, 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->msgtype); - -	/* Free the msg that was allocated in VmbusOnMsgDPC() */ -	kfree(msg);  }  /* 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)  	hv_cleanup();  } +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); +} +  /*   * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior   */ @@ -212,20 +227,19 @@ static void vmbus_on_msg_dpc(struct hv_driver *drv)  	void *page_addr = hv_context.synic_message_page[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.message_type == HVMSG_NONE) {  			/* 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.message_type = HVMSG_NONE; | 
