fate#314663 hyper-v memory ballooning support
[opensuse:kernel-source.git] / patches.suse / suse-hv-fate314665-0022-Drivers-hv-Manage-event-tasklets-on-per-cpu-basis.patch
1 Patch-mainline: submitted
2 From: <ohering@suse.de>
3 Date: Sat, 1 Dec 2012 06:46:53 -0800
4 Subject: [PATCH 22/28] Drivers: hv: Manage event tasklets on per-cpu basis
5
6 Now that we can potentially take vmbus interrupts on any CPU, make the
7 tasklets per-CPU.
8
9 Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
10 Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
11 ---
12  drivers/hv/hv.c           | 12 ++++++++++++
13  drivers/hv/hyperv_vmbus.h |  6 ++++++
14  drivers/hv/vmbus_drv.c    |  4 +---
15  3 files changed, 19 insertions(+), 3 deletions(-)
16
17 diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
18 index e989c6fd..363532a 100644
19 --- a/drivers/hv/hv.c
20 +++ b/drivers/hv/hv.c
21 @@ -27,6 +27,7 @@
22  #include <linux/vmalloc.h>
23  #include <linux/hyperv.h>
24  #include <linux/version.h>
25 +#include <linux/interrupt.h>
26  #include <asm/hyperv.h>
27  #include "hyperv_vmbus.h"
28  
29 @@ -137,6 +138,8 @@ int hv_init(void)
30                sizeof(void *) * NR_CPUS);
31         memset(hv_context.vp_index, 0,
32                sizeof(int) * NR_CPUS);
33 +       memset(hv_context.event_dpc, 0,
34 +              sizeof(void *) * NR_CPUS);
35  
36         max_leaf = query_hypervisor_info();
37  
38 @@ -285,6 +288,15 @@ void hv_synic_init(void *irqarg)
39         /* Check the version */
40         rdmsrl(HV_X64_MSR_SVERSION, version);
41  
42 +       hv_context.event_dpc[cpu] = (struct tasklet_struct *)
43 +                                       kmalloc(sizeof(struct tasklet_struct),
44 +                                               GFP_ATOMIC);
45 +       if (hv_context.event_dpc[cpu] == NULL) {
46 +               pr_err("Unable to allocate event dpc\n");
47 +               goto cleanup;
48 +       }
49 +       tasklet_init(hv_context.event_dpc[cpu], vmbus_on_event, cpu);
50 +
51         hv_context.synic_message_page[cpu] =
52                 (void *)get_zeroed_page(GFP_ATOMIC);
53  
54 diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
55 index 9135a6f..becb106 100644
56 --- a/drivers/hv/hyperv_vmbus.h
57 +++ b/drivers/hv/hyperv_vmbus.h
58 @@ -504,6 +504,12 @@ struct hv_context {
59          * Linux cpuid 'a'.
60          */
61         u32 vp_index[NR_CPUS];
62 +       /*
63 +        * Starting with win8, we can take channel interrupts on any CPU;
64 +        * we will manage the tasklet that handles events on a per CPU
65 +        * basis.
66 +        */
67 +       struct tasklet_struct *event_dpc[NR_CPUS];
68  };
69  
70  extern struct hv_context hv_context;
71 diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
72 index 4c92337..6e4f857 100644
73 --- a/drivers/hv/vmbus_drv.c
74 +++ b/drivers/hv/vmbus_drv.c
75 @@ -41,7 +41,6 @@
76  static struct acpi_device  *hv_acpi_dev;
77  
78  static struct tasklet_struct msg_dpc;
79 -static struct tasklet_struct event_dpc;
80  static struct completion probe_event;
81  static int irq;
82  
83 @@ -483,7 +482,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
84         }
85  
86         if (handled)
87 -               tasklet_schedule(&event_dpc);
88 +               tasklet_schedule(hv_context.event_dpc[cpu]);
89  
90  
91         page_addr = hv_context.synic_message_page[cpu];
92 @@ -523,7 +522,6 @@ static int vmbus_bus_init(int irq)
93         }
94  
95         tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
96 -       tasklet_init(&event_dpc, vmbus_on_event, 0);
97  
98         ret = bus_register(&hv_bus);
99         if (ret)
100 -- 
101 1.8.0.1
102