A recent fix to the shadow timestamp inadvertly broke the running time accounting. We must not update the running timestamp if we fail to schedule the event, the event will not have ran. This can (and did) result in negative total runtime because the stopped timestamp was before the running timestamp (we 'started' but never stopped the event -- because it never really started we didn't have to stop it either).
Unified · Split
| @@ -1868,8 +1868,6 @@ event_sched_in(struct perf_event *event, · 1867 unmodified lines | ||
| 1868 | 1868 | |
| 1869 | 1869 | perf_pmu_disable(event->pmu); |
| 1870 | 1870 | |
| 1871 | − event->tstamp_running += tstamp - event->tstamp_stopped; | |
| 1872 | − | |
| 1873 | 1871 | perf_set_shadow_time(event, ctx, tstamp); |
| 1874 | 1872 | |
| 1875 | 1873 | perf_log_itrace_start(event); |
| @@ -1881,6 +1879,8 @@ event_sched_in(struct perf_event *event, · 5 unmodified lines | ||
| 1881 | 1879 | goto out; |
| 1882 | 1880 | } |
| 1883 | 1881 | |
| 1882 | + event->tstamp_running += tstamp - event->tstamp_stopped; | |
| 1883 | + | |
| 1884 | 1884 | if (!is_software_event(event)) |
| 1885 | 1885 | cpuctx->active_oncpu++; |
| 1886 | 1886 | if (!ctx->nr_active++) |