|
@@ -268,6 +268,12 @@ static void update_context_time(struct perf_event_context *ctx)
|
|
|
ctx->timestamp = now;
|
|
|
}
|
|
|
|
|
|
+static u64 perf_event_time(struct perf_event *event)
|
|
|
+{
|
|
|
+ struct perf_event_context *ctx = event->ctx;
|
|
|
+ return ctx ? ctx->time : 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Update the total_time_enabled and total_time_running fields for a event.
|
|
|
*/
|
|
@@ -281,7 +287,7 @@ static void update_event_times(struct perf_event *event)
|
|
|
return;
|
|
|
|
|
|
if (ctx->is_active)
|
|
|
- run_end = ctx->time;
|
|
|
+ run_end = perf_event_time(event);
|
|
|
else
|
|
|
run_end = event->tstamp_stopped;
|
|
|
|
|
@@ -290,7 +296,7 @@ static void update_event_times(struct perf_event *event)
|
|
|
if (event->state == PERF_EVENT_STATE_INACTIVE)
|
|
|
run_end = event->tstamp_stopped;
|
|
|
else
|
|
|
- run_end = ctx->time;
|
|
|
+ run_end = perf_event_time(event);
|
|
|
|
|
|
event->total_time_running = run_end - event->tstamp_running;
|
|
|
}
|
|
@@ -546,6 +552,7 @@ event_sched_out(struct perf_event *event,
|
|
|
struct perf_cpu_context *cpuctx,
|
|
|
struct perf_event_context *ctx)
|
|
|
{
|
|
|
+ u64 tstamp = perf_event_time(event);
|
|
|
u64 delta;
|
|
|
/*
|
|
|
* An event which could not be activated because of
|
|
@@ -557,7 +564,7 @@ event_sched_out(struct perf_event *event,
|
|
|
&& !event_filter_match(event)) {
|
|
|
delta = ctx->time - event->tstamp_stopped;
|
|
|
event->tstamp_running += delta;
|
|
|
- event->tstamp_stopped = ctx->time;
|
|
|
+ event->tstamp_stopped = tstamp;
|
|
|
}
|
|
|
|
|
|
if (event->state != PERF_EVENT_STATE_ACTIVE)
|
|
@@ -568,7 +575,7 @@ event_sched_out(struct perf_event *event,
|
|
|
event->pending_disable = 0;
|
|
|
event->state = PERF_EVENT_STATE_OFF;
|
|
|
}
|
|
|
- event->tstamp_stopped = ctx->time;
|
|
|
+ event->tstamp_stopped = tstamp;
|
|
|
event->pmu->del(event, 0);
|
|
|
event->oncpu = -1;
|
|
|
|
|
@@ -780,6 +787,8 @@ event_sched_in(struct perf_event *event,
|
|
|
struct perf_cpu_context *cpuctx,
|
|
|
struct perf_event_context *ctx)
|
|
|
{
|
|
|
+ u64 tstamp = perf_event_time(event);
|
|
|
+
|
|
|
if (event->state <= PERF_EVENT_STATE_OFF)
|
|
|
return 0;
|
|
|
|
|
@@ -796,9 +805,9 @@ event_sched_in(struct perf_event *event,
|
|
|
return -EAGAIN;
|
|
|
}
|
|
|
|
|
|
- event->tstamp_running += ctx->time - event->tstamp_stopped;
|
|
|
+ event->tstamp_running += tstamp - event->tstamp_stopped;
|
|
|
|
|
|
- event->shadow_ctx_time = ctx->time - ctx->timestamp;
|
|
|
+ event->shadow_ctx_time = tstamp - ctx->timestamp;
|
|
|
|
|
|
if (!is_software_event(event))
|
|
|
cpuctx->active_oncpu++;
|
|
@@ -910,11 +919,13 @@ static int group_can_go_on(struct perf_event *event,
|
|
|
static void add_event_to_ctx(struct perf_event *event,
|
|
|
struct perf_event_context *ctx)
|
|
|
{
|
|
|
+ u64 tstamp = perf_event_time(event);
|
|
|
+
|
|
|
list_add_event(event, ctx);
|
|
|
perf_group_attach(event);
|
|
|
- event->tstamp_enabled = ctx->time;
|
|
|
- event->tstamp_running = ctx->time;
|
|
|
- event->tstamp_stopped = ctx->time;
|
|
|
+ event->tstamp_enabled = tstamp;
|
|
|
+ event->tstamp_running = tstamp;
|
|
|
+ event->tstamp_stopped = tstamp;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1054,14 +1065,13 @@ static void __perf_event_mark_enabled(struct perf_event *event,
|
|
|
struct perf_event_context *ctx)
|
|
|
{
|
|
|
struct perf_event *sub;
|
|
|
+ u64 tstamp = perf_event_time(event);
|
|
|
|
|
|
event->state = PERF_EVENT_STATE_INACTIVE;
|
|
|
- event->tstamp_enabled = ctx->time - event->total_time_enabled;
|
|
|
+ event->tstamp_enabled = tstamp - event->total_time_enabled;
|
|
|
list_for_each_entry(sub, &event->sibling_list, group_entry) {
|
|
|
- if (sub->state >= PERF_EVENT_STATE_INACTIVE) {
|
|
|
- sub->tstamp_enabled =
|
|
|
- ctx->time - sub->total_time_enabled;
|
|
|
- }
|
|
|
+ if (sub->state >= PERF_EVENT_STATE_INACTIVE)
|
|
|
+ sub->tstamp_enabled = tstamp - sub->total_time_enabled;
|
|
|
}
|
|
|
}
|
|
|
|