aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/oprofile/nmi_int.c
diff options
context:
space:
mode:
authorDon Zickus <dzickus@redhat.com>2006-09-26 04:52:26 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:26 -0400
commitcb9c448c661d40ce2efbce8e9c19cc4d420d8ccc (patch)
tree2aa5614f06e57e8f5266f91ccfff1a92fa9f3792 /arch/i386/oprofile/nmi_int.c
parent828f0afda123a96ff4e8078f057a302f4b4232ae (diff)
[PATCH] i386: Utilize performance counter reservation framework in oprofile
Incorporates the new performance counter reservation system in oprofile. Also cleans up a lot of the initialization code. The code original zero'd out every register associated with performance counters regardless if those registers were used or not. This causes issues with the nmi watchdog. Now oprofile tries to reserve registers and gives up if it can't get them. Cc: levon@movementarian.org Cc: oprofile-list@lists.sf.net Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386/oprofile/nmi_int.c')
-rw-r--r--arch/i386/oprofile/nmi_int.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index 5f8dc8a21bd7..8710ca081b1e 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -98,15 +98,19 @@ static void nmi_cpu_save_registers(struct op_msrs * msrs)
98 unsigned int i; 98 unsigned int i;
99 99
100 for (i = 0; i < nr_ctrs; ++i) { 100 for (i = 0; i < nr_ctrs; ++i) {
101 rdmsr(counters[i].addr, 101 if (counters[i].addr){
102 counters[i].saved.low, 102 rdmsr(counters[i].addr,
103 counters[i].saved.high); 103 counters[i].saved.low,
104 counters[i].saved.high);
105 }
104 } 106 }
105 107
106 for (i = 0; i < nr_ctrls; ++i) { 108 for (i = 0; i < nr_ctrls; ++i) {
107 rdmsr(controls[i].addr, 109 if (controls[i].addr){
108 controls[i].saved.low, 110 rdmsr(controls[i].addr,
109 controls[i].saved.high); 111 controls[i].saved.low,
112 controls[i].saved.high);
113 }
110 } 114 }
111} 115}
112 116
@@ -205,15 +209,19 @@ static void nmi_restore_registers(struct op_msrs * msrs)
205 unsigned int i; 209 unsigned int i;
206 210
207 for (i = 0; i < nr_ctrls; ++i) { 211 for (i = 0; i < nr_ctrls; ++i) {
208 wrmsr(controls[i].addr, 212 if (controls[i].addr){
209 controls[i].saved.low, 213 wrmsr(controls[i].addr,
210 controls[i].saved.high); 214 controls[i].saved.low,
215 controls[i].saved.high);
216 }
211 } 217 }
212 218
213 for (i = 0; i < nr_ctrs; ++i) { 219 for (i = 0; i < nr_ctrs; ++i) {
214 wrmsr(counters[i].addr, 220 if (counters[i].addr){
215 counters[i].saved.low, 221 wrmsr(counters[i].addr,
216 counters[i].saved.high); 222 counters[i].saved.low,
223 counters[i].saved.high);
224 }
217 } 225 }
218} 226}
219 227
@@ -234,6 +242,7 @@ static void nmi_cpu_shutdown(void * dummy)
234 apic_write(APIC_LVTPC, saved_lvtpc[cpu]); 242 apic_write(APIC_LVTPC, saved_lvtpc[cpu]);
235 apic_write(APIC_LVTERR, v); 243 apic_write(APIC_LVTERR, v);
236 nmi_restore_registers(msrs); 244 nmi_restore_registers(msrs);
245 model->shutdown(msrs);
237} 246}
238 247
239 248
@@ -284,6 +293,14 @@ static int nmi_create_files(struct super_block * sb, struct dentry * root)
284 struct dentry * dir; 293 struct dentry * dir;
285 char buf[4]; 294 char buf[4];
286 295
296 /* quick little hack to _not_ expose a counter if it is not
297 * available for use. This should protect userspace app.
298 * NOTE: assumes 1:1 mapping here (that counters are organized
299 * sequentially in their struct assignment).
300 */
301 if (unlikely(!avail_to_resrv_perfctr_nmi_bit(i)))
302 continue;
303
287 snprintf(buf, sizeof(buf), "%d", i); 304 snprintf(buf, sizeof(buf), "%d", i);
288 dir = oprofilefs_mkdir(sb, root, buf); 305 dir = oprofilefs_mkdir(sb, root, buf);
289 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); 306 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);