perf tsc: Calculate timestamp with cap_user_time_short
[linux-2.6-microblaze.git] / tools / perf / util / tsc.c
index 9e3f04d..c0ca402 100644 (file)
@@ -28,6 +28,10 @@ u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
 {
        u64 quot, rem;
 
+       if (tc->cap_user_time_short)
+               cyc = tc->time_cycles +
+                       ((cyc - tc->time_cycles) & tc->time_mask);
+
        quot = cyc >> tc->time_shift;
        rem  = cyc & (((u64)1 << tc->time_shift) - 1);
        return tc->time_zero + quot * tc->time_mult +
@@ -37,7 +41,6 @@ u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc)
 int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
                             struct perf_tsc_conversion *tc)
 {
-       bool cap_user_time_zero;
        u32 seq;
        int i = 0;
 
@@ -47,7 +50,10 @@ int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
                tc->time_mult = pc->time_mult;
                tc->time_shift = pc->time_shift;
                tc->time_zero = pc->time_zero;
-               cap_user_time_zero = pc->cap_user_time_zero;
+               tc->time_cycles = pc->time_cycles;
+               tc->time_mask = pc->time_mask;
+               tc->cap_user_time_zero = pc->cap_user_time_zero;
+               tc->cap_user_time_short = pc->cap_user_time_short;
                rmb();
                if (pc->lock == seq && !(seq & 1))
                        break;
@@ -57,7 +63,7 @@ int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
                }
        }
 
-       if (!cap_user_time_zero)
+       if (!tc->cap_user_time_zero)
                return -EOPNOTSUPP;
 
        return 0;