From patchwork Tue Oct 21 20:09:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamal Mostafa X-Patchwork-Id: 401714 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 7B250140088; Wed, 22 Oct 2014 07:11:11 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1Xgfls-0003Hv-LV; Tue, 21 Oct 2014 20:11:08 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1Xgfk8-0002Cy-9W for kernel-team@lists.ubuntu.com; Tue, 21 Oct 2014 20:09:20 +0000 Received: from c-76-102-4-12.hsd1.ca.comcast.net ([76.102.4.12] helo=fourier) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1Xgfk8-00088T-1J; Tue, 21 Oct 2014 20:09:20 +0000 Received: from kamal by fourier with local (Exim 4.82) (envelope-from ) id 1Xgfk6-0006eQ-Au; Tue, 21 Oct 2014 13:09:18 -0700 From: Kamal Mostafa To: "K. Y. Srinivasan" Subject: [3.13.y.z extended stable] Patch "Drivers: hv: vmbus: Cleanup hv_post_message()" has been added to staging queue Date: Tue, 21 Oct 2014 13:09:18 -0700 Message-Id: <1413922158-25535-1-git-send-email-kamal@canonical.com> X-Mailer: git-send-email 1.9.1 X-Extended-Stable: 3.13 Cc: Greg Kroah-Hartman , Kamal Mostafa , Sitsofe Wheeler , kernel-team@lists.ubuntu.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com This is a note to let you know that I have just added a patch titled Drivers: hv: vmbus: Cleanup hv_post_message() to the linux-3.13.y-queue branch of the 3.13.y.z extended stable tree which can be found at: http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.13.y-queue This patch is scheduled to be released in version 3.13.11.10. If you, or anyone else, feels it should not be added to this tree, please reply to this email. For more information about the 3.13.y.z tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Kamal ------ From 181da8685bd6e7899475f069f51dab23b30c641f Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 28 Aug 2014 18:29:52 -0700 Subject: Drivers: hv: vmbus: Cleanup hv_post_message() commit b29ef3546aecb253a5552b198cef23750d56e1e4 upstream. Minimize failures in this function by pre-allocating the buffer for posting messages. The hypercall for posting the message can fail for a number of reasons: 1. Transient resource related issues 2. Buffer alignment 3. Buffer cannot span a page boundry We address issues 2 and 3 by preallocating a per-cpu page for the buffer. Transient resource related failures are handled by retrying by the callers of this function. This patch is based on the investigation done by Dexuan Cui . I would like to thank Sitsofe Wheeler for reporting the issue and helping in debuggging. Signed-off-by: K. Y. Srinivasan Reported-by: Sitsofe Wheeler Tested-by: Sitsofe Wheeler Signed-off-by: Greg Kroah-Hartman Signed-off-by: Kamal Mostafa --- drivers/hv/hv.c | 27 +++++++++++++++------------ drivers/hv/hyperv_vmbus.h | 4 ++++ 2 files changed, 19 insertions(+), 12 deletions(-) -- 1.9.1 diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index f0c5e07..0e3c124 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -138,6 +138,8 @@ int hv_init(void) memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS); memset(hv_context.synic_message_page, 0, sizeof(void *) * NR_CPUS); + memset(hv_context.post_msg_page, 0, + sizeof(void *) * NR_CPUS); memset(hv_context.vp_index, 0, sizeof(int) * NR_CPUS); memset(hv_context.event_dpc, 0, @@ -217,26 +219,18 @@ int hv_post_message(union hv_connection_id connection_id, enum hv_message_type message_type, void *payload, size_t payload_size) { - struct aligned_input { - u64 alignment8; - struct hv_input_post_message msg; - }; struct hv_input_post_message *aligned_msg; u16 status; - unsigned long addr; if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT) return -EMSGSIZE; - addr = (unsigned long)kmalloc(sizeof(struct aligned_input), GFP_ATOMIC); - if (!addr) - return -ENOMEM; - aligned_msg = (struct hv_input_post_message *) - (ALIGN(addr, HV_HYPERCALL_PARAM_ALIGN)); + hv_context.post_msg_page[get_cpu()]; aligned_msg->connectionid = connection_id; + aligned_msg->reserved = 0; aligned_msg->message_type = message_type; aligned_msg->payload_size = payload_size; memcpy((void *)aligned_msg->payload, payload, payload_size); @@ -244,8 +238,7 @@ int hv_post_message(union hv_connection_id connection_id, status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL) & 0xFFFF; - kfree((void *)addr); - + put_cpu(); return status; } @@ -294,6 +287,14 @@ int hv_synic_alloc(void) pr_err("Unable to allocate SYNIC event page\n"); goto err; } + + hv_context.post_msg_page[cpu] = + (void *)get_zeroed_page(GFP_ATOMIC); + + if (hv_context.post_msg_page[cpu] == NULL) { + pr_err("Unable to allocate post msg page\n"); + goto err; + } } return 0; @@ -308,6 +309,8 @@ void hv_synic_free_cpu(int cpu) free_page((unsigned long)hv_context.synic_event_page[cpu]); if (hv_context.synic_message_page[cpu]) free_page((unsigned long)hv_context.synic_message_page[cpu]); + if (hv_context.post_msg_page[cpu]) + free_page((unsigned long)hv_context.post_msg_page[cpu]); } void hv_synic_free(void) diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index e055176..9fa0cab 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -510,6 +510,10 @@ struct hv_context { * basis. */ struct tasklet_struct *event_dpc[NR_CPUS]; + /* + * buffer to post messages to the host. + */ + void *post_msg_page[NR_CPUS]; }; extern struct hv_context hv_context;