diff options
Diffstat (limited to 'drivers/oprofile/buffer_sync.c')
-rw-r--r-- | drivers/oprofile/buffer_sync.c | 65 |
1 files changed, 25 insertions, 40 deletions
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index 944a5832d9e4..737bd9484822 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c | |||
@@ -268,18 +268,6 @@ lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset) | |||
268 | return cookie; | 268 | return cookie; |
269 | } | 269 | } |
270 | 270 | ||
271 | static void increment_tail(struct oprofile_cpu_buffer *b) | ||
272 | { | ||
273 | unsigned long new_tail = b->tail_pos + 1; | ||
274 | |||
275 | rmb(); /* be sure fifo pointers are synchronized */ | ||
276 | |||
277 | if (new_tail < b->buffer_size) | ||
278 | b->tail_pos = new_tail; | ||
279 | else | ||
280 | b->tail_pos = 0; | ||
281 | } | ||
282 | |||
283 | static unsigned long last_cookie = INVALID_COOKIE; | 271 | static unsigned long last_cookie = INVALID_COOKIE; |
284 | 272 | ||
285 | static void add_cpu_switch(int i) | 273 | static void add_cpu_switch(int i) |
@@ -331,26 +319,25 @@ static void add_trace_begin(void) | |||
331 | 319 | ||
332 | #define IBS_FETCH_CODE_SIZE 2 | 320 | #define IBS_FETCH_CODE_SIZE 2 |
333 | #define IBS_OP_CODE_SIZE 5 | 321 | #define IBS_OP_CODE_SIZE 5 |
334 | #define IBS_EIP(cpu_buf) ((cpu_buffer_read_entry(cpu_buf))->eip) | ||
335 | #define IBS_EVENT(cpu_buf) ((cpu_buffer_read_entry(cpu_buf))->event) | ||
336 | 322 | ||
337 | /* | 323 | /* |
338 | * Add IBS fetch and op entries to event buffer | 324 | * Add IBS fetch and op entries to event buffer |
339 | */ | 325 | */ |
340 | static void add_ibs_begin(struct oprofile_cpu_buffer *cpu_buf, int code, | 326 | static void add_ibs_begin(int cpu, int code, struct mm_struct *mm) |
341 | struct mm_struct *mm) | ||
342 | { | 327 | { |
343 | unsigned long rip; | 328 | unsigned long rip; |
344 | int i, count; | 329 | int i, count; |
345 | unsigned long ibs_cookie = 0; | 330 | unsigned long ibs_cookie = 0; |
346 | off_t offset; | 331 | off_t offset; |
332 | struct op_sample *sample; | ||
347 | 333 | ||
348 | increment_tail(cpu_buf); /* move to RIP entry */ | 334 | sample = cpu_buffer_read_entry(cpu); |
349 | 335 | if (!sample) | |
350 | rip = IBS_EIP(cpu_buf); | 336 | goto Error; |
337 | rip = sample->eip; | ||
351 | 338 | ||
352 | #ifdef __LP64__ | 339 | #ifdef __LP64__ |
353 | rip += IBS_EVENT(cpu_buf) << 32; | 340 | rip += sample->event << 32; |
354 | #endif | 341 | #endif |
355 | 342 | ||
356 | if (mm) { | 343 | if (mm) { |
@@ -374,8 +361,8 @@ static void add_ibs_begin(struct oprofile_cpu_buffer *cpu_buf, int code, | |||
374 | add_event_entry(offset); /* Offset from Dcookie */ | 361 | add_event_entry(offset); /* Offset from Dcookie */ |
375 | 362 | ||
376 | /* we send the Dcookie offset, but send the raw Linear Add also*/ | 363 | /* we send the Dcookie offset, but send the raw Linear Add also*/ |
377 | add_event_entry(IBS_EIP(cpu_buf)); | 364 | add_event_entry(sample->eip); |
378 | add_event_entry(IBS_EVENT(cpu_buf)); | 365 | add_event_entry(sample->event); |
379 | 366 | ||
380 | if (code == IBS_FETCH_CODE) | 367 | if (code == IBS_FETCH_CODE) |
381 | count = IBS_FETCH_CODE_SIZE; /*IBS FETCH is 2 int64s*/ | 368 | count = IBS_FETCH_CODE_SIZE; /*IBS FETCH is 2 int64s*/ |
@@ -383,10 +370,17 @@ static void add_ibs_begin(struct oprofile_cpu_buffer *cpu_buf, int code, | |||
383 | count = IBS_OP_CODE_SIZE; /*IBS OP is 5 int64s*/ | 370 | count = IBS_OP_CODE_SIZE; /*IBS OP is 5 int64s*/ |
384 | 371 | ||
385 | for (i = 0; i < count; i++) { | 372 | for (i = 0; i < count; i++) { |
386 | increment_tail(cpu_buf); | 373 | sample = cpu_buffer_read_entry(cpu); |
387 | add_event_entry(IBS_EIP(cpu_buf)); | 374 | if (!sample) |
388 | add_event_entry(IBS_EVENT(cpu_buf)); | 375 | goto Error; |
376 | add_event_entry(sample->eip); | ||
377 | add_event_entry(sample->event); | ||
389 | } | 378 | } |
379 | |||
380 | return; | ||
381 | |||
382 | Error: | ||
383 | return; | ||
390 | } | 384 | } |
391 | 385 | ||
392 | #endif | 386 | #endif |
@@ -530,33 +524,26 @@ typedef enum { | |||
530 | */ | 524 | */ |
531 | void sync_buffer(int cpu) | 525 | void sync_buffer(int cpu) |
532 | { | 526 | { |
533 | struct oprofile_cpu_buffer *cpu_buf = &per_cpu(cpu_buffer, cpu); | ||
534 | struct mm_struct *mm = NULL; | 527 | struct mm_struct *mm = NULL; |
535 | struct mm_struct *oldmm; | 528 | struct mm_struct *oldmm; |
536 | struct task_struct *new; | 529 | struct task_struct *new; |
537 | unsigned long cookie = 0; | 530 | unsigned long cookie = 0; |
538 | int in_kernel = 1; | 531 | int in_kernel = 1; |
539 | sync_buffer_state state = sb_buffer_start; | 532 | sync_buffer_state state = sb_buffer_start; |
540 | #ifndef CONFIG_OPROFILE_IBS | ||
541 | unsigned int i; | 533 | unsigned int i; |
542 | unsigned long available; | 534 | unsigned long available; |
543 | #endif | ||
544 | 535 | ||
545 | mutex_lock(&buffer_mutex); | 536 | mutex_lock(&buffer_mutex); |
546 | 537 | ||
547 | add_cpu_switch(cpu); | 538 | add_cpu_switch(cpu); |
548 | 539 | ||
549 | /* Remember, only we can modify tail_pos */ | ||
550 | |||
551 | cpu_buffer_reset(cpu); | 540 | cpu_buffer_reset(cpu); |
552 | #ifndef CONFIG_OPROFILE_IBS | 541 | available = cpu_buffer_entries(cpu); |
553 | available = cpu_buffer_entries(cpu_buf); | ||
554 | 542 | ||
555 | for (i = 0; i < available; ++i) { | 543 | for (i = 0; i < available; ++i) { |
556 | #else | 544 | struct op_sample *s = cpu_buffer_read_entry(cpu); |
557 | while (cpu_buffer_entries(cpu_buf)) { | 545 | if (!s) |
558 | #endif | 546 | break; |
559 | struct op_sample *s = cpu_buffer_read_entry(cpu_buf); | ||
560 | 547 | ||
561 | if (is_code(s->eip)) { | 548 | if (is_code(s->eip)) { |
562 | switch (s->event) { | 549 | switch (s->event) { |
@@ -575,11 +562,11 @@ void sync_buffer(int cpu) | |||
575 | #ifdef CONFIG_OPROFILE_IBS | 562 | #ifdef CONFIG_OPROFILE_IBS |
576 | case IBS_FETCH_BEGIN: | 563 | case IBS_FETCH_BEGIN: |
577 | state = sb_bt_start; | 564 | state = sb_bt_start; |
578 | add_ibs_begin(cpu_buf, IBS_FETCH_CODE, mm); | 565 | add_ibs_begin(cpu, IBS_FETCH_CODE, mm); |
579 | break; | 566 | break; |
580 | case IBS_OP_BEGIN: | 567 | case IBS_OP_BEGIN: |
581 | state = sb_bt_start; | 568 | state = sb_bt_start; |
582 | add_ibs_begin(cpu_buf, IBS_OP_CODE, mm); | 569 | add_ibs_begin(cpu, IBS_OP_CODE, mm); |
583 | break; | 570 | break; |
584 | #endif | 571 | #endif |
585 | default: | 572 | default: |
@@ -600,8 +587,6 @@ void sync_buffer(int cpu) | |||
600 | atomic_inc(&oprofile_stats.bt_lost_no_mapping); | 587 | atomic_inc(&oprofile_stats.bt_lost_no_mapping); |
601 | } | 588 | } |
602 | } | 589 | } |
603 | |||
604 | increment_tail(cpu_buf); | ||
605 | } | 590 | } |
606 | release_mm(mm); | 591 | release_mm(mm); |
607 | 592 | ||