]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 6 May 2019 21:16:36 +0000 (14:16 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 6 May 2019 21:16:36 +0000 (14:16 -0700)
Pull perf updates from Ingo Molnar:
 "The main kernel changes were:

   - add support for Intel's "adaptive PEBS v4" - which embedds LBS data
     in PEBS records and can thus batch up and reduce the IRQ (NMI) rate
     significantly - reducing overhead and making call-graph profiling
     less intrusive.

   - add Intel CPU core and uncore support updates for Tremont, Icelake,

   - extend the x86 PMU constraints scheduler with 'constraint ranges'
     to better support Icelake hw constraints,

   - make x86 call-chain support work better with CONFIG_FRAME_POINTER=y

   - misc other changes

  Tooling changes:

   - updates to the main tools: 'perf record', 'perf trace', 'perf
     stat'

   - updated Intel and S/390 vendor events

   - libtraceevent updates

   - misc other updates and fixes"

* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (69 commits)
  perf/x86: Make perf callchains work without CONFIG_FRAME_POINTER
  watchdog: Fix typo in comment
  perf/x86/intel: Add Tremont core PMU support
  perf/x86/intel/uncore: Add Intel Icelake uncore support
  perf/x86/msr: Add Icelake support
  perf/x86/intel/rapl: Add Icelake support
  perf/x86/intel/cstate: Add Icelake support
  perf/x86/intel: Add Icelake support
  perf/x86: Support constraint ranges
  perf/x86/lbr: Avoid reading the LBRs when adaptive PEBS handles them
  perf/x86/intel: Support adaptive PEBS v4
  perf/x86/intel/ds: Extract code of event update in short period
  perf/x86/intel: Extract memory code PEBS parser for reuse
  perf/x86: Support outputting XMM registers
  perf/x86/intel: Force resched when TFA sysctl is modified
  perf/core: Add perf_pmu_resched() as global function
  perf/headers: Fix stale comment for struct perf_addr_filter
  perf/core: Make perf_swevent_init_cpu() static
  perf/x86: Add sanity checks to x86_schedule_events()
  perf/x86: Optimize x86_schedule_events()
  ...

1  2 
arch/x86/events/intel/core.c
arch/x86/events/intel/cstate.c
include/linux/perf_event.h
tools/lib/traceevent/event-parse.c
tools/perf/Makefile.config
tools/perf/builtin-stat.c
tools/perf/util/evlist.c
tools/perf/util/evsel.c

index d35f4775d5f10ac51bec2ea0178ed65ad1b1b3e7,4b4dac089635b1df915f2fc41e56390470e00ca5..ef763f535e3abbd034857ad48a678c1281a358c4
@@@ -239,6 -239,35 +239,35 @@@ static struct extra_reg intel_skl_extra
        EVENT_EXTRA_END
  };
  
+ static struct event_constraint intel_icl_event_constraints[] = {
+       FIXED_EVENT_CONSTRAINT(0x00c0, 0),      /* INST_RETIRED.ANY */
+       INTEL_UEVENT_CONSTRAINT(0x1c0, 0),      /* INST_RETIRED.PREC_DIST */
+       FIXED_EVENT_CONSTRAINT(0x003c, 1),      /* CPU_CLK_UNHALTED.CORE */
+       FIXED_EVENT_CONSTRAINT(0x0300, 2),      /* CPU_CLK_UNHALTED.REF */
+       FIXED_EVENT_CONSTRAINT(0x0400, 3),      /* SLOTS */
+       INTEL_EVENT_CONSTRAINT_RANGE(0x03, 0x0a, 0xf),
+       INTEL_EVENT_CONSTRAINT_RANGE(0x1f, 0x28, 0xf),
+       INTEL_EVENT_CONSTRAINT(0x32, 0xf),      /* SW_PREFETCH_ACCESS.* */
+       INTEL_EVENT_CONSTRAINT_RANGE(0x48, 0x54, 0xf),
+       INTEL_EVENT_CONSTRAINT_RANGE(0x60, 0x8b, 0xf),
+       INTEL_UEVENT_CONSTRAINT(0x04a3, 0xff),  /* CYCLE_ACTIVITY.STALLS_TOTAL */
+       INTEL_UEVENT_CONSTRAINT(0x10a3, 0xff),  /* CYCLE_ACTIVITY.STALLS_MEM_ANY */
+       INTEL_EVENT_CONSTRAINT(0xa3, 0xf),      /* CYCLE_ACTIVITY.* */
+       INTEL_EVENT_CONSTRAINT_RANGE(0xa8, 0xb0, 0xf),
+       INTEL_EVENT_CONSTRAINT_RANGE(0xb7, 0xbd, 0xf),
+       INTEL_EVENT_CONSTRAINT_RANGE(0xd0, 0xe6, 0xf),
+       INTEL_EVENT_CONSTRAINT_RANGE(0xf0, 0xf4, 0xf),
+       EVENT_CONSTRAINT_END
+ };
+ static struct extra_reg intel_icl_extra_regs[] __read_mostly = {
+       INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff9fffull, RSP_0),
+       INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff9fffull, RSP_1),
+       INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
+       INTEL_UEVENT_EXTRA_REG(0x01c6, MSR_PEBS_FRONTEND, 0x7fff17, FE),
+       EVENT_EXTRA_END
+ };
  EVENT_ATTR_STR(mem-loads,     mem_ld_nhm,     "event=0x0b,umask=0x10,ldlat=3");
  EVENT_ATTR_STR(mem-loads,     mem_ld_snb,     "event=0xcd,umask=0x1,ldlat=3");
  EVENT_ATTR_STR(mem-stores,    mem_st_snb,     "event=0xcd,umask=0x2");
@@@ -1827,6 -1856,45 +1856,45 @@@ static __initconst const u64 glp_hw_cac
        },
  };
  
+ #define TNT_LOCAL_DRAM                        BIT_ULL(26)
+ #define TNT_DEMAND_READ                       GLM_DEMAND_DATA_RD
+ #define TNT_DEMAND_WRITE              GLM_DEMAND_RFO
+ #define TNT_LLC_ACCESS                        GLM_ANY_RESPONSE
+ #define TNT_SNP_ANY                   (SNB_SNP_NOT_NEEDED|SNB_SNP_MISS| \
+                                        SNB_NO_FWD|SNB_SNP_FWD|SNB_HITM)
+ #define TNT_LLC_MISS                  (TNT_SNP_ANY|SNB_NON_DRAM|TNT_LOCAL_DRAM)
+ static __initconst const u64 tnt_hw_cache_extra_regs
+                               [PERF_COUNT_HW_CACHE_MAX]
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+                               [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = TNT_DEMAND_READ|
+                                                 TNT_LLC_ACCESS,
+                       [C(RESULT_MISS)]        = TNT_DEMAND_READ|
+                                                 TNT_LLC_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = TNT_DEMAND_WRITE|
+                                                 TNT_LLC_ACCESS,
+                       [C(RESULT_MISS)]        = TNT_DEMAND_WRITE|
+                                                 TNT_LLC_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = 0x0,
+                       [C(RESULT_MISS)]        = 0x0,
+               },
+       },
+ };
+ static struct extra_reg intel_tnt_extra_regs[] __read_mostly = {
+       /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
+       INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffffff9fffull, RSP_0),
+       INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0xffffff9fffull, RSP_1),
+       EVENT_EXTRA_END
+ };
  #define KNL_OT_L2_HITE                BIT_ULL(19) /* Other Tile L2 Hit */
  #define KNL_OT_L2_HITF                BIT_ULL(20) /* Other Tile L2 Hit */
  #define KNL_MCDRAM_LOCAL      BIT_ULL(21)
@@@ -2015,7 -2083,7 +2083,7 @@@ static void intel_tfa_commit_scheduling
        /*
         * We're going to use PMC3, make sure TFA is set before we touch it.
         */
-       if (cntr == 3 && !cpuc->is_fake)
+       if (cntr == 3)
                intel_set_tfa(cpuc, true);
  }
  
@@@ -2091,19 -2159,15 +2159,19 @@@ static void intel_pmu_disable_event(str
        cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx);
        cpuc->intel_cp_status &= ~(1ull << hwc->idx);
  
 -      if (unlikely(event->attr.precise_ip))
 -              intel_pmu_pebs_disable(event);
 -
        if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
                intel_pmu_disable_fixed(hwc);
                return;
        }
  
        x86_pmu_disable_event(event);
 +
 +      /*
 +       * Needs to be called after x86_pmu_disable_event,
 +       * so we don't trigger the event without PEBS bit set.
 +       */
 +      if (unlikely(event->attr.precise_ip))
 +              intel_pmu_pebs_disable(event);
  }
  
  static void intel_pmu_del_event(struct perf_event *event)
@@@ -2149,6 -2213,11 +2217,11 @@@ static void intel_pmu_enable_fixed(stru
        bits <<= (idx * 4);
        mask = 0xfULL << (idx * 4);
  
+       if (x86_pmu.intel_cap.pebs_baseline && event->attr.precise_ip) {
+               bits |= ICL_FIXED_0_ADAPTIVE << (idx * 4);
+               mask |= ICL_FIXED_0_ADAPTIVE << (idx * 4);
+       }
        rdmsrl(hwc->config_base, ctrl_val);
        ctrl_val &= ~mask;
        ctrl_val |= bits;
@@@ -2692,7 -2761,7 +2765,7 @@@ x86_get_event_constraints(struct cpu_hw
  
        if (x86_pmu.event_constraints) {
                for_each_event_constraint(c, x86_pmu.event_constraints) {
-                       if ((event->hw.config & c->cmask) == c->code) {
+                       if (constraint_match(c, event->hw.config)) {
                                event->hw.flags |= c->flags;
                                return c;
                        }
@@@ -2842,7 -2911,7 +2915,7 @@@ intel_get_excl_constraints(struct cpu_h
        struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
        struct intel_excl_states *xlo;
        int tid = cpuc->excl_thread_id;
-       int is_excl, i;
+       int is_excl, i, w;
  
        /*
         * validating a group does not require
         * SHARED   : sibling counter measuring non-exclusive event
         * UNUSED   : sibling counter unused
         */
+       w = c->weight;
        for_each_set_bit(i, c->idxmsk, X86_PMC_IDX_MAX) {
                /*
                 * exclusive event in sibling counter
                 * our corresponding counter cannot be used
                 * regardless of our event
                 */
-               if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE)
+               if (xlo->state[i] == INTEL_EXCL_EXCLUSIVE) {
                        __clear_bit(i, c->idxmsk);
+                       w--;
+                       continue;
+               }
                /*
                 * if measuring an exclusive event, sibling
                 * measuring non-exclusive, then counter cannot
                 * be used
                 */
-               if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED)
+               if (is_excl && xlo->state[i] == INTEL_EXCL_SHARED) {
                        __clear_bit(i, c->idxmsk);
+                       w--;
+                       continue;
+               }
        }
  
-       /*
-        * recompute actual bit weight for scheduling algorithm
-        */
-       c->weight = hweight64(c->idxmsk64);
        /*
         * if we return an empty mask, then switch
         * back to static empty constraint to avoid
         * the cost of freeing later on
         */
-       if (c->weight == 0)
+       if (!w)
                c = &emptyconstraint;
  
+       c->weight = w;
        return c;
  }
  
@@@ -2935,11 -3008,9 +3012,9 @@@ static struct event_constraint 
  intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
                            struct perf_event *event)
  {
-       struct event_constraint *c1 = NULL;
-       struct event_constraint *c2;
+       struct event_constraint *c1, *c2;
  
-       if (idx >= 0) /* fake does < 0 */
-               c1 = cpuc->event_constraint[idx];
+       c1 = cpuc->event_constraint[idx];
  
        /*
         * first time only
         * - dynamic constraint: handled by intel_get_excl_constraints()
         */
        c2 = __intel_get_event_constraints(cpuc, idx, event);
-       if (c1 && (c1->flags & PERF_X86_EVENT_DYNAMIC)) {
+       if (c1) {
+               WARN_ON_ONCE(!(c1->flags & PERF_X86_EVENT_DYNAMIC));
                bitmap_copy(c1->idxmsk, c2->idxmsk, X86_PMC_IDX_MAX);
                c1->weight = c2->weight;
                c2 = c1;
@@@ -3370,6 -3442,12 +3446,12 @@@ static struct event_constraint counter0
  static struct event_constraint counter2_constraint =
                        EVENT_CONSTRAINT(0, 0x4, 0);
  
+ static struct event_constraint fixed0_constraint =
+                       FIXED_EVENT_CONSTRAINT(0x00c0, 0);
+ static struct event_constraint fixed0_counter0_constraint =
+                       INTEL_ALL_EVENT_CONSTRAINT(0, 0x100000001ULL);
  static struct event_constraint *
  hsw_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
                          struct perf_event *event)
        return c;
  }
  
+ static struct event_constraint *
+ icl_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+                         struct perf_event *event)
+ {
+       /*
+        * Fixed counter 0 has less skid.
+        * Force instruction:ppp in Fixed counter 0
+        */
+       if ((event->attr.precise_ip == 3) &&
+           constraint_match(&fixed0_constraint, event->hw.config))
+               return &fixed0_constraint;
+       return hsw_get_event_constraints(cpuc, idx, event);
+ }
  static struct event_constraint *
  glp_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
                          struct perf_event *event)
        return c;
  }
  
+ static struct event_constraint *
+ tnt_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+                         struct perf_event *event)
+ {
+       struct event_constraint *c;
+       /*
+        * :ppp means to do reduced skid PEBS,
+        * which is available on PMC0 and fixed counter 0.
+        */
+       if (event->attr.precise_ip == 3) {
+               /* Force instruction:ppp on PMC0 and Fixed counter 0 */
+               if (constraint_match(&fixed0_constraint, event->hw.config))
+                       return &fixed0_counter0_constraint;
+               return &counter0_constraint;
+       }
+       c = intel_get_event_constraints(cpuc, idx, event);
+       return c;
+ }
  static bool allow_tsx_force_abort = true;
  
  static struct event_constraint *
