diff options
-rw-r--r-- | tools/perf/builtin-sched.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 1f0f9be34faa..2d542368de3c 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -119,6 +119,7 @@ static unsigned long replay_repeat = 10; | |||
119 | static unsigned long nr_timestamps; | 119 | static unsigned long nr_timestamps; |
120 | static unsigned long nr_unordered_timestamps; | 120 | static unsigned long nr_unordered_timestamps; |
121 | static unsigned long nr_state_machine_bugs; | 121 | static unsigned long nr_state_machine_bugs; |
122 | static unsigned long nr_context_switch_bugs; | ||
122 | static unsigned long nr_events; | 123 | static unsigned long nr_events; |
123 | static unsigned long nr_lost_chunks; | 124 | static unsigned long nr_lost_chunks; |
124 | static unsigned long nr_lost_events; | 125 | static unsigned long nr_lost_events; |
@@ -1399,6 +1400,14 @@ static void __cmd_lat(void) | |||
1399 | printf(" (due to lost events?)"); | 1400 | printf(" (due to lost events?)"); |
1400 | printf("\n"); | 1401 | printf("\n"); |
1401 | } | 1402 | } |
1403 | if (nr_context_switch_bugs && nr_timestamps) { | ||
1404 | printf(" INFO: %.3f%% context switch bugs (%ld out of %ld)", | ||
1405 | (double)nr_context_switch_bugs/(double)nr_timestamps*100.0, | ||
1406 | nr_context_switch_bugs, nr_timestamps); | ||
1407 | if (nr_lost_events) | ||
1408 | printf(" (due to lost events?)"); | ||
1409 | printf("\n"); | ||
1410 | } | ||
1402 | printf("\n"); | 1411 | printf("\n"); |
1403 | 1412 | ||
1404 | } | 1413 | } |
@@ -1425,10 +1434,16 @@ process_sched_wakeup_event(struct raw_event_sample *raw, | |||
1425 | trace_handler->wakeup_event(&wakeup_event, event, cpu, timestamp, thread); | 1434 | trace_handler->wakeup_event(&wakeup_event, event, cpu, timestamp, thread); |
1426 | } | 1435 | } |
1427 | 1436 | ||
1437 | /* | ||
1438 | * Track the current task - that way we can know whether there's any | ||
1439 | * weird events, such as a task being switched away that is not current. | ||
1440 | */ | ||
1441 | static u32 curr_pid[MAX_CPUS] = { [0 ... MAX_CPUS-1] = -1 }; | ||
1442 | |||
1428 | static void | 1443 | static void |
1429 | process_sched_switch_event(struct raw_event_sample *raw, | 1444 | process_sched_switch_event(struct raw_event_sample *raw, |
1430 | struct event *event, | 1445 | struct event *event, |
1431 | int cpu __used, | 1446 | int cpu, |
1432 | u64 timestamp __used, | 1447 | u64 timestamp __used, |
1433 | struct thread *thread __used) | 1448 | struct thread *thread __used) |
1434 | { | 1449 | { |
@@ -1444,6 +1459,16 @@ process_sched_switch_event(struct raw_event_sample *raw, | |||
1444 | FILL_FIELD(switch_event, next_pid, event, raw->data); | 1459 | FILL_FIELD(switch_event, next_pid, event, raw->data); |
1445 | FILL_FIELD(switch_event, next_prio, event, raw->data); | 1460 | FILL_FIELD(switch_event, next_prio, event, raw->data); |
1446 | 1461 | ||
1462 | if (curr_pid[cpu] != (u32)-1) { | ||
1463 | /* | ||
1464 | * Are we trying to switch away a PID that is | ||
1465 | * not current? | ||
1466 | */ | ||
1467 | if (curr_pid[cpu] != switch_event.prev_pid) | ||
1468 | nr_context_switch_bugs++; | ||
1469 | } | ||
1470 | curr_pid[cpu] = switch_event.next_pid; | ||
1471 | |||
1447 | trace_handler->switch_event(&switch_event, event, cpu, timestamp, thread); | 1472 | trace_handler->switch_event(&switch_event, event, cpu, timestamp, thread); |
1448 | } | 1473 | } |
1449 | 1474 | ||