aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/oprofile/cpu_buffer.c
diff options
context:
space:
mode:
authorRobert Richter <robert.richter@amd.com>2009-01-05 04:35:31 -0500
committerRobert Richter <robert.richter@amd.com>2009-01-07 16:47:23 -0500
commit1acda878e20ea0cd3708ba66dca67d52eaafdd2b (patch)
tree97eb93396efc357f91dbd0ce080a5df51f29fd9b /drivers/oprofile/cpu_buffer.c
parentbd7dc46f770d317ada1348294ff1f319243b803b (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.c39
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
366void 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 */
372void 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) 396fail:
390 cpu_buf->sample_lost_overflow++; 397 cpu_buf->sample_lost_overflow++;
391} 398}
392 399
393#endif 400#endif