diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2009-04-03 10:43:45 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-07 07:36:27 -0400 |
commit | 3a68eef945b234f286406d96dc690fe17863c203 (patch) | |
tree | 10b648ac75a70dc35c637b906395f84402019e51 | |
parent | 01f6569ece6915616f6cae1d7d8b46ab8da9c1bd (diff) |
x86, ds: add task tracing selftest
Add selftests to cover per-task branch tracing.
Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
Cc: roland@redhat.com
Cc: eranian@googlemail.com
Cc: oleg@redhat.com
Cc: juan.villacis@intel.com
Cc: ak@linux.jf.intel.com
LKML-Reference: <20090403144600.329346000@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/kernel/ds_selftest.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/arch/x86/kernel/ds_selftest.c b/arch/x86/kernel/ds_selftest.c index 599a96300628..a40b2533c71e 100644 --- a/arch/x86/kernel/ds_selftest.c +++ b/arch/x86/kernel/ds_selftest.c | |||
@@ -280,10 +280,51 @@ static int ds_selftest_bts_bad_release_noirq(int cpu, | |||
280 | return error ? 0 : -1; | 280 | return error ? 0 : -1; |
281 | } | 281 | } |
282 | 282 | ||
283 | static int ds_selftest_bts_bad_request_cpu(int cpu, void *buffer) | ||
284 | { | ||
285 | struct bts_tracer *tracer; | ||
286 | int error; | ||
287 | |||
288 | /* Try to request cpu tracing while task tracing is active. */ | ||
289 | tracer = ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, NULL, | ||
290 | (size_t)-1, BTS_KERNEL); | ||
291 | error = PTR_ERR(tracer); | ||
292 | if (!IS_ERR(tracer)) { | ||
293 | ds_release_bts(tracer); | ||
294 | error = 0; | ||
295 | } | ||
296 | |||
297 | if (error != -EPERM) | ||
298 | printk(KERN_CONT "cpu/task tracing overlap..."); | ||
299 | |||
300 | return error ? 0 : -1; | ||
301 | } | ||
302 | |||
303 | static int ds_selftest_bts_bad_request_task(void *buffer) | ||
304 | { | ||
305 | struct bts_tracer *tracer; | ||
306 | int error; | ||
307 | |||
308 | /* Try to request cpu tracing while task tracing is active. */ | ||
309 | tracer = ds_request_bts_task(current, buffer, BUFFER_SIZE, NULL, | ||
310 | (size_t)-1, BTS_KERNEL); | ||
311 | error = PTR_ERR(tracer); | ||
312 | if (!IS_ERR(tracer)) { | ||
313 | error = 0; | ||
314 | ds_release_bts(tracer); | ||
315 | } | ||
316 | |||
317 | if (error != -EPERM) | ||
318 | printk(KERN_CONT "task/cpu tracing overlap..."); | ||
319 | |||
320 | return error ? 0 : -1; | ||
321 | } | ||
322 | |||
283 | int ds_selftest_bts(void) | 323 | int ds_selftest_bts(void) |
284 | { | 324 | { |
285 | struct ds_selftest_bts_conf conf; | 325 | struct ds_selftest_bts_conf conf; |
286 | unsigned char buffer[BUFFER_SIZE]; | 326 | unsigned char buffer[BUFFER_SIZE]; |
327 | unsigned long irq; | ||
287 | int cpu; | 328 | int cpu; |
288 | 329 | ||
289 | printk(KERN_INFO "[ds] bts selftest..."); | 330 | printk(KERN_INFO "[ds] bts selftest..."); |
@@ -297,6 +338,8 @@ int ds_selftest_bts(void) | |||
297 | ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, | 338 | ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, |
298 | NULL, (size_t)-1, BTS_KERNEL); | 339 | NULL, (size_t)-1, BTS_KERNEL); |
299 | ds_selftest_bts_cpu(&conf); | 340 | ds_selftest_bts_cpu(&conf); |
341 | if (conf.error >= 0) | ||
342 | conf.error = ds_selftest_bts_bad_request_task(buffer); | ||
300 | ds_release_bts(conf.tracer); | 343 | ds_release_bts(conf.tracer); |
301 | if (conf.error < 0) | 344 | if (conf.error < 0) |
302 | goto out; | 345 | goto out; |
@@ -315,12 +358,40 @@ int ds_selftest_bts(void) | |||
315 | if (conf.error < 0) | 358 | if (conf.error < 0) |
316 | conf.tracer = NULL; | 359 | conf.tracer = NULL; |
317 | } | 360 | } |
361 | if (conf.error >= 0) | ||
362 | conf.error = ds_selftest_bts_bad_request_task(buffer); | ||
318 | smp_call_function_single(cpu, ds_release_bts_noirq_wrap, | 363 | smp_call_function_single(cpu, ds_release_bts_noirq_wrap, |
319 | conf.tracer, 1); | 364 | conf.tracer, 1); |
320 | if (conf.error < 0) | 365 | if (conf.error < 0) |
321 | goto out; | 366 | goto out; |
322 | } | 367 | } |
323 | 368 | ||
369 | conf.suspend = ds_suspend_bts_wrap; | ||
370 | conf.resume = ds_resume_bts_wrap; | ||
371 | conf.tracer = | ||
372 | ds_request_bts_task(current, buffer, BUFFER_SIZE, | ||
373 | NULL, (size_t)-1, BTS_KERNEL); | ||
374 | ds_selftest_bts_cpu(&conf); | ||
375 | if (conf.error >= 0) | ||
376 | conf.error = ds_selftest_bts_bad_request_cpu(0, buffer); | ||
377 | ds_release_bts(conf.tracer); | ||
378 | if (conf.error < 0) | ||
379 | goto out; | ||
380 | |||
381 | conf.suspend = ds_suspend_bts_noirq; | ||
382 | conf.resume = ds_resume_bts_noirq; | ||
383 | conf.tracer = | ||
384 | ds_request_bts_task(current, buffer, BUFFER_SIZE, | ||
385 | NULL, (size_t)-1, BTS_KERNEL); | ||
386 | local_irq_save(irq); | ||
387 | ds_selftest_bts_cpu(&conf); | ||
388 | if (conf.error >= 0) | ||
389 | conf.error = ds_selftest_bts_bad_request_cpu(0, buffer); | ||
390 | ds_release_bts_noirq(conf.tracer); | ||
391 | local_irq_restore(irq); | ||
392 | if (conf.error < 0) | ||
393 | goto out; | ||
394 | |||
324 | conf.error = 0; | 395 | conf.error = 0; |
325 | out: | 396 | out: |
326 | put_online_cpus(); | 397 | put_online_cpus(); |