This is a note to let you know that I've just added the patch titled

    staging: hv: convert vmbus_on_msg_dpc to not call osd_schedule_callback

to my staging git tree which can be found at
    git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git
in the staging-next branch.

The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)

The patch will also will be merged in the next major kernel release
during the merge window.

If you have any questions about this process, please let me know.


From bf6506f60c46c8a709df534408cc6d470df657ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <[email protected]>
Date: Wed, 15 Dec 2010 20:48:08 +0200
Subject: staging: hv: convert vmbus_on_msg_dpc to not call osd_schedule_callback
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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 <[email protected]>
Cc: Haiyang Zhang <[email protected]>
Signed-off-by: Timo Teräs <[email protected]>
Cc: stable <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 drivers/staging/hv/channel_mgmt.c |    4 ----
 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 0f4d609..6f393e7 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 d794b60..84fdb64 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;
-- 
1.7.1


_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to