@@@ -3414,7 -3530,7 +3534,7 @@@ tfa_get_event_constraints(struct cpu_hw
        /*
         * Without TFA we must not use PMC3.
         */
-       if (!allow_tsx_force_abort && test_bit(3, c->idxmsk) && idx >= 0) {
+       if (!allow_tsx_force_abort && test_bit(3, c->idxmsk)) {
                c = dyn_constraint(cpuc, c, idx);
                c->idxmsk64 &= ~(1ULL << 3);
                c->weight--;
@@@ -3511,6 -3627,8 +3631,8 @@@ static struct intel_excl_cntrs *allocat
  
  int intel_cpuc_prepare(struct cpu_hw_events *cpuc, int cpu)
  {
+       cpuc->pebs_record_size = x86_pmu.pebs_record_size;
        if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) {
                cpuc->shared_regs = allocate_shared_regs(cpu);
                if (!cpuc->shared_regs)
@@@ -4118,6 -4236,42 +4240,42 @@@ static struct attribute *hsw_tsx_events
        NULL
  };
  
+ EVENT_ATTR_STR(tx-capacity-read,  tx_capacity_read,  "event=0x54,umask=0x80");
+ EVENT_ATTR_STR(tx-capacity-write, tx_capacity_write, "event=0x54,umask=0x2");
+ EVENT_ATTR_STR(el-capacity-read,  el_capacity_read,  "event=0x54,umask=0x80");
+ EVENT_ATTR_STR(el-capacity-write, el_capacity_write, "event=0x54,umask=0x2");
+ static struct attribute *icl_events_attrs[] = {
+       EVENT_PTR(mem_ld_hsw),
+       EVENT_PTR(mem_st_hsw),
+       NULL,
+ };
+ static struct attribute *icl_tsx_events_attrs[] = {
+       EVENT_PTR(tx_start),
+       EVENT_PTR(tx_abort),
+       EVENT_PTR(tx_commit),
+       EVENT_PTR(tx_capacity_read),
+       EVENT_PTR(tx_capacity_write),
+       EVENT_PTR(tx_conflict),
+       EVENT_PTR(el_start),
+       EVENT_PTR(el_abort),
+       EVENT_PTR(el_commit),
+       EVENT_PTR(el_capacity_read),
+       EVENT_PTR(el_capacity_write),
+       EVENT_PTR(el_conflict),
+       EVENT_PTR(cycles_t),
+       EVENT_PTR(cycles_ct),
+       NULL,
+ };
+ static __init struct attribute **get_icl_events_attrs(void)
+ {
+       return boot_cpu_has(X86_FEATURE_RTM) ?
+               merge_attr(icl_events_attrs, icl_tsx_events_attrs) :
+               icl_events_attrs;
+ }
  static ssize_t freeze_on_smi_show(struct device *cdev,
                                  struct device_attribute *attr,
                                  char *buf)
@@@ -4157,6 -4311,50 +4315,50 @@@ done
        return count;
  }
  
+ static void update_tfa_sched(void *ignored)
+ {
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+       /*
+        * check if PMC3 is used
+        * and if so force schedule out for all event types all contexts
+        */
+       if (test_bit(3, cpuc->active_mask))
+               perf_pmu_resched(x86_get_pmu());
+ }
+ static ssize_t show_sysctl_tfa(struct device *cdev,
+                             struct device_attribute *attr,
+                             char *buf)
+ {
+       return snprintf(buf, 40, "%d\n", allow_tsx_force_abort);
+ }
+ static ssize_t set_sysctl_tfa(struct device *cdev,
+                             struct device_attribute *attr,
+                             const char *buf, size_t count)
+ {
+       bool val;
+       ssize_t ret;
+       ret = kstrtobool(buf, &val);
+       if (ret)
+               return ret;
+       /* no change */
+       if (val == allow_tsx_force_abort)
+               return count;
+       allow_tsx_force_abort = val;
+       get_online_cpus();
+       on_each_cpu(update_tfa_sched, NULL, 1);
+       put_online_cpus();
+       return count;
+ }
  static DEVICE_ATTR_RW(freeze_on_smi);
  
  static ssize_t branches_show(struct device *cdev,
@@@ -4189,7 -4387,9 +4391,9 @@@ static struct attribute *intel_pmu_caps
         NULL
  };
  
- static DEVICE_BOOL_ATTR(allow_tsx_force_abort, 0644, allow_tsx_force_abort);
+ static DEVICE_ATTR(allow_tsx_force_abort, 0644,
+                  show_sysctl_tfa,
+                  set_sysctl_tfa);
  
  static struct attribute *intel_pmu_attrs[] = {
        &dev_attr_freeze_on_smi.attr,
@@@ -4450,6 -4650,32 +4654,32 @@@ __init int intel_pmu_init(void
                name = "goldmont_plus";
                break;
  
+       case INTEL_FAM6_ATOM_TREMONT_X:
+               x86_pmu.late_ack = true;
+               memcpy(hw_cache_event_ids, glp_hw_cache_event_ids,
+                      sizeof(hw_cache_event_ids));
+               memcpy(hw_cache_extra_regs, tnt_hw_cache_extra_regs,
+                      sizeof(hw_cache_extra_regs));
+               hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1;
+               intel_pmu_lbr_init_skl();
+               x86_pmu.event_constraints = intel_slm_event_constraints;
+               x86_pmu.extra_regs = intel_tnt_extra_regs;
+               /*
+                * It's recommended to use CPU_CLK_UNHALTED.CORE_P + NPEBS
+                * for precise cycles.
+                */
+               x86_pmu.pebs_aliases = NULL;
+               x86_pmu.pebs_prec_dist = true;
+               x86_pmu.lbr_pt_coexist = true;
+               x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+               x86_pmu.get_event_constraints = tnt_get_event_constraints;
+               extra_attr = slm_format_attr;
+               pr_cont("Tremont events, ");
+               name = "Tremont";
+               break;
        case INTEL_FAM6_WESTMERE:
        case INTEL_FAM6_WESTMERE_EP:
        case INTEL_FAM6_WESTMERE_EX:
                        x86_pmu.get_event_constraints = tfa_get_event_constraints;
                        x86_pmu.enable_all = intel_tfa_pmu_enable_all;
                        x86_pmu.commit_scheduling = intel_tfa_commit_scheduling;
-                       intel_pmu_attrs[1] = &dev_attr_allow_tsx_force_abort.attr.attr;
+                       intel_pmu_attrs[1] = &dev_attr_allow_tsx_force_abort.attr;
                }
  
                pr_cont("Skylake events, ");
                name = "skylake";
                break;
  
+       case INTEL_FAM6_ICELAKE_MOBILE:
+               x86_pmu.late_ack = true;
+               memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+               memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+               hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1;
+               intel_pmu_lbr_init_skl();
+               x86_pmu.event_constraints = intel_icl_event_constraints;
+               x86_pmu.pebs_constraints = intel_icl_pebs_event_constraints;
+               x86_pmu.extra_regs = intel_icl_extra_regs;
+               x86_pmu.pebs_aliases = NULL;
+               x86_pmu.pebs_prec_dist = true;
+               x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+               x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+               x86_pmu.hw_config = hsw_hw_config;
+               x86_pmu.get_event_constraints = icl_get_event_constraints;
+               extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
+                       hsw_format_attr : nhm_format_attr;
+               extra_attr = merge_attr(extra_attr, skl_format_attr);
+               x86_pmu.cpu_events = get_icl_events_attrs();
+               x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xca, .umask=0x02);
+               x86_pmu.lbr_pt_coexist = true;
+               intel_pmu_pebs_data_source_skl(false);
+               pr_cont("Icelake events, ");
+               name = "icelake";
+               break;
        default:
                switch (x86_pmu.version) {
                case 1:
index d41de9af7a39b52bcd2913b2f1ef5edf4f3552b3,dd5658ec31d5e9c2883cfc9c36faa44f858a603c..6072f92cb8eaffbc141582ff56cc1c2ff840c37c
   *                           Scope: Package (physical package)
   *    MSR_PKG_C8_RESIDENCY:  Package C8 Residency Counter.
   *                           perf code: 0x04
 - *                           Available model: HSW ULT,CNL
 + *                           Available model: HSW ULT,KBL,CNL
   *                           Scope: Package (physical package)
   *    MSR_PKG_C9_RESIDENCY:  Package C9 Residency Counter.
   *                           perf code: 0x05
 - *                           Available model: HSW ULT,CNL
 + *                           Available model: HSW ULT,KBL,CNL
   *                           Scope: Package (physical package)
   *    MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
   *                           perf code: 0x06
 - *                           Available model: HSW ULT,GLM,CNL
 + *                           Available model: HSW ULT,KBL,GLM,CNL
   *                           Scope: Package (physical package)
   *
   */
@@@ -566,8 -566,8 +566,8 @@@ static const struct x86_cpu_id intel_cs
        X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_DESKTOP, snb_cstates),
        X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_X, snb_cstates),
  
 -      X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_MOBILE,  snb_cstates),
 -      X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_DESKTOP, snb_cstates),
 +      X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_MOBILE,  hswult_cstates),
 +      X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_DESKTOP, hswult_cstates),
  
        X86_CSTATES_MODEL(INTEL_FAM6_CANNONLAKE_MOBILE, cnl_cstates),
  
        X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_X, glm_cstates),
  
        X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates),
+       X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_MOBILE, snb_cstates),
        { },
  };
  MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
index 1f678f0238505d549ac088f8bbf4a5c9a98f16cd,cf023db0e8a2fd411d5e53d306c4ce981a9027f6..15a82ff0aefe8be73ffe262cd76d7c7ce3ff7a00
@@@ -240,6 -240,7 +240,6 @@@ struct perf_event
  #define PERF_PMU_CAP_NO_INTERRUPT             0x01
  #define PERF_PMU_CAP_NO_NMI                   0x02
  #define PERF_PMU_CAP_AUX_NO_SG                        0x04
 -#define PERF_PMU_CAP_AUX_SW_DOUBLEBUF         0x08
  #define PERF_PMU_CAP_EXCLUSIVE                        0x10
  #define PERF_PMU_CAP_ITRACE                   0x20
  #define PERF_PMU_CAP_HETEROGENEOUS_CPUS               0x40
@@@ -463,7 -464,7 +463,7 @@@ enum perf_addr_filter_action_t 
  /**
   * struct perf_addr_filter - address range filter definition
   * @entry:    event's filter list linkage
-  * @inode:    object file's inode for file-based filters
+  * @path:     object file's path for file-based filters
   * @offset:   filter range offset
   * @size:     filter range size (size==0 means single address trigger)
   * @action:   filter/start/stop
@@@ -887,6 -888,9 +887,9 @@@ extern void perf_sched_cb_dec(struct pm
  extern void perf_sched_cb_inc(struct pmu *pmu);
  extern int perf_event_task_disable(void);
  extern int perf_event_task_enable(void);
+ extern void perf_pmu_resched(struct pmu *pmu);
  extern int perf_event_refresh(struct perf_event *event, int refresh);
  extern void perf_event_update_userpage(struct perf_event *event);
  extern int perf_event_release_kernel(struct perf_event *event);
@@@ -1054,12 -1058,18 +1057,18 @@@ static inline void perf_arch_fetch_call
  #endif
  
  /*
-  * Take a snapshot of the regs. Skip ip and frame pointer to
-  * the nth caller. We only need a few of the regs:
+  * When generating a perf sample in-line, instead of from an interrupt /
+  * exception, we lack a pt_regs. This is typically used from software events
+  * like: SW_CONTEXT_SWITCHES, SW_MIGRATIONS and the tie-in with tracepoints.
+  *
+  * We typically don't need a full set, but (for x86) do require:
   * - ip for PERF_SAMPLE_IP
   * - cs for user_mode() tests
-  * - bp for callchains
-  * - eflags, for future purposes, just in case
+  * - sp for PERF_SAMPLE_CALLCHAIN
+  * - eflags for MISC bits and CALLCHAIN (see: perf_hw_regs())
+  *
+  * NOTE: assumes @regs is otherwise already 0 filled; this is important for
+  * things like PERF_SAMPLE_REGS_INTR.
   */
  static inline void perf_fetch_caller_regs(struct pt_regs *regs)
  {
index 981c6ce2da2c76cee9d6a3b96b37bf6fa5cdaa33,7d4faaecd243ebfb0eb31b3430e4aa716c2765c0..b36b536a9fcbaa9ce8ee336a6c1df355fa533295
@@@ -148,14 -148,14 +148,14 @@@ struct cmdline_list 
        int                     pid;
  };
  
- static int cmdline_init(struct tep_handle *pevent)
+ static int cmdline_init(struct tep_handle *tep)
  {
-       struct cmdline_list *cmdlist = pevent->cmdlist;
+       struct cmdline_list *cmdlist = tep->cmdlist;
        struct cmdline_list *item;
        struct tep_cmdline *cmdlines;
        int i;
  
-       cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count);
+       cmdlines = malloc(sizeof(*cmdlines) * tep->cmdline_count);
        if (!cmdlines)
                return -1;
  
                free(item);
        }
  
-       qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
+       qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
  
-       pevent->cmdlines = cmdlines;
-       pevent->cmdlist = NULL;
+       tep->cmdlines = cmdlines;
+       tep->cmdlist = NULL;
  
        return 0;
  }
  
