diff options
Diffstat (limited to 'drivers/oprofile')
| -rw-r--r-- | drivers/oprofile/buffer_sync.c | 53 | ||||
| -rw-r--r-- | drivers/oprofile/cpu_buffer.c | 39 | ||||
| -rw-r--r-- | drivers/oprofile/cpu_buffer.h | 2 |
3 files changed, 35 insertions, 59 deletions
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index f9031d31eeb7..d692fdc1a211 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c | |||
| @@ -318,29 +318,18 @@ static void add_trace_begin(void) | |||
| 318 | 318 | ||
| 319 | #ifdef CONFIG_OPROFILE_IBS | 319 | #ifdef CONFIG_OPROFILE_IBS |
| 320 | 320 | ||
| 321 | #define IBS_FETCH_CODE_SIZE 2 | 321 | static void add_data(struct op_entry *entry, struct mm_struct *mm) |
| 322 | #define IBS_OP_CODE_SIZE 5 | ||
| 323 | |||
| 324 | /* | ||
| 325 | * Add IBS fetch and op entries to event buffer | ||
| 326 | */ | ||
| 327 | static void add_ibs_begin(int cpu, int code, struct mm_struct *mm) | ||
| 328 | { | 322 | { |
| 329 | unsigned long pc; | 323 | unsigned long code, pc, val; |
| 330 | int i, count; | 324 | unsigned long cookie; |
| 331 | unsigned long cookie = 0; | ||
| 332 | off_t offset; | 325 | off_t offset; |
| 333 | struct op_entry entry; | ||
| 334 | struct op_sample *sample; | ||
| 335 | 326 | ||
| 336 | sample = op_cpu_buffer_read_entry(&entry, cpu); | 327 | if (!op_cpu_buffer_get_data(entry, &code)) |
| 337 | if (!sample) | 328 | return; |
| 329 | if (!op_cpu_buffer_get_data(entry, &pc)) | ||
| 330 | return; | ||
| 331 | if (!op_cpu_buffer_get_size(entry)) | ||
| 338 | return; | 332 | return; |
| 339 | pc = sample->eip; | ||
| 340 | |||
| 341 | #ifdef __LP64__ | ||
| 342 | pc += sample->event << 32; | ||
| 343 | #endif | ||
| 344 | 333 | ||
| 345 | if (mm) { | 334 | if (mm) { |
| 346 | cookie = lookup_dcookie(mm, pc, &offset); | 335 | cookie = lookup_dcookie(mm, pc, &offset); |
| @@ -362,24 +351,8 @@ static void add_ibs_begin(int cpu, int code, struct mm_struct *mm) | |||
| 362 | add_event_entry(code); | 351 | add_event_entry(code); |
| 363 | add_event_entry(offset); /* Offset from Dcookie */ | 352 | add_event_entry(offset); /* Offset from Dcookie */ |
| 364 | 353 | ||
| 365 | /* we send the Dcookie offset, but send the raw Linear Add also*/ | 354 | while (op_cpu_buffer_get_data(entry, &val)) |
| 366 | add_event_entry(sample->eip); | 355 | add_event_entry(val); |
| 367 | add_event_entry(sample->event); | ||
| 368 | |||
| 369 | if (code == IBS_FETCH_CODE) | ||
| 370 | count = IBS_FETCH_CODE_SIZE; /*IBS FETCH is 2 int64s*/ | ||
| 371 | else | ||
| 372 | count = IBS_OP_CODE_SIZE; /*IBS OP is 5 int64s*/ | ||
| 373 | |||
| 374 | for (i = 0; i < count; i++) { | ||
| 375 | sample = op_cpu_buffer_read_entry(&entry, cpu); | ||
| 376 | if (!sample) | ||
| 377 | return; | ||
| 378 | add_event_entry(sample->eip); | ||
| 379 | add_event_entry(sample->event); | ||
| 380 | } | ||
| 381 | |||
| 382 | return; | ||
| 383 | } | 356 | } |
| 384 | 357 | ||
| 385 | #endif | 358 | #endif |
| @@ -572,10 +545,8 @@ void sync_buffer(int cpu) | |||
| 572 | add_user_ctx_switch(new, cookie); | 545 | add_user_ctx_switch(new, cookie); |
| 573 | } | 546 | } |
| 574 | #ifdef CONFIG_OPROFILE_IBS | 547 | #ifdef CONFIG_OPROFILE_IBS |
| 575 | if (flags & IBS_FETCH_BEGIN) | 548 | if (op_cpu_buffer_get_size(&entry)) |
| 576 | add_ibs_begin(cpu, IBS_FETCH_CODE, mm); | 549 | add_data(&entry, mm); |
| 577 | if (flags & IBS_OP_BEGIN) | ||
| 578 | add_ibs_begin(cpu, IBS_OP_CODE, mm); | ||
| 579 | #endif | 550 | #endif |
| 580 | continue; | 551 | continue; |
| 581 | } | 552 | } |
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 |
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index f34376046573..525cc4d13d8d 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h | |||
| @@ -115,7 +115,5 @@ int op_cpu_buffer_get_data(struct op_entry *entry, unsigned long *val) | |||
| 115 | #define IS_KERNEL (1UL << 1) | 115 | #define IS_KERNEL (1UL << 1) |
| 116 | #define TRACE_BEGIN (1UL << 2) | 116 | #define TRACE_BEGIN (1UL << 2) |
| 117 | #define USER_CTX_SWITCH (1UL << 3) | 117 | #define USER_CTX_SWITCH (1UL << 3) |
| 118 | #define IBS_FETCH_BEGIN (1UL << 4) | ||
| 119 | #define IBS_OP_BEGIN (1UL << 5) | ||
| 120 | 118 | ||
| 121 | #endif /* OPROFILE_CPU_BUFFER_H */ | 119 | #endif /* OPROFILE_CPU_BUFFER_H */ |
