diff options
author | Robert Richter <robert.richter@amd.com> | 2009-01-05 04:35:31 -0500 |
---|---|---|
committer | Robert Richter <robert.richter@amd.com> | 2009-01-07 16:47:23 -0500 |
commit | 1acda878e20ea0cd3708ba66dca67d52eaafdd2b (patch) | |
tree | 97eb93396efc357f91dbd0ce080a5df51f29fd9b /drivers/oprofile/cpu_buffer.c | |
parent | bd7dc46f770d317ada1348294ff1f319243b803b (diff) |
oprofile: use new data sample format for ibs
The new ring buffer implementation allows the storage of samples with
different size. This patch implements the usage of the new sample
format to store ibs samples in the cpu buffer. Until now, writing to
the cpu buffer could lead to incomplete sampling sequences since IBS
samples were transfered in multiple samples. Due to a full buffer,
data could be lost at any time. This can't happen any more since the
complete data is reserved in advance and then stored in a single
sample.
Signed-off-by: Robert Richter <robert.richter@amd.com>
Diffstat (limited to 'drivers/oprofile/cpu_buffer.c')
-rw-r--r-- | drivers/oprofile/cpu_buffer.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index 1b6590746be4..ddba9d01f09b 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c | |||
@@ -363,31 +363,38 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) | |||
363 | 363 | ||
364 | #ifdef CONFIG_OPROFILE_IBS | 364 | #ifdef CONFIG_OPROFILE_IBS |
365 | 365 | ||
366 | void oprofile_add_ibs_sample(struct pt_regs * const regs, | 366 | /* |
367 | unsigned int * const ibs_sample, int ibs_code) | 367 | * Add samples with data to the ring buffer. |
368 | * | ||
369 | * Use op_cpu_buffer_add_data(&entry, val) to add data and | ||
370 | * op_cpu_buffer_write_commit(&entry) to commit the sample. | ||
371 | */ | ||
372 | void oprofile_add_data(struct op_entry *entry, struct pt_regs * const regs, | ||
373 | unsigned long pc, int code, int size) | ||
368 | { | 374 | { |
375 | struct op_sample *sample; | ||
369 | int is_kernel = !user_mode(regs); | 376 | int is_kernel = !user_mode(regs); |
370 | struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer); | 377 | struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer); |
371 | int fail = 0; | ||
372 | 378 | ||
373 | cpu_buf->sample_received++; | 379 | cpu_buf->sample_received++; |
374 | 380 | ||
375 | /* backtraces disabled for ibs */ | 381 | /* no backtraces for samples with data */ |
376 | fail = fail || op_add_code(cpu_buf, 0, is_kernel, current); | 382 | if (op_add_code(cpu_buf, 0, is_kernel, current)) |
383 | goto fail; | ||
377 | 384 | ||
378 | fail = fail || op_add_sample(cpu_buf, ESCAPE_CODE, ibs_code); | 385 | sample = op_cpu_buffer_write_reserve(entry, size + 2); |
379 | fail = fail || op_add_sample(cpu_buf, ibs_sample[0], ibs_sample[1]); | 386 | if (!sample) |
380 | fail = fail || op_add_sample(cpu_buf, ibs_sample[2], ibs_sample[3]); | 387 | goto fail; |
381 | fail = fail || op_add_sample(cpu_buf, ibs_sample[4], ibs_sample[5]); | 388 | sample->eip = ESCAPE_CODE; |
389 | sample->event = 0; /* no flags */ | ||
382 | 390 | ||
383 | if (ibs_code == IBS_OP_BEGIN) { | 391 | op_cpu_buffer_add_data(entry, code); |
384 | fail = fail || op_add_sample(cpu_buf, ibs_sample[6], ibs_sample[7]); | 392 | op_cpu_buffer_add_data(entry, pc); |
385 | fail = fail || op_add_sample(cpu_buf, ibs_sample[8], ibs_sample[9]); | 393 | |
386 | fail = fail || op_add_sample(cpu_buf, ibs_sample[10], ibs_sample[11]); | 394 | return; |
387 | } | ||
388 | 395 | ||
389 | if (fail) | 396 | fail: |
390 | cpu_buf->sample_lost_overflow++; | 397 | cpu_buf->sample_lost_overflow++; |
391 | } | 398 | } |
392 | 399 | ||
393 | #endif | 400 | #endif |