- static const char *find_cmdline(struct tep_handle *pevent, int pid)
+ static const char *find_cmdline(struct tep_handle *tep, int pid)
  {
        const struct tep_cmdline *comm;
        struct tep_cmdline key;
        if (!pid)
                return "<idle>";
  
-       if (!pevent->cmdlines && cmdline_init(pevent))
+       if (!tep->cmdlines && cmdline_init(tep))
                return "<not enough memory for cmdlines!>";
  
        key.pid = pid;
  
-       comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
-                      sizeof(*pevent->cmdlines), cmdline_cmp);
+       comm = bsearch(&key, tep->cmdlines, tep->cmdline_count,
+                      sizeof(*tep->cmdlines), cmdline_cmp);
  
        if (comm)
                return comm->comm;
  }
  
  /**
-  * tep_pid_is_registered - return if a pid has a cmdline registered
-  * @pevent: handle for the pevent
+  * tep_is_pid_registered - return if a pid has a cmdline registered
+  * @tep: a handle to the trace event parser context
   * @pid: The pid to check if it has a cmdline registered with.
   *
-  * Returns 1 if the pid has a cmdline mapped to it
-  * 0 otherwise.
+  * Returns true if the pid has a cmdline mapped to it
+  * false otherwise.
   */
int tep_pid_is_registered(struct tep_handle *pevent, int pid)
bool tep_is_pid_registered(struct tep_handle *tep, int pid)
  {
        const struct tep_cmdline *comm;
        struct tep_cmdline key;
  
        if (!pid)
-               return 1;
+               return true;
  
-       if (!pevent->cmdlines && cmdline_init(pevent))
-               return 0;
+       if (!tep->cmdlines && cmdline_init(tep))
+               return false;
  
        key.pid = pid;
  
-       comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
-                      sizeof(*pevent->cmdlines), cmdline_cmp);
+       comm = bsearch(&key, tep->cmdlines, tep->cmdline_count,
+                      sizeof(*tep->cmdlines), cmdline_cmp);
  
        if (comm)
-               return 1;
-       return 0;
+               return true;
+       return false;
  }
  
  /*
   * we must add this pid. This is much slower than when cmdlines
   * are added before the array is initialized.
   */
- static int add_new_comm(struct tep_handle *pevent,
+ static int add_new_comm(struct tep_handle *tep,
                        const char *comm, int pid, bool override)
  {
-       struct tep_cmdline *cmdlines = pevent->cmdlines;
+       struct tep_cmdline *cmdlines = tep->cmdlines;
        struct tep_cmdline *cmdline;
        struct tep_cmdline key;
        char *new_comm;
        /* avoid duplicates */
        key.pid = pid;
  
-       cmdline = bsearch(&key, pevent->cmdlines, pevent->cmdline_count,
-                      sizeof(*pevent->cmdlines), cmdline_cmp);
+       cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count,
+                         sizeof(*tep->cmdlines), cmdline_cmp);
        if (cmdline) {
                if (!override) {
                        errno = EEXIST;
                return 0;
        }
  
-       cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (pevent->cmdline_count + 1));
+       cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (tep->cmdline_count + 1));
        if (!cmdlines) {
                errno = ENOMEM;
                return -1;
        }
  
-       cmdlines[pevent->cmdline_count].comm = strdup(comm);
-       if (!cmdlines[pevent->cmdline_count].comm) {
+       cmdlines[tep->cmdline_count].comm = strdup(comm);
+       if (!cmdlines[tep->cmdline_count].comm) {
                free(cmdlines);
                errno = ENOMEM;
                return -1;
        }
  
-       cmdlines[pevent->cmdline_count].pid = pid;
+       cmdlines[tep->cmdline_count].pid = pid;
                
-       if (cmdlines[pevent->cmdline_count].comm)
-               pevent->cmdline_count++;
+       if (cmdlines[tep->cmdline_count].comm)
+               tep->cmdline_count++;
  
-       qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
-       pevent->cmdlines = cmdlines;
+       qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
+       tep->cmdlines = cmdlines;
  
        return 0;
  }
  
- static int _tep_register_comm(struct tep_handle *pevent,
+ static int _tep_register_comm(struct tep_handle *tep,
                              const char *comm, int pid, bool override)
  {
        struct cmdline_list *item;
  
-       if (pevent->cmdlines)
-               return add_new_comm(pevent, comm, pid, override);
+       if (tep->cmdlines)
+               return add_new_comm(tep, comm, pid, override);
  
        item = malloc(sizeof(*item));
        if (!item)
                return -1;
        }
        item->pid = pid;
-       item->next = pevent->cmdlist;
+       item->next = tep->cmdlist;
  
-       pevent->cmdlist = item;
-       pevent->cmdline_count++;
+       tep->cmdlist = item;
+       tep->cmdline_count++;
  
        return 0;
  }
  
  /**
   * tep_register_comm - register a pid / comm mapping
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   * @comm: the command line to register
   * @pid: the pid to map the command line to
   *
   * a given pid. The comm is duplicated. If a command with the same pid
   * already exist, -1 is returned and errno is set to EEXIST
   */
- int tep_register_comm(struct tep_handle *pevent, const char *comm, int pid)
+ int tep_register_comm(struct tep_handle *tep, const char *comm, int pid)
  {
-       return _tep_register_comm(pevent, comm, pid, false);
+       return _tep_register_comm(tep, comm, pid, false);
  }
  
  /**
   * tep_override_comm - register a pid / comm mapping
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   * @comm: the command line to register
   * @pid: the pid to map the command line to
   *
   * a given pid. The comm is duplicated. If a command with the same pid
   * already exist, the command string is udapted with the new one
   */
