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
6 #include <linux/oprofile.h>
7 #include <linux/sysdev.h>
8 +#include <linux/slab.h>
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;
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);
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);
43 +static void free_msrs(void)
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;
55 +static int allocate_msrs(void)
58 + size_t controls_size = sizeof(struct op_msr) * model->num_controls;
59 + size_t counters_size = sizeof(struct op_msr) * model->num_counters;
62 + for (i = 0; i < NR_CPUS; ++i) {
66 + cpu_msrs[i].counters = kmalloc(counters_size, GFP_KERNEL);
67 + if (!cpu_msrs[i].counters) {
71 + cpu_msrs[i].controls = kmalloc(controls_size, GFP_KERNEL);
72 + if (!cpu_msrs[i].controls) {
85 static void nmi_cpu_setup(void * dummy)
87 int cpu = smp_processor_id();
90 static int nmi_setup(void)
92 + if (!allocate_msrs())
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
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;
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);
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);
128 on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
129 unset_nmi_callback();
130 enable_lapic_nmi_watchdog();
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
139 #define NUM_COUNTERS 4
140 #define NUM_CONTROLS 4
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)))
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))
157 static void athlon_fill_in_addresses(struct op_msrs * const msrs)
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;
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;
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;
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
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;
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;
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;
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;
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;
219 /* there are 2 remaining non-contiguously located ESCRs */
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;
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;
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;
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
248 #define NUM_COUNTERS 2
249 #define NUM_CONTROLS 2
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)))
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))
266 static void ppro_fill_in_addresses(struct op_msrs * const msrs)
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;
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;
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
284 #ifndef OP_X86_MODEL_H
285 #define OP_X86_MODEL_H
287 -/* Pentium IV needs all these */
290 struct op_saved_msr {
295 -struct op_msr_group {
296 - unsigned int addrs[MAX_MSR];
297 - struct op_saved_msr saved[MAX_MSR];
299 + unsigned long addr;
300 + struct op_saved_msr saved;
304 - struct op_msr_group counters;
305 - struct op_msr_group controls;
306 + struct op_msr * counters;
307 + struct op_msr * controls;