]>
Commit | Line | Data |
---|---|---|
12f2d15d | 1 | diff -X dontdiff -Naur linux-cvs/arch/i386/oprofile/nmi_int.c linux-fixes/arch/i386/oprofile/nmi_int.c |
2 | --- linux-cvs/arch/i386/oprofile/nmi_int.c 2003-06-18 15:06:05.000000000 +0100 | |
3 | +++ linux-fixes/arch/i386/oprofile/nmi_int.c 2003-08-11 20:40:22.000000000 +0100 | |
4 | @@ -12,6 +12,7 @@ | |
5 | #include <linux/smp.h> | |
6 | #include <linux/oprofile.h> | |
7 | #include <linux/sysdev.h> | |
8 | +#include <linux/slab.h> | |
9 | #include <asm/nmi.h> | |
10 | #include <asm/msr.h> | |
11 | #include <asm/apic.h> | |
12 | @@ -91,24 +92,66 @@ | |
13 | { | |
14 | unsigned int const nr_ctrs = model->num_counters; | |
15 | unsigned int const nr_ctrls = model->num_controls; | |
16 | - struct op_msr_group * counters = &msrs->counters; | |
17 | - struct op_msr_group * controls = &msrs->controls; | |
18 | + struct op_msr * counters = msrs->counters; | |
19 | + struct op_msr * controls = msrs->controls; | |
20 | unsigned int i; | |
21 | ||
22 | for (i = 0; i < nr_ctrs; ++i) { | |
23 | - rdmsr(counters->addrs[i], | |
24 | - counters->saved[i].low, | |
25 | - counters->saved[i].high); | |
26 | + rdmsr(counters[i].addr, | |
27 | + counters[i].saved.low, | |
28 | + counters[i].saved.high); | |
29 | } | |
30 | ||
31 | for (i = 0; i < nr_ctrls; ++i) { | |
32 | - rdmsr(controls->addrs[i], | |
33 | - controls->saved[i].low, | |
34 | - controls->saved[i].high); | |
35 | + rdmsr(controls[i].addr, | |
36 | + controls[i].saved.low, | |
37 | + controls[i].saved.high); | |
38 | } | |
39 | } | |
40 | ||
41 | - | |
42 | + | |
43 | +static void free_msrs(void) | |
44 | +{ | |
45 | + int i; | |
46 | + for (i = 0; i < NR_CPUS; ++i) { | |
47 | + kfree(cpu_msrs[i].counters); | |
48 | + cpu_msrs[i].counters = NULL; | |
49 | + kfree(cpu_msrs[i].controls); | |
50 | + cpu_msrs[i].controls = NULL; | |
51 | + } | |
52 | +} | |
53 | + | |
54 | + | |
55 | +static int allocate_msrs(void) | |
56 | +{ | |
57 | + int success = 1; | |
58 | + size_t controls_size = sizeof(struct op_msr) * model->num_controls; | |
59 | + size_t counters_size = sizeof(struct op_msr) * model->num_counters; | |
60 | + | |
61 | + int i; | |
62 | + for (i = 0; i < NR_CPUS; ++i) { | |
63 | + if (!cpu_online(i)) | |
64 | + continue; | |
65 | + | |
66 | + cpu_msrs[i].counters = kmalloc(counters_size, GFP_KERNEL); | |
67 | + if (!cpu_msrs[i].counters) { | |
68 | + success = 0; | |
69 | + break; | |
70 | + } | |
71 | + cpu_msrs[i].controls = kmalloc(controls_size, GFP_KERNEL); | |
72 | + if (!cpu_msrs[i].controls) { | |
73 | + success = 0; | |
74 | + break; | |
75 | + } | |
76 | + } | |
77 | + | |
78 | + if (!success) | |
79 | + free_msrs(); | |
80 | + | |
81 | + return success; | |
82 | +} | |
83 | + | |
84 | + | |
85 | static void nmi_cpu_setup(void * dummy) | |
86 | { | |
87 | int cpu = smp_processor_id(); | |
88 | @@ -125,6 +168,9 @@ | |
89 | ||
90 | static int nmi_setup(void) | |
91 | { | |
92 | + if (!allocate_msrs()) | |
93 | + return -ENOMEM; | |
94 | + | |
95 | /* We walk a thin line between law and rape here. | |
96 | * We need to be careful to install our NMI handler | |
97 | * without actually triggering any NMIs as this will | |
98 | @@ -142,20 +188,20 @@ | |
99 | { | |
100 | unsigned int const nr_ctrs = model->num_counters; | |
101 | unsigned int const nr_ctrls = model->num_controls; | |
102 | - struct op_msr_group * counters = &msrs->counters; | |
103 | - struct op_msr_group * controls = &msrs->controls; | |
104 | + struct op_msr * counters = msrs->counters; | |
105 | + struct op_msr * controls = msrs->controls; | |
106 | unsigned int i; | |
107 | ||
108 | for (i = 0; i < nr_ctrls; ++i) { | |
109 | - wrmsr(controls->addrs[i], | |
110 | - controls->saved[i].low, | |
111 | - controls->saved[i].high); | |
112 | + wrmsr(controls[i].addr, | |
113 | + controls[i].saved.low, | |
114 | + controls[i].saved.high); | |
115 | } | |
116 | ||
117 | for (i = 0; i < nr_ctrs; ++i) { | |
118 | - wrmsr(counters->addrs[i], | |
119 | - counters->saved[i].low, | |
120 | - counters->saved[i].high); | |
121 | + wrmsr(counters[i].addr, | |
122 | + counters[i].saved.low, | |
123 | + counters[i].saved.high); | |
124 | } | |
125 | } | |
126 | ||
127 | @@ -185,6 +231,7 @@ | |
128 | on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1); | |
129 | unset_nmi_callback(); | |
130 | enable_lapic_nmi_watchdog(); | |
131 | + free_msrs(); | |
132 | } | |
133 | ||
134 | ||
135 | diff -X dontdiff -Naur linux-cvs/arch/i386/oprofile/op_model_athlon.c linux-fixes/arch/i386/oprofile/op_model_athlon.c | |
136 | --- linux-cvs/arch/i386/oprofile/op_model_athlon.c 2003-06-15 02:06:38.000000000 +0100 | |
137 | +++ linux-fixes/arch/i386/oprofile/op_model_athlon.c 2003-08-11 20:28:31.000000000 +0100 | |
138 | @@ -20,12 +20,12 @@ | |
139 | #define NUM_COUNTERS 4 | |
140 | #define NUM_CONTROLS 4 | |
141 | ||
142 | -#define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters.addrs[(c)], (l), (h));} while (0) | |
143 | -#define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters.addrs[(c)], -(unsigned int)(l), -1);} while (0) | |
144 | +#define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0) | |
145 | +#define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1);} while (0) | |
146 | #define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) | |
147 | ||
148 | -#define CTRL_READ(l,h,msrs,c) do {rdmsr(msrs->controls.addrs[(c)], (l), (h));} while (0) | |
149 | -#define CTRL_WRITE(l,h,msrs,c) do {wrmsr(msrs->controls.addrs[(c)], (l), (h));} while (0) | |
150 | +#define CTRL_READ(l,h,msrs,c) do {rdmsr(msrs->controls[(c)].addr, (l), (h));} while (0) | |
151 | +#define CTRL_WRITE(l,h,msrs,c) do {wrmsr(msrs->controls[(c)].addr, (l), (h));} while (0) | |
152 | #define CTRL_SET_ACTIVE(n) (n |= (1<<22)) | |
153 | #define CTRL_SET_INACTIVE(n) (n &= ~(1<<22)) | |
154 | #define CTRL_CLEAR(x) (x &= (1<<21)) | |
155 | @@ -39,15 +39,15 @@ | |
156 | ||
157 | static void athlon_fill_in_addresses(struct op_msrs * const msrs) | |
158 | { | |
159 | - msrs->counters.addrs[0] = MSR_K7_PERFCTR0; | |
160 | - msrs->counters.addrs[1] = MSR_K7_PERFCTR1; | |
161 | - msrs->counters.addrs[2] = MSR_K7_PERFCTR2; | |
162 | - msrs->counters.addrs[3] = MSR_K7_PERFCTR3; | |
163 | - | |
164 | - msrs->controls.addrs[0] = MSR_K7_EVNTSEL0; | |
165 | - msrs->controls.addrs[1] = MSR_K7_EVNTSEL1; | |
166 | - msrs->controls.addrs[2] = MSR_K7_EVNTSEL2; | |
167 | - msrs->controls.addrs[3] = MSR_K7_EVNTSEL3; | |
168 | + msrs->counters[0].addr = MSR_K7_PERFCTR0; | |
169 | + msrs->counters[1].addr = MSR_K7_PERFCTR1; | |
170 | + msrs->counters[2].addr = MSR_K7_PERFCTR2; | |
171 | + msrs->counters[3].addr = MSR_K7_PERFCTR3; | |
172 | + | |
173 | + msrs->controls[0].addr = MSR_K7_EVNTSEL0; | |
174 | + msrs->controls[1].addr = MSR_K7_EVNTSEL1; | |
175 | + msrs->controls[2].addr = MSR_K7_EVNTSEL2; | |
176 | + msrs->controls[3].addr = MSR_K7_EVNTSEL3; | |
177 | } | |
178 | ||
179 | ||
180 | diff -X dontdiff -Naur linux-cvs/arch/i386/oprofile/op_model_p4.c linux-fixes/arch/i386/oprofile/op_model_p4.c | |
181 | --- linux-cvs/arch/i386/oprofile/op_model_p4.c 2003-08-14 13:21:20.000000000 +0100 | |
182 | +++ linux-fixes/arch/i386/oprofile/op_model_p4.c 2003-08-14 13:19:23.000000000 +0100 | |
183 | @@ -410,7 +410,7 @@ | |
184 | ||
185 | /* the counter registers we pay attention to */ | |
186 | for (i = 0; i < num_counters; ++i) { | |
187 | - msrs->counters.addrs[i] = | |
188 | + msrs->counters[i].addr = | |
189 | p4_counters[VIRT_CTR(stag, i)].counter_address; | |
190 | } | |
191 | ||
192 | @@ -419,42 +419,42 @@ | |
193 | /* 18 CCCR registers */ | |
194 | for (i = 0, addr = MSR_P4_BPU_CCCR0 + stag; | |
195 | addr <= MSR_P4_IQ_CCCR5; ++i, addr += addr_increment()) { | |
196 | - msrs->controls.addrs[i] = addr; | |
197 | + msrs->controls[i].addr = addr; | |
198 | } | |
199 | ||
200 | /* 43 ESCR registers in three discontiguous group */ | |
201 | for (addr = MSR_P4_BSU_ESCR0 + stag; | |
202 | addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { | |
203 | - msrs->controls.addrs[i] = addr; | |
204 | + msrs->controls[i].addr = addr; | |
205 | } | |
206 | ||
207 | for (addr = MSR_P4_MS_ESCR0 + stag; | |
208 | addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) { | |
209 | - msrs->controls.addrs[i] = addr; | |
210 | + msrs->controls[i].addr = addr; | |
211 | } | |
212 | ||
213 | for (addr = MSR_P4_IX_ESCR0 + stag; | |
214 | addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) { | |
215 | - msrs->controls.addrs[i] = addr; | |
216 | + msrs->controls[i].addr = addr; | |
217 | } | |
218 | ||
219 | /* there are 2 remaining non-contiguously located ESCRs */ | |
220 | ||
221 | if (num_counters == NUM_COUNTERS_NON_HT) { | |
222 | /* standard non-HT CPUs handle both remaining ESCRs*/ | |
223 | - msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR5; | |
224 | - msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR4; | |
225 | + msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; | |
226 | + msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; | |
227 | ||
228 | } else if (stag == 0) { | |
229 | /* HT CPUs give the first remainder to the even thread, as | |
230 | the 32nd control register */ | |
231 | - msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR4; | |
232 | + msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; | |
233 | ||
234 | } else { | |
235 | /* and two copies of the second to the odd thread, | |
236 | for the 22st and 23nd control registers */ | |
237 | - msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR5; | |
238 | - msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR5; | |
239 | + msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; | |
240 | + msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; | |
241 | } | |
242 | } | |
243 | ||
244 | diff -X dontdiff -Naur linux-cvs/arch/i386/oprofile/op_model_ppro.c linux-fixes/arch/i386/oprofile/op_model_ppro.c | |
245 | --- linux-cvs/arch/i386/oprofile/op_model_ppro.c 2003-06-15 02:06:38.000000000 +0100 | |
246 | +++ linux-fixes/arch/i386/oprofile/op_model_ppro.c 2003-08-11 20:29:33.000000000 +0100 | |
247 | @@ -20,12 +20,12 @@ | |
248 | #define NUM_COUNTERS 2 | |
249 | #define NUM_CONTROLS 2 | |
250 | ||
251 | -#define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters.addrs[(c)], (l), (h));} while (0) | |
252 | -#define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters.addrs[(c)], -(u32)(l), -1);} while (0) | |
253 | +#define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0) | |
254 | +#define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(u32)(l), -1);} while (0) | |
255 | #define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) | |
256 | ||
257 | -#define CTRL_READ(l,h,msrs,c) do {rdmsr((msrs->controls.addrs[(c)]), (l), (h));} while (0) | |
258 | -#define CTRL_WRITE(l,h,msrs,c) do {wrmsr((msrs->controls.addrs[(c)]), (l), (h));} while (0) | |
259 | +#define CTRL_READ(l,h,msrs,c) do {rdmsr((msrs->controls[(c)].addr), (l), (h));} while (0) | |
260 | +#define CTRL_WRITE(l,h,msrs,c) do {wrmsr((msrs->controls[(c)].addr), (l), (h));} while (0) | |
261 | #define CTRL_SET_ACTIVE(n) (n |= (1<<22)) | |
262 | #define CTRL_SET_INACTIVE(n) (n &= ~(1<<22)) | |
263 | #define CTRL_CLEAR(x) (x &= (1<<21)) | |
264 | @@ -39,11 +39,11 @@ | |
265 | ||
266 | static void ppro_fill_in_addresses(struct op_msrs * const msrs) | |
267 | { | |
268 | - msrs->counters.addrs[0] = MSR_P6_PERFCTR0; | |
269 | - msrs->counters.addrs[1] = MSR_P6_PERFCTR1; | |
270 | + msrs->counters[0].addr = MSR_P6_PERFCTR0; | |
271 | + msrs->counters[1].addr = MSR_P6_PERFCTR1; | |
272 | ||
273 | - msrs->controls.addrs[0] = MSR_P6_EVNTSEL0; | |
274 | - msrs->controls.addrs[1] = MSR_P6_EVNTSEL1; | |
275 | + msrs->controls[0].addr = MSR_P6_EVNTSEL0; | |
276 | + msrs->controls[1].addr = MSR_P6_EVNTSEL1; | |
277 | } | |
278 | ||
279 | ||
280 | diff -X dontdiff -Naur linux-cvs/arch/i386/oprofile/op_x86_model.h linux-fixes/arch/i386/oprofile/op_x86_model.h | |
281 | --- linux-cvs/arch/i386/oprofile/op_x86_model.h 2003-06-15 02:06:38.000000000 +0100 | |
282 | +++ linux-fixes/arch/i386/oprofile/op_x86_model.h 2003-08-11 20:08:27.000000000 +0100 | |
283 | @@ -11,22 +11,19 @@ | |
284 | #ifndef OP_X86_MODEL_H | |
285 | #define OP_X86_MODEL_H | |
286 | ||
287 | -/* Pentium IV needs all these */ | |
288 | -#define MAX_MSR 63 | |
289 | - | |
290 | struct op_saved_msr { | |
291 | unsigned int high; | |
292 | unsigned int low; | |
293 | }; | |
294 | ||
295 | -struct op_msr_group { | |
296 | - unsigned int addrs[MAX_MSR]; | |
297 | - struct op_saved_msr saved[MAX_MSR]; | |
298 | +struct op_msr { | |
299 | + unsigned long addr; | |
300 | + struct op_saved_msr saved; | |
301 | }; | |
302 | ||
303 | struct op_msrs { | |
304 | - struct op_msr_group counters; | |
305 | - struct op_msr_group controls; | |
306 | + struct op_msr * counters; | |
307 | + struct op_msr * controls; | |
308 | }; | |
309 | ||
310 | struct pt_regs; | |
311 |