- int tep_override_comm(struct tep_handle *pevent, const char *comm, int pid)
+ int tep_override_comm(struct tep_handle *tep, const char *comm, int pid)
  {
-       if (!pevent->cmdlines && cmdline_init(pevent)) {
+       if (!tep->cmdlines && cmdline_init(tep)) {
                errno = ENOMEM;
                return -1;
        }
-       return _tep_register_comm(pevent, comm, pid, true);
+       return _tep_register_comm(tep, comm, pid, true);
  }
  
- int tep_register_trace_clock(struct tep_handle *pevent, const char *trace_clock)
+ int tep_register_trace_clock(struct tep_handle *tep, const char *trace_clock)
  {
-       pevent->trace_clock = strdup(trace_clock);
-       if (!pevent->trace_clock) {
+       tep->trace_clock = strdup(trace_clock);
+       if (!tep->trace_clock) {
                errno = ENOMEM;
                return -1;
        }
@@@ -408,18 -408,18 +408,18 @@@ static int func_bcmp(const void *a, con
        return 1;
  }
  
- static int func_map_init(struct tep_handle *pevent)
+ static int func_map_init(struct tep_handle *tep)
  {
        struct func_list *funclist;
        struct func_list *item;
        struct func_map *func_map;
        int i;
  
-       func_map = malloc(sizeof(*func_map) * (pevent->func_count + 1));
+       func_map = malloc(sizeof(*func_map) * (tep->func_count + 1));
        if (!func_map)
                return -1;
  
-       funclist = pevent->funclist;
+       funclist = tep->funclist;
  
        i = 0;
        while (funclist) {
                free(item);
        }
  
-       qsort(func_map, pevent->func_count, sizeof(*func_map), func_cmp);
+       qsort(func_map, tep->func_count, sizeof(*func_map), func_cmp);
  
        /*
         * Add a special record at the end.
         */
-       func_map[pevent->func_count].func = NULL;
-       func_map[pevent->func_count].addr = 0;
-       func_map[pevent->func_count].mod = NULL;
+       func_map[tep->func_count].func = NULL;
+       func_map[tep->func_count].addr = 0;
+       func_map[tep->func_count].mod = NULL;
  
-       pevent->func_map = func_map;
-       pevent->funclist = NULL;
+       tep->func_map = func_map;
+       tep->funclist = NULL;
  
        return 0;
  }
  
  static struct func_map *
- __find_func(struct tep_handle *pevent, unsigned long long addr)
+ __find_func(struct tep_handle *tep, unsigned long long addr)
  {
        struct func_map *func;
        struct func_map key;
  
-       if (!pevent->func_map)
-               func_map_init(pevent);
+       if (!tep->func_map)
+               func_map_init(tep);
  
        key.addr = addr;
  
-       func = bsearch(&key, pevent->func_map, pevent->func_count,
-                      sizeof(*pevent->func_map), func_bcmp);
+       func = bsearch(&key, tep->func_map, tep->func_count,
+                      sizeof(*tep->func_map), func_bcmp);
  
        return func;
  }
@@@ -472,15 -472,14 +472,14 @@@ struct func_resolver 
  
  /**
   * tep_set_function_resolver - set an alternative function resolver
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   * @resolver: function to be used
   * @priv: resolver function private state.
   *
   * Some tools may have already a way to resolve kernel functions, allow them to
-  * keep using it instead of duplicating all the entries inside
-  * pevent->funclist.
+  * keep using it instead of duplicating all the entries inside tep->funclist.
   */
- int tep_set_function_resolver(struct tep_handle *pevent,
+ int tep_set_function_resolver(struct tep_handle *tep,
                              tep_func_resolver_t *func, void *priv)
  {
        struct func_resolver *resolver = malloc(sizeof(*resolver));
        resolver->func = func;
        resolver->priv = priv;
  
-       free(pevent->func_resolver);
-       pevent->func_resolver = resolver;
+       free(tep->func_resolver);
+       tep->func_resolver = resolver;
  
        return 0;
  }
  
  /**
   * tep_reset_function_resolver - reset alternative function resolver
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   *
   * Stop using whatever alternative resolver was set, use the default
   * one instead.
   */
- void tep_reset_function_resolver(struct tep_handle *pevent)
+ void tep_reset_function_resolver(struct tep_handle *tep)
  {
-       free(pevent->func_resolver);
-       pevent->func_resolver = NULL;
+       free(tep->func_resolver);
+       tep->func_resolver = NULL;
  }
  
  static struct func_map *
- find_func(struct tep_handle *pevent, unsigned long long addr)
+ find_func(struct tep_handle *tep, unsigned long long addr)
  {
        struct func_map *map;
  
-       if (!pevent->func_resolver)
-               return __find_func(pevent, addr);
+       if (!tep->func_resolver)
+               return __find_func(tep, addr);
  
-       map = &pevent->func_resolver->map;
+       map = &tep->func_resolver->map;
        map->mod  = NULL;
        map->addr = addr;
-       map->func = pevent->func_resolver->func(pevent->func_resolver->priv,
-                                               &map->addr, &map->mod);
+       map->func = tep->func_resolver->func(tep->func_resolver->priv,
+                                            &map->addr, &map->mod);
        if (map->func == NULL)
                return NULL;
  
  
  /**
   * tep_find_function - find a function by a given address
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   * @addr: the address to find the function with
   *
   * Returns a pointer to the function stored that has the given
   * address. Note, the address does not have to be exact, it
   * will select the function that would contain the address.
   */
- const char *tep_find_function(struct tep_handle *pevent, unsigned long long addr)
+ const char *tep_find_function(struct tep_handle *tep, unsigned long long addr)
  {
        struct func_map *map;
  
-       map = find_func(pevent, addr);
+       map = find_func(tep, addr);
        if (!map)
                return NULL;
  
  
  /**
   * tep_find_function_address - find a function address by a given address
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   * @addr: the address to find the function with
   *
   * Returns the address the function starts at. This can be used in
   * name and the function offset.
   */
  unsigned long long
- tep_find_function_address(struct tep_handle *pevent, unsigned long long addr)
+ tep_find_function_address(struct tep_handle *tep, unsigned long long addr)
  {
        struct func_map *map;
  
-       map = find_func(pevent, addr);
+       map = find_func(tep, addr);
        if (!map)
                return 0;
  
  
  /**
   * tep_register_function - register a function with a given address
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   * @function: the function name to register
   * @addr: the address the function starts at
   * @mod: the kernel module the function may be in (NULL for none)
   * This registers a function name with an address and module.
   * The @func passed in is duplicated.
   */
- int tep_register_function(struct tep_handle *pevent, char *func,
+ int tep_register_function(struct tep_handle *tep, char *func,
                          unsigned long long addr, char *mod)
  {
        struct func_list *item = malloc(sizeof(*item));
        if (!item)
                return -1;
  
-       item->next = pevent->funclist;
+       item->next = tep->funclist;
        item->func = strdup(func);
        if (!item->func)
                goto out_free;
                item->mod = NULL;
        item->addr = addr;
  
-       pevent->funclist = item;
-       pevent->func_count++;
+       tep->funclist = item;
+       tep->func_count++;
  
        return 0;
  
@@@ -617,23 -616,23 +616,23 @@@ out_free
  
  /**
   * tep_print_funcs - print out the stored functions
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   *
   * This prints out the stored functions.
   */
- void tep_print_funcs(struct tep_handle *pevent)
+ void tep_print_funcs(struct tep_handle *tep)
  {
        int i;
  
-       if (!pevent->func_map)
-               func_map_init(pevent);
+       if (!tep->func_map)
+               func_map_init(tep);
  
-       for (i = 0; i < (int)pevent->func_count; i++) {
+       for (i = 0; i < (int)tep->func_count; i++) {
                printf("%016llx %s",
-                      pevent->func_map[i].addr,
-                      pevent->func_map[i].func);
-               if (pevent->func_map[i].mod)
-                       printf(" [%s]\n", pevent->func_map[i].mod);
+                      tep->func_map[i].addr,
+                      tep->func_map[i].func);
+               if (tep->func_map[i].mod)
+                       printf(" [%s]\n", tep->func_map[i].mod);
                else
                        printf("\n");
        }
@@@ -663,18 -662,18 +662,18 @@@ static int printk_cmp(const void *a, co
        return 0;
  }
  
- static int printk_map_init(struct tep_handle *pevent)
+ static int printk_map_init(struct tep_handle *tep)
  {
        struct printk_list *printklist;
        struct printk_list *item;
        struct printk_map *printk_map;
        int i;
  
-       printk_map = malloc(sizeof(*printk_map) * (pevent->printk_count + 1));
+       printk_map = malloc(sizeof(*printk_map) * (tep->printk_count + 1));
        if (!printk_map)
                return -1;
  
-       printklist = pevent->printklist;
+       printklist = tep->printklist;
  
        i = 0;
        while (printklist) {
                free(item);
        }
  
-       qsort(printk_map, pevent->printk_count, sizeof(*printk_map), printk_cmp);
+       qsort(printk_map, tep->printk_count, sizeof(*printk_map), printk_cmp);
  
-       pevent->printk_map = printk_map;
-       pevent->printklist = NULL;
+       tep->printk_map = printk_map;
+       tep->printklist = NULL;
  
        return 0;
  }
  
  static struct printk_map *
- find_printk(struct tep_handle *pevent, unsigned long long addr)
+ find_printk(struct tep_handle *tep, unsigned long long addr)
  {
        struct printk_map *printk;
        struct printk_map key;
  
-       if (!pevent->printk_map && printk_map_init(pevent))
+       if (!tep->printk_map && printk_map_init(tep))
                return NULL;
  
        key.addr = addr;
  
-       printk = bsearch(&key, pevent->printk_map, pevent->printk_count,
-                        sizeof(*pevent->printk_map), printk_cmp);
+       printk = bsearch(&key, tep->printk_map, tep->printk_count,
+                        sizeof(*tep->printk_map), printk_cmp);
  
        return printk;
  }
  
  /**
   * tep_register_print_string - register a string by its address
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   * @fmt: the string format to register
   * @addr: the address the string was located at
   *
   * This registers a string by the address it was stored in the kernel.
   * The @fmt passed in is duplicated.
   */
- int tep_register_print_string(struct tep_handle *pevent, const char *fmt,
+ int tep_register_print_string(struct tep_handle *tep, const char *fmt,
                              unsigned long long addr)
  {
        struct printk_list *item = malloc(sizeof(*item));
        if (!item)
                return -1;
  
-       item->next = pevent->printklist;
+       item->next = tep->printklist;
        item->addr = addr;
  
        /* Strip off quotes and '\n' from the end */
        if (strcmp(p, "\\n") == 0)
                *p = 0;
  
-       pevent->printklist = item;
-       pevent->printk_count++;
+       tep->printklist = item;
+       tep->printk_count++;
  
        return 0;
  
@@@ -760,21 -759,21 +759,21 @@@ out_free
  
  /**
   * tep_print_printk - print out the stored strings
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   *
   * This prints the string formats that were stored.
   */
- void tep_print_printk(struct tep_handle *pevent)
+ void tep_print_printk(struct tep_handle *tep)
  {
        int i;
  
-       if (!pevent->printk_map)
-               printk_map_init(pevent);
+       if (!tep->printk_map)
+               printk_map_init(tep);
  
-       for (i = 0; i < (int)pevent->printk_count; i++) {
+       for (i = 0; i < (int)tep->printk_count; i++) {
                printf("%016llx %s\n",
-                      pevent->printk_map[i].addr,
-                      pevent->printk_map[i].printk);
+                      tep->printk_map[i].addr,
+                      tep->printk_map[i].printk);
        }
  }
  
@@@ -783,29 -782,29 +782,29 @@@ static struct tep_event *alloc_event(vo
        return calloc(1, sizeof(struct tep_event));
  }
  
- static int add_event(struct tep_handle *pevent, struct tep_event *event)
+ static int add_event(struct tep_handle *tep, struct tep_event *event)
  {
        int i;
-       struct tep_event **events = realloc(pevent->events, sizeof(event) *
-                                           (pevent->nr_events + 1));
+       struct tep_event **events = realloc(tep->events, sizeof(event) *
+                                           (tep->nr_events + 1));
        if (!events)
                return -1;
  
-       pevent->events = events;
+       tep->events = events;
  
-       for (i = 0; i < pevent->nr_events; i++) {
-               if (pevent->events[i]->id > event->id)
+       for (i = 0; i < tep->nr_events; i++) {
+               if (tep->events[i]->id > event->id)
                        break;
        }
-       if (i < pevent->nr_events)
-               memmove(&pevent->events[i + 1],
-                       &pevent->events[i],
-                       sizeof(event) * (pevent->nr_events - i));
+       if (i < tep->nr_events)
+               memmove(&tep->events[i + 1],
+                       &tep->events[i],
+                       sizeof(event) * (tep->nr_events - i));
  
-       pevent->events[i] = event;
-       pevent->nr_events++;
+       tep->events[i] = event;
+       tep->nr_events++;
  
-       event->pevent = pevent;
+       event->tep = tep;
  
        return 0;
  }
@@@ -1184,7 -1183,7 +1183,7 @@@ static enum tep_event_type read_token(c
  }
  
  /**
-  * tep_read_token - access to utilities to use the pevent parser
+  * tep_read_token - access to utilities to use the tep parser
   * @tok: The token to return
   *
   * This will parse tokens from the string given by
@@@ -1657,8 -1656,8 +1656,8 @@@ static int event_read_fields(struct tep
                        else if (field->flags & TEP_FIELD_IS_STRING)
                                field->elementsize = 1;
                        else if (field->flags & TEP_FIELD_IS_LONG)
-                               field->elementsize = event->pevent ?
-                                                    event->pevent->long_size :
+                               field->elementsize = event->tep ?
+                                                    event->tep->long_size :
                                                     sizeof(long);
                } else
                        field->elementsize = field->size;
@@@ -2233,7 -2232,7 +2232,7 @@@ eval_type_str(unsigned long long val, c
                return val & 0xffffffff;
  
        if (strcmp(type, "u64") == 0 ||
 -          strcmp(type, "s64"))
 +          strcmp(type, "s64") == 0)
                return val;
  
        if (strcmp(type, "s8") == 0)
@@@ -2942,14 -2941,14 +2941,14 @@@ process_bitmask(struct tep_event *even
  }
  
  static struct tep_function_handler *
- find_func_handler(struct tep_handle *pevent, char *func_name)
+ find_func_handler(struct tep_handle *tep, char *func_name)
  {
        struct tep_function_handler *func;
  
-       if (!pevent)
+       if (!tep)
                return NULL;
  
-       for (func = pevent->func_handlers; func; func = func->next) {
+       for (func = tep->func_handlers; func; func = func->next) {
                if (strcmp(func->name, func_name) == 0)
                        break;
        }
        return func;
  }
  
- static void remove_func_handler(struct tep_handle *pevent, char *func_name)
+ static void remove_func_handler(struct tep_handle *tep, char *func_name)
  {
        struct tep_function_handler *func;
        struct tep_function_handler **next;
  
-       next = &pevent->func_handlers;
+       next = &tep->func_handlers;
        while ((func = *next)) {
                if (strcmp(func->name, func_name) == 0) {
                        *next = func->next;
@@@ -3076,7 -3075,7 +3075,7 @@@ process_function(struct tep_event *even
                return process_dynamic_array_len(event, arg, tok);
        }
  
-       func = find_func_handler(event->pevent, token);
+       func = find_func_handler(event->tep, token);
        if (func) {
                free_token(token);
                return process_func_handler(event, func, arg, tok);
@@@ -3357,14 -3356,14 +3356,14 @@@ tep_find_any_field(struct tep_event *ev
  
  /**
   * tep_read_number - read a number from data
-  * @pevent: handle for the pevent
+  * @tep: a handle to the trace event parser context
   * @ptr: the raw data
   * @size: the size of the data that holds the number
   *
   * Returns the number (converted to host) from the
   * raw data.
   */
- unsigned long long tep_read_number(struct tep_handle *pevent,
+ unsigned long long tep_read_number(struct tep_handle *tep,
                                   const void *ptr, int size)
  {
        unsigned long long val;
        case 1:
                return *(unsigned char *)ptr;
        case 2:
-               return tep_data2host2(pevent, *(unsigned short *)ptr);
+               return tep_data2host2(tep, *(unsigned short *)ptr);
        case 4:
-               return tep_data2host4(pevent, *(unsigned int *)ptr);
+               return tep_data2host4(tep, *(unsigned int *)ptr);
        case 8:
                memcpy(&val, (ptr), sizeof(unsigned long long));
-               return tep_data2host8(pevent, val);
+               return tep_data2host8(tep, val);
        default:
                /* BUG! */
                return 0;
@@@ -3406,7 -3405,7 +3405,7 @@@ int tep_read_number_field(struct tep_fo
        case 2:
        case 4:
        case 8:
-               *value = tep_read_number(field->event->pevent,
+               *value = tep_read_number(field->event->tep,
                                         data + field->offset, field->size);
                return 0;
        default:
        }
  }
  
- static int get_common_info(struct tep_handle *pevent,
+ static int get_common_info(struct tep_handle *tep,
                           const char *type, int *offset, int *size)
  {
        struct tep_event *event;
         * All events should have the same common elements.
         * Pick any event to find where the type is;
         */
-       if (!pevent->events) {
+       if (!tep->events) {
                do_warning("no event_list!");
                return -1;
        }
  
-       event = pevent->events[0];
+       event = tep->events[0];
        field = tep_find_common_field(event, type);
        if (!field)
                return -1;
        return 0;
  }
  
- static int __parse_common(struct tep_handle *pevent, void *data,
+ static int __parse_common(struct tep_handle *tep, void *data,
                          int *size, int *offset, const char *name)
  {
        int ret;
  
        if (!*size) {
-               ret = get_common_info(pevent, name, offset, size);
+               ret = get_common_info(tep, name, offset, size);
                if (ret < 0)
                        return ret;
        }
-       return tep_read_number(pevent, data + *offset, *size);
+       return tep_read_number(tep, data + *offset, *size);
  }
  
- static int trace_parse_common_type(struct tep_handle *pevent, void *data)
+ static int trace_parse_common_type(struct tep_handle *tep, void *data)
  {
-       return __parse_common(pevent, data,
-                             &pevent->type_size, &pevent->type_offset,
+       return __parse_common(tep, data,
+                             &tep->type_size, &tep->type_offset,
                              "common_type");
  }
  
- static int parse_common_pid(struct tep_handle *pevent, void *data)
+ static int parse_common_pid(struct tep_handle *tep, void *data)
  {
-       return __parse_common(pevent, data,
-                             &pevent->pid_size, &pevent->pid_offset,
+       return __parse_common(tep, data,
+                             &tep->pid_size, &tep->pid_offset,
                              "common_pid");
  }
  
- static int parse_common_pc(struct tep_handle *pevent, void *data)
+ static int parse_common_pc(struct tep_handle *tep, void *data)
  {
-       return __parse_common(pevent, data,
-                             &pevent->pc_size, &pevent->pc_offset,
+       return __parse_common(tep, data,
+                             &tep->pc_size, &tep->pc_offset,
                              "common_preempt_count");
  }
  
- static int parse_common_flags(struct tep_handle *pevent, void *data)
+ static int parse_common_flags(struct tep_handle *tep, void *data)
  {
-       return __parse_common(pevent, data,
-                             &pevent->flags_size, &pevent->flags_offset,
+       return __parse_common(tep, data,
+                             &tep->flags_size, &tep->flags_offset,
                              "common_flags");
  }
  
- static int parse_common_lock_depth(struct tep_handle *pevent, void *data)
+ static int parse_common_lock_depth(struct tep_handle *tep, void *data)
  {
-       return __parse_common(pevent, data,
-                             &pevent->ld_size, &pevent->ld_offset,
+       return __parse_common(tep, data,
+                             &tep->ld_size, &tep->ld_offset,
                              "common_lock_depth");
  }
  
- static int parse_common_migrate_disable(struct tep_handle *pevent, void *data)
+ static int parse_common_migrate_disable(struct tep_handle *tep, void *data)
  {
-       return __parse_common(pevent, data,
-                             &pevent->ld_size, &pevent->ld_offset,
+       return __parse_common(tep, data,
+                             &tep->ld_size, &tep->ld_offset,
                              "common_migrate_disable");
  }
  
@@@ -3499,28 -3498,28 +3498,28 @@@ static int events_id_cmp(const void *a
  
  /**
   * tep_find_event - find an event by given id
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @id: the id of the event
   *
   * Returns an event that has a given @id.
   */
- struct tep_event *tep_find_event(struct tep_handle *pevent, int id)
+ struct tep_event *tep_find_event(struct tep_handle *tep, int id)
  {
        struct tep_event **eventptr;
        struct tep_event key;
        struct tep_event *pkey = &key;
  
        /* Check cache first */
-       if (pevent->last_event && pevent->last_event->id == id)
-               return pevent->last_event;
+       if (tep->last_event && tep->last_event->id == id)
+               return tep->last_event;
  
        key.id = id;
  
-       eventptr = bsearch(&pkey, pevent->events, pevent->nr_events,
-                          sizeof(*pevent->events), events_id_cmp);
+       eventptr = bsearch(&pkey, tep->events, tep->nr_events,
+                          sizeof(*tep->events), events_id_cmp);
  
        if (eventptr) {
-               pevent->last_event = *eventptr;
+               tep->last_event = *eventptr;
                return *eventptr;
        }
  
  
  /**
   * tep_find_event_by_name - find an event by given name
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @sys: the system name to search for
   * @name: the name of the event to search for
   *
   * @sys. If @sys is NULL the first event with @name is returned.
   */
  struct tep_event *
- tep_find_event_by_name(struct tep_handle *pevent,
+ tep_find_event_by_name(struct tep_handle *tep,
                       const char *sys, const char *name)
  {
        struct tep_event *event = NULL;
        int i;
  
-       if (pevent->last_event &&
-           strcmp(pevent->last_event->name, name) == 0 &&
-           (!sys || strcmp(pevent->last_event->system, sys) == 0))
-               return pevent->last_event;
+       if (tep->last_event &&
+           strcmp(tep->last_event->name, name) == 0 &&
+           (!sys || strcmp(tep->last_event->system, sys) == 0))
+               return tep->last_event;
  
-       for (i = 0; i < pevent->nr_events; i++) {
-               event = pevent->events[i];
+       for (i = 0; i < tep->nr_events; i++) {
+               event = tep->events[i];
                if (strcmp(event->name, name) == 0) {
                        if (!sys)
                                break;
                                break;
                }
        }
-       if (i == pevent->nr_events)
+       if (i == tep->nr_events)
                event = NULL;
  
-       pevent->last_event = event;
+       tep->last_event = event;
        return event;
  }
  
  static unsigned long long
  eval_num_arg(void *data, int size, struct tep_event *event, struct tep_print_arg *arg)
  {
-       struct tep_handle *pevent = event->pevent;
+       struct tep_handle *tep = event->tep;
        unsigned long long val = 0;
        unsigned long long left, right;
        struct tep_print_arg *typearg = NULL;
                        
                }
                /* must be a number */
-               val = tep_read_number(pevent, data + arg->field.field->offset,
+               val = tep_read_number(tep, data + arg->field.field->offset,
                                      arg->field.field->size);
                break;
        case TEP_PRINT_FLAGS:
                        }
  
                        /* Default to long size */
-                       field_size = pevent->long_size;
+                       field_size = tep->long_size;
  
                        switch (larg->type) {
                        case TEP_PRINT_DYNAMIC_ARRAY:
-                               offset = tep_read_number(pevent,
+                               offset = tep_read_number(tep,
                                                   data + larg->dynarray.field->offset,
                                                   larg->dynarray.field->size);
                                if (larg->dynarray.field->elementsize)
                        default:
                                goto default_op; /* oops, all bets off */
                        }
-                       val = tep_read_number(pevent,
+                       val = tep_read_number(tep,
                                              data + offset, field_size);
                        if (typearg)
                                val = eval_type(val, typearg, 1);
                }
                break;
        case TEP_PRINT_DYNAMIC_ARRAY_LEN:
-               offset = tep_read_number(pevent,
+               offset = tep_read_number(tep,
                                         data + arg->dynarray.field->offset,
                                         arg->dynarray.field->size);
                /*
                break;
        case TEP_PRINT_DYNAMIC_ARRAY:
                /* Without [], we pass the address to the dynamic data */
-               offset = tep_read_number(pevent,
+               offset = tep_read_number(tep,
                                         data + arg->dynarray.field->offset,
                                         arg->dynarray.field->size);
                /*
@@@ -3850,7 -3849,7 +3849,7 @@@ static void print_str_to_seq(struct tra
                trace_seq_printf(s, format, str);
  }
  
- static void print_bitmask_to_seq(struct tep_handle *pevent,
+ static void print_bitmask_to_seq(struct tep_handle *tep,
                                 struct trace_seq *s, const char *format,
                                 int len_arg, const void *data, int size)
  {
                 * In the kernel, this is an array of long words, thus
                 * endianness is very important.
                 */
-               if (pevent->file_bigendian)
+               if (tep->file_bigendian)
                        index = size - (len + 1);
                else
                        index = len;
@@@ -3908,7 -3907,7 +3907,7 @@@ static void print_str_arg(struct trace_
                          struct tep_event *event, const char *format,
                          int len_arg, struct tep_print_arg *arg)
  {
-       struct tep_handle *pevent = event->pevent;
+       struct tep_handle *tep = event->tep;
        struct tep_print_flag_sym *flag;
        struct tep_format_field *field;
        struct printk_map *printk;
                 * is a pointer.
                 */
                if (!(field->flags & TEP_FIELD_IS_ARRAY) &&
-                   field->size == pevent->long_size) {
+                   field->size == tep->long_size) {
  
                        /* Handle heterogeneous recording and processing
                         * architectures
                         * on 32-bit devices:
                         * In this case, 64 bits must be read.
                         */
-                       addr = (pevent->long_size == 8) ?
+                       addr = (tep->long_size == 8) ?
                                *(unsigned long long *)(data + field->offset) :
                                (unsigned long long)*(unsigned int *)(data + field->offset);
  
                        /* Check if it matches a print format */
-                       printk = find_printk(pevent, addr);
+                       printk = find_printk(tep, addr);
                        if (printk)
                                trace_seq_puts(s, printk->printk);
                        else
        case TEP_PRINT_HEX_STR:
                if (arg->hex.field->type == TEP_PRINT_DYNAMIC_ARRAY) {
                        unsigned long offset;
-                       offset = tep_read_number(pevent,
+                       offset = tep_read_number(tep,
                                data + arg->hex.field->dynarray.field->offset,
                                arg->hex.field->dynarray.field->size);
                        hex = data + (offset & 0xffff);
                        unsigned long offset;
                        struct tep_format_field *field =
                                arg->int_array.field->dynarray.field;
-                       offset = tep_read_number(pevent,
+                       offset = tep_read_number(tep,
                                                 data + field->offset,
                                                 field->size);
                        num = data + (offset & 0xffff);
                        f = tep_find_any_field(event, arg->string.string);
                        arg->string.offset = f->offset;
                }
-               str_offset = tep_data2host4(pevent, *(unsigned int *)(data + arg->string.offset));
+               str_offset = tep_data2host4(tep, *(unsigned int *)(data + arg->string.offset));
                str_offset &= 0xffff;
                print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset);
                break;
                        f = tep_find_any_field(event, arg->bitmask.bitmask);
                        arg->bitmask.offset = f->offset;
                }
-               bitmask_offset = tep_data2host4(pevent, *(unsigned int *)(data + arg->bitmask.offset));
+               bitmask_offset = tep_data2host4(tep, *(unsigned int *)(data + arg->bitmask.offset));
                bitmask_size = bitmask_offset >> 16;
                bitmask_offset &= 0xffff;
-               print_bitmask_to_seq(pevent, s, format, len_arg,
+               print_bitmask_to_seq(tep, s, format, len_arg,
                                     data + bitmask_offset, bitmask_size);
                break;
        }
@@@ -4257,7 -4256,7 +4256,7 @@@ static void free_args(struct tep_print_
  
  static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, struct tep_event *event)
  {
-       struct tep_handle *pevent = event->pevent;
+       struct tep_handle *tep = event->tep;
        struct tep_format_field *field, *ip_field;
        struct tep_print_arg *args, *arg, **next;
        unsigned long long ip, val;
        void *bptr;
        int vsize = 0;
  
-       field = pevent->bprint_buf_field;
-       ip_field = pevent->bprint_ip_field;
+       field = tep->bprint_buf_field;
+       ip_field = tep->bprint_ip_field;
  
        if (!field) {
                field = tep_find_field(event, "buf");
                        do_warning_event(event, "can't find ip field for binary printk");
                        return NULL;
                }
-               pevent->bprint_buf_field = field;
-               pevent->bprint_ip_field = ip_field;
+               tep->bprint_buf_field = field;
+               tep->bprint_ip_field = ip_field;
        }
  
-       ip = tep_read_number(pevent, data + ip_field->offset, ip_field->size);
+       ip = tep_read_number(tep, data + ip_field->offset, ip_field->size);
  
        /*
         * The first arg is the IP pointer.
                                        case 'S':
                                        case 'f':
                                        case 'F':
+                                       case 'x':
                                                break;
                                        default:
                                                /*
                                        vsize = 4;
                                        break;
                                case 1:
-                                       vsize = pevent->long_size;
+                                       vsize = tep->long_size;
                                        break;
                                case 2:
                                        vsize = 8;
                                /* the pointers are always 4 bytes aligned */
                                bptr = (void *)(((unsigned long)bptr + 3) &
                                                ~3);
-                               val = tep_read_number(pevent, bptr, vsize);
+                               val = tep_read_number(tep, bptr, vsize);
                                bptr += vsize;
                                arg = alloc_arg();
                                if (!arg) {
@@@ -4434,13 -4434,13 +4434,13 @@@ static char 
  get_bprint_format(void *data, int size __maybe_unused,
                  struct tep_event *event)
  {
-       struct tep_handle *pevent = event->pevent;
+       struct tep_handle *tep = event->tep;
        unsigned long long addr;
        struct tep_format_field *field;
        struct printk_map *printk;
        char *format;
  
-       field = pevent->bprint_fmt_field;
+       field = tep->bprint_fmt_field;
  
        if (!field) {
                field = tep_find_field(event, "fmt");
                        do_warning_event(event, "can't find format field for binary printk");
                        return NULL;
                }
-               pevent->bprint_fmt_field = field;
+               tep->bprint_fmt_field = field;
        }
  
-       addr = tep_read_number(pevent, data + field->offset, field->size);
+       addr = tep_read_number(tep, data + field->offset, field->size);
  
-       printk = find_printk(pevent, addr);
+       printk = find_printk(tep, addr);
        if (!printk) {
                if (asprintf(&format, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0)
                        return NULL;
@@@ -4835,13 -4835,13 +4835,13 @@@ void tep_print_field(struct trace_seq *
  {
        unsigned long long val;
        unsigned int offset, len, i;
-       struct tep_handle *pevent = field->event->pevent;
+       struct tep_handle *tep = field->event->tep;
  
        if (field->flags & TEP_FIELD_IS_ARRAY) {
                offset = field->offset;
                len = field->size;
                if (field->flags & TEP_FIELD_IS_DYNAMIC) {
-                       val = tep_read_number(pevent, data + offset, len);
+                       val = tep_read_number(tep, data + offset, len);
                        offset = val;
                        len = offset >> 16;
                        offset &= 0xffff;
                        field->flags &= ~TEP_FIELD_IS_STRING;
                }
        } else {
-               val = tep_read_number(pevent, data + field->offset,
+               val = tep_read_number(tep, data + field->offset,
                                      field->size);
                if (field->flags & TEP_FIELD_IS_POINTER) {
                        trace_seq_printf(s, "0x%llx", val);
@@@ -4910,7 -4910,7 +4910,7 @@@ void tep_print_fields(struct trace_seq 
  
  static void pretty_print(struct trace_seq *s, void *data, int size, struct tep_event *event)
  {
-       struct tep_handle *pevent = event->pevent;
+       struct tep_handle *tep = event->tep;
        struct tep_print_fmt *print_fmt = &event->print_fmt;
        struct tep_print_arg *arg = print_fmt->args;
        struct tep_print_arg *args = NULL;
                        case '-':
                                goto cont_process;
                        case 'p':
-                               if (pevent->long_size == 4)
+                               if (tep->long_size == 4)
                                        ls = 1;
                                else
                                        ls = 2;
                                arg = arg->next;
  
                                if (show_func) {
-                                       func = find_func(pevent, val);
+                                       func = find_func(tep, val);
                                        if (func) {
                                                trace_seq_puts(s, func->func);
                                                if (show_func == 'F')
                                                break;
                                        }
                                }
-                               if (pevent->long_size == 8 && ls == 1 &&
+                               if (tep->long_size == 8 && ls == 1 &&
                                    sizeof(long) != 8) {
                                        char *p;
  
@@@ -5171,8 -5171,8 +5171,8 @@@ out_failed
  }
  
  /**
-  * tep_data_lat_fmt - parse the data for the latency format
-  * @pevent: a handle to the pevent
+  * tep_data_latency_format - parse the data for the latency format
+  * @tep: a handle to the trace event parser context
   * @s: the trace_seq to write to
   * @record: the record to read from
   *
   * need rescheduling, in hard/soft interrupt, preempt count
   * and lock depth) and places it into the trace_seq.
   */
- void tep_data_lat_fmt(struct tep_handle *pevent,
-                     struct trace_seq *s, struct tep_record *record)
+ void tep_data_latency_format(struct tep_handle *tep,
+                            struct trace_seq *s, struct tep_record *record)
  {
        static int check_lock_depth = 1;
        static int check_migrate_disable = 1;
        int softirq;
        void *data = record->data;
  
-       lat_flags = parse_common_flags(pevent, data);
-       pc = parse_common_pc(pevent, data);
+       lat_flags = parse_common_flags(tep, data);
+       pc = parse_common_pc(tep, data);
        /* lock_depth may not always exist */
        if (lock_depth_exists)
-               lock_depth = parse_common_lock_depth(pevent, data);
+               lock_depth = parse_common_lock_depth(tep, data);
        else if (check_lock_depth) {
-               lock_depth = parse_common_lock_depth(pevent, data);
+               lock_depth = parse_common_lock_depth(tep, data);
                if (lock_depth < 0)
                        check_lock_depth = 0;
                else
  
        /* migrate_disable may not always exist */
        if (migrate_disable_exists)
-               migrate_disable = parse_common_migrate_disable(pevent, data);
+               migrate_disable = parse_common_migrate_disable(tep, data);
        else if (check_migrate_disable) {
-               migrate_disable = parse_common_migrate_disable(pevent, data);
+               migrate_disable = parse_common_migrate_disable(tep, data);
                if (migrate_disable < 0)
                        check_migrate_disable = 0;
                else
  
  /**
   * tep_data_type - parse out the given event type
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @rec: the record to read from
   *
   * This returns the event id from the @rec.
   */
- int tep_data_type(struct tep_handle *pevent, struct tep_record *rec)
+ int tep_data_type(struct tep_handle *tep, struct tep_record *rec)
  {
-       return trace_parse_common_type(pevent, rec->data);
+       return trace_parse_common_type(tep, rec->data);
  }
  
  /**
   * tep_data_pid - parse the PID from record
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @rec: the record to parse
   *
   * This returns the PID from a record.
   */
- int tep_data_pid(struct tep_handle *pevent, struct tep_record *rec)
+ int tep_data_pid(struct tep_handle *tep, struct tep_record *rec)
  {
-       return parse_common_pid(pevent, rec->data);
+       return parse_common_pid(tep, rec->data);
  }
  
  /**
   * tep_data_preempt_count - parse the preempt count from the record
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @rec: the record to parse
   *
   * This returns the preempt count from a record.
   */
- int tep_data_preempt_count(struct tep_handle *pevent, struct tep_record *rec)
+ int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec)
  {
-       return parse_common_pc(pevent, rec->data);
+       return parse_common_pc(tep, rec->data);
  }
  
  /**
   * tep_data_flags - parse the latency flags from the record
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @rec: the record to parse
   *
   * This returns the latency flags from a record.
   *
   *  Use trace_flag_type enum for the flags (see event-parse.h).
   */
- int tep_data_flags(struct tep_handle *pevent, struct tep_record *rec)
+ int tep_data_flags(struct tep_handle *tep, struct tep_record *rec)
  {
-       return parse_common_flags(pevent, rec->data);
+       return parse_common_flags(tep, rec->data);
  }
  
  /**
   * tep_data_comm_from_pid - return the command line from PID
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @pid: the PID of the task to search for
   *
   * This returns a pointer to the command line that has the given
   * @pid.
   */
- const char *tep_data_comm_from_pid(struct tep_handle *pevent, int pid)
+ const char *tep_data_comm_from_pid(struct tep_handle *tep, int pid)
  {
        const char *comm;
  
-       comm = find_cmdline(pevent, pid);
+       comm = find_cmdline(tep, pid);
        return comm;
  }
  
  static struct tep_cmdline *
- pid_from_cmdlist(struct tep_handle *pevent, const char *comm, struct tep_cmdline *next)
+ pid_from_cmdlist(struct tep_handle *tep, const char *comm, struct tep_cmdline *next)
  {
        struct cmdline_list *cmdlist = (struct cmdline_list *)next;
  
        if (cmdlist)
                cmdlist = cmdlist->next;
        else
-               cmdlist = pevent->cmdlist;
+               cmdlist = tep->cmdlist;
  
        while (cmdlist && strcmp(cmdlist->comm, comm) != 0)
                cmdlist = cmdlist->next;
  
  /**
   * tep_data_pid_from_comm - return the pid from a given comm
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @comm: the cmdline to find the pid from
   * @next: the cmdline structure to find the next comm
   *
   * next pid.
   * Also, it does a linear search, so it may be slow.
   */
- struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *pevent, const char *comm,
+ struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *tep, const char *comm,
                                           struct tep_cmdline *next)
  {
        struct tep_cmdline *cmdline;
         * If the cmdlines have not been converted yet, then use
         * the list.
         */
-       if (!pevent->cmdlines)
-               return pid_from_cmdlist(pevent, comm, next);
+       if (!tep->cmdlines)
+               return pid_from_cmdlist(tep, comm, next);
  
        if (next) {
                /*
                 * The next pointer could have been still from
                 * a previous call before cmdlines were created
                 */
-               if (next < pevent->cmdlines ||
-                   next >= pevent->cmdlines + pevent->cmdline_count)
+               if (next < tep->cmdlines ||
+                   next >= tep->cmdlines + tep->cmdline_count)
                        next = NULL;
                else
                        cmdline  = next++;
        }
  
        if (!next)
-               cmdline = pevent->cmdlines;
+               cmdline = tep->cmdlines;
  
-       while (cmdline < pevent->cmdlines + pevent->cmdline_count) {
+       while (cmdline < tep->cmdlines + tep->cmdline_count) {
                if (strcmp(cmdline->comm, comm) == 0)
                        return cmdline;
                cmdline++;
  
  /**
   * tep_cmdline_pid - return the pid associated to a given cmdline
+  * @tep: a handle to the trace event parser context
   * @cmdline: The cmdline structure to get the pid from
   *
   * Returns the pid for a give cmdline. If @cmdline is NULL, then
   * -1 is returned.
   */
- int tep_cmdline_pid(struct tep_handle *pevent, struct tep_cmdline *cmdline)
+ int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline)
  {
        struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline;
  
         * If cmdlines have not been created yet, or cmdline is
         * not part of the array, then treat it as a cmdlist instead.
         */
-       if (!pevent->cmdlines ||
-           cmdline < pevent->cmdlines ||
-           cmdline >= pevent->cmdlines + pevent->cmdline_count)
+       if (!tep->cmdlines ||
+           cmdline < tep->cmdlines ||
+           cmdline >= tep->cmdlines + tep->cmdline_count)
                return cmdlist->pid;
  
        return cmdline->pid;
@@@ -5423,7 -5424,7 +5424,7 @@@ void tep_event_info(struct trace_seq *s
  {
        int print_pretty = 1;
  
-       if (event->pevent->print_raw || (event->flags & TEP_EVENT_FL_PRINTRAW))
+       if (event->tep->print_raw || (event->flags & TEP_EVENT_FL_PRINTRAW))
                tep_print_fields(s, record->data, record->size, event);
        else {
  
@@@ -5444,7 -5445,8 +5445,8 @@@ static bool is_timestamp_in_us(char *tr
                return true;
  
        if (!strcmp(trace_clock, "local") || !strcmp(trace_clock, "global")
-           || !strcmp(trace_clock, "uptime") || !strcmp(trace_clock, "perf"))
+           || !strcmp(trace_clock, "uptime") || !strcmp(trace_clock, "perf")
+           || !strncmp(trace_clock, "mono", 4))
                return true;
  
        /* trace_clock is setting in tsc or counter mode */
  
  /**
   * tep_find_event_by_record - return the event from a given record
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @record: The record to get the event from
   *
   * Returns the associated event for a given record, or NULL if non is
   * is found.
   */
  struct tep_event *
- tep_find_event_by_record(struct tep_handle *pevent, struct tep_record *record)
+ tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record)
  {
        int type;
  
                return NULL;
        }
  
-       type = trace_parse_common_type(pevent, record->data);
+       type = trace_parse_common_type(tep, record->data);
  
-       return tep_find_event(pevent, type);
+       return tep_find_event(tep, type);
  }
  
  /**
   * tep_print_event_task - Write the event task comm, pid and CPU
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @s: the trace_seq to write to
   * @event: the handle to the record's event
   * @record: The record to get the event from
   *
   * Writes the tasks comm, pid and CPU to @s.
   */
- void tep_print_event_task(struct tep_handle *pevent, struct trace_seq *s,
+ void tep_print_event_task(struct tep_handle *tep, struct trace_seq *s,
                          struct tep_event *event,
                          struct tep_record *record)
  {
        const char *comm;
        int pid;
  
-       pid = parse_common_pid(pevent, data);
-       comm = find_cmdline(pevent, pid);
+       pid = parse_common_pid(tep, data);
+       comm = find_cmdline(tep, pid);
  
-       if (pevent->latency_format) {
-               trace_seq_printf(s, "%8.8s-%-5d %3d",
-                      comm, pid, record->cpu);
-       } else
+       if (tep->latency_format)
+               trace_seq_printf(s, "%8.8s-%-5d %3d", comm, pid, record->cpu);
+       else
                trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
  }
  
  /**
   * tep_print_event_time - Write the event timestamp
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @s: the trace_seq to write to
   * @event: the handle to the record's event
   * @record: The record to get the event from
-  * @use_trace_clock: Set to parse according to the @pevent->trace_clock
+  * @use_trace_clock: Set to parse according to the @tep->trace_clock
   *
   * Writes the timestamp of the record into @s.
   */
- void tep_print_event_time(struct tep_handle *pevent, struct trace_seq *s,
+ void tep_print_event_time(struct tep_handle *tep, struct trace_seq *s,
                          struct tep_event *event,
                          struct tep_record *record,
                          bool use_trace_clock)
        int p;
        bool use_usec_format;
  
-       use_usec_format = is_timestamp_in_us(pevent->trace_clock,
-                                                       use_trace_clock);
+       use_usec_format = is_timestamp_in_us(tep->trace_clock, use_trace_clock);
        if (use_usec_format) {
                secs = record->ts / NSEC_PER_SEC;
                nsecs = record->ts - secs * NSEC_PER_SEC;
        }
  
-       if (pevent->latency_format) {
-               tep_data_lat_fmt(pevent, s, record);
+       if (tep->latency_format) {
+               tep_data_latency_format(tep, s, record);
        }
  
        if (use_usec_format) {
-               if (pevent->flags & TEP_NSEC_OUTPUT) {
+               if (tep->flags & TEP_NSEC_OUTPUT) {
                        usecs = nsecs;
                        p = 9;
                } else {
  
  /**
   * tep_print_event_data - Write the event data section
-  * @pevent: a handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @s: the trace_seq to write to
   * @event: the handle to the record's event
   * @record: The record to get the event from
   *
   * Writes the parsing of the record's data to @s.
   */
- void tep_print_event_data(struct tep_handle *pevent, struct trace_seq *s,
+ void tep_print_event_data(struct tep_handle *tep, struct trace_seq *s,
                          struct tep_event *event,
                          struct tep_record *record)
  {
        tep_event_info(s, event, record);
  }
  
- void tep_print_event(struct tep_handle *pevent, struct trace_seq *s,
+ void tep_print_event(struct tep_handle *tep, struct trace_seq *s,
                     struct tep_record *record, bool use_trace_clock)
  {
        struct tep_event *event;
  
-       event = tep_find_event_by_record(pevent, record);
+       event = tep_find_event_by_record(tep, record);
        if (!event) {
                int i;
-               int type = trace_parse_common_type(pevent, record->data);
+               int type = trace_parse_common_type(tep, record->data);
  
                do_warning("ug! no event found for type %d", type);
                trace_seq_printf(s, "[UNKNOWN TYPE %d]", type);
                return;
        }
  
-       tep_print_event_task(pevent, s, event, record);
-       tep_print_event_time(pevent, s, event, record, use_trace_clock);
-       tep_print_event_data(pevent, s, event, record);
+       tep_print_event_task(tep, s, event, record);
+       tep_print_event_time(tep, s, event, record, use_trace_clock);
+       tep_print_event_data(tep, s, event, record);
  }
  
  static int events_id_cmp(const void *a, const void *b)
@@@ -5649,32 -5649,26 +5649,26 @@@ static int events_system_cmp(const voi
        return events_id_cmp(a, b);
  }
  
- struct tep_event **tep_list_events(struct tep_handle *pevent, enum tep_event_sort_type sort_type)
+ static struct tep_event **list_events_copy(struct tep_handle *tep)
  {
        struct tep_event **events;
-       int (*sort)(const void *a, const void *b);
-       events = pevent->sort_events;
-       if (events && pevent->last_type == sort_type)
-               return events;
  
-       if (!events) {
-               events = malloc(sizeof(*events) * (pevent->nr_events + 1));
-               if (!events)
-                       return NULL;
+       if (!tep)
+               return NULL;
  
-               memcpy(events, pevent->events, sizeof(*events) * pevent->nr_events);
-               events[pevent->nr_events] = NULL;
+       events = malloc(sizeof(*events) * (tep->nr_events + 1));
+       if (!events)
+               return NULL;
  
-               pevent->sort_events = events;
+       memcpy(events, tep->events, sizeof(*events) * tep->nr_events);
+       events[tep->nr_events] = NULL;
+       return events;
+ }
  
-               /* the internal events are sorted by id */
-               if (sort_type == TEP_EVENT_SORT_ID) {
-                       pevent->last_type = sort_type;
-                       return events;
-               }
-       }
+ static void list_events_sort(struct tep_event **events, int nr_events,
+                            enum tep_event_sort_type sort_type)
+ {
+       int (*sort)(const void *a, const void *b);
  
        switch (sort_type) {
        case TEP_EVENT_SORT_ID:
                sort = events_system_cmp;
                break;
        default:
+               sort = NULL;
+       }
+       if (sort)
+               qsort(events, nr_events, sizeof(*events), sort);
+ }
+ /**
+  * tep_list_events - Get events, sorted by given criteria.
+  * @tep: a handle to the tep context
+  * @sort_type: desired sort order of the events in the array
+  *
+  * Returns an array of pointers to all events, sorted by the given
+  * @sort_type criteria. The last element of the array is NULL. The returned
+  * memory must not be freed, it is managed by the library.
+  * The function is not thread safe.
+  */
+ struct tep_event **tep_list_events(struct tep_handle *tep,
+                                  enum tep_event_sort_type sort_type)
+ {
+       struct tep_event **events;
+       if (!tep)
+               return NULL;
+       events = tep->sort_events;
+       if (events && tep->last_type == sort_type)
                return events;
+       if (!events) {
+               events = list_events_copy(tep);
+               if (!events)
+                       return NULL;
+               tep->sort_events = events;
+               /* the internal events are sorted by id */
+               if (sort_type == TEP_EVENT_SORT_ID) {
+                       tep->last_type = sort_type;
+                       return events;
+               }
        }
  
-       qsort(events, pevent->nr_events, sizeof(*events), sort);
-       pevent->last_type = sort_type;
+       list_events_sort(events, tep->nr_events, sort_type);
+       tep->last_type = sort_type;
+       return events;
+ }
+ /**
+  * tep_list_events_copy - Thread safe version of tep_list_events()
+  * @tep: a handle to the tep context
+  * @sort_type: desired sort order of the events in the array
+  *
+  * Returns an array of pointers to all events, sorted by the given
+  * @sort_type criteria. The last element of the array is NULL. The returned
+  * array is newly allocated inside the function and must be freed by the caller
+  */
+ struct tep_event **tep_list_events_copy(struct tep_handle *tep,
+                                       enum tep_event_sort_type sort_type)
+ {
+       struct tep_event **events;
+       if (!tep)
+               return NULL;
+       events = list_events_copy(tep);
+       if (!events)
+               return NULL;
+       /* the internal events are sorted by id */
+       if (sort_type == TEP_EVENT_SORT_ID)
+               return events;
+       list_events_sort(events, tep->nr_events, sort_type);
  
        return events;
  }
@@@ -5950,7 -6015,7 +6015,7 @@@ static void parse_header_field(const ch
  
  /**
   * tep_parse_header_page - parse the data stored in the header page
-  * @pevent: the handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @buf: the buffer storing the header page format string
   * @size: the size of @buf
   * @long_size: the long size to use if there is no header
   *
   * /sys/kernel/debug/tracing/events/header_page
   */
- int tep_parse_header_page(struct tep_handle *pevent, char *buf, unsigned long size,
+ int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size,
                          int long_size)
  {
        int ignore;
                 * Old kernels did not have header page info.
                 * Sorry but we just use what we find here in user space.
                 */
-               pevent->header_page_ts_size = sizeof(long long);
-               pevent->header_page_size_size = long_size;
-               pevent->header_page_data_offset = sizeof(long long) + long_size;
-               pevent->old_format = 1;
+               tep->header_page_ts_size = sizeof(long long);
+               tep->header_page_size_size = long_size;
+               tep->header_page_data_offset = sizeof(long long) + long_size;
+               tep->old_format = 1;
                return -1;
        }
        init_input_buf(buf, size);
  
-       parse_header_field("timestamp", &pevent->header_page_ts_offset,
-                          &pevent->header_page_ts_size, 1);
-       parse_header_field("commit", &pevent->header_page_size_offset,
-                          &pevent->header_page_size_size, 1);
-       parse_header_field("overwrite", &pevent->header_page_overwrite,
+       parse_header_field("timestamp", &tep->header_page_ts_offset,
+                          &tep->header_page_ts_size, 1);
+       parse_header_field("commit", &tep->header_page_size_offset,
+                          &tep->header_page_size_size, 1);
+       parse_header_field("overwrite", &tep->header_page_overwrite,
                           &ignore, 0);
-       parse_header_field("data", &pevent->header_page_data_offset,
-                          &pevent->header_page_data_size, 1);
+       parse_header_field("data", &tep->header_page_data_offset,
+                          &tep->header_page_data_size, 1);
  
        return 0;
  }
@@@ -6013,11 -6078,11 +6078,11 @@@ static void free_handler(struct event_h
        free(handle);
  }
  
- static int find_event_handle(struct tep_handle *pevent, struct tep_event *event)
+ static int find_event_handle(struct tep_handle *tep, struct tep_event *event)
  {
        struct event_handler *handle, **next;
  
-       for (next = &pevent->handlers; *next;
+       for (next = &tep->handlers; *next;
             next = &(*next)->next) {
                handle = *next;
                if (event_matches(event, handle->id,
   * /sys/kernel/debug/tracing/events/.../.../format
   */
  enum tep_errno __tep_parse_format(struct tep_event **eventp,
-                                 struct tep_handle *pevent, const char *buf,
+                                 struct tep_handle *tep, const char *buf,
                                  unsigned long size, const char *sys)
  {
        struct tep_event *event;
                goto event_alloc_failed;
        }
  
-       /* Add pevent to event so that it can be referenced */
-       event->pevent = pevent;
+       /* Add tep to event so that it can be referenced */
+       event->tep = tep;
  
        ret = event_read_format(event);
        if (ret < 0) {
         * If the event has an override, don't print warnings if the event
         * print format fails to parse.
         */
-       if (pevent && find_event_handle(pevent, event))
+       if (tep && find_event_handle(tep, event))
                show_warning = 0;
  
        ret = event_read_print(event);
  }
  
  static enum tep_errno
- __parse_event(struct tep_handle *pevent,
+ __parse_event(struct tep_handle *tep,
              struct tep_event **eventp,
              const char *buf, unsigned long size,
              const char *sys)
  {
-       int ret = __tep_parse_format(eventp, pevent, buf, size, sys);
+       int ret = __tep_parse_format(eventp, tep, buf, size, sys);
        struct tep_event *event = *eventp;
  
        if (event == NULL)
                return ret;
  
-       if (pevent && add_event(pevent, event)) {
+       if (tep && add_event(tep, event)) {
                ret = TEP_ERRNO__MEM_ALLOC_FAILED;
                goto event_add_failed;
        }
@@@ -6191,7 -6256,7 +6256,7 @@@ event_add_failed
  
  /**
   * tep_parse_format - parse the event format
-  * @pevent: the handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @eventp: returned format
   * @buf: the buffer storing the event format string
   * @size: the size of @buf
   *
   * /sys/kernel/debug/tracing/events/.../.../format
   */
- enum tep_errno tep_parse_format(struct tep_handle *pevent,
+ enum tep_errno tep_parse_format(struct tep_handle *tep,
                                struct tep_event **eventp,
                                const char *buf,
                                unsigned long size, const char *sys)
  {
-       return __parse_event(pevent, eventp, buf, size, sys);
+       return __parse_event(tep, eventp, buf, size, sys);
  }
  
  /**
   * tep_parse_event - parse the event format
-  * @pevent: the handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @buf: the buffer storing the event format string
   * @size: the size of @buf
   * @sys: the system the event belongs to
   *
   * /sys/kernel/debug/tracing/events/.../.../format
   */
- enum tep_errno tep_parse_event(struct tep_handle *pevent, const char *buf,
+ enum tep_errno tep_parse_event(struct tep_handle *tep, const char *buf,
                               unsigned long size, const char *sys)
  {
        struct tep_event *event = NULL;
-       return __parse_event(pevent, &event, buf, size, sys);
+       return __parse_event(tep, &event, buf, size, sys);
  }
  
  int get_field_val(struct trace_seq *s, struct tep_format_field *field,
@@@ -6292,8 -6357,8 +6357,8 @@@ void *tep_get_field_raw(struct trace_se
  
        offset = field->offset;
        if (field->flags & TEP_FIELD_IS_DYNAMIC) {
-               offset = tep_read_number(event->pevent,
-                                           data + offset, field->size);
+               offset = tep_read_number(event->tep,
+                                        data + offset, field->size);
                *len = offset >> 16;
                offset &= 0xffff;
        } else
@@@ -6386,7 -6451,8 +6451,8 @@@ int tep_get_any_field_val(struct trace_
   * @record: The record with the field name.
   * @err: print default error if failed.
   *
-  * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
+  * Returns positive value on success, negative in case of an error,
+  * or 0 if buffer is full.
   */
  int tep_print_num_field(struct trace_seq *s, const char *fmt,
                        struct tep_event *event, const char *name,
   * @record: The record with the field name.
   * @err: print default error if failed.
   *
-  * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
+  * Returns positive value on success, negative in case of an error,
+  * or 0 if buffer is full.
   */
  int tep_print_func_field(struct trace_seq *s, const char *fmt,
                         struct tep_event *event, const char *name,
                         struct tep_record *record, int err)
  {
        struct tep_format_field *field = tep_find_field(event, name);
-       struct tep_handle *pevent = event->pevent;
+       struct tep_handle *tep = event->tep;
        unsigned long long val;
        struct func_map *func;
        char tmp[128];
        if (tep_read_number_field(field, record->data, &val))
                goto failed;
  
-       func = find_func(pevent, val);
+       func = find_func(tep, val);
  
        if (func)
                snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val);
@@@ -6468,7 -6535,7 +6535,7 @@@ static void free_func_handle(struct tep
  
  /**
   * tep_register_print_function - register a helper function
-  * @pevent: the handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @func: the function to process the helper function
   * @ret_type: the return type of the helper function
   * @name: the name of the helper function
   * The @parameters is a variable list of tep_func_arg_type enums that
   * must end with TEP_FUNC_ARG_VOID.
   */
- int tep_register_print_function(struct tep_handle *pevent,
+ int tep_register_print_function(struct tep_handle *tep,
                                tep_func_handler func,
                                enum tep_func_arg_type ret_type,
                                char *name, ...)
        va_list ap;
        int ret;
  
-       func_handle = find_func_handler(pevent, name);
+       func_handle = find_func_handler(tep, name);
        if (func_handle) {
                /*
                 * This is most like caused by the users own
                 * system defaults.
                 */
                pr_stat("override of function helper '%s'", name);
-               remove_func_handler(pevent, name);
+               remove_func_handler(tep, name);
        }
  
        func_handle = calloc(1, sizeof(*func_handle));
        }
        va_end(ap);
  
-       func_handle->next = pevent->func_handlers;
-       pevent->func_handlers = func_handle;
+       func_handle->next = tep->func_handlers;
+       tep->func_handlers = func_handle;
  
        return 0;
   out_free:
  
  /**
   * tep_unregister_print_function - unregister a helper function
-  * @pevent: the handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @func: the function to process the helper function
   * @name: the name of the helper function
   *
   *
   * Returns 0 if the handler was removed successully, -1 otherwise.
   */
- int tep_unregister_print_function(struct tep_handle *pevent,
+ int tep_unregister_print_function(struct tep_handle *tep,
                                  tep_func_handler func, char *name)
  {
        struct tep_function_handler *func_handle;
  
-       func_handle = find_func_handler(pevent, name);
+       func_handle = find_func_handler(tep, name);
        if (func_handle && func_handle->func == func) {
-               remove_func_handler(pevent, name);
+               remove_func_handler(tep, name);
                return 0;
        }
        return -1;
  }
  
- static struct tep_event *search_event(struct tep_handle *pevent, int id,
+ static struct tep_event *search_event(struct tep_handle *tep, int id,
                                      const char *sys_name,
                                      const char *event_name)
  {
  
        if (id >= 0) {
                /* search by id */
-               event = tep_find_event(pevent, id);
+               event = tep_find_event(tep, id);
                if (!event)
                        return NULL;
                if (event_name && (strcmp(event_name, event->name) != 0))
                if (sys_name && (strcmp(sys_name, event->system) != 0))
                        return NULL;
        } else {
-               event = tep_find_event_by_name(pevent, sys_name, event_name);
+               event = tep_find_event_by_name(tep, sys_name, event_name);
                if (!event)
                        return NULL;
        }
  
  /**
   * tep_register_event_handler - register a way to parse an event
-  * @pevent: the handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @id: the id of the event to register
   * @sys_name: the system name the event belongs to
   * @event_name: the name of the event
   *  negative TEP_ERRNO_... in case of an error
   *
   */
- int tep_register_event_handler(struct tep_handle *pevent, int id,
+ int tep_register_event_handler(struct tep_handle *tep, int id,
                               const char *sys_name, const char *event_name,
                               tep_event_handler_func func, void *context)
  {
        struct tep_event *event;
        struct event_handler *handle;
  
-       event = search_event(pevent, id, sys_name, event_name);
+       event = search_event(tep, id, sys_name, event_name);
        if (event == NULL)
                goto not_found;
  
        }
  
        handle->func = func;
-       handle->next = pevent->handlers;
-       pevent->handlers = handle;
+       handle->next = tep->handlers;
+       tep->handlers = handle;
        handle->context = context;
  
        return TEP_REGISTER_SUCCESS;
@@@ -6697,7 -6764,7 +6764,7 @@@ static int handle_matches(struct event_
  
  /**
   * tep_unregister_event_handler - unregister an existing event handler
-  * @pevent: the handle to the pevent
+  * @tep: a handle to the trace event parser context
   * @id: the id of the event to unregister
   * @sys_name: the system name the handler belongs to
   * @event_name: the name of the event handler
   *
   * Returns 0 if handler was removed successfully, -1 if event was not found.
   */
- int tep_unregister_event_handler(struct tep_handle *pevent, int id,
+ int tep_unregister_event_handler(struct tep_handle *tep, int id,
                                 const char *sys_name, const char *event_name,
                                 tep_event_handler_func func, void *context)
  {
        struct event_handler *handle;
        struct event_handler **next;
  
-       event = search_event(pevent, id, sys_name, event_name);
+       event = search_event(tep, id, sys_name, event_name);
        if (event == NULL)
                goto not_found;
  
        }
  
  not_found:
-       for (next = &pevent->handlers; *next; next = &(*next)->next) {
+       for (next = &tep->handlers; *next; next = &(*next)->next) {
                handle = *next;
                if (handle_matches(handle, id, sys_name, event_name,
                                   func, context))
  }
  
  /**
-  * tep_alloc - create a pevent handle
+  * tep_alloc - create a tep handle
   */
  struct tep_handle *tep_alloc(void)
  {
-       struct tep_handle *pevent = calloc(1, sizeof(*pevent));
+       struct tep_handle *tep = calloc(1, sizeof(*tep));
  
-       if (pevent) {
-               pevent->ref_count = 1;
-               pevent->host_bigendian = tep_host_bigendian();
+       if (tep) {
+               tep->ref_count = 1;
+               tep->host_bigendian = tep_is_bigendian();
        }
  
-       return pevent;
+       return tep;
  }
  
- void tep_ref(struct tep_handle *pevent)
+ void tep_ref(struct tep_handle *tep)
  {
-       pevent->ref_count++;
+       tep->ref_count++;
  }
  
  int tep_get_ref(struct tep_handle *tep)
@@@ -6816,10 -6883,10 +6883,10 @@@ void tep_free_event(struct tep_event *e
  }
  
  /**
-  * tep_free - free a pevent handle
-  * @pevent: the pevent handle to free
+  * tep_free - free a tep handle
+  * @tep: the tep handle to free
   */
- void tep_free(struct tep_handle *pevent)
+ void tep_free(struct tep_handle *tep)
  {
        struct cmdline_list *cmdlist, *cmdnext;
        struct func_list *funclist, *funcnext;
        struct event_handler *handle;
        int i;
  
-       if (!pevent)
+       if (!tep)
                return;
  
-       cmdlist = pevent->cmdlist;
-       funclist = pevent->funclist;
-       printklist = pevent->printklist;
+       cmdlist = tep->cmdlist;
+       funclist = tep->funclist;
+       printklist = tep->printklist;
  
-       pevent->ref_count--;
-       if (pevent->ref_count)
+       tep->ref_count--;
+       if (tep->ref_count)
                return;
  
-       if (pevent->cmdlines) {
-               for (i = 0; i < pevent->cmdline_count; i++)
-                       free(pevent->cmdlines[i].comm);
-               free(pevent->cmdlines);
+       if (tep->cmdlines) {
+               for (i = 0; i < tep->cmdline_count; i++)
+                       free(tep->cmdlines[i].comm);
+               free(tep->cmdlines);
        }
  
        while (cmdlist) {
                cmdlist = cmdnext;
        }
  
-       if (pevent->func_map) {
-               for (i = 0; i < (int)pevent->func_count; i++) {
-                       free(pevent->func_map[i].func);
-                       free(pevent->func_map[i].mod);
+       if (tep->func_map) {
+               for (i = 0; i < (int)tep->func_count; i++) {
+                       free(tep->func_map[i].func);
+                       free(tep->func_map[i].mod);
                }
-               free(pevent->func_map);
+               free(tep->func_map);
        }
  
        while (funclist) {
                funclist = funcnext;
        }
  
-       while (pevent->func_handlers) {
-               func_handler = pevent->func_handlers;
-               pevent->func_handlers = func_handler->next;
+       while (tep->func_handlers) {
+               func_handler = tep->func_handlers;
+               tep->func_handlers = func_handler->next;
                free_func_handle(func_handler);
        }
  
-       if (pevent->printk_map) {
-               for (i = 0; i < (int)pevent->printk_count; i++)
-                       free(pevent->printk_map[i].printk);
-               free(pevent->printk_map);
+       if (tep->printk_map) {
+               for (i = 0; i < (int)tep->printk_count; i++)
+                       free(tep->printk_map[i].printk);
+               free(tep->printk_map);
        }
  
        while (printklist) {
                printklist = printknext;
        }
  
-       for (i = 0; i < pevent->nr_events; i++)
-               tep_free_event(pevent->events[i]);
+       for (i = 0; i < tep->nr_events; i++)
+               tep_free_event(tep->events[i]);
  
-       while (pevent->handlers) {
-               handle = pevent->handlers;
-               pevent->handlers = handle->next;
+       while (tep->handlers) {
+               handle = tep->handlers;
+               tep->handlers = handle->next;
                free_handler(handle);
        }
  
-       free(pevent->trace_clock);
-       free(pevent->events);
-       free(pevent->sort_events);
-       free(pevent->func_resolver);
+       free(tep->trace_clock);
+       free(tep->events);
+       free(tep->sort_events);
+       free(tep->func_resolver);
  
-       free(pevent);
+       free(tep);
  }
  
- void tep_unref(struct tep_handle *pevent)
+ void tep_unref(struct tep_handle *tep)
  {
-       tep_free(pevent);
+       tep_free(tep);
  }
index 6d65874e16c3d6e9af02ac498cd891ffb90ef972,beb8b48b44e61d0e53e3ca8d1fd4e0e86e2276de..0c52a01dc759af86ab21f604c96a240bff3f6f5f
@@@ -152,6 -152,13 +152,13 @@@ endi
  FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS)
  FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf
  
+ ifdef LIBZSTD_DIR
+   LIBZSTD_CFLAGS  := -I$(LIBZSTD_DIR)/lib
+   LIBZSTD_LDFLAGS := -L$(LIBZSTD_DIR)/lib
+ endif
+ FEATURE_CHECK_CFLAGS-libzstd := $(LIBZSTD_CFLAGS)
+ FEATURE_CHECK_LDFLAGS-libzstd := $(LIBZSTD_LDFLAGS)
  FEATURE_CHECK_CFLAGS-bpf = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi -I$(srctree)/tools/include/uapi
  # include ARCH specific config
  -include $(src-perf)/arch/$(SRCARCH)/Makefile
@@@ -227,7 -234,7 +234,7 @@@ FEATURE_CHECK_LDFLAGS-libpython-versio
  
  FEATURE_CHECK_LDFLAGS-libaio = -lrt
  
 -FEATURE_CHECK_LDFLAGS-disassembler-four-args = -lbfd -lopcodes
 +FEATURE_CHECK_LDFLAGS-disassembler-four-args = -lbfd -lopcodes -ldl
  
  CFLAGS += -fno-omit-frame-pointer
  CFLAGS += -ggdb3
@@@ -787,6 -794,19 +794,19 @@@ ifndef NO_LZM
    endif
  endif
  
+ ifndef NO_LIBZSTD
+   ifeq ($(feature-libzstd), 1)
+     CFLAGS += -DHAVE_ZSTD_SUPPORT
+     CFLAGS += $(LIBZSTD_CFLAGS)
+     LDFLAGS += $(LIBZSTD_LDFLAGS)
+     EXTLIBS += -lzstd
+     $(call detected,CONFIG_ZSTD)
+   else
+     msg := $(warning No libzstd found, disables trace compression, please install libzstd-dev[el] and/or set LIBZSTD_DIR);
+     NO_LIBZSTD := 1
+   endif
+ endif
  ifndef NO_BACKTRACE
    ifeq ($(feature-backtrace), 1)
      CFLAGS += -DHAVE_BACKTRACE_SUPPORT
index c3625ec374e0658e66a3ed7beadbcbe19b5929c0,7f9c4b7f5d69a0bd35ff32ae78ac10c191ad2c09..a3c060878faab185ee2174f2e8a862ac039b6fe6
@@@ -244,11 -244,25 +244,25 @@@ perf_evsel__write_stat_event(struct per
                                           process_synthesized_event, NULL);
  }
  
+ static int read_single_counter(struct perf_evsel *counter, int cpu,
+                              int thread, struct timespec *rs)
+ {
+       if (counter->tool_event == PERF_TOOL_DURATION_TIME) {
+               u64 val = rs->tv_nsec + rs->tv_sec*1000000000ULL;
+               struct perf_counts_values *count =
+                       perf_counts(counter->counts, cpu, thread);
+               count->ena = count->run = val;
+               count->val = val;
+               return 0;
+       }
+       return perf_evsel__read_counter(counter, cpu, thread);
+ }
  /*
   * Read out the results of a single counter:
   * do not aggregate counts across CPUs in system-wide mode
   */
- static int read_counter(struct perf_evsel *counter)
+ static int read_counter(struct perf_evsel *counter, struct timespec *rs)
  {
        int nthreads = thread_map__nr(evsel_list->threads);
        int ncpus, cpu, thread;
                         * (via perf_evsel__read_counter) and sets threir count->loaded.
                         */
                        if (!count->loaded &&
-                           perf_evsel__read_counter(counter, cpu, thread)) {
+                           read_single_counter(counter, cpu, thread, rs)) {
                                counter->counts->scaled = -1;
                                perf_counts(counter->counts, cpu, thread)->ena = 0;
                                perf_counts(counter->counts, cpu, thread)->run = 0;
        return 0;
  }
  
- static void read_counters(void)
+ static void read_counters(struct timespec *rs)
  {
        struct perf_evsel *counter;
        int ret;
  
        evlist__for_each_entry(evsel_list, counter) {
-               ret = read_counter(counter);
+               ret = read_counter(counter, rs);
                if (ret)
                        pr_debug("failed to read counter %s\n", counter->name);
  
@@@ -323,11 -337,11 +337,11 @@@ static void process_interval(void
  {
        struct timespec ts, rs;
  
-       read_counters();
        clock_gettime(CLOCK_MONOTONIC, &ts);
        diff_timespec(&rs, &ts, &ref_time);
  
+       read_counters(&rs);
        if (STAT_RECORD) {
                if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL))
                        pr_err("failed to write stat round event\n");
@@@ -593,7 -607,7 +607,7 @@@ try_again
         * avoid arbitrary skew, we must read all counters before closing any
         * group leaders.
         */
-       read_counters();
+       read_counters(&(struct timespec) { .tv_nsec = t1-t0 });
        perf_evlist__close(evsel_list);
  
        return WEXITSTATUS(status);
@@@ -1308,7 -1322,6 +1322,7 @@@ static void init_features(struct perf_s
        for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
                perf_header__set_feat(&session->header, feat);
  
 +      perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
        perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
        perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
        perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
diff --combined tools/perf/util/evlist.c
index 51ead577533fa6f6ee8c8cc49b8fc084490f0ef1,f2bbae38278d09426c99b33854a56548a7422dd1..4b6783ff58131280d87fe2d9809baa566d9467ef
@@@ -1009,7 -1009,7 +1009,7 @@@ int perf_evlist__parse_mmap_pages(cons
   */
  int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
                         unsigned int auxtrace_pages,
-                        bool auxtrace_overwrite, int nr_cblocks, int affinity)
+                        bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush)
  {
        struct perf_evsel *evsel;
        const struct cpu_map *cpus = evlist->cpus;
         * Its value is decided by evsel's write_backward.
         * So &mp should not be passed through const pointer.
         */
-       struct mmap_params mp = { .nr_cblocks = nr_cblocks, .affinity = affinity };
+       struct mmap_params mp = { .nr_cblocks = nr_cblocks, .affinity = affinity, .flush = flush };
  
        if (!evlist->mmap)
                evlist->mmap = perf_evlist__alloc_mmap(evlist, false);
  
  int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages)
  {
-       return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS);
+       return perf_evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1);
  }
  
  int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
@@@ -1868,12 -1868,12 +1868,12 @@@ static void *perf_evlist__poll_thread(v
  {
        struct perf_evlist *evlist = arg;
        bool draining = false;
 -      int i;
 +      int i, done = 0;
 +
 +      while (!done) {
 +              bool got_data = false;
  
 -      while (draining || !(evlist->thread.done)) {
 -              if (draining)
 -                      draining = false;
 -              else if (evlist->thread.done)
 +              if (evlist->thread.done)
                        draining = true;
  
                if (!draining)
                                        pr_warning("cannot locate proper evsel for the side band event\n");
  
                                perf_mmap__consume(map);
 +                              got_data = true;
                        }
                        perf_mmap__read_done(map);
                }
 +
 +              if (draining && !got_data)
 +                      break;
        }
        return NULL;
  }
diff --combined tools/perf/util/evsel.c
index 966360844fffbd10b4d97c318b22e0fc8446c1ee,84cfb9fe2fc6ac91886fb94baefaad9b7200737b..a10cf4cde92059b3b667216bc625a5b472f7237a
@@@ -580,6 -580,12 +580,12 @@@ static int perf_evsel__raw_name(struct 
        return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret);
  }
  
+ static int perf_evsel__tool_name(char *bf, size_t size)
+ {
+       int ret = scnprintf(bf, size, "duration_time");
+       return ret;
+ }
  const char *perf_evsel__name(struct perf_evsel *evsel)
  {
        char bf[128];
                break;
  
        case PERF_TYPE_SOFTWARE:
-               perf_evsel__sw_name(evsel, bf, sizeof(bf));
+               if (evsel->tool_event)
+                       perf_evsel__tool_name(bf, sizeof(bf));
+               else
+                       perf_evsel__sw_name(evsel, bf, sizeof(bf));
                break;
  
        case PERF_TYPE_TRACEPOINT:
@@@ -2368,7 -2377,7 +2377,7 @@@ int perf_evsel__parse_sample(struct per
                if (data->user_regs.abi) {
                        u64 mask = evsel->attr.sample_regs_user;
  
 -                      sz = hweight_long(mask) * sizeof(u64);
 +                      sz = hweight64(mask) * sizeof(u64);
                        OVERFLOW_CHECK(array, sz, max_size);
                        data->user_regs.mask = mask;
                        data->user_regs.regs = (u64 *)array;
                if (data->intr_regs.abi != PERF_SAMPLE_REGS_ABI_NONE) {
                        u64 mask = evsel->attr.sample_regs_intr;
  
 -                      sz = hweight_long(mask) * sizeof(u64);
 +                      sz = hweight64(mask) * sizeof(u64);
                        OVERFLOW_CHECK(array, sz, max_size);
                        data->intr_regs.mask = mask;
                        data->intr_regs.regs = (u64 *)array;
@@@ -2552,7 -2561,7 +2561,7 @@@ size_t perf_event__sample_event_size(co
        if (type & PERF_SAMPLE_REGS_USER) {
                if (sample->user_regs.abi) {
                        result += sizeof(u64);
 -                      sz = hweight_long(sample->user_regs.mask) * sizeof(u64);
 +                      sz = hweight64(sample->user_regs.mask) * sizeof(u64);
                        result += sz;
                } else {
                        result += sizeof(u64);
        if (type & PERF_SAMPLE_REGS_INTR) {
                if (sample->intr_regs.abi) {
                        result += sizeof(u64);
 -                      sz = hweight_long(sample->intr_regs.mask) * sizeof(u64);
 +                      sz = hweight64(sample->intr_regs.mask) * sizeof(u64);
                        result += sz;
                } else {
                        result += sizeof(u64);
@@@ -2710,7 -2719,7 +2719,7 @@@ int perf_event__synthesize_sample(unio
        if (type & PERF_SAMPLE_REGS_USER) {
                if (sample->user_regs.abi) {
                        *array++ = sample->user_regs.abi;
 -                      sz = hweight_long(sample->user_regs.mask) * sizeof(u64);
 +                      sz = hweight64(sample->user_regs.mask) * sizeof(u64);
                        memcpy(array, sample->user_regs.regs, sz);
                        array = (void *)array + sz;
                } else {
        if (type & PERF_SAMPLE_REGS_INTR) {
                if (sample->intr_regs.abi) {
                        *array++ = sample->intr_regs.abi;
 -                      sz = hweight_long(sample->intr_regs.mask) * sizeof(u64);
 +                      sz = hweight64(sample->intr_regs.mask) * sizeof(u64);
                        memcpy(array, sample->intr_regs.regs, sz);
                        array = (void *)array + sz;
                } else {