From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1423289AbcBZVfk (ORCPT ); Fri, 26 Feb 2016 16:35:40 -0500 Received: from p3plsmtps2ded04.prod.phx3.secureserver.net ([208.109.80.198]:43778 "EHLO p3plsmtps2ded04.prod.phx3.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755451AbcBZVfG (ORCPT ); Fri, 26 Feb 2016 16:35:06 -0500 x-originating-ip: 72.167.245.219 From: "K. Y. Srinivasan" To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com, vkuznets@redhat.com, jasowang@redhat.com Cc: "K. Y. Srinivasan" Subject: [PATCH 7/8] Drivers: hv: vmbus: Support handling messages on multiple CPUs Date: Fri, 26 Feb 2016 15:13:21 -0800 Message-Id: <1456528402-21982-7-git-send-email-kys@microsoft.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1456528402-21982-1-git-send-email-kys@microsoft.com> References: <1456528381-21943-1-git-send-email-kys@microsoft.com> <1456528402-21982-1-git-send-email-kys@microsoft.com> X-CMAE-Envelope: MS4wfD1K5A0ldY65PoiKQ6NNMhmgiA8dXxkBXgeySkvoYLnSVCWV4HhRB4r3WF3GXamv/AVtbWLXTgaa/TvQuHPFT6PX1xAi8FMSyaFrkCLqb92tsyF8HSCc 5KP7CDUUzMQfHWPGUstznjZnxMeGsOT96SrkBqoFRlG0D3vfVYE2EZ68dl/UOJ5XOVb2NVhci8yhxAPLWS5PKzMSwe9q6+SvwcuAhx6BcUGmnwEhW5Ww8i3s jOS8H2Kwhj+expV01WfjieUrpFxbLzWCxpPoXPsEnl5KN+oZMzvlm44v4FEstQwQre12pei2FMaYJsrVLfhsAtFIta/jSONxw4lTQhx4VFt00Xw8MVbUnZIS 2XGtvdea+SpQ+zyw3Uggp+yVAIW9dpkOaUpmdi/e0K6m+oPG8wKYB5SsWCwXygA2uyMALMLZ Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Starting with Windows 2012 R2, message inteerupts can be delivered on any VCPU in the guest. Support this functionality. Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv.c | 10 ++++++++++ drivers/hv/hyperv_vmbus.h | 4 +++- drivers/hv/vmbus_drv.c | 10 ++++------ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index ccb335f..a1c086b 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -204,6 +204,8 @@ int hv_init(void) sizeof(int) * NR_CPUS); memset(hv_context.event_dpc, 0, sizeof(void *) * NR_CPUS); + memset(hv_context.msg_dpc, 0, + sizeof(void *) * NR_CPUS); memset(hv_context.clk_evt, 0, sizeof(void *) * NR_CPUS); @@ -415,6 +417,13 @@ int hv_synic_alloc(void) } tasklet_init(hv_context.event_dpc[cpu], vmbus_on_event, cpu); + hv_context.msg_dpc[cpu] = kmalloc(size, GFP_ATOMIC); + if (hv_context.msg_dpc[cpu] == NULL) { + pr_err("Unable to allocate event dpc\n"); + goto err; + } + tasklet_init(hv_context.msg_dpc[cpu], vmbus_on_msg_dpc, cpu); + hv_context.clk_evt[cpu] = kzalloc(ced_size, GFP_ATOMIC); if (hv_context.clk_evt[cpu] == NULL) { pr_err("Unable to allocate clock event device\n"); @@ -456,6 +465,7 @@ err: static void hv_synic_free_cpu(int cpu) { kfree(hv_context.event_dpc[cpu]); + kfree(hv_context.msg_dpc[cpu]); kfree(hv_context.clk_evt[cpu]); if (hv_context.synic_event_page[cpu]) free_page((unsigned long)hv_context.synic_event_page[cpu]); diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index cada56a..a64b176 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -449,10 +449,11 @@ struct hv_context { u32 vp_index[NR_CPUS]; /* * Starting with win8, we can take channel interrupts on any CPU; - * we will manage the tasklet that handles events on a per CPU + * we will manage the tasklet that handles events messages on a per CPU * basis. */ struct tasklet_struct *event_dpc[NR_CPUS]; + struct tasklet_struct *msg_dpc[NR_CPUS]; /* * To optimize the mapping of relid to channel, maintain * per-cpu list of the channels based on their CPU affinity. @@ -675,6 +676,7 @@ int vmbus_post_msg(void *buffer, size_t buflen); void vmbus_set_event(struct vmbus_channel *channel); void vmbus_on_event(unsigned long data); +void vmbus_on_msg_dpc(unsigned long data); int hv_kvp_init(struct hv_util_service *); void hv_kvp_deinit(void); diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 6cd12f1..64713ff 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -45,7 +45,6 @@ static struct acpi_device *hv_acpi_dev; -static struct tasklet_struct msg_dpc; static struct completion probe_event; @@ -712,7 +711,7 @@ static void hv_process_timer_expiration(struct hv_message *msg, int cpu) vmbus_signal_eom(msg); } -static void vmbus_on_msg_dpc(unsigned long data) +void vmbus_on_msg_dpc(unsigned long data) { int cpu = smp_processor_id(); void *page_addr = hv_context.synic_message_page[cpu]; @@ -800,7 +799,7 @@ static void vmbus_isr(void) if (msg->header.message_type == HVMSG_TIMER_EXPIRED) hv_process_timer_expiration(msg, cpu); else - tasklet_schedule(&msg_dpc); + tasklet_schedule(hv_context.msg_dpc[cpu]); } } @@ -824,8 +823,6 @@ static int vmbus_bus_init(void) return ret; } - tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0); - ret = bus_register(&hv_bus); if (ret) goto err_cleanup; @@ -1321,7 +1318,8 @@ static void __exit vmbus_exit(void) hv_synic_clockevents_cleanup(); vmbus_disconnect(); hv_remove_vmbus_irq(); - tasklet_kill(&msg_dpc); + for_each_online_cpu(cpu) + tasklet_kill(hv_context.msg_dpc[cpu]); vmbus_free_channels(); if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { unregister_die_notifier(&hyperv_die_block); -- 1.7.4.1