aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2012-12-01 09:46:53 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-17 14:39:15 -0500
commitdb11f12a11c9f04d504510e1cc20775209b0e509 (patch)
tree8c19d9cf2f84d8d395a240eda7386d92eed699fd
parent01986313289bd2e143d693f803c7675ea121a832 (diff)
Drivers: hv: Manage event tasklets on per-cpu basis
Now that we can potentially take vmbus interrupts on any CPU, make the tasklets per-CPU. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/hv/hv.c12
-rw-r--r--drivers/hv/hyperv_vmbus.h6
-rw-r--r--drivers/hv/vmbus_drv.c4
3 files changed, 19 insertions, 3 deletions
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index e989c6fd1f8f..363532add4c7 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -27,6 +27,7 @@
27#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
28#include <linux/hyperv.h> 28#include <linux/hyperv.h>
29#include <linux/version.h> 29#include <linux/version.h>
30#include <linux/interrupt.h>
30#include <asm/hyperv.h> 31#include <asm/hyperv.h>
31#include "hyperv_vmbus.h" 32#include "hyperv_vmbus.h"
32 33
@@ -137,6 +138,8 @@ int hv_init(void)
137 sizeof(void *) * NR_CPUS); 138 sizeof(void *) * NR_CPUS);
138 memset(hv_context.vp_index, 0, 139 memset(hv_context.vp_index, 0,
139 sizeof(int) * NR_CPUS); 140 sizeof(int) * NR_CPUS);
141 memset(hv_context.event_dpc, 0,
142 sizeof(void *) * NR_CPUS);
140 143
141 max_leaf = query_hypervisor_info(); 144 max_leaf = query_hypervisor_info();
142 145
@@ -285,6 +288,15 @@ void hv_synic_init(void *irqarg)
285 /* Check the version */ 288 /* Check the version */
286 rdmsrl(HV_X64_MSR_SVERSION, version); 289 rdmsrl(HV_X64_MSR_SVERSION, version);
287 290
291 hv_context.event_dpc[cpu] = (struct tasklet_struct *)
292 kmalloc(sizeof(struct tasklet_struct),
293 GFP_ATOMIC);
294 if (hv_context.event_dpc[cpu] == NULL) {
295 pr_err("Unable to allocate event dpc\n");
296 goto cleanup;
297 }
298 tasklet_init(hv_context.event_dpc[cpu], vmbus_on_event, cpu);
299
288 hv_context.synic_message_page[cpu] = 300 hv_context.synic_message_page[cpu] =
289 (void *)get_zeroed_page(GFP_ATOMIC); 301 (void *)get_zeroed_page(GFP_ATOMIC);
290 302
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 9135a6fcf3bd..becb106918d6 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -504,6 +504,12 @@ struct hv_context {
504 * Linux cpuid 'a'. 504 * Linux cpuid 'a'.
505 */ 505 */
506 u32 vp_index[NR_CPUS]; 506 u32 vp_index[NR_CPUS];
507 /*
508 * Starting with win8, we can take channel interrupts on any CPU;
509 * we will manage the tasklet that handles events on a per CPU
510 * basis.
511 */
512 struct tasklet_struct *event_dpc[NR_CPUS];
507}; 513};
508 514
509extern struct hv_context hv_context; 515extern struct hv_context hv_context;
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 4c92337ddae6..6e4f85720f26 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -41,7 +41,6 @@
41static struct acpi_device *hv_acpi_dev; 41static struct acpi_device *hv_acpi_dev;
42 42
43static struct tasklet_struct msg_dpc; 43static struct tasklet_struct msg_dpc;
44static struct tasklet_struct event_dpc;
45static struct completion probe_event; 44static struct completion probe_event;
46static int irq; 45static int irq;
47 46
@@ -483,7 +482,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
483 } 482 }
484 483
485 if (handled) 484 if (handled)
486 tasklet_schedule(&event_dpc); 485 tasklet_schedule(hv_context.event_dpc[cpu]);
487 486
488 487
489 page_addr = hv_context.synic_message_page[cpu]; 488 page_addr = hv_context.synic_message_page[cpu];
@@ -523,7 +522,6 @@ static int vmbus_bus_init(int irq)
523 } 522 }
524 523
525 tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0); 524 tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
526 tasklet_init(&event_dpc, vmbus_on_event, 0);
527 525
528 ret = bus_register(&hv_bus); 526 ret = bus_register(&hv_bus);
529 if (ret) 527 if (ret)