1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdbool.h> 2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <errno.h> 3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <linux/perf_event.h> 5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../../perf.h" 7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../../util/types.h" 8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../../util/debug.h" 9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "tsc.h" 10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengu64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc) 12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 t, quot, rem; 14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng t = ns - tc->time_zero; 16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng quot = t / tc->time_mult; 17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng rem = t % tc->time_mult; 18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return (quot << tc->time_shift) + 19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng (rem << tc->time_shift) / tc->time_mult; 20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengu64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc) 23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u64 quot, rem; 25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng quot = cyc >> tc->time_shift; 27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng rem = cyc & ((1 << tc->time_shift) - 1); 28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return tc->time_zero + quot * tc->time_mult + 29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ((rem * tc->time_mult) >> tc->time_shift); 30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint perf_read_tsc_conversion(const struct perf_event_mmap_page *pc, 33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_tsc_conversion *tc) 34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng bool cap_user_time_zero; 36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng u32 seq; 37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int i = 0; 38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (1) { 40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng seq = pc->lock; 41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng rmb(); 42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tc->time_mult = pc->time_mult; 43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tc->time_shift = pc->time_shift; 44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng tc->time_zero = pc->time_zero; 45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng cap_user_time_zero = pc->cap_user_time_zero; 46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng rmb(); 47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (pc->lock == seq && !(seq & 1)) 48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng break; 49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (++i > 10000) { 50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_debug("failed to get perf_event_mmap_page lock\n"); 51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -EINVAL; 52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!cap_user_time_zero) 56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -EOPNOTSUPP; 57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 60