diff options
64 files changed, 882 insertions, 910 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events index 7b40a3cbc26a..20979f8b3edb 100644 --- a/Documentation/ABI/testing/sysfs-bus-event_source-devices-events +++ b/Documentation/ABI/testing/sysfs-bus-event_source-devices-events | |||
| @@ -27,575 +27,62 @@ Description: Generic performance monitoring events | |||
| 27 | "basename". | 27 | "basename". |
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | What: /sys/devices/cpu/events/PM_1PLUS_PPC_CMPL | 30 | What: /sys/bus/event_source/devices/<pmu>/events/<event> |
| 31 | /sys/devices/cpu/events/PM_BRU_FIN | 31 | Date: 2014/02/24 |
| 32 | /sys/devices/cpu/events/PM_BR_MPRED | 32 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> |
| 33 | /sys/devices/cpu/events/PM_CMPLU_STALL | 33 | Description: Per-pmu performance monitoring events specific to the running system |
| 34 | /sys/devices/cpu/events/PM_CMPLU_STALL_BRU | ||
| 35 | /sys/devices/cpu/events/PM_CMPLU_STALL_DCACHE_MISS | ||
| 36 | /sys/devices/cpu/events/PM_CMPLU_STALL_DFU | ||
| 37 | /sys/devices/cpu/events/PM_CMPLU_STALL_DIV | ||
| 38 | /sys/devices/cpu/events/PM_CMPLU_STALL_ERAT_MISS | ||
| 39 | /sys/devices/cpu/events/PM_CMPLU_STALL_FXU | ||
| 40 | /sys/devices/cpu/events/PM_CMPLU_STALL_IFU | ||
| 41 | /sys/devices/cpu/events/PM_CMPLU_STALL_LSU | ||
| 42 | /sys/devices/cpu/events/PM_CMPLU_STALL_REJECT | ||
| 43 | /sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR | ||
| 44 | /sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR_LONG | ||
| 45 | /sys/devices/cpu/events/PM_CMPLU_STALL_STORE | ||
| 46 | /sys/devices/cpu/events/PM_CMPLU_STALL_THRD | ||
| 47 | /sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR | ||
| 48 | /sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR_LONG | ||
| 49 | /sys/devices/cpu/events/PM_CYC | ||
| 50 | /sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED | ||
| 51 | /sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED_IC_MISS | ||
| 52 | /sys/devices/cpu/events/PM_GCT_NOSLOT_CYC | ||
| 53 | /sys/devices/cpu/events/PM_GCT_NOSLOT_IC_MISS | ||
| 54 | /sys/devices/cpu/events/PM_GRP_CMPL | ||
| 55 | /sys/devices/cpu/events/PM_INST_CMPL | ||
| 56 | /sys/devices/cpu/events/PM_LD_MISS_L1 | ||
| 57 | /sys/devices/cpu/events/PM_LD_REF_L1 | ||
| 58 | /sys/devices/cpu/events/PM_RUN_CYC | ||
| 59 | /sys/devices/cpu/events/PM_RUN_INST_CMPL | ||
| 60 | /sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_ALL | ||
| 61 | /sys/devices/cpu/events/PM_GCT_UTIL_7_TO_10_SLOTS | ||
| 62 | /sys/devices/cpu/events/PM_PMC2_SAVED | ||
| 63 | /sys/devices/cpu/events/PM_VSU0_16FLOP | ||
| 64 | /sys/devices/cpu/events/PM_MRK_LSU_DERAT_MISS | ||
| 65 | /sys/devices/cpu/events/PM_MRK_ST_CMPL | ||
| 66 | /sys/devices/cpu/events/PM_NEST_PAIR3_ADD | ||
| 67 | /sys/devices/cpu/events/PM_L2_ST_DISP | ||
| 68 | /sys/devices/cpu/events/PM_L2_CASTOUT_MOD | ||
| 69 | /sys/devices/cpu/events/PM_ISEG | ||
| 70 | /sys/devices/cpu/events/PM_MRK_INST_TIMEO | ||
| 71 | /sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_ADDR | ||
| 72 | /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM | ||
| 73 | /sys/devices/cpu/events/PM_IERAT_WR_64K | ||
| 74 | /sys/devices/cpu/events/PM_MRK_DTLB_MISS_16M | ||
| 75 | /sys/devices/cpu/events/PM_IERAT_MISS | ||
| 76 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_LMEM | ||
| 77 | /sys/devices/cpu/events/PM_FLOP | ||
| 78 | /sys/devices/cpu/events/PM_THRD_PRIO_4_5_CYC | ||
| 79 | /sys/devices/cpu/events/PM_BR_PRED_TA | ||
| 80 | /sys/devices/cpu/events/PM_EXT_INT | ||
| 81 | /sys/devices/cpu/events/PM_VSU_FSQRT_FDIV | ||
| 82 | /sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC | ||
| 83 | /sys/devices/cpu/events/PM_LSU1_LDF | ||
| 84 | /sys/devices/cpu/events/PM_IC_WRITE_ALL | ||
| 85 | /sys/devices/cpu/events/PM_LSU0_SRQ_STFWD | ||
| 86 | /sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_MOD | ||
| 87 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR | ||
| 88 | /sys/devices/cpu/events/PM_DATA_FROM_L21_MOD | ||
| 89 | /sys/devices/cpu/events/PM_VSU1_SCAL_DOUBLE_ISSUED | ||
| 90 | /sys/devices/cpu/events/PM_VSU0_8FLOP | ||
| 91 | /sys/devices/cpu/events/PM_POWER_EVENT1 | ||
| 92 | /sys/devices/cpu/events/PM_DISP_CLB_HELD_BAL | ||
| 93 | /sys/devices/cpu/events/PM_VSU1_2FLOP | ||
| 94 | /sys/devices/cpu/events/PM_LWSYNC_HELD | ||
| 95 | /sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_SHR | ||
| 96 | /sys/devices/cpu/events/PM_INST_FROM_L21_MOD | ||
| 97 | /sys/devices/cpu/events/PM_IERAT_XLATE_WR_16MPLUS | ||
| 98 | /sys/devices/cpu/events/PM_IC_REQ_ALL | ||
| 99 | /sys/devices/cpu/events/PM_DSLB_MISS | ||
| 100 | /sys/devices/cpu/events/PM_L3_MISS | ||
| 101 | /sys/devices/cpu/events/PM_LSU0_L1_PREF | ||
| 102 | /sys/devices/cpu/events/PM_VSU_SCALAR_SINGLE_ISSUED | ||
| 103 | /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM_STRIDE | ||
| 104 | /sys/devices/cpu/events/PM_L2_INST | ||
| 105 | /sys/devices/cpu/events/PM_VSU0_FRSP | ||
| 106 | /sys/devices/cpu/events/PM_FLUSH_DISP | ||
| 107 | /sys/devices/cpu/events/PM_PTEG_FROM_L2MISS | ||
| 108 | /sys/devices/cpu/events/PM_VSU1_DQ_ISSUED | ||
| 109 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM | ||
| 110 | /sys/devices/cpu/events/PM_LSU_FLUSH_ULD | ||
| 111 | /sys/devices/cpu/events/PM_PTEG_FROM_LMEM | ||
| 112 | /sys/devices/cpu/events/PM_MRK_DERAT_MISS_16M | ||
| 113 | /sys/devices/cpu/events/PM_THRD_ALL_RUN_CYC | ||
| 114 | /sys/devices/cpu/events/PM_MEM0_PREFETCH_DISP | ||
| 115 | /sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC_COUNT | ||
| 116 | /sys/devices/cpu/events/PM_DATA_FROM_DL2L3_MOD | ||
| 117 | /sys/devices/cpu/events/PM_VSU_FRSP | ||
| 118 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD | ||
| 119 | /sys/devices/cpu/events/PM_PMC1_OVERFLOW | ||
| 120 | /sys/devices/cpu/events/PM_VSU0_SINGLE | ||
| 121 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3MISS | ||
| 122 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_SHR | ||
| 123 | /sys/devices/cpu/events/PM_VSU0_VECTOR_SP_ISSUED | ||
| 124 | /sys/devices/cpu/events/PM_VSU1_FEST | ||
| 125 | /sys/devices/cpu/events/PM_MRK_INST_DISP | ||
| 126 | /sys/devices/cpu/events/PM_VSU0_COMPLEX_ISSUED | ||
| 127 | /sys/devices/cpu/events/PM_LSU1_FLUSH_UST | ||
| 128 | /sys/devices/cpu/events/PM_FXU_IDLE | ||
| 129 | /sys/devices/cpu/events/PM_LSU0_FLUSH_ULD | ||
| 130 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD | ||
| 131 | /sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_ALL_CYC | ||
| 132 | /sys/devices/cpu/events/PM_LSU1_REJECT_LMQ_FULL | ||
| 133 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_MOD | ||
| 134 | /sys/devices/cpu/events/PM_INST_FROM_RL2L3_MOD | ||
| 135 | /sys/devices/cpu/events/PM_SHL_CREATED | ||
| 136 | /sys/devices/cpu/events/PM_L2_ST_HIT | ||
| 137 | /sys/devices/cpu/events/PM_DATA_FROM_DMEM | ||
| 138 | /sys/devices/cpu/events/PM_L3_LD_MISS | ||
| 139 | /sys/devices/cpu/events/PM_FXU1_BUSY_FXU0_IDLE | ||
| 140 | /sys/devices/cpu/events/PM_DISP_CLB_HELD_RES | ||
| 141 | /sys/devices/cpu/events/PM_L2_SN_SX_I_DONE | ||
| 142 | /sys/devices/cpu/events/PM_STCX_CMPL | ||
| 143 | /sys/devices/cpu/events/PM_VSU0_2FLOP | ||
| 144 | /sys/devices/cpu/events/PM_L3_PREF_MISS | ||
| 145 | /sys/devices/cpu/events/PM_LSU_SRQ_SYNC_CYC | ||
| 146 | /sys/devices/cpu/events/PM_LSU_REJECT_ERAT_MISS | ||
| 147 | /sys/devices/cpu/events/PM_L1_ICACHE_MISS | ||
| 148 | /sys/devices/cpu/events/PM_LSU1_FLUSH_SRQ | ||
| 149 | /sys/devices/cpu/events/PM_LD_REF_L1_LSU0 | ||
| 150 | /sys/devices/cpu/events/PM_VSU0_FEST | ||
| 151 | /sys/devices/cpu/events/PM_VSU_VECTOR_SINGLE_ISSUED | ||
| 152 | /sys/devices/cpu/events/PM_FREQ_UP | ||
| 153 | /sys/devices/cpu/events/PM_DATA_FROM_LMEM | ||
| 154 | /sys/devices/cpu/events/PM_LSU1_LDX | ||
| 155 | /sys/devices/cpu/events/PM_PMC3_OVERFLOW | ||
| 156 | /sys/devices/cpu/events/PM_MRK_BR_MPRED | ||
| 157 | /sys/devices/cpu/events/PM_SHL_MATCH | ||
| 158 | /sys/devices/cpu/events/PM_MRK_BR_TAKEN | ||
| 159 | /sys/devices/cpu/events/PM_ISLB_MISS | ||
| 160 | /sys/devices/cpu/events/PM_DISP_HELD_THERMAL | ||
| 161 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_SHR | ||
| 162 | /sys/devices/cpu/events/PM_LSU1_SRQ_STFWD | ||
| 163 | /sys/devices/cpu/events/PM_PTEG_FROM_DMEM | ||
| 164 | /sys/devices/cpu/events/PM_VSU_2FLOP | ||
| 165 | /sys/devices/cpu/events/PM_GCT_FULL_CYC | ||
| 166 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3_CYC | ||
| 167 | /sys/devices/cpu/events/PM_LSU_SRQ_S0_ALLOC | ||
| 168 | /sys/devices/cpu/events/PM_MRK_DERAT_MISS_4K | ||
| 169 | /sys/devices/cpu/events/PM_BR_MPRED_TA | ||
| 170 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_L2MISS | ||
| 171 | /sys/devices/cpu/events/PM_DPU_HELD_POWER | ||
| 172 | /sys/devices/cpu/events/PM_MRK_VSU_FIN | ||
| 173 | /sys/devices/cpu/events/PM_LSU_SRQ_S0_VALID | ||
| 174 | /sys/devices/cpu/events/PM_GCT_EMPTY_CYC | ||
| 175 | /sys/devices/cpu/events/PM_IOPS_DISP | ||
| 176 | /sys/devices/cpu/events/PM_RUN_SPURR | ||
| 177 | /sys/devices/cpu/events/PM_PTEG_FROM_L21_MOD | ||
| 178 | /sys/devices/cpu/events/PM_VSU0_1FLOP | ||
| 179 | /sys/devices/cpu/events/PM_SNOOP_TLBIE | ||
| 180 | /sys/devices/cpu/events/PM_DATA_FROM_L3MISS | ||
| 181 | /sys/devices/cpu/events/PM_VSU_SINGLE | ||
| 182 | /sys/devices/cpu/events/PM_DTLB_MISS_16G | ||
| 183 | /sys/devices/cpu/events/PM_FLUSH | ||
| 184 | /sys/devices/cpu/events/PM_L2_LD_HIT | ||
| 185 | /sys/devices/cpu/events/PM_NEST_PAIR2_AND | ||
| 186 | /sys/devices/cpu/events/PM_VSU1_1FLOP | ||
| 187 | /sys/devices/cpu/events/PM_IC_PREF_REQ | ||
| 188 | /sys/devices/cpu/events/PM_L3_LD_HIT | ||
| 189 | /sys/devices/cpu/events/PM_DISP_HELD | ||
| 190 | /sys/devices/cpu/events/PM_L2_LD | ||
| 191 | /sys/devices/cpu/events/PM_LSU_FLUSH_SRQ | ||
| 192 | /sys/devices/cpu/events/PM_BC_PLUS_8_CONV | ||
| 193 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD_CYC | ||
| 194 | /sys/devices/cpu/events/PM_L2_RCST_BUSY_RC_FULL | ||
| 195 | /sys/devices/cpu/events/PM_TB_BIT_TRANS | ||
| 196 | /sys/devices/cpu/events/PM_THERMAL_MAX | ||
| 197 | /sys/devices/cpu/events/PM_LSU1_FLUSH_ULD | ||
| 198 | /sys/devices/cpu/events/PM_LSU1_REJECT_LHS | ||
| 199 | /sys/devices/cpu/events/PM_LSU_LRQ_S0_ALLOC | ||
| 200 | /sys/devices/cpu/events/PM_L3_CO_L31 | ||
| 201 | /sys/devices/cpu/events/PM_POWER_EVENT4 | ||
| 202 | /sys/devices/cpu/events/PM_DATA_FROM_L31_SHR | ||
| 203 | /sys/devices/cpu/events/PM_BR_UNCOND | ||
| 204 | /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_ALLOC | ||
| 205 | /sys/devices/cpu/events/PM_PMC4_REWIND | ||
| 206 | /sys/devices/cpu/events/PM_L2_RCLD_DISP | ||
| 207 | /sys/devices/cpu/events/PM_THRD_PRIO_2_3_CYC | ||
| 208 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2MISS | ||
| 209 | /sys/devices/cpu/events/PM_IC_DEMAND_L2_BHT_REDIRECT | ||
| 210 | /sys/devices/cpu/events/PM_DATA_FROM_L31_SHR | ||
| 211 | /sys/devices/cpu/events/PM_IC_PREF_CANCEL_L2 | ||
| 212 | /sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC_COUNT | ||
| 213 | /sys/devices/cpu/events/PM_BR_PRED_CCACHE | ||
| 214 | /sys/devices/cpu/events/PM_GCT_UTIL_1_TO_2_SLOTS | ||
| 215 | /sys/devices/cpu/events/PM_MRK_ST_CMPL_INT | ||
| 216 | /sys/devices/cpu/events/PM_LSU_TWO_TABLEWALK_CYC | ||
| 217 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3MISS | ||
| 218 | /sys/devices/cpu/events/PM_LSU_SET_MPRED | ||
| 219 | /sys/devices/cpu/events/PM_FLUSH_DISP_TLBIE | ||
| 220 | /sys/devices/cpu/events/PM_VSU1_FCONV | ||
| 221 | /sys/devices/cpu/events/PM_DERAT_MISS_16G | ||
| 222 | /sys/devices/cpu/events/PM_INST_FROM_LMEM | ||
| 223 | /sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_REDIRECT | ||
| 224 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_L2 | ||
| 225 | /sys/devices/cpu/events/PM_PTEG_FROM_L2 | ||
| 226 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR_CYC | ||
| 227 | /sys/devices/cpu/events/PM_MRK_DTLB_MISS_4K | ||
| 228 | /sys/devices/cpu/events/PM_VSU0_FPSCR | ||
| 229 | /sys/devices/cpu/events/PM_VSU1_VECT_DOUBLE_ISSUED | ||
| 230 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_MOD | ||
| 231 | /sys/devices/cpu/events/PM_MEM0_RQ_DISP | ||
| 232 | /sys/devices/cpu/events/PM_L2_LD_MISS | ||
| 233 | /sys/devices/cpu/events/PM_VMX_RESULT_SAT_1 | ||
| 234 | /sys/devices/cpu/events/PM_L1_PREF | ||
| 235 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM_CYC | ||
| 236 | /sys/devices/cpu/events/PM_GRP_IC_MISS_NONSPEC | ||
| 237 | /sys/devices/cpu/events/PM_PB_NODE_PUMP | ||
| 238 | /sys/devices/cpu/events/PM_SHL_MERGED | ||
| 239 | /sys/devices/cpu/events/PM_NEST_PAIR1_ADD | ||
| 240 | /sys/devices/cpu/events/PM_DATA_FROM_L3 | ||
| 241 | /sys/devices/cpu/events/PM_LSU_FLUSH | ||
| 242 | /sys/devices/cpu/events/PM_LSU_SRQ_SYNC_COUNT | ||
| 243 | /sys/devices/cpu/events/PM_PMC2_OVERFLOW | ||
| 244 | /sys/devices/cpu/events/PM_LSU_LDF | ||
| 245 | /sys/devices/cpu/events/PM_POWER_EVENT3 | ||
| 246 | /sys/devices/cpu/events/PM_DISP_WT | ||
| 247 | /sys/devices/cpu/events/PM_IC_BANK_CONFLICT | ||
| 248 | /sys/devices/cpu/events/PM_BR_MPRED_CR_TA | ||
| 249 | /sys/devices/cpu/events/PM_L2_INST_MISS | ||
| 250 | /sys/devices/cpu/events/PM_NEST_PAIR2_ADD | ||
| 251 | /sys/devices/cpu/events/PM_MRK_LSU_FLUSH | ||
| 252 | /sys/devices/cpu/events/PM_L2_LDST | ||
| 253 | /sys/devices/cpu/events/PM_INST_FROM_L31_SHR | ||
| 254 | /sys/devices/cpu/events/PM_VSU0_FIN | ||
| 255 | /sys/devices/cpu/events/PM_VSU1_FCONV | ||
| 256 | /sys/devices/cpu/events/PM_INST_FROM_RMEM | ||
| 257 | /sys/devices/cpu/events/PM_DISP_CLB_HELD_TLBIE | ||
| 258 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM_CYC | ||
| 259 | /sys/devices/cpu/events/PM_BR_PRED_CR | ||
| 260 | /sys/devices/cpu/events/PM_LSU_REJECT | ||
| 261 | /sys/devices/cpu/events/PM_GCT_UTIL_3_TO_6_SLOTS | ||
| 262 | /sys/devices/cpu/events/PM_CMPLU_STALL_END_GCT_NOSLOT | ||
| 263 | /sys/devices/cpu/events/PM_LSU0_REJECT_LMQ_FULL | ||
| 264 | /sys/devices/cpu/events/PM_VSU_FEST | ||
| 265 | /sys/devices/cpu/events/PM_NEST_PAIR0_AND | ||
| 266 | /sys/devices/cpu/events/PM_PTEG_FROM_L3 | ||
| 267 | /sys/devices/cpu/events/PM_POWER_EVENT2 | ||
| 268 | /sys/devices/cpu/events/PM_IC_PREF_CANCEL_PAGE | ||
| 269 | /sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV | ||
| 270 | /sys/devices/cpu/events/PM_MRK_GRP_CMPL | ||
| 271 | /sys/devices/cpu/events/PM_VSU0_SCAL_DOUBLE_ISSUED | ||
| 272 | /sys/devices/cpu/events/PM_GRP_DISP | ||
| 273 | /sys/devices/cpu/events/PM_LSU0_LDX | ||
| 274 | /sys/devices/cpu/events/PM_DATA_FROM_L2 | ||
| 275 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD | ||
| 276 | /sys/devices/cpu/events/PM_VSU0_VECT_DOUBLE_ISSUED | ||
| 277 | /sys/devices/cpu/events/PM_VSU1_2FLOP_DOUBLE | ||
| 278 | /sys/devices/cpu/events/PM_THRD_PRIO_6_7_CYC | ||
| 279 | /sys/devices/cpu/events/PM_BC_PLUS_8_RSLV_TAKEN | ||
| 280 | /sys/devices/cpu/events/PM_BR_MPRED_CR | ||
| 281 | /sys/devices/cpu/events/PM_L3_CO_MEM | ||
| 282 | /sys/devices/cpu/events/PM_DATA_FROM_RL2L3_MOD | ||
| 283 | /sys/devices/cpu/events/PM_LSU_SRQ_FULL_CYC | ||
| 284 | /sys/devices/cpu/events/PM_TABLEWALK_CYC | ||
| 285 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RMEM | ||
| 286 | /sys/devices/cpu/events/PM_LSU_SRQ_STFWD | ||
| 287 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_RMEM | ||
| 288 | /sys/devices/cpu/events/PM_FXU0_FIN | ||
| 289 | /sys/devices/cpu/events/PM_LSU1_L1_SW_PREF | ||
| 290 | /sys/devices/cpu/events/PM_PTEG_FROM_L31_MOD | ||
| 291 | /sys/devices/cpu/events/PM_PMC5_OVERFLOW | ||
| 292 | /sys/devices/cpu/events/PM_LD_REF_L1_LSU1 | ||
| 293 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_SHR | ||
| 294 | /sys/devices/cpu/events/PM_DATA_FROM_RMEM | ||
| 295 | /sys/devices/cpu/events/PM_VSU0_SCAL_SINGLE_ISSUED | ||
| 296 | /sys/devices/cpu/events/PM_BR_MPRED_LSTACK | ||
| 297 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD_CYC | ||
| 298 | /sys/devices/cpu/events/PM_LSU0_FLUSH_UST | ||
| 299 | /sys/devices/cpu/events/PM_LSU_NCST | ||
| 300 | /sys/devices/cpu/events/PM_BR_TAKEN | ||
| 301 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_LMEM | ||
| 302 | /sys/devices/cpu/events/PM_DTLB_MISS_4K | ||
| 303 | /sys/devices/cpu/events/PM_PMC4_SAVED | ||
| 304 | /sys/devices/cpu/events/PM_VSU1_PERMUTE_ISSUED | ||
| 305 | /sys/devices/cpu/events/PM_SLB_MISS | ||
| 306 | /sys/devices/cpu/events/PM_LSU1_FLUSH_LRQ | ||
| 307 | /sys/devices/cpu/events/PM_DTLB_MISS | ||
| 308 | /sys/devices/cpu/events/PM_VSU1_FRSP | ||
| 309 | /sys/devices/cpu/events/PM_VSU_VECTOR_DOUBLE_ISSUED | ||
| 310 | /sys/devices/cpu/events/PM_L2_CASTOUT_SHR | ||
| 311 | /sys/devices/cpu/events/PM_DATA_FROM_DL2L3_SHR | ||
| 312 | /sys/devices/cpu/events/PM_VSU1_STF | ||
| 313 | /sys/devices/cpu/events/PM_ST_FIN | ||
| 314 | /sys/devices/cpu/events/PM_PTEG_FROM_L21_SHR | ||
| 315 | /sys/devices/cpu/events/PM_L2_LOC_GUESS_WRONG | ||
| 316 | /sys/devices/cpu/events/PM_MRK_STCX_FAIL | ||
| 317 | /sys/devices/cpu/events/PM_LSU0_REJECT_LHS | ||
| 318 | /sys/devices/cpu/events/PM_IC_PREF_CANCEL_HIT | ||
| 319 | /sys/devices/cpu/events/PM_L3_PREF_BUSY | ||
| 320 | /sys/devices/cpu/events/PM_MRK_BRU_FIN | ||
| 321 | /sys/devices/cpu/events/PM_LSU1_NCLD | ||
| 322 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_MOD | ||
| 323 | /sys/devices/cpu/events/PM_LSU_NCLD | ||
| 324 | /sys/devices/cpu/events/PM_LSU_LDX | ||
| 325 | /sys/devices/cpu/events/PM_L2_LOC_GUESS_CORRECT | ||
| 326 | /sys/devices/cpu/events/PM_THRESH_TIMEO | ||
| 327 | /sys/devices/cpu/events/PM_L3_PREF_ST | ||
| 328 | /sys/devices/cpu/events/PM_DISP_CLB_HELD_SYNC | ||
| 329 | /sys/devices/cpu/events/PM_VSU_SIMPLE_ISSUED | ||
| 330 | /sys/devices/cpu/events/PM_VSU1_SINGLE | ||
| 331 | /sys/devices/cpu/events/PM_DATA_TABLEWALK_CYC | ||
| 332 | /sys/devices/cpu/events/PM_L2_RC_ST_DONE | ||
| 333 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_MOD | ||
| 334 | /sys/devices/cpu/events/PM_LARX_LSU1 | ||
| 335 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM | ||
| 336 | /sys/devices/cpu/events/PM_DISP_CLB_HELD | ||
| 337 | /sys/devices/cpu/events/PM_DERAT_MISS_4K | ||
| 338 | /sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_ADDR | ||
| 339 | /sys/devices/cpu/events/PM_SEG_EXCEPTION | ||
| 340 | /sys/devices/cpu/events/PM_FLUSH_DISP_SB | ||
| 341 | /sys/devices/cpu/events/PM_L2_DC_INV | ||
| 342 | /sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_MOD | ||
| 343 | /sys/devices/cpu/events/PM_DSEG | ||
| 344 | /sys/devices/cpu/events/PM_BR_PRED_LSTACK | ||
| 345 | /sys/devices/cpu/events/PM_VSU0_STF | ||
| 346 | /sys/devices/cpu/events/PM_LSU_FX_FIN | ||
| 347 | /sys/devices/cpu/events/PM_DERAT_MISS_16M | ||
| 348 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_MOD | ||
| 349 | /sys/devices/cpu/events/PM_GCT_UTIL_11_PLUS_SLOTS | ||
| 350 | /sys/devices/cpu/events/PM_INST_FROM_L3 | ||
| 351 | /sys/devices/cpu/events/PM_MRK_IFU_FIN | ||
| 352 | /sys/devices/cpu/events/PM_ITLB_MISS | ||
| 353 | /sys/devices/cpu/events/PM_VSU_STF | ||
| 354 | /sys/devices/cpu/events/PM_LSU_FLUSH_UST | ||
| 355 | /sys/devices/cpu/events/PM_L2_LDST_MISS | ||
| 356 | /sys/devices/cpu/events/PM_FXU1_FIN | ||
| 357 | /sys/devices/cpu/events/PM_SHL_DEALLOCATED | ||
| 358 | /sys/devices/cpu/events/PM_L2_SN_M_WR_DONE | ||
| 359 | /sys/devices/cpu/events/PM_LSU_REJECT_SET_MPRED | ||
| 360 | /sys/devices/cpu/events/PM_L3_PREF_LD | ||
| 361 | /sys/devices/cpu/events/PM_L2_SN_M_RD_DONE | ||
| 362 | /sys/devices/cpu/events/PM_MRK_DERAT_MISS_16G | ||
| 363 | /sys/devices/cpu/events/PM_VSU_FCONV | ||
| 364 | /sys/devices/cpu/events/PM_ANY_THRD_RUN_CYC | ||
| 365 | /sys/devices/cpu/events/PM_LSU_LMQ_FULL_CYC | ||
| 366 | /sys/devices/cpu/events/PM_MRK_LSU_REJECT_LHS | ||
| 367 | /sys/devices/cpu/events/PM_MRK_LD_MISS_L1_CYC | ||
| 368 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2_CYC | ||
| 369 | /sys/devices/cpu/events/PM_INST_IMC_MATCH_DISP | ||
| 370 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM_CYC | ||
| 371 | /sys/devices/cpu/events/PM_VSU0_SIMPLE_ISSUED | ||
| 372 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_SHR | ||
| 373 | /sys/devices/cpu/events/PM_VSU_FMA_DOUBLE | ||
| 374 | /sys/devices/cpu/events/PM_VSU_4FLOP | ||
| 375 | /sys/devices/cpu/events/PM_VSU1_FIN | ||
| 376 | /sys/devices/cpu/events/PM_NEST_PAIR1_AND | ||
| 377 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_MOD | ||
| 378 | /sys/devices/cpu/events/PM_PTEG_FROM_RMEM | ||
| 379 | /sys/devices/cpu/events/PM_LSU_LRQ_S0_VALID | ||
| 380 | /sys/devices/cpu/events/PM_LSU0_LDF | ||
| 381 | /sys/devices/cpu/events/PM_FLUSH_COMPLETION | ||
| 382 | /sys/devices/cpu/events/PM_ST_MISS_L1 | ||
| 383 | /sys/devices/cpu/events/PM_L2_NODE_PUMP | ||
| 384 | /sys/devices/cpu/events/PM_INST_FROM_DL2L3_SHR | ||
| 385 | /sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC | ||
| 386 | /sys/devices/cpu/events/PM_VSU1_DENORM | ||
| 387 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR_CYC | ||
| 388 | /sys/devices/cpu/events/PM_NEST_PAIR0_ADD | ||
| 389 | /sys/devices/cpu/events/PM_INST_FROM_L3MISS | ||
| 390 | /sys/devices/cpu/events/PM_EE_OFF_EXT_INT | ||
| 391 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_DMEM | ||
| 392 | /sys/devices/cpu/events/PM_INST_FROM_DL2L3_MOD | ||
| 393 | /sys/devices/cpu/events/PM_PMC6_OVERFLOW | ||
| 394 | /sys/devices/cpu/events/PM_VSU_2FLOP_DOUBLE | ||
| 395 | /sys/devices/cpu/events/PM_TLB_MISS | ||
| 396 | /sys/devices/cpu/events/PM_FXU_BUSY | ||
| 397 | /sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_OTHER | ||
| 398 | /sys/devices/cpu/events/PM_LSU_REJECT_LMQ_FULL | ||
| 399 | /sys/devices/cpu/events/PM_IC_RELOAD_SHR | ||
| 400 | /sys/devices/cpu/events/PM_GRP_MRK | ||
| 401 | /sys/devices/cpu/events/PM_MRK_ST_NEST | ||
| 402 | /sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV | ||
| 403 | /sys/devices/cpu/events/PM_LSU0_FLUSH_LRQ | ||
| 404 | /sys/devices/cpu/events/PM_LARX_LSU0 | ||
| 405 | /sys/devices/cpu/events/PM_IBUF_FULL_CYC | ||
| 406 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR_CYC | ||
| 407 | /sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_ALLOC | ||
| 408 | /sys/devices/cpu/events/PM_GRP_MRK_CYC | ||
| 409 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR_CYC | ||
| 410 | /sys/devices/cpu/events/PM_L2_GLOB_GUESS_CORRECT | ||
| 411 | /sys/devices/cpu/events/PM_LSU_REJECT_LHS | ||
| 412 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM | ||
| 413 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_L3 | ||
| 414 | /sys/devices/cpu/events/PM_FREQ_DOWN | ||
| 415 | /sys/devices/cpu/events/PM_PB_RETRY_NODE_PUMP | ||
| 416 | /sys/devices/cpu/events/PM_INST_FROM_RL2L3_SHR | ||
| 417 | /sys/devices/cpu/events/PM_MRK_INST_ISSUED | ||
| 418 | /sys/devices/cpu/events/PM_PTEG_FROM_L3MISS | ||
| 419 | /sys/devices/cpu/events/PM_RUN_PURR | ||
| 420 | /sys/devices/cpu/events/PM_MRK_GRP_IC_MISS | ||
| 421 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3 | ||
| 422 | /sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_SHR | ||
| 423 | /sys/devices/cpu/events/PM_LSU_FLUSH_LRQ | ||
| 424 | /sys/devices/cpu/events/PM_MRK_DERAT_MISS_64K | ||
| 425 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_MOD | ||
| 426 | /sys/devices/cpu/events/PM_L2_ST_MISS | ||
| 427 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_SHR | ||
| 428 | /sys/devices/cpu/events/PM_LWSYNC | ||
| 429 | /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM_STRIDE | ||
| 430 | /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_LRQ | ||
| 431 | /sys/devices/cpu/events/PM_INST_IMC_MATCH_CMPL | ||
| 432 | /sys/devices/cpu/events/PM_NEST_PAIR3_AND | ||
| 433 | /sys/devices/cpu/events/PM_PB_RETRY_SYS_PUMP | ||
| 434 | /sys/devices/cpu/events/PM_MRK_INST_FIN | ||
| 435 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_SHR | ||
| 436 | /sys/devices/cpu/events/PM_INST_FROM_L31_MOD | ||
| 437 | /sys/devices/cpu/events/PM_MRK_DTLB_MISS_64K | ||
| 438 | /sys/devices/cpu/events/PM_LSU_FIN | ||
| 439 | /sys/devices/cpu/events/PM_MRK_LSU_REJECT | ||
| 440 | /sys/devices/cpu/events/PM_L2_CO_FAIL_BUSY | ||
| 441 | /sys/devices/cpu/events/PM_MEM0_WQ_DISP | ||
| 442 | /sys/devices/cpu/events/PM_DATA_FROM_L31_MOD | ||
| 443 | /sys/devices/cpu/events/PM_THERMAL_WARN | ||
| 444 | /sys/devices/cpu/events/PM_VSU0_4FLOP | ||
| 445 | /sys/devices/cpu/events/PM_BR_MPRED_CCACHE | ||
| 446 | /sys/devices/cpu/events/PM_L1_DEMAND_WRITE | ||
| 447 | /sys/devices/cpu/events/PM_FLUSH_BR_MPRED | ||
| 448 | /sys/devices/cpu/events/PM_MRK_DTLB_MISS_16G | ||
| 449 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DMEM | ||
| 450 | /sys/devices/cpu/events/PM_L2_RCST_DISP | ||
| 451 | /sys/devices/cpu/events/PM_LSU_PARTIAL_CDF | ||
| 452 | /sys/devices/cpu/events/PM_DISP_CLB_HELD_SB | ||
| 453 | /sys/devices/cpu/events/PM_VSU0_FMA_DOUBLE | ||
| 454 | /sys/devices/cpu/events/PM_FXU0_BUSY_FXU1_IDLE | ||
| 455 | /sys/devices/cpu/events/PM_IC_DEMAND_CYC | ||
| 456 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR | ||
| 457 | /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_UST | ||
| 458 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_L3MISS | ||
| 459 | /sys/devices/cpu/events/PM_VSU_DENORM | ||
| 460 | /sys/devices/cpu/events/PM_MRK_LSU_PARTIAL_CDF | ||
| 461 | /sys/devices/cpu/events/PM_INST_FROM_L21_SHR | ||
| 462 | /sys/devices/cpu/events/PM_IC_PREF_WRITE | ||
| 463 | /sys/devices/cpu/events/PM_BR_PRED | ||
| 464 | /sys/devices/cpu/events/PM_INST_FROM_DMEM | ||
| 465 | /sys/devices/cpu/events/PM_IC_PREF_CANCEL_ALL | ||
| 466 | /sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_CONFIRM | ||
| 467 | /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_SRQ | ||
| 468 | /sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC | ||
| 469 | /sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_OTHER | ||
| 470 | /sys/devices/cpu/events/PM_VSU1_DD_ISSUED | ||
| 471 | /sys/devices/cpu/events/PM_PTEG_FROM_L31_SHR | ||
| 472 | /sys/devices/cpu/events/PM_DATA_FROM_L21_SHR | ||
| 473 | /sys/devices/cpu/events/PM_LSU0_NCLD | ||
| 474 | /sys/devices/cpu/events/PM_VSU1_4FLOP | ||
| 475 | /sys/devices/cpu/events/PM_VSU1_8FLOP | ||
| 476 | /sys/devices/cpu/events/PM_VSU_8FLOP | ||
| 477 | /sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_CYC | ||
| 478 | /sys/devices/cpu/events/PM_DTLB_MISS_64K | ||
| 479 | /sys/devices/cpu/events/PM_THRD_CONC_RUN_INST | ||
| 480 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2 | ||
| 481 | /sys/devices/cpu/events/PM_PB_SYS_PUMP | ||
| 482 | /sys/devices/cpu/events/PM_VSU_FIN | ||
| 483 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD | ||
| 484 | /sys/devices/cpu/events/PM_THRD_PRIO_0_1_CYC | ||
| 485 | /sys/devices/cpu/events/PM_DERAT_MISS_64K | ||
| 486 | /sys/devices/cpu/events/PM_PMC2_REWIND | ||
| 487 | /sys/devices/cpu/events/PM_INST_FROM_L2 | ||
| 488 | /sys/devices/cpu/events/PM_GRP_BR_MPRED_NONSPEC | ||
| 489 | /sys/devices/cpu/events/PM_INST_DISP | ||
| 490 | /sys/devices/cpu/events/PM_MEM0_RD_CANCEL_TOTAL | ||
| 491 | /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM | ||
| 492 | /sys/devices/cpu/events/PM_L1_DCACHE_RELOAD_VALID | ||
| 493 | /sys/devices/cpu/events/PM_VSU_SCALAR_DOUBLE_ISSUED | ||
| 494 | /sys/devices/cpu/events/PM_L3_PREF_HIT | ||
| 495 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_MOD | ||
| 496 | /sys/devices/cpu/events/PM_MRK_FXU_FIN | ||
| 497 | /sys/devices/cpu/events/PM_PMC4_OVERFLOW | ||
| 498 | /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3 | ||
| 499 | /sys/devices/cpu/events/PM_LSU0_LMQ_LHR_MERGE | ||
| 500 | /sys/devices/cpu/events/PM_BTAC_HIT | ||
| 501 | /sys/devices/cpu/events/PM_L3_RD_BUSY | ||
| 502 | /sys/devices/cpu/events/PM_LSU0_L1_SW_PREF | ||
| 503 | /sys/devices/cpu/events/PM_INST_FROM_L2MISS | ||
| 504 | /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_ALLOC | ||
| 505 | /sys/devices/cpu/events/PM_L2_ST | ||
| 506 | /sys/devices/cpu/events/PM_VSU0_DENORM | ||
| 507 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR | ||
| 508 | /sys/devices/cpu/events/PM_BR_PRED_CR_TA | ||
| 509 | /sys/devices/cpu/events/PM_VSU0_FCONV | ||
| 510 | /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_ULD | ||
| 511 | /sys/devices/cpu/events/PM_BTAC_MISS | ||
| 512 | /sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC_COUNT | ||
| 513 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2 | ||
| 514 | /sys/devices/cpu/events/PM_LSU_DCACHE_RELOAD_VALID | ||
| 515 | /sys/devices/cpu/events/PM_VSU_FMA | ||
| 516 | /sys/devices/cpu/events/PM_LSU0_FLUSH_SRQ | ||
| 517 | /sys/devices/cpu/events/PM_LSU1_L1_PREF | ||
| 518 | /sys/devices/cpu/events/PM_IOPS_CMPL | ||
| 519 | /sys/devices/cpu/events/PM_L2_SYS_PUMP | ||
| 520 | /sys/devices/cpu/events/PM_L2_RCLD_BUSY_RC_FULL | ||
| 521 | /sys/devices/cpu/events/PM_LSU_LMQ_S0_ALLOC | ||
| 522 | /sys/devices/cpu/events/PM_FLUSH_DISP_SYNC | ||
| 523 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD_CYC | ||
| 524 | /sys/devices/cpu/events/PM_L2_IC_INV | ||
| 525 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD_CYC | ||
| 526 | /sys/devices/cpu/events/PM_L3_PREF_LDST | ||
| 527 | /sys/devices/cpu/events/PM_LSU_SRQ_EMPTY_CYC | ||
| 528 | /sys/devices/cpu/events/PM_LSU_LMQ_S0_VALID | ||
| 529 | /sys/devices/cpu/events/PM_FLUSH_PARTIAL | ||
| 530 | /sys/devices/cpu/events/PM_VSU1_FMA_DOUBLE | ||
| 531 | /sys/devices/cpu/events/PM_1PLUS_PPC_DISP | ||
| 532 | /sys/devices/cpu/events/PM_DATA_FROM_L2MISS | ||
| 533 | /sys/devices/cpu/events/PM_SUSPENDED | ||
| 534 | /sys/devices/cpu/events/PM_VSU0_FMA | ||
| 535 | /sys/devices/cpu/events/PM_STCX_FAIL | ||
| 536 | /sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV_DOUBLE | ||
| 537 | /sys/devices/cpu/events/PM_DC_PREF_DST | ||
| 538 | /sys/devices/cpu/events/PM_VSU1_SCAL_SINGLE_ISSUED | ||
| 539 | /sys/devices/cpu/events/PM_L3_HIT | ||
| 540 | /sys/devices/cpu/events/PM_L2_GLOB_GUESS_WRONG | ||
| 541 | /sys/devices/cpu/events/PM_MRK_DFU_FIN | ||
| 542 | /sys/devices/cpu/events/PM_INST_FROM_L1 | ||
| 543 | /sys/devices/cpu/events/PM_IC_DEMAND_REQ | ||
| 544 | /sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV_DOUBLE | ||
| 545 | /sys/devices/cpu/events/PM_VSU1_FMA | ||
| 546 | /sys/devices/cpu/events/PM_MRK_LD_MISS_L1 | ||
| 547 | /sys/devices/cpu/events/PM_VSU0_2FLOP_DOUBLE | ||
| 548 | /sys/devices/cpu/events/PM_LSU_DC_PREF_STRIDED_STREAM_CONFIRM | ||
| 549 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_SHR | ||
| 550 | /sys/devices/cpu/events/PM_MRK_LSU_REJECT_ERAT_MISS | ||
| 551 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2MISS | ||
| 552 | /sys/devices/cpu/events/PM_DATA_FROM_RL2L3_SHR | ||
| 553 | /sys/devices/cpu/events/PM_INST_FROM_PREF | ||
| 554 | /sys/devices/cpu/events/PM_VSU1_SQ | ||
| 555 | /sys/devices/cpu/events/PM_L2_LD_DISP | ||
| 556 | /sys/devices/cpu/events/PM_L2_DISP_ALL | ||
| 557 | /sys/devices/cpu/events/PM_THRD_GRP_CMPL_BOTH_CYC | ||
| 558 | /sys/devices/cpu/events/PM_VSU_FSQRT_FDIV_DOUBLE | ||
| 559 | /sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_SHR | ||
| 560 | /sys/devices/cpu/events/PM_VSU_1FLOP | ||
| 561 | /sys/devices/cpu/events/PM_HV_CYC | ||
| 562 | /sys/devices/cpu/events/PM_MRK_LSU_FIN | ||
| 563 | /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR | ||
| 564 | /sys/devices/cpu/events/PM_DTLB_MISS_16M | ||
| 565 | /sys/devices/cpu/events/PM_LSU1_LMQ_LHR_MERGE | ||
| 566 | /sys/devices/cpu/events/PM_IFU_FIN | ||
| 567 | /sys/devices/cpu/events/PM_1THRD_CON_RUN_INSTR | ||
| 568 | /sys/devices/cpu/events/PM_CMPLU_STALL_COUNT | ||
| 569 | /sys/devices/cpu/events/PM_MEM0_PB_RD_CL | ||
| 570 | /sys/devices/cpu/events/PM_THRD_1_RUN_CYC | ||
| 571 | /sys/devices/cpu/events/PM_THRD_2_CONC_RUN_INSTR | ||
| 572 | /sys/devices/cpu/events/PM_THRD_2_RUN_CYC | ||
| 573 | /sys/devices/cpu/events/PM_THRD_3_CONC_RUN_INST | ||
| 574 | /sys/devices/cpu/events/PM_THRD_3_RUN_CYC | ||
| 575 | /sys/devices/cpu/events/PM_THRD_4_CONC_RUN_INST | ||
| 576 | /sys/devices/cpu/events/PM_THRD_4_RUN_CYC | ||
| 577 | 34 | ||
| 578 | Date: 2013/01/08 | 35 | Each file (except for some of those with a '.' in them, '.unit' |
| 36 | and '.scale') in the 'events' directory describes a single | ||
| 37 | performance monitoring event supported by the <pmu>. The name | ||
| 38 | of the file is the name of the event. | ||
| 39 | |||
| 40 | File contents: | ||
| 41 | |||
| 42 | <term>[=<value>][,<term>[=<value>]]... | ||
| 43 | |||
| 44 | Where <term> is one of the terms listed under | ||
| 45 | /sys/bus/event_source/devices/<pmu>/format/ and <value> is | ||
| 46 | a number is base-16 format with a '0x' prefix (lowercase only). | ||
| 47 | If a <term> is specified alone (without an assigned value), it | ||
| 48 | is implied that 0x1 is assigned to that <term>. | ||
| 579 | 49 | ||
| 50 | Examples (each of these lines would be in a seperate file): | ||
| 51 | |||
| 52 | event=0x2abc | ||
| 53 | event=0x423,inv,cmask=0x3 | ||
| 54 | domain=0x1,offset=0x8,starting_index=0xffff | ||
| 55 | |||
| 56 | Each of the assignments indicates a value to be assigned to a | ||
| 57 | particular set of bits (as defined by the format file | ||
| 58 | corresponding to the <term>) in the perf_event structure passed | ||
| 59 | to the perf_open syscall. | ||
| 60 | |||
| 61 | What: /sys/bus/event_source/devices/<pmu>/events/<event>.unit | ||
| 62 | Date: 2014/02/24 | ||
| 580 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> | 63 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> |
| 581 | Linux Powerpc mailing list <linuxppc-dev@ozlabs.org> | 64 | Description: Perf event units |
| 582 | 65 | ||
| 583 | Description: POWER-systems specific performance monitoring events | 66 | A string specifying the English plural numerical unit that <event> |
| 67 | (once multiplied by <event>.scale) represents. | ||
| 584 | 68 | ||
| 585 | A collection of performance monitoring events that may be | 69 | Example: |
| 586 | supported by the POWER CPU. These events can be monitored | ||
| 587 | using the 'perf(1)' tool. | ||
| 588 | 70 | ||
| 589 | These events may not be supported by other CPUs. | 71 | Joules |
| 590 | 72 | ||
| 591 | The contents of each file would look like: | 73 | What: /sys/bus/event_source/devices/<pmu>/events/<event>.scale |
| 74 | Date: 2014/02/24 | ||
| 75 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> | ||
| 76 | Description: Perf event scaling factors | ||
| 592 | 77 | ||
| 593 | event=0xNNNN | 78 | A string representing a floating point value expressed in |
| 79 | scientific notation to be multiplied by the event count | ||
| 80 | recieved from the kernel to match the unit specified in the | ||
| 81 | <event>.unit file. | ||
| 594 | 82 | ||
| 595 | where 'N' is a hex digit and the number '0xNNNN' shows the | 83 | Example: |
| 596 | "raw code" for the perf event identified by the file's | 84 | |
| 597 | "basename". | 85 | 2.3283064365386962890625e-10 |
| 598 | 86 | ||
| 599 | Further, multiple terms like 'event=0xNNNN' can be specified | 87 | This is provided to avoid performing floating point arithmetic |
| 600 | and separated with comma. All available terms are defined in | 88 | in the kernel. |
| 601 | the /sys/bus/event_source/devices/<dev>/format file. | ||
diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h index 53cdfb2857ab..4421b5da409d 100644 --- a/arch/x86/include/asm/kprobes.h +++ b/arch/x86/include/asm/kprobes.h | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <asm/insn.h> | 27 | #include <asm/insn.h> |
| 28 | 28 | ||
| 29 | #define __ARCH_WANT_KPROBES_INSN_SLOT | 29 | #define __ARCH_WANT_KPROBES_INSN_SLOT |
| 30 | #define ARCH_SUPPORTS_KPROBES_ON_FTRACE | ||
| 31 | 30 | ||
| 32 | struct pt_regs; | 31 | struct pt_regs; |
| 33 | struct kprobe; | 32 | struct kprobe; |
diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index b3b8abae62b8..e463caa3eb49 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt | |||
| @@ -196,10 +196,10 @@ If specified the 'Weighted diff' column is displayed with value 'd' computed as: | |||
| 196 | 196 | ||
| 197 | - period being the hist entry period value | 197 | - period being the hist entry period value |
| 198 | 198 | ||
| 199 | - WEIGHT-A/WEIGHT-B being user suplied weights in the the '-c' option | 199 | - WEIGHT-A/WEIGHT-B being user supplied weights in the the '-c' option |
| 200 | behind ':' separator like '-c wdiff:1,2'. | 200 | behind ':' separator like '-c wdiff:1,2'. |
| 201 | - WIEGHT-A being the weight of the data file | 201 | - WEIGHT-A being the weight of the data file |
| 202 | - WIEGHT-B being the weight of the baseline data file | 202 | - WEIGHT-B being the weight of the baseline data file |
| 203 | 203 | ||
| 204 | SEE ALSO | 204 | SEE ALSO |
| 205 | -------- | 205 | -------- |
diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt index 6e689dc89a2f..6252e776009c 100644 --- a/tools/perf/Documentation/perf-kvm.txt +++ b/tools/perf/Documentation/perf-kvm.txt | |||
| @@ -100,7 +100,7 @@ OPTIONS | |||
| 100 | STAT REPORT OPTIONS | 100 | STAT REPORT OPTIONS |
| 101 | ------------------- | 101 | ------------------- |
| 102 | --vcpu=<value>:: | 102 | --vcpu=<value>:: |
| 103 | analyze events which occures on this vcpu. (default: all vcpus) | 103 | analyze events which occur on this vcpu. (default: all vcpus) |
| 104 | 104 | ||
| 105 | --event=<value>:: | 105 | --event=<value>:: |
| 106 | event to be analyzed. Possible values: vmexit, mmio (x86 only), | 106 | event to be analyzed. Possible values: vmexit, mmio (x86 only), |
| @@ -134,7 +134,7 @@ STAT LIVE OPTIONS | |||
| 134 | Analyze events only for given process ID(s) (comma separated list). | 134 | Analyze events only for given process ID(s) (comma separated list). |
| 135 | 135 | ||
| 136 | --vcpu=<value>:: | 136 | --vcpu=<value>:: |
| 137 | analyze events which occures on this vcpu. (default: all vcpus) | 137 | analyze events which occur on this vcpu. (default: all vcpus) |
| 138 | 138 | ||
| 139 | 139 | ||
| 140 | --event=<value>:: | 140 | --event=<value>:: |
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index 6fce6a622206..cbb4f743d921 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt | |||
| @@ -19,7 +19,7 @@ various perf commands with the -e option. | |||
| 19 | EVENT MODIFIERS | 19 | EVENT MODIFIERS |
| 20 | --------------- | 20 | --------------- |
| 21 | 21 | ||
| 22 | Events can optionally have a modifer by appending a colon and one or | 22 | Events can optionally have a modifier by appending a colon and one or |
| 23 | more modifiers. Modifiers allow the user to restrict the events to be | 23 | more modifiers. Modifiers allow the user to restrict the events to be |
| 24 | counted. The following modifiers exist: | 24 | counted. The following modifiers exist: |
| 25 | 25 | ||
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index d460049cae8e..398f8d53bd6d 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt | |||
| @@ -146,7 +146,7 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. | |||
| 146 | 146 | ||
| 147 | -N:: | 147 | -N:: |
| 148 | --no-buildid-cache:: | 148 | --no-buildid-cache:: |
| 149 | Do not update the builid cache. This saves some overhead in situations | 149 | Do not update the buildid cache. This saves some overhead in situations |
| 150 | where the information in the perf.data file (which includes buildids) | 150 | where the information in the perf.data file (which includes buildids) |
| 151 | is sufficient. | 151 | is sufficient. |
| 152 | 152 | ||
diff --git a/tools/perf/Documentation/perf-script-perl.txt b/tools/perf/Documentation/perf-script-perl.txt index d00bef231340..dfbb506d2c34 100644 --- a/tools/perf/Documentation/perf-script-perl.txt +++ b/tools/perf/Documentation/perf-script-perl.txt | |||
| @@ -181,8 +181,8 @@ strings for flag and symbolic fields. These correspond to the strings | |||
| 181 | and values parsed from the 'print fmt' fields of the event format | 181 | and values parsed from the 'print fmt' fields of the event format |
| 182 | files: | 182 | files: |
| 183 | 183 | ||
| 184 | flag_str($event_name, $field_name, $field_value) - returns the string represention corresponding to $field_value for the flag field $field_name of event $event_name | 184 | flag_str($event_name, $field_name, $field_value) - returns the string representation corresponding to $field_value for the flag field $field_name of event $event_name |
| 185 | symbol_str($event_name, $field_name, $field_value) - returns the string represention corresponding to $field_value for the symbolic field $field_name of event $event_name | 185 | symbol_str($event_name, $field_name, $field_value) - returns the string representation corresponding to $field_value for the symbolic field $field_name of event $event_name |
| 186 | 186 | ||
| 187 | Perf::Trace::Context Module | 187 | Perf::Trace::Context Module |
| 188 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 188 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
diff --git a/tools/perf/Documentation/perf-script-python.txt b/tools/perf/Documentation/perf-script-python.txt index 9f1f054b8432..54acba221558 100644 --- a/tools/perf/Documentation/perf-script-python.txt +++ b/tools/perf/Documentation/perf-script-python.txt | |||
| @@ -263,7 +263,7 @@ and having the counts we've tallied as values. | |||
| 263 | 263 | ||
| 264 | The print_syscall_totals() function iterates over the entries in the | 264 | The print_syscall_totals() function iterates over the entries in the |
| 265 | dictionary and displays a line for each entry containing the syscall | 265 | dictionary and displays a line for each entry containing the syscall |
| 266 | name (the dictonary keys contain the syscall ids, which are passed to | 266 | name (the dictionary keys contain the syscall ids, which are passed to |
| 267 | the Util function syscall_name(), which translates the raw syscall | 267 | the Util function syscall_name(), which translates the raw syscall |
| 268 | numbers to the corresponding syscall name strings). The output is | 268 | numbers to the corresponding syscall name strings). The output is |
| 269 | displayed after all the events in the trace have been processed, by | 269 | displayed after all the events in the trace have been processed, by |
| @@ -576,8 +576,8 @@ strings for flag and symbolic fields. These correspond to the strings | |||
| 576 | and values parsed from the 'print fmt' fields of the event format | 576 | and values parsed from the 'print fmt' fields of the event format |
| 577 | files: | 577 | files: |
| 578 | 578 | ||
| 579 | flag_str(event_name, field_name, field_value) - returns the string represention corresponding to field_value for the flag field field_name of event event_name | 579 | flag_str(event_name, field_name, field_value) - returns the string representation corresponding to field_value for the flag field field_name of event event_name |
| 580 | symbol_str(event_name, field_name, field_value) - returns the string represention corresponding to field_value for the symbolic field field_name of event event_name | 580 | symbol_str(event_name, field_name, field_value) - returns the string representation corresponding to field_value for the symbolic field field_name of event event_name |
| 581 | 581 | ||
| 582 | The *autodict* function returns a special kind of Python | 582 | The *autodict* function returns a special kind of Python |
| 583 | dictionary that implements Perl's 'autovivifying' hashes in Python | 583 | dictionary that implements Perl's 'autovivifying' hashes in Python |
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 05f9a0a6784c..21494806c0ab 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt | |||
| @@ -115,7 +115,7 @@ OPTIONS | |||
| 115 | -f:: | 115 | -f:: |
| 116 | --fields:: | 116 | --fields:: |
| 117 | Comma separated list of fields to print. Options are: | 117 | Comma separated list of fields to print. Options are: |
| 118 | comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline. | 118 | comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period. |
| 119 | Field list can be prepended with the type, trace, sw or hw, | 119 | Field list can be prepended with the type, trace, sw or hw, |
| 120 | to indicate to which event type the field list applies. | 120 | to indicate to which event type the field list applies. |
| 121 | e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace | 121 | e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace |
| @@ -140,7 +140,7 @@ OPTIONS | |||
| 140 | 140 | ||
| 141 | "Overriding previous field request for all events." | 141 | "Overriding previous field request for all events." |
| 142 | 142 | ||
| 143 | Alternativey, consider the order: | 143 | Alternatively, consider the order: |
| 144 | 144 | ||
| 145 | -f comm,tid,time,ip,sym -f trace: | 145 | -f comm,tid,time,ip,sym -f trace: |
| 146 | 146 | ||
diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt index d1d3e5121f89..31a5c3ea7f74 100644 --- a/tools/perf/Documentation/perf-test.txt +++ b/tools/perf/Documentation/perf-test.txt | |||
| @@ -25,7 +25,7 @@ OPTIONS | |||
| 25 | ------- | 25 | ------- |
| 26 | -s:: | 26 | -s:: |
| 27 | --skip:: | 27 | --skip:: |
| 28 | Tests to skip (comma separater numeric list). | 28 | Tests to skip (comma separated numeric list). |
| 29 | 29 | ||
| 30 | -v:: | 30 | -v:: |
| 31 | --verbose:: | 31 | --verbose:: |
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 02aac831bdd9..7e1b1f2bb83c 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt | |||
| @@ -20,7 +20,7 @@ scheduling events, etc. | |||
| 20 | This is a live mode tool in addition to working with perf.data files like | 20 | This is a live mode tool in addition to working with perf.data files like |
| 21 | the other perf tools. Files can be generated using the 'perf record' command | 21 | the other perf tools. Files can be generated using the 'perf record' command |
| 22 | but the session needs to include the raw_syscalls events (-e 'raw_syscalls:*'). | 22 | but the session needs to include the raw_syscalls events (-e 'raw_syscalls:*'). |
| 23 | Alernatively, the 'perf trace record' can be used as a shortcut to | 23 | Alternatively, 'perf trace record' can be used as a shortcut to |
| 24 | automatically include the raw_syscalls events when writing events to a file. | 24 | automatically include the raw_syscalls events when writing events to a file. |
| 25 | 25 | ||
| 26 | The following options apply to perf trace; options to perf trace record are | 26 | The following options apply to perf trace; options to perf trace record are |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index be5939418425..e7417fe97a97 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -51,6 +51,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, | |||
| 51 | struct addr_location *al, | 51 | struct addr_location *al, |
| 52 | struct perf_annotate *ann) | 52 | struct perf_annotate *ann) |
| 53 | { | 53 | { |
| 54 | struct hists *hists = evsel__hists(evsel); | ||
| 54 | struct hist_entry *he; | 55 | struct hist_entry *he; |
| 55 | int ret; | 56 | int ret; |
| 56 | 57 | ||
| @@ -66,13 +67,12 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, | |||
| 66 | return 0; | 67 | return 0; |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0, | 70 | he = __hists__add_entry(hists, al, NULL, NULL, NULL, 1, 1, 0, true); |
| 70 | true); | ||
| 71 | if (he == NULL) | 71 | if (he == NULL) |
| 72 | return -ENOMEM; | 72 | return -ENOMEM; |
| 73 | 73 | ||
| 74 | ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); | 74 | ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); |
| 75 | hists__inc_nr_samples(&evsel->hists, true); | 75 | hists__inc_nr_samples(hists, true); |
| 76 | return ret; | 76 | return ret; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| @@ -214,6 +214,7 @@ static int __cmd_annotate(struct perf_annotate *ann) | |||
| 214 | 214 | ||
| 215 | if (dump_trace) { | 215 | if (dump_trace) { |
| 216 | perf_session__fprintf_nr_events(session, stdout); | 216 | perf_session__fprintf_nr_events(session, stdout); |
| 217 | perf_evlist__fprintf_nr_events(session->evlist, stdout); | ||
| 217 | goto out; | 218 | goto out; |
| 218 | } | 219 | } |
| 219 | 220 | ||
| @@ -225,7 +226,7 @@ static int __cmd_annotate(struct perf_annotate *ann) | |||
| 225 | 226 | ||
| 226 | total_nr_samples = 0; | 227 | total_nr_samples = 0; |
| 227 | evlist__for_each(session->evlist, pos) { | 228 | evlist__for_each(session->evlist, pos) { |
| 228 | struct hists *hists = &pos->hists; | 229 | struct hists *hists = evsel__hists(pos); |
| 229 | u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; | 230 | u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; |
| 230 | 231 | ||
| 231 | if (nr_samples > 0) { | 232 | if (nr_samples > 0) { |
| @@ -325,7 +326,10 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 325 | "Show event group information together"), | 326 | "Show event group information together"), |
| 326 | OPT_END() | 327 | OPT_END() |
| 327 | }; | 328 | }; |
| 328 | int ret; | 329 | int ret = hists__init(); |
| 330 | |||
| 331 | if (ret < 0) | ||
| 332 | return ret; | ||
| 329 | 333 | ||
| 330 | argc = parse_options(argc, argv, options, annotate_usage, 0); | 334 | argc = parse_options(argc, argv, options, annotate_usage, 0); |
| 331 | 335 | ||
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index a3ce19f7aebd..8c5c11ca8c53 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
| @@ -327,6 +327,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, | |||
| 327 | struct machine *machine) | 327 | struct machine *machine) |
| 328 | { | 328 | { |
| 329 | struct addr_location al; | 329 | struct addr_location al; |
| 330 | struct hists *hists = evsel__hists(evsel); | ||
| 330 | 331 | ||
| 331 | if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { | 332 | if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { |
| 332 | pr_warning("problem processing %d event, skipping it.\n", | 333 | pr_warning("problem processing %d event, skipping it.\n", |
| @@ -334,7 +335,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, | |||
| 334 | return -1; | 335 | return -1; |
| 335 | } | 336 | } |
| 336 | 337 | ||
| 337 | if (hists__add_entry(&evsel->hists, &al, sample->period, | 338 | if (hists__add_entry(hists, &al, sample->period, |
| 338 | sample->weight, sample->transaction)) { | 339 | sample->weight, sample->transaction)) { |
| 339 | pr_warning("problem incrementing symbol period, skipping event\n"); | 340 | pr_warning("problem incrementing symbol period, skipping event\n"); |
| 340 | return -1; | 341 | return -1; |
| @@ -346,9 +347,9 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, | |||
| 346 | * hists__output_resort() and precompute needs the total | 347 | * hists__output_resort() and precompute needs the total |
| 347 | * period in order to sort entries by percentage delta. | 348 | * period in order to sort entries by percentage delta. |
| 348 | */ | 349 | */ |
| 349 | evsel->hists.stats.total_period += sample->period; | 350 | hists->stats.total_period += sample->period; |
| 350 | if (!al.filtered) | 351 | if (!al.filtered) |
| 351 | evsel->hists.stats.total_non_filtered_period += sample->period; | 352 | hists->stats.total_non_filtered_period += sample->period; |
| 352 | 353 | ||
| 353 | return 0; | 354 | return 0; |
| 354 | } | 355 | } |
| @@ -382,7 +383,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist) | |||
| 382 | struct perf_evsel *evsel; | 383 | struct perf_evsel *evsel; |
| 383 | 384 | ||
| 384 | evlist__for_each(evlist, evsel) { | 385 | evlist__for_each(evlist, evsel) { |
| 385 | struct hists *hists = &evsel->hists; | 386 | struct hists *hists = evsel__hists(evsel); |
| 386 | 387 | ||
| 387 | hists__collapse_resort(hists, NULL); | 388 | hists__collapse_resort(hists, NULL); |
| 388 | } | 389 | } |
| @@ -631,24 +632,26 @@ static void data_process(void) | |||
| 631 | bool first = true; | 632 | bool first = true; |
| 632 | 633 | ||
| 633 | evlist__for_each(evlist_base, evsel_base) { | 634 | evlist__for_each(evlist_base, evsel_base) { |
| 635 | struct hists *hists_base = evsel__hists(evsel_base); | ||
| 634 | struct data__file *d; | 636 | struct data__file *d; |
| 635 | int i; | 637 | int i; |
| 636 | 638 | ||
| 637 | data__for_each_file_new(i, d) { | 639 | data__for_each_file_new(i, d) { |
| 638 | struct perf_evlist *evlist = d->session->evlist; | 640 | struct perf_evlist *evlist = d->session->evlist; |
| 639 | struct perf_evsel *evsel; | 641 | struct perf_evsel *evsel; |
| 642 | struct hists *hists; | ||
| 640 | 643 | ||
| 641 | evsel = evsel_match(evsel_base, evlist); | 644 | evsel = evsel_match(evsel_base, evlist); |
| 642 | if (!evsel) | 645 | if (!evsel) |
| 643 | continue; | 646 | continue; |
| 644 | 647 | ||
| 645 | d->hists = &evsel->hists; | 648 | hists = evsel__hists(evsel); |
| 649 | d->hists = hists; | ||
| 646 | 650 | ||
| 647 | hists__match(&evsel_base->hists, &evsel->hists); | 651 | hists__match(hists_base, hists); |
| 648 | 652 | ||
| 649 | if (!show_baseline_only) | 653 | if (!show_baseline_only) |
| 650 | hists__link(&evsel_base->hists, | 654 | hists__link(hists_base, hists); |
| 651 | &evsel->hists); | ||
| 652 | } | 655 | } |
| 653 | 656 | ||
| 654 | fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", | 657 | fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", |
| @@ -659,7 +662,7 @@ static void data_process(void) | |||
| 659 | if (verbose || data__files_cnt > 2) | 662 | if (verbose || data__files_cnt > 2) |
| 660 | data__fprintf(); | 663 | data__fprintf(); |
| 661 | 664 | ||
| 662 | hists__process(&evsel_base->hists); | 665 | hists__process(hists_base); |
| 663 | } | 666 | } |
| 664 | } | 667 | } |
| 665 | 668 | ||
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index d8bf2271f4ea..b65eb0507b38 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
| @@ -376,7 +376,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread, | |||
| 376 | struct perf_sample *sample) | 376 | struct perf_sample *sample) |
| 377 | { | 377 | { |
| 378 | /* Only kvm_entry records vcpu id. */ | 378 | /* Only kvm_entry records vcpu id. */ |
| 379 | if (!thread->priv && kvm_entry_event(evsel)) { | 379 | if (!thread__priv(thread) && kvm_entry_event(evsel)) { |
| 380 | struct vcpu_event_record *vcpu_record; | 380 | struct vcpu_event_record *vcpu_record; |
| 381 | 381 | ||
| 382 | vcpu_record = zalloc(sizeof(*vcpu_record)); | 382 | vcpu_record = zalloc(sizeof(*vcpu_record)); |
| @@ -386,10 +386,10 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread, | |||
| 386 | } | 386 | } |
| 387 | 387 | ||
| 388 | vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, VCPU_ID); | 388 | vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample, VCPU_ID); |
| 389 | thread->priv = vcpu_record; | 389 | thread__set_priv(thread, vcpu_record); |
| 390 | } | 390 | } |
| 391 | 391 | ||
| 392 | return thread->priv; | 392 | return thread__priv(thread); |
| 393 | } | 393 | } |
| 394 | 394 | ||
| 395 | static bool handle_kvm_event(struct perf_kvm_stat *kvm, | 395 | static bool handle_kvm_event(struct perf_kvm_stat *kvm, |
| @@ -896,8 +896,7 @@ static int perf_kvm__handle_stdin(void) | |||
| 896 | 896 | ||
| 897 | static int kvm_events_live_report(struct perf_kvm_stat *kvm) | 897 | static int kvm_events_live_report(struct perf_kvm_stat *kvm) |
| 898 | { | 898 | { |
| 899 | struct pollfd *pollfds = NULL; | 899 | int nr_stdin, ret, err = -EINVAL; |
| 900 | int nr_fds, nr_stdin, ret, err = -EINVAL; | ||
| 901 | struct termios save; | 900 | struct termios save; |
| 902 | 901 | ||
| 903 | /* live flag must be set first */ | 902 | /* live flag must be set first */ |
| @@ -919,34 +918,27 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) | |||
| 919 | signal(SIGINT, sig_handler); | 918 | signal(SIGINT, sig_handler); |
| 920 | signal(SIGTERM, sig_handler); | 919 | signal(SIGTERM, sig_handler); |
| 921 | 920 | ||
| 922 | /* use pollfds -- need to add timerfd and stdin */ | ||
| 923 | nr_fds = kvm->evlist->pollfd.nr; | ||
| 924 | |||
| 925 | /* add timer fd */ | 921 | /* add timer fd */ |
| 926 | if (perf_kvm__timerfd_create(kvm) < 0) { | 922 | if (perf_kvm__timerfd_create(kvm) < 0) { |
| 927 | err = -1; | 923 | err = -1; |
| 928 | goto out; | 924 | goto out; |
| 929 | } | 925 | } |
| 930 | 926 | ||
| 931 | if (perf_evlist__add_pollfd(kvm->evlist, kvm->timerfd)) | 927 | if (perf_evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0) |
| 932 | goto out; | 928 | goto out; |
| 933 | 929 | ||
| 934 | nr_fds++; | 930 | nr_stdin = perf_evlist__add_pollfd(kvm->evlist, fileno(stdin)); |
| 935 | 931 | if (nr_stdin < 0) | |
| 936 | if (perf_evlist__add_pollfd(kvm->evlist, fileno(stdin))) | ||
| 937 | goto out; | 932 | goto out; |
| 938 | 933 | ||
| 939 | nr_stdin = nr_fds; | ||
| 940 | nr_fds++; | ||
| 941 | if (fd_set_nonblock(fileno(stdin)) != 0) | 934 | if (fd_set_nonblock(fileno(stdin)) != 0) |
| 942 | goto out; | 935 | goto out; |
| 943 | 936 | ||
| 944 | pollfds = kvm->evlist->pollfd.entries; | ||
| 945 | |||
| 946 | /* everything is good - enable the events and process */ | 937 | /* everything is good - enable the events and process */ |
| 947 | perf_evlist__enable(kvm->evlist); | 938 | perf_evlist__enable(kvm->evlist); |
| 948 | 939 | ||
| 949 | while (!done) { | 940 | while (!done) { |
| 941 | struct fdarray *fda = &kvm->evlist->pollfd; | ||
| 950 | int rc; | 942 | int rc; |
| 951 | 943 | ||
| 952 | rc = perf_kvm__mmap_read(kvm); | 944 | rc = perf_kvm__mmap_read(kvm); |
| @@ -957,11 +949,11 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) | |||
| 957 | if (err) | 949 | if (err) |
| 958 | goto out; | 950 | goto out; |
| 959 | 951 | ||
| 960 | if (pollfds[nr_stdin].revents & POLLIN) | 952 | if (fda->entries[nr_stdin].revents & POLLIN) |
| 961 | done = perf_kvm__handle_stdin(); | 953 | done = perf_kvm__handle_stdin(); |
| 962 | 954 | ||
| 963 | if (!rc && !done) | 955 | if (!rc && !done) |
| 964 | err = poll(pollfds, nr_fds, 100); | 956 | err = fdarray__poll(fda, 100); |
| 965 | } | 957 | } |
| 966 | 958 | ||
| 967 | perf_evlist__disable(kvm->evlist); | 959 | perf_evlist__disable(kvm->evlist); |
| @@ -1366,6 +1358,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
| 1366 | } | 1358 | } |
| 1367 | kvm->session->evlist = kvm->evlist; | 1359 | kvm->session->evlist = kvm->evlist; |
| 1368 | perf_session__set_id_hdr_size(kvm->session); | 1360 | perf_session__set_id_hdr_size(kvm->session); |
| 1361 | ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true); | ||
| 1369 | machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, | 1362 | machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.target, |
| 1370 | kvm->evlist->threads, false); | 1363 | kvm->evlist->threads, false); |
| 1371 | err = kvm_live_open_events(kvm); | 1364 | err = kvm_live_open_events(kvm); |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 44c6f3d55ce7..2583a9b04317 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -14,6 +14,8 @@ | |||
| 14 | #include "util/parse-options.h" | 14 | #include "util/parse-options.h" |
| 15 | #include "util/parse-events.h" | 15 | #include "util/parse-events.h" |
| 16 | 16 | ||
| 17 | #include "util/callchain.h" | ||
| 18 | #include "util/cgroup.h" | ||
| 17 | #include "util/header.h" | 19 | #include "util/header.h" |
| 18 | #include "util/event.h" | 20 | #include "util/event.h" |
| 19 | #include "util/evlist.h" | 21 | #include "util/evlist.h" |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index ac145fae0521..140a6cd88351 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -257,6 +257,13 @@ static int report__setup_sample_type(struct report *rep) | |||
| 257 | } | 257 | } |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) { | ||
| 261 | if ((sample_type & PERF_SAMPLE_REGS_USER) && | ||
| 262 | (sample_type & PERF_SAMPLE_STACK_USER)) | ||
| 263 | callchain_param.record_mode = CALLCHAIN_DWARF; | ||
| 264 | else | ||
| 265 | callchain_param.record_mode = CALLCHAIN_FP; | ||
| 266 | } | ||
| 260 | return 0; | 267 | return 0; |
| 261 | } | 268 | } |
| 262 | 269 | ||
| @@ -288,12 +295,14 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report | |||
| 288 | evname = buf; | 295 | evname = buf; |
| 289 | 296 | ||
| 290 | for_each_group_member(pos, evsel) { | 297 | for_each_group_member(pos, evsel) { |
| 298 | const struct hists *pos_hists = evsel__hists(pos); | ||
| 299 | |||
| 291 | if (symbol_conf.filter_relative) { | 300 | if (symbol_conf.filter_relative) { |
| 292 | nr_samples += pos->hists.stats.nr_non_filtered_samples; | 301 | nr_samples += pos_hists->stats.nr_non_filtered_samples; |
| 293 | nr_events += pos->hists.stats.total_non_filtered_period; | 302 | nr_events += pos_hists->stats.total_non_filtered_period; |
| 294 | } else { | 303 | } else { |
| 295 | nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; | 304 | nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE]; |
| 296 | nr_events += pos->hists.stats.total_period; | 305 | nr_events += pos_hists->stats.total_period; |
| 297 | } | 306 | } |
| 298 | } | 307 | } |
| 299 | } | 308 | } |
| @@ -318,7 +327,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | |||
| 318 | struct perf_evsel *pos; | 327 | struct perf_evsel *pos; |
| 319 | 328 | ||
| 320 | evlist__for_each(evlist, pos) { | 329 | evlist__for_each(evlist, pos) { |
| 321 | struct hists *hists = &pos->hists; | 330 | struct hists *hists = evsel__hists(pos); |
| 322 | const char *evname = perf_evsel__name(pos); | 331 | const char *evname = perf_evsel__name(pos); |
| 323 | 332 | ||
| 324 | if (symbol_conf.event_group && | 333 | if (symbol_conf.event_group && |
| @@ -427,7 +436,7 @@ static void report__collapse_hists(struct report *rep) | |||
| 427 | ui_progress__init(&prog, rep->nr_entries, "Merging related events..."); | 436 | ui_progress__init(&prog, rep->nr_entries, "Merging related events..."); |
| 428 | 437 | ||
| 429 | evlist__for_each(rep->session->evlist, pos) { | 438 | evlist__for_each(rep->session->evlist, pos) { |
| 430 | struct hists *hists = &pos->hists; | 439 | struct hists *hists = evsel__hists(pos); |
| 431 | 440 | ||
| 432 | if (pos->idx == 0) | 441 | if (pos->idx == 0) |
| 433 | hists->symbol_filter_str = rep->symbol_filter_str; | 442 | hists->symbol_filter_str = rep->symbol_filter_str; |
| @@ -437,7 +446,7 @@ static void report__collapse_hists(struct report *rep) | |||
| 437 | /* Non-group events are considered as leader */ | 446 | /* Non-group events are considered as leader */ |
| 438 | if (symbol_conf.event_group && | 447 | if (symbol_conf.event_group && |
| 439 | !perf_evsel__is_group_leader(pos)) { | 448 | !perf_evsel__is_group_leader(pos)) { |
| 440 | struct hists *leader_hists = &pos->leader->hists; | 449 | struct hists *leader_hists = evsel__hists(pos->leader); |
| 441 | 450 | ||
| 442 | hists__match(leader_hists, hists); | 451 | hists__match(leader_hists, hists); |
| 443 | hists__link(leader_hists, hists); | 452 | hists__link(leader_hists, hists); |
| @@ -485,6 +494,7 @@ static int __cmd_report(struct report *rep) | |||
| 485 | 494 | ||
| 486 | if (dump_trace) { | 495 | if (dump_trace) { |
| 487 | perf_session__fprintf_nr_events(session, stdout); | 496 | perf_session__fprintf_nr_events(session, stdout); |
| 497 | perf_evlist__fprintf_nr_events(session->evlist, stdout); | ||
| 488 | return 0; | 498 | return 0; |
| 489 | } | 499 | } |
| 490 | } | 500 | } |
| @@ -500,7 +510,7 @@ static int __cmd_report(struct report *rep) | |||
| 500 | } | 510 | } |
| 501 | 511 | ||
| 502 | evlist__for_each(session->evlist, pos) | 512 | evlist__for_each(session->evlist, pos) |
| 503 | hists__output_resort(&pos->hists); | 513 | hists__output_resort(evsel__hists(pos)); |
| 504 | 514 | ||
| 505 | return report__browse_hists(rep); | 515 | return report__browse_hists(rep); |
| 506 | } | 516 | } |
| @@ -565,7 +575,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 565 | struct stat st; | 575 | struct stat st; |
| 566 | bool has_br_stack = false; | 576 | bool has_br_stack = false; |
| 567 | int branch_mode = -1; | 577 | int branch_mode = -1; |
| 568 | int ret = -1; | ||
| 569 | char callchain_default_opt[] = "fractal,0.5,callee"; | 578 | char callchain_default_opt[] = "fractal,0.5,callee"; |
| 570 | const char * const report_usage[] = { | 579 | const char * const report_usage[] = { |
| 571 | "perf report [<options>]", | 580 | "perf report [<options>]", |
| @@ -692,6 +701,10 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 692 | struct perf_data_file file = { | 701 | struct perf_data_file file = { |
| 693 | .mode = PERF_DATA_MODE_READ, | 702 | .mode = PERF_DATA_MODE_READ, |
| 694 | }; | 703 | }; |
| 704 | int ret = hists__init(); | ||
| 705 | |||
| 706 | if (ret < 0) | ||
| 707 | return ret; | ||
| 695 | 708 | ||
| 696 | perf_config(report__config, &report); | 709 | perf_config(report__config, &report); |
| 697 | 710 | ||
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 9c9287fbf8e9..891c3930080e 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
| @@ -1431,9 +1431,6 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool __maybe_ | |||
| 1431 | { | 1431 | { |
| 1432 | int err = 0; | 1432 | int err = 0; |
| 1433 | 1433 | ||
| 1434 | evsel->hists.stats.total_period += sample->period; | ||
| 1435 | hists__inc_nr_samples(&evsel->hists, true); | ||
| 1436 | |||
| 1437 | if (evsel->handler != NULL) { | 1434 | if (evsel->handler != NULL) { |
| 1438 | tracepoint_handler f = evsel->handler; | 1435 | tracepoint_handler f = evsel->handler; |
| 1439 | err = f(tool, evsel, sample, machine); | 1436 | err = f(tool, evsel, sample, machine); |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index b9b9e58a6c39..9708a1290571 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
| @@ -44,6 +44,7 @@ enum perf_output_field { | |||
| 44 | PERF_OUTPUT_ADDR = 1U << 10, | 44 | PERF_OUTPUT_ADDR = 1U << 10, |
| 45 | PERF_OUTPUT_SYMOFFSET = 1U << 11, | 45 | PERF_OUTPUT_SYMOFFSET = 1U << 11, |
| 46 | PERF_OUTPUT_SRCLINE = 1U << 12, | 46 | PERF_OUTPUT_SRCLINE = 1U << 12, |
| 47 | PERF_OUTPUT_PERIOD = 1U << 13, | ||
| 47 | }; | 48 | }; |
| 48 | 49 | ||
| 49 | struct output_option { | 50 | struct output_option { |
| @@ -63,6 +64,7 @@ struct output_option { | |||
| 63 | {.str = "addr", .field = PERF_OUTPUT_ADDR}, | 64 | {.str = "addr", .field = PERF_OUTPUT_ADDR}, |
| 64 | {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, | 65 | {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, |
| 65 | {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, | 66 | {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, |
| 67 | {.str = "period", .field = PERF_OUTPUT_PERIOD}, | ||
| 66 | }; | 68 | }; |
| 67 | 69 | ||
| 68 | /* default set to maintain compatibility with current format */ | 70 | /* default set to maintain compatibility with current format */ |
| @@ -80,7 +82,8 @@ static struct { | |||
| 80 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | | 82 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | |
| 81 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | | 83 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | |
| 82 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | | 84 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | |
| 83 | PERF_OUTPUT_SYM | PERF_OUTPUT_DSO, | 85 | PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | |
| 86 | PERF_OUTPUT_PERIOD, | ||
| 84 | 87 | ||
| 85 | .invalid_fields = PERF_OUTPUT_TRACE, | 88 | .invalid_fields = PERF_OUTPUT_TRACE, |
| 86 | }, | 89 | }, |
| @@ -91,7 +94,8 @@ static struct { | |||
| 91 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | | 94 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | |
| 92 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | | 95 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | |
| 93 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | | 96 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | |
| 94 | PERF_OUTPUT_SYM | PERF_OUTPUT_DSO, | 97 | PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | |
| 98 | PERF_OUTPUT_PERIOD, | ||
| 95 | 99 | ||
| 96 | .invalid_fields = PERF_OUTPUT_TRACE, | 100 | .invalid_fields = PERF_OUTPUT_TRACE, |
| 97 | }, | 101 | }, |
| @@ -110,7 +114,8 @@ static struct { | |||
| 110 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | | 114 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | |
| 111 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | | 115 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | |
| 112 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | | 116 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | |
| 113 | PERF_OUTPUT_SYM | PERF_OUTPUT_DSO, | 117 | PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | |
| 118 | PERF_OUTPUT_PERIOD, | ||
| 114 | 119 | ||
| 115 | .invalid_fields = PERF_OUTPUT_TRACE, | 120 | .invalid_fields = PERF_OUTPUT_TRACE, |
| 116 | }, | 121 | }, |
| @@ -229,6 +234,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, | |||
| 229 | PERF_OUTPUT_CPU)) | 234 | PERF_OUTPUT_CPU)) |
| 230 | return -EINVAL; | 235 | return -EINVAL; |
| 231 | 236 | ||
| 237 | if (PRINT_FIELD(PERIOD) && | ||
| 238 | perf_evsel__check_stype(evsel, PERF_SAMPLE_PERIOD, "PERIOD", | ||
| 239 | PERF_OUTPUT_PERIOD)) | ||
| 240 | return -EINVAL; | ||
| 241 | |||
| 232 | return 0; | 242 | return 0; |
| 233 | } | 243 | } |
| 234 | 244 | ||
| @@ -448,6 +458,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample, | |||
| 448 | 458 | ||
| 449 | print_sample_start(sample, thread, evsel); | 459 | print_sample_start(sample, thread, evsel); |
| 450 | 460 | ||
| 461 | if (PRINT_FIELD(PERIOD)) | ||
| 462 | printf("%10" PRIu64 " ", sample->period); | ||
| 463 | |||
| 451 | if (PRINT_FIELD(EVNAME)) { | 464 | if (PRINT_FIELD(EVNAME)) { |
| 452 | const char *evname = perf_evsel__name(evsel); | 465 | const char *evname = perf_evsel__name(evsel); |
| 453 | printf("%s: ", evname ? evname : "[unknown]"); | 466 | printf("%s: ", evname ? evname : "[unknown]"); |
| @@ -572,7 +585,6 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, | |||
| 572 | 585 | ||
| 573 | scripting_ops->process_event(event, sample, evsel, thread, &al); | 586 | scripting_ops->process_event(event, sample, evsel, thread, &al); |
| 574 | 587 | ||
| 575 | evsel->hists.stats.total_period += sample->period; | ||
| 576 | return 0; | 588 | return 0; |
| 577 | } | 589 | } |
| 578 | 590 | ||
| @@ -1544,7 +1556,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 1544 | "comma separated output fields prepend with 'type:'. " | 1556 | "comma separated output fields prepend with 'type:'. " |
| 1545 | "Valid types: hw,sw,trace,raw. " | 1557 | "Valid types: hw,sw,trace,raw. " |
| 1546 | "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," | 1558 | "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," |
| 1547 | "addr,symoff", parse_output_fields), | 1559 | "addr,symoff,period", parse_output_fields), |
| 1548 | OPT_BOOLEAN('a', "all-cpus", &system_wide, | 1560 | OPT_BOOLEAN('a', "all-cpus", &system_wide, |
| 1549 | "system-wide collection from all CPUs"), | 1561 | "system-wide collection from all CPUs"), |
| 1550 | OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", | 1562 | OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index b22c62f80078..055ce9232c9e 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | #include "perf.h" | 44 | #include "perf.h" |
| 45 | #include "builtin.h" | 45 | #include "builtin.h" |
| 46 | #include "util/cgroup.h" | ||
| 46 | #include "util/util.h" | 47 | #include "util/util.h" |
| 47 | #include "util/parse-options.h" | 48 | #include "util/parse-options.h" |
| 48 | #include "util/parse-events.h" | 49 | #include "util/parse-events.h" |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index fc3d55f832ac..0aa7747ff139 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -251,6 +251,7 @@ static void perf_top__print_sym_table(struct perf_top *top) | |||
| 251 | char bf[160]; | 251 | char bf[160]; |
| 252 | int printed = 0; | 252 | int printed = 0; |
| 253 | const int win_width = top->winsize.ws_col - 1; | 253 | const int win_width = top->winsize.ws_col - 1; |
| 254 | struct hists *hists = evsel__hists(top->sym_evsel); | ||
| 254 | 255 | ||
| 255 | puts(CONSOLE_CLEAR); | 256 | puts(CONSOLE_CLEAR); |
| 256 | 257 | ||
| @@ -261,13 +262,13 @@ static void perf_top__print_sym_table(struct perf_top *top) | |||
| 261 | 262 | ||
| 262 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); | 263 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); |
| 263 | 264 | ||
| 264 | if (top->sym_evsel->hists.stats.nr_lost_warned != | 265 | if (hists->stats.nr_lost_warned != |
| 265 | top->sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]) { | 266 | hists->stats.nr_events[PERF_RECORD_LOST]) { |
| 266 | top->sym_evsel->hists.stats.nr_lost_warned = | 267 | hists->stats.nr_lost_warned = |
| 267 | top->sym_evsel->hists.stats.nr_events[PERF_RECORD_LOST]; | 268 | hists->stats.nr_events[PERF_RECORD_LOST]; |
| 268 | color_fprintf(stdout, PERF_COLOR_RED, | 269 | color_fprintf(stdout, PERF_COLOR_RED, |
| 269 | "WARNING: LOST %d chunks, Check IO/CPU overload", | 270 | "WARNING: LOST %d chunks, Check IO/CPU overload", |
| 270 | top->sym_evsel->hists.stats.nr_lost_warned); | 271 | hists->stats.nr_lost_warned); |
| 271 | ++printed; | 272 | ++printed; |
| 272 | } | 273 | } |
| 273 | 274 | ||
| @@ -277,21 +278,18 @@ static void perf_top__print_sym_table(struct perf_top *top) | |||
| 277 | } | 278 | } |
| 278 | 279 | ||
| 279 | if (top->zero) { | 280 | if (top->zero) { |
| 280 | hists__delete_entries(&top->sym_evsel->hists); | 281 | hists__delete_entries(hists); |
| 281 | } else { | 282 | } else { |
| 282 | hists__decay_entries(&top->sym_evsel->hists, | 283 | hists__decay_entries(hists, top->hide_user_symbols, |
| 283 | top->hide_user_symbols, | ||
| 284 | top->hide_kernel_symbols); | 284 | top->hide_kernel_symbols); |
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | hists__collapse_resort(&top->sym_evsel->hists, NULL); | 287 | hists__collapse_resort(hists, NULL); |
| 288 | hists__output_resort(&top->sym_evsel->hists); | 288 | hists__output_resort(hists); |
| 289 | 289 | ||
| 290 | hists__output_recalc_col_len(&top->sym_evsel->hists, | 290 | hists__output_recalc_col_len(hists, top->print_entries - printed); |
| 291 | top->print_entries - printed); | ||
| 292 | putchar('\n'); | 291 | putchar('\n'); |
| 293 | hists__fprintf(&top->sym_evsel->hists, false, | 292 | hists__fprintf(hists, false, top->print_entries - printed, win_width, |
| 294 | top->print_entries - printed, win_width, | ||
| 295 | top->min_percent, stdout); | 293 | top->min_percent, stdout); |
| 296 | } | 294 | } |
| 297 | 295 | ||
| @@ -334,6 +332,7 @@ static void perf_top__prompt_symbol(struct perf_top *top, const char *msg) | |||
| 334 | { | 332 | { |
| 335 | char *buf = malloc(0), *p; | 333 | char *buf = malloc(0), *p; |
| 336 | struct hist_entry *syme = top->sym_filter_entry, *n, *found = NULL; | 334 | struct hist_entry *syme = top->sym_filter_entry, *n, *found = NULL; |
| 335 | struct hists *hists = evsel__hists(top->sym_evsel); | ||
| 337 | struct rb_node *next; | 336 | struct rb_node *next; |
| 338 | size_t dummy = 0; | 337 | size_t dummy = 0; |
| 339 | 338 | ||
| @@ -351,7 +350,7 @@ static void perf_top__prompt_symbol(struct perf_top *top, const char *msg) | |||
| 351 | if (p) | 350 | if (p) |
| 352 | *p = 0; | 351 | *p = 0; |
| 353 | 352 | ||
| 354 | next = rb_first(&top->sym_evsel->hists.entries); | 353 | next = rb_first(&hists->entries); |
| 355 | while (next) { | 354 | while (next) { |
| 356 | n = rb_entry(next, struct hist_entry, rb_node); | 355 | n = rb_entry(next, struct hist_entry, rb_node); |
| 357 | if (n->ms.sym && !strcmp(buf, n->ms.sym->name)) { | 356 | if (n->ms.sym && !strcmp(buf, n->ms.sym->name)) { |
| @@ -538,21 +537,24 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) | |||
| 538 | static void perf_top__sort_new_samples(void *arg) | 537 | static void perf_top__sort_new_samples(void *arg) |
| 539 | { | 538 | { |
| 540 | struct perf_top *t = arg; | 539 | struct perf_top *t = arg; |
| 540 | struct hists *hists; | ||
| 541 | |||
| 541 | perf_top__reset_sample_counters(t); | 542 | perf_top__reset_sample_counters(t); |
| 542 | 543 | ||
| 543 | if (t->evlist->selected != NULL) | 544 | if (t->evlist->selected != NULL) |
| 544 | t->sym_evsel = t->evlist->selected; | 545 | t->sym_evsel = t->evlist->selected; |
| 545 | 546 | ||
| 547 | hists = evsel__hists(t->sym_evsel); | ||
| 548 | |||
| 546 | if (t->zero) { | 549 | if (t->zero) { |
| 547 | hists__delete_entries(&t->sym_evsel->hists); | 550 | hists__delete_entries(hists); |
| 548 | } else { | 551 | } else { |
| 549 | hists__decay_entries(&t->sym_evsel->hists, | 552 | hists__decay_entries(hists, t->hide_user_symbols, |
| 550 | t->hide_user_symbols, | ||
| 551 | t->hide_kernel_symbols); | 553 | t->hide_kernel_symbols); |
| 552 | } | 554 | } |
| 553 | 555 | ||
| 554 | hists__collapse_resort(&t->sym_evsel->hists, NULL); | 556 | hists__collapse_resort(hists, NULL); |
| 555 | hists__output_resort(&t->sym_evsel->hists); | 557 | hists__output_resort(hists); |
| 556 | } | 558 | } |
| 557 | 559 | ||
| 558 | static void *display_thread_tui(void *arg) | 560 | static void *display_thread_tui(void *arg) |
| @@ -573,8 +575,10 @@ static void *display_thread_tui(void *arg) | |||
| 573 | * Zooming in/out UIDs. For now juse use whatever the user passed | 575 | * Zooming in/out UIDs. For now juse use whatever the user passed |
| 574 | * via --uid. | 576 | * via --uid. |
| 575 | */ | 577 | */ |
| 576 | evlist__for_each(top->evlist, pos) | 578 | evlist__for_each(top->evlist, pos) { |
| 577 | pos->hists.uid_filter_str = top->record_opts.target.uid_str; | 579 | struct hists *hists = evsel__hists(pos); |
| 580 | hists->uid_filter_str = top->record_opts.target.uid_str; | ||
| 581 | } | ||
| 578 | 582 | ||
| 579 | perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent, | 583 | perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent, |
| 580 | &top->session->header.env); | 584 | &top->session->header.env); |
| @@ -768,6 +772,7 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
| 768 | } | 772 | } |
| 769 | 773 | ||
| 770 | if (al.sym == NULL || !al.sym->ignore) { | 774 | if (al.sym == NULL || !al.sym->ignore) { |
| 775 | struct hists *hists = evsel__hists(evsel); | ||
| 771 | struct hist_entry_iter iter = { | 776 | struct hist_entry_iter iter = { |
| 772 | .add_entry_cb = hist_iter__top_callback, | 777 | .add_entry_cb = hist_iter__top_callback, |
| 773 | }; | 778 | }; |
| @@ -777,14 +782,14 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
| 777 | else | 782 | else |
| 778 | iter.ops = &hist_iter_normal; | 783 | iter.ops = &hist_iter_normal; |
| 779 | 784 | ||
| 780 | pthread_mutex_lock(&evsel->hists.lock); | 785 | pthread_mutex_lock(&hists->lock); |
| 781 | 786 | ||
| 782 | err = hist_entry_iter__add(&iter, &al, evsel, sample, | 787 | err = hist_entry_iter__add(&iter, &al, evsel, sample, |
| 783 | top->max_stack, top); | 788 | top->max_stack, top); |
| 784 | if (err < 0) | 789 | if (err < 0) |
| 785 | pr_err("Problem incrementing symbol period, skipping event\n"); | 790 | pr_err("Problem incrementing symbol period, skipping event\n"); |
| 786 | 791 | ||
| 787 | pthread_mutex_unlock(&evsel->hists.lock); | 792 | pthread_mutex_unlock(&hists->lock); |
| 788 | } | 793 | } |
| 789 | 794 | ||
| 790 | return; | 795 | return; |
| @@ -849,7 +854,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | |||
| 849 | perf_event__process_sample(&top->tool, event, evsel, | 854 | perf_event__process_sample(&top->tool, event, evsel, |
| 850 | &sample, machine); | 855 | &sample, machine); |
| 851 | } else if (event->header.type < PERF_RECORD_MAX) { | 856 | } else if (event->header.type < PERF_RECORD_MAX) { |
| 852 | hists__inc_nr_events(&evsel->hists, event->header.type); | 857 | hists__inc_nr_events(evsel__hists(evsel), event->header.type); |
| 853 | machine__process_event(machine, event, &sample); | 858 | machine__process_event(machine, event, &sample); |
| 854 | } else | 859 | } else |
| 855 | ++session->stats.nr_unknown_events; | 860 | ++session->stats.nr_unknown_events; |
| @@ -1042,7 +1047,6 @@ parse_percent_limit(const struct option *opt, const char *arg, | |||
| 1042 | 1047 | ||
| 1043 | int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | 1048 | int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) |
| 1044 | { | 1049 | { |
| 1045 | int status = -1; | ||
| 1046 | char errbuf[BUFSIZ]; | 1050 | char errbuf[BUFSIZ]; |
| 1047 | struct perf_top top = { | 1051 | struct perf_top top = { |
| 1048 | .count_filter = 5, | 1052 | .count_filter = 5, |
| @@ -1160,6 +1164,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 1160 | "perf top [<options>]", | 1164 | "perf top [<options>]", |
| 1161 | NULL | 1165 | NULL |
| 1162 | }; | 1166 | }; |
| 1167 | int status = hists__init(); | ||
| 1168 | |||
| 1169 | if (status < 0) | ||
| 1170 | return status; | ||
| 1163 | 1171 | ||
| 1164 | top.evlist = perf_evlist__new(); | 1172 | top.evlist = perf_evlist__new(); |
| 1165 | if (top.evlist == NULL) | 1173 | if (top.evlist == NULL) |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 09bcf2393910..fb126459b134 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -1189,13 +1189,13 @@ static struct thread_trace *thread__trace(struct thread *thread, FILE *fp) | |||
| 1189 | if (thread == NULL) | 1189 | if (thread == NULL) |
| 1190 | goto fail; | 1190 | goto fail; |
| 1191 | 1191 | ||
| 1192 | if (thread->priv == NULL) | 1192 | if (thread__priv(thread) == NULL) |
| 1193 | thread->priv = thread_trace__new(); | 1193 | thread__set_priv(thread, thread_trace__new()); |
| 1194 | 1194 | ||
| 1195 | if (thread->priv == NULL) | 1195 | if (thread__priv(thread) == NULL) |
| 1196 | goto fail; | 1196 | goto fail; |
| 1197 | 1197 | ||
| 1198 | ttrace = thread->priv; | 1198 | ttrace = thread__priv(thread); |
| 1199 | ++ttrace->nr_events; | 1199 | ++ttrace->nr_events; |
| 1200 | 1200 | ||
| 1201 | return ttrace; | 1201 | return ttrace; |
| @@ -1248,7 +1248,7 @@ struct trace { | |||
| 1248 | 1248 | ||
| 1249 | static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) | 1249 | static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) |
| 1250 | { | 1250 | { |
| 1251 | struct thread_trace *ttrace = thread->priv; | 1251 | struct thread_trace *ttrace = thread__priv(thread); |
| 1252 | 1252 | ||
| 1253 | if (fd > ttrace->paths.max) { | 1253 | if (fd > ttrace->paths.max) { |
| 1254 | char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *)); | 1254 | char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *)); |
| @@ -1301,7 +1301,7 @@ static int thread__read_fd_path(struct thread *thread, int fd) | |||
| 1301 | static const char *thread__fd_path(struct thread *thread, int fd, | 1301 | static const char *thread__fd_path(struct thread *thread, int fd, |
| 1302 | struct trace *trace) | 1302 | struct trace *trace) |
| 1303 | { | 1303 | { |
| 1304 | struct thread_trace *ttrace = thread->priv; | 1304 | struct thread_trace *ttrace = thread__priv(thread); |
| 1305 | 1305 | ||
| 1306 | if (ttrace == NULL) | 1306 | if (ttrace == NULL) |
| 1307 | return NULL; | 1307 | return NULL; |
| @@ -1338,7 +1338,7 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, | |||
| 1338 | { | 1338 | { |
| 1339 | int fd = arg->val; | 1339 | int fd = arg->val; |
| 1340 | size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); | 1340 | size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); |
| 1341 | struct thread_trace *ttrace = arg->thread->priv; | 1341 | struct thread_trace *ttrace = thread__priv(arg->thread); |
| 1342 | 1342 | ||
| 1343 | if (ttrace && fd >= 0 && fd <= ttrace->paths.max) | 1343 | if (ttrace && fd >= 0 && fd <= ttrace->paths.max) |
| 1344 | zfree(&ttrace->paths.table[fd]); | 1344 | zfree(&ttrace->paths.table[fd]); |
| @@ -2381,7 +2381,7 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv) | |||
| 2381 | FILE *fp = data->fp; | 2381 | FILE *fp = data->fp; |
| 2382 | size_t printed = data->printed; | 2382 | size_t printed = data->printed; |
| 2383 | struct trace *trace = data->trace; | 2383 | struct trace *trace = data->trace; |
| 2384 | struct thread_trace *ttrace = thread->priv; | 2384 | struct thread_trace *ttrace = thread__priv(thread); |
| 2385 | double ratio; | 2385 | double ratio; |
| 2386 | 2386 | ||
| 2387 | if (ttrace == NULL) | 2387 | if (ttrace == NULL) |
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index ac655b0700e7..162c978f1491 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <unistd.h> | 6 | #include <unistd.h> |
| 7 | #include <string.h> | 7 | #include <string.h> |
| 8 | #include "builtin.h" | 8 | #include "builtin.h" |
| 9 | #include "hist.h" | ||
| 9 | #include "intlist.h" | 10 | #include "intlist.h" |
| 10 | #include "tests.h" | 11 | #include "tests.h" |
| 11 | #include "debug.h" | 12 | #include "debug.h" |
| @@ -302,6 +303,10 @@ int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 302 | OPT_END() | 303 | OPT_END() |
| 303 | }; | 304 | }; |
| 304 | struct intlist *skiplist = NULL; | 305 | struct intlist *skiplist = NULL; |
| 306 | int ret = hists__init(); | ||
| 307 | |||
| 308 | if (ret < 0) | ||
| 309 | return ret; | ||
| 305 | 310 | ||
| 306 | argc = parse_options(argc, argv, test_options, test_usage, 0); | 311 | argc = parse_options(argc, argv, test_options, test_usage, 0); |
| 307 | if (argc >= 1 && !strcmp(argv[0], "list")) | 312 | if (argc >= 1 && !strcmp(argv[0], "list")) |
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 96adb730b744..fc25e57f4a5d 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "perf_regs.h" | 9 | #include "perf_regs.h" |
| 10 | #include "map.h" | 10 | #include "map.h" |
| 11 | #include "thread.h" | 11 | #include "thread.h" |
| 12 | #include "callchain.h" | ||
| 12 | 13 | ||
| 13 | static int mmap_handler(struct perf_tool *tool __maybe_unused, | 14 | static int mmap_handler(struct perf_tool *tool __maybe_unused, |
| 14 | union perf_event *event, | 15 | union perf_event *event, |
| @@ -120,6 +121,8 @@ int test__dwarf_unwind(void) | |||
| 120 | return -1; | 121 | return -1; |
| 121 | } | 122 | } |
| 122 | 123 | ||
| 124 | callchain_param.record_mode = CALLCHAIN_DWARF; | ||
| 125 | |||
| 123 | if (init_live_machine(machine)) { | 126 | if (init_live_machine(machine)) { |
| 124 | pr_err("Could not init machine\n"); | 127 | pr_err("Could not init machine\n"); |
| 125 | goto out; | 128 | goto out; |
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 0ac240db2e24..614d5c4978ab 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c | |||
| @@ -245,7 +245,7 @@ static int do_test(struct hists *hists, struct result *expected, size_t nr_expec | |||
| 245 | static int test1(struct perf_evsel *evsel, struct machine *machine) | 245 | static int test1(struct perf_evsel *evsel, struct machine *machine) |
| 246 | { | 246 | { |
| 247 | int err; | 247 | int err; |
| 248 | struct hists *hists = &evsel->hists; | 248 | struct hists *hists = evsel__hists(evsel); |
| 249 | /* | 249 | /* |
| 250 | * expected output: | 250 | * expected output: |
| 251 | * | 251 | * |
| @@ -295,7 +295,7 @@ out: | |||
| 295 | static int test2(struct perf_evsel *evsel, struct machine *machine) | 295 | static int test2(struct perf_evsel *evsel, struct machine *machine) |
| 296 | { | 296 | { |
| 297 | int err; | 297 | int err; |
| 298 | struct hists *hists = &evsel->hists; | 298 | struct hists *hists = evsel__hists(evsel); |
| 299 | /* | 299 | /* |
| 300 | * expected output: | 300 | * expected output: |
| 301 | * | 301 | * |
| @@ -442,7 +442,7 @@ out: | |||
| 442 | static int test3(struct perf_evsel *evsel, struct machine *machine) | 442 | static int test3(struct perf_evsel *evsel, struct machine *machine) |
| 443 | { | 443 | { |
| 444 | int err; | 444 | int err; |
| 445 | struct hists *hists = &evsel->hists; | 445 | struct hists *hists = evsel__hists(evsel); |
| 446 | /* | 446 | /* |
| 447 | * expected output: | 447 | * expected output: |
| 448 | * | 448 | * |
| @@ -498,7 +498,7 @@ out: | |||
| 498 | static int test4(struct perf_evsel *evsel, struct machine *machine) | 498 | static int test4(struct perf_evsel *evsel, struct machine *machine) |
| 499 | { | 499 | { |
| 500 | int err; | 500 | int err; |
| 501 | struct hists *hists = &evsel->hists; | 501 | struct hists *hists = evsel__hists(evsel); |
| 502 | /* | 502 | /* |
| 503 | * expected output: | 503 | * expected output: |
| 504 | * | 504 | * |
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 821f581fd930..5a31787cc6b9 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c | |||
| @@ -66,11 +66,12 @@ static int add_hist_entries(struct perf_evlist *evlist, | |||
| 66 | .ops = &hist_iter_normal, | 66 | .ops = &hist_iter_normal, |
| 67 | .hide_unresolved = false, | 67 | .hide_unresolved = false, |
| 68 | }; | 68 | }; |
| 69 | struct hists *hists = evsel__hists(evsel); | ||
| 69 | 70 | ||
| 70 | /* make sure it has no filter at first */ | 71 | /* make sure it has no filter at first */ |
| 71 | evsel->hists.thread_filter = NULL; | 72 | hists->thread_filter = NULL; |
| 72 | evsel->hists.dso_filter = NULL; | 73 | hists->dso_filter = NULL; |
| 73 | evsel->hists.symbol_filter_str = NULL; | 74 | hists->symbol_filter_str = NULL; |
| 74 | 75 | ||
| 75 | sample.pid = fake_samples[i].pid; | 76 | sample.pid = fake_samples[i].pid; |
| 76 | sample.tid = fake_samples[i].pid; | 77 | sample.tid = fake_samples[i].pid; |
| @@ -134,7 +135,7 @@ int test__hists_filter(void) | |||
| 134 | goto out; | 135 | goto out; |
| 135 | 136 | ||
| 136 | evlist__for_each(evlist, evsel) { | 137 | evlist__for_each(evlist, evsel) { |
| 137 | struct hists *hists = &evsel->hists; | 138 | struct hists *hists = evsel__hists(evsel); |
| 138 | 139 | ||
| 139 | hists__collapse_resort(hists, NULL); | 140 | hists__collapse_resort(hists, NULL); |
| 140 | hists__output_resort(hists); | 141 | hists__output_resort(hists); |
| @@ -160,7 +161,7 @@ int test__hists_filter(void) | |||
| 160 | hists->stats.total_non_filtered_period); | 161 | hists->stats.total_non_filtered_period); |
| 161 | 162 | ||
| 162 | /* now applying thread filter for 'bash' */ | 163 | /* now applying thread filter for 'bash' */ |
| 163 | evsel->hists.thread_filter = fake_samples[9].thread; | 164 | hists->thread_filter = fake_samples[9].thread; |
| 164 | hists__filter_by_thread(hists); | 165 | hists__filter_by_thread(hists); |
| 165 | 166 | ||
| 166 | if (verbose > 2) { | 167 | if (verbose > 2) { |
| @@ -185,11 +186,11 @@ int test__hists_filter(void) | |||
| 185 | hists->stats.total_non_filtered_period == 400); | 186 | hists->stats.total_non_filtered_period == 400); |
| 186 | 187 | ||
| 187 | /* remove thread filter first */ | 188 | /* remove thread filter first */ |
| 188 | evsel->hists.thread_filter = NULL; | 189 | hists->thread_filter = NULL; |
| 189 | hists__filter_by_thread(hists); | 190 | hists__filter_by_thread(hists); |
| 190 | 191 | ||
| 191 | /* now applying dso filter for 'kernel' */ | 192 | /* now applying dso filter for 'kernel' */ |
| 192 | evsel->hists.dso_filter = fake_samples[0].map->dso; | 193 | hists->dso_filter = fake_samples[0].map->dso; |
| 193 | hists__filter_by_dso(hists); | 194 | hists__filter_by_dso(hists); |
| 194 | 195 | ||
| 195 | if (verbose > 2) { | 196 | if (verbose > 2) { |
| @@ -214,7 +215,7 @@ int test__hists_filter(void) | |||
| 214 | hists->stats.total_non_filtered_period == 300); | 215 | hists->stats.total_non_filtered_period == 300); |
| 215 | 216 | ||
| 216 | /* remove dso filter first */ | 217 | /* remove dso filter first */ |
| 217 | evsel->hists.dso_filter = NULL; | 218 | hists->dso_filter = NULL; |
| 218 | hists__filter_by_dso(hists); | 219 | hists__filter_by_dso(hists); |
| 219 | 220 | ||
| 220 | /* | 221 | /* |
| @@ -224,7 +225,7 @@ int test__hists_filter(void) | |||
| 224 | * be counted as a separate entry but the sample count and | 225 | * be counted as a separate entry but the sample count and |
| 225 | * total period will be remained. | 226 | * total period will be remained. |
| 226 | */ | 227 | */ |
| 227 | evsel->hists.symbol_filter_str = "main"; | 228 | hists->symbol_filter_str = "main"; |
| 228 | hists__filter_by_symbol(hists); | 229 | hists__filter_by_symbol(hists); |
| 229 | 230 | ||
| 230 | if (verbose > 2) { | 231 | if (verbose > 2) { |
| @@ -249,8 +250,8 @@ int test__hists_filter(void) | |||
| 249 | hists->stats.total_non_filtered_period == 300); | 250 | hists->stats.total_non_filtered_period == 300); |
| 250 | 251 | ||
| 251 | /* now applying all filters at once. */ | 252 | /* now applying all filters at once. */ |
| 252 | evsel->hists.thread_filter = fake_samples[1].thread; | 253 | hists->thread_filter = fake_samples[1].thread; |
| 253 | evsel->hists.dso_filter = fake_samples[1].map->dso; | 254 | hists->dso_filter = fake_samples[1].map->dso; |
| 254 | hists__filter_by_thread(hists); | 255 | hists__filter_by_thread(hists); |
| 255 | hists__filter_by_dso(hists); | 256 | hists__filter_by_dso(hists); |
| 256 | 257 | ||
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index d4b34b0f50a2..278ba8344c23 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c | |||
| @@ -73,6 +73,8 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) | |||
| 73 | * "bash [libc] malloc" so total 9 entries will be in the tree. | 73 | * "bash [libc] malloc" so total 9 entries will be in the tree. |
| 74 | */ | 74 | */ |
| 75 | evlist__for_each(evlist, evsel) { | 75 | evlist__for_each(evlist, evsel) { |
| 76 | struct hists *hists = evsel__hists(evsel); | ||
| 77 | |||
| 76 | for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { | 78 | for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { |
| 77 | const union perf_event event = { | 79 | const union perf_event event = { |
| 78 | .header = { | 80 | .header = { |
| @@ -87,7 +89,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) | |||
| 87 | &sample) < 0) | 89 | &sample) < 0) |
| 88 | goto out; | 90 | goto out; |
| 89 | 91 | ||
| 90 | he = __hists__add_entry(&evsel->hists, &al, NULL, | 92 | he = __hists__add_entry(hists, &al, NULL, |
| 91 | NULL, NULL, 1, 1, 0, true); | 93 | NULL, NULL, 1, 1, 0, true); |
| 92 | if (he == NULL) | 94 | if (he == NULL) |
| 93 | goto out; | 95 | goto out; |
| @@ -111,7 +113,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) | |||
| 111 | &sample) < 0) | 113 | &sample) < 0) |
| 112 | goto out; | 114 | goto out; |
| 113 | 115 | ||
| 114 | he = __hists__add_entry(&evsel->hists, &al, NULL, | 116 | he = __hists__add_entry(hists, &al, NULL, |
| 115 | NULL, NULL, 1, 1, 0, true); | 117 | NULL, NULL, 1, 1, 0, true); |
| 116 | if (he == NULL) | 118 | if (he == NULL) |
| 117 | goto out; | 119 | goto out; |
| @@ -271,6 +273,7 @@ static int validate_link(struct hists *leader, struct hists *other) | |||
| 271 | int test__hists_link(void) | 273 | int test__hists_link(void) |
| 272 | { | 274 | { |
| 273 | int err = -1; | 275 | int err = -1; |
| 276 | struct hists *hists, *first_hists; | ||
| 274 | struct machines machines; | 277 | struct machines machines; |
| 275 | struct machine *machine = NULL; | 278 | struct machine *machine = NULL; |
| 276 | struct perf_evsel *evsel, *first; | 279 | struct perf_evsel *evsel, *first; |
| @@ -306,24 +309,28 @@ int test__hists_link(void) | |||
| 306 | goto out; | 309 | goto out; |
| 307 | 310 | ||
| 308 | evlist__for_each(evlist, evsel) { | 311 | evlist__for_each(evlist, evsel) { |
| 309 | hists__collapse_resort(&evsel->hists, NULL); | 312 | hists = evsel__hists(evsel); |
| 313 | hists__collapse_resort(hists, NULL); | ||
| 310 | 314 | ||
| 311 | if (verbose > 2) | 315 | if (verbose > 2) |
| 312 | print_hists_in(&evsel->hists); | 316 | print_hists_in(hists); |
| 313 | } | 317 | } |
| 314 | 318 | ||
| 315 | first = perf_evlist__first(evlist); | 319 | first = perf_evlist__first(evlist); |
| 316 | evsel = perf_evlist__last(evlist); | 320 | evsel = perf_evlist__last(evlist); |
| 317 | 321 | ||
| 322 | first_hists = evsel__hists(first); | ||
| 323 | hists = evsel__hists(evsel); | ||
| 324 | |||
| 318 | /* match common entries */ | 325 | /* match common entries */ |
| 319 | hists__match(&first->hists, &evsel->hists); | 326 | hists__match(first_hists, hists); |
| 320 | err = validate_match(&first->hists, &evsel->hists); | 327 | err = validate_match(first_hists, hists); |
| 321 | if (err) | 328 | if (err) |
| 322 | goto out; | 329 | goto out; |
| 323 | 330 | ||
| 324 | /* link common and/or dummy entries */ | 331 | /* link common and/or dummy entries */ |
| 325 | hists__link(&first->hists, &evsel->hists); | 332 | hists__link(first_hists, hists); |
| 326 | err = validate_link(&first->hists, &evsel->hists); | 333 | err = validate_link(first_hists, hists); |
| 327 | if (err) | 334 | if (err) |
| 328 | goto out; | 335 | goto out; |
| 329 | 336 | ||
diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index e3bbd6c54c1b..a748f2be1222 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c | |||
| @@ -122,7 +122,7 @@ typedef int (*test_fn_t)(struct perf_evsel *, struct machine *); | |||
| 122 | static int test1(struct perf_evsel *evsel, struct machine *machine) | 122 | static int test1(struct perf_evsel *evsel, struct machine *machine) |
| 123 | { | 123 | { |
| 124 | int err; | 124 | int err; |
| 125 | struct hists *hists = &evsel->hists; | 125 | struct hists *hists = evsel__hists(evsel); |
| 126 | struct hist_entry *he; | 126 | struct hist_entry *he; |
| 127 | struct rb_root *root; | 127 | struct rb_root *root; |
| 128 | struct rb_node *node; | 128 | struct rb_node *node; |
| @@ -159,7 +159,7 @@ static int test1(struct perf_evsel *evsel, struct machine *machine) | |||
| 159 | print_hists_out(hists); | 159 | print_hists_out(hists); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | root = &evsel->hists.entries; | 162 | root = &hists->entries; |
| 163 | node = rb_first(root); | 163 | node = rb_first(root); |
| 164 | he = rb_entry(node, struct hist_entry, rb_node); | 164 | he = rb_entry(node, struct hist_entry, rb_node); |
| 165 | TEST_ASSERT_VAL("Invalid hist entry", | 165 | TEST_ASSERT_VAL("Invalid hist entry", |
| @@ -224,7 +224,7 @@ out: | |||
| 224 | static int test2(struct perf_evsel *evsel, struct machine *machine) | 224 | static int test2(struct perf_evsel *evsel, struct machine *machine) |
| 225 | { | 225 | { |
| 226 | int err; | 226 | int err; |
| 227 | struct hists *hists = &evsel->hists; | 227 | struct hists *hists = evsel__hists(evsel); |
| 228 | struct hist_entry *he; | 228 | struct hist_entry *he; |
| 229 | struct rb_root *root; | 229 | struct rb_root *root; |
| 230 | struct rb_node *node; | 230 | struct rb_node *node; |
| @@ -259,7 +259,7 @@ static int test2(struct perf_evsel *evsel, struct machine *machine) | |||
| 259 | print_hists_out(hists); | 259 | print_hists_out(hists); |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | root = &evsel->hists.entries; | 262 | root = &hists->entries; |
| 263 | node = rb_first(root); | 263 | node = rb_first(root); |
| 264 | he = rb_entry(node, struct hist_entry, rb_node); | 264 | he = rb_entry(node, struct hist_entry, rb_node); |
| 265 | TEST_ASSERT_VAL("Invalid hist entry", | 265 | TEST_ASSERT_VAL("Invalid hist entry", |
| @@ -280,7 +280,7 @@ out: | |||
| 280 | static int test3(struct perf_evsel *evsel, struct machine *machine) | 280 | static int test3(struct perf_evsel *evsel, struct machine *machine) |
| 281 | { | 281 | { |
| 282 | int err; | 282 | int err; |
| 283 | struct hists *hists = &evsel->hists; | 283 | struct hists *hists = evsel__hists(evsel); |
| 284 | struct hist_entry *he; | 284 | struct hist_entry *he; |
| 285 | struct rb_root *root; | 285 | struct rb_root *root; |
| 286 | struct rb_node *node; | 286 | struct rb_node *node; |
| @@ -313,7 +313,7 @@ static int test3(struct perf_evsel *evsel, struct machine *machine) | |||
| 313 | print_hists_out(hists); | 313 | print_hists_out(hists); |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | root = &evsel->hists.entries; | 316 | root = &hists->entries; |
| 317 | node = rb_first(root); | 317 | node = rb_first(root); |
| 318 | he = rb_entry(node, struct hist_entry, rb_node); | 318 | he = rb_entry(node, struct hist_entry, rb_node); |
| 319 | TEST_ASSERT_VAL("Invalid hist entry", | 319 | TEST_ASSERT_VAL("Invalid hist entry", |
| @@ -354,7 +354,7 @@ out: | |||
| 354 | static int test4(struct perf_evsel *evsel, struct machine *machine) | 354 | static int test4(struct perf_evsel *evsel, struct machine *machine) |
| 355 | { | 355 | { |
| 356 | int err; | 356 | int err; |
| 357 | struct hists *hists = &evsel->hists; | 357 | struct hists *hists = evsel__hists(evsel); |
| 358 | struct hist_entry *he; | 358 | struct hist_entry *he; |
| 359 | struct rb_root *root; | 359 | struct rb_root *root; |
| 360 | struct rb_node *node; | 360 | struct rb_node *node; |
| @@ -391,7 +391,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) | |||
| 391 | print_hists_out(hists); | 391 | print_hists_out(hists); |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | root = &evsel->hists.entries; | 394 | root = &hists->entries; |
| 395 | node = rb_first(root); | 395 | node = rb_first(root); |
| 396 | he = rb_entry(node, struct hist_entry, rb_node); | 396 | he = rb_entry(node, struct hist_entry, rb_node); |
| 397 | TEST_ASSERT_VAL("Invalid hist entry", | 397 | TEST_ASSERT_VAL("Invalid hist entry", |
| @@ -456,7 +456,7 @@ out: | |||
| 456 | static int test5(struct perf_evsel *evsel, struct machine *machine) | 456 | static int test5(struct perf_evsel *evsel, struct machine *machine) |
| 457 | { | 457 | { |
| 458 | int err; | 458 | int err; |
| 459 | struct hists *hists = &evsel->hists; | 459 | struct hists *hists = evsel__hists(evsel); |
| 460 | struct hist_entry *he; | 460 | struct hist_entry *he; |
| 461 | struct rb_root *root; | 461 | struct rb_root *root; |
| 462 | struct rb_node *node; | 462 | struct rb_node *node; |
| @@ -494,7 +494,7 @@ static int test5(struct perf_evsel *evsel, struct machine *machine) | |||
| 494 | print_hists_out(hists); | 494 | print_hists_out(hists); |
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | root = &evsel->hists.entries; | 497 | root = &hists->entries; |
| 498 | node = rb_first(root); | 498 | node = rb_first(root); |
| 499 | he = rb_entry(node, struct hist_entry, rb_node); | 499 | he = rb_entry(node, struct hist_entry, rb_node); |
| 500 | 500 | ||
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 5941927a4b7f..7f2f51f93619 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c | |||
| @@ -457,6 +457,36 @@ static int test__checkevent_pmu_events(struct perf_evlist *evlist) | |||
| 457 | return 0; | 457 | return 0; |
| 458 | } | 458 | } |
| 459 | 459 | ||
| 460 | |||
| 461 | static int test__checkevent_pmu_events_mix(struct perf_evlist *evlist) | ||
| 462 | { | ||
| 463 | struct perf_evsel *evsel = perf_evlist__first(evlist); | ||
| 464 | |||
| 465 | /* pmu-event:u */ | ||
| 466 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); | ||
| 467 | TEST_ASSERT_VAL("wrong exclude_user", | ||
| 468 | !evsel->attr.exclude_user); | ||
| 469 | TEST_ASSERT_VAL("wrong exclude_kernel", | ||
| 470 | evsel->attr.exclude_kernel); | ||
| 471 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
| 472 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
| 473 | TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned); | ||
| 474 | |||
| 475 | /* cpu/pmu-event/u*/ | ||
| 476 | evsel = perf_evsel__next(evsel); | ||
| 477 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); | ||
| 478 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | ||
| 479 | TEST_ASSERT_VAL("wrong exclude_user", | ||
| 480 | !evsel->attr.exclude_user); | ||
| 481 | TEST_ASSERT_VAL("wrong exclude_kernel", | ||
| 482 | evsel->attr.exclude_kernel); | ||
| 483 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
| 484 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | ||
| 485 | TEST_ASSERT_VAL("wrong pinned", !evsel->attr.pinned); | ||
| 486 | |||
| 487 | return 0; | ||
| 488 | } | ||
| 489 | |||
| 460 | static int test__checkterms_simple(struct list_head *terms) | 490 | static int test__checkterms_simple(struct list_head *terms) |
| 461 | { | 491 | { |
| 462 | struct parse_events_term *term; | 492 | struct parse_events_term *term; |
| @@ -1554,6 +1584,12 @@ static int test_pmu_events(void) | |||
| 1554 | e.check = test__checkevent_pmu_events; | 1584 | e.check = test__checkevent_pmu_events; |
| 1555 | 1585 | ||
| 1556 | ret = test_event(&e); | 1586 | ret = test_event(&e); |
| 1587 | if (ret) | ||
| 1588 | break; | ||
| 1589 | snprintf(name, MAX_NAME, "%s:u,cpu/event=%s/u", ent->d_name, ent->d_name); | ||
| 1590 | e.name = name; | ||
| 1591 | e.check = test__checkevent_pmu_events_mix; | ||
| 1592 | ret = test_event(&e); | ||
| 1557 | #undef MAX_NAME | 1593 | #undef MAX_NAME |
| 1558 | } | 1594 | } |
| 1559 | 1595 | ||
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c index 89c16b988618..e8278c558d4a 100644 --- a/tools/perf/ui/browsers/header.c +++ b/tools/perf/ui/browsers/header.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #include "util/cache.h" | 1 | #include "util/cache.h" |
| 2 | #include "util/debug.h" | 2 | #include "util/debug.h" |
| 3 | #include "ui/browser.h" | 3 | #include "ui/browser.h" |
| 4 | #include "ui/keysyms.h" | ||
| 4 | #include "ui/ui.h" | 5 | #include "ui/ui.h" |
| 5 | #include "ui/util.h" | 6 | #include "ui/util.h" |
| 6 | #include "ui/libslang.h" | 7 | #include "ui/libslang.h" |
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 8f60a970404f..cfb976b3de3a 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
| @@ -35,7 +35,9 @@ struct hist_browser { | |||
| 35 | 35 | ||
| 36 | extern void hist_browser__init_hpp(void); | 36 | extern void hist_browser__init_hpp(void); |
| 37 | 37 | ||
| 38 | static int hists__browser_title(struct hists *hists, char *bf, size_t size); | 38 | static int hists__browser_title(struct hists *hists, |
| 39 | struct hist_browser_timer *hbt, | ||
| 40 | char *bf, size_t size); | ||
| 39 | static void hist_browser__update_nr_entries(struct hist_browser *hb); | 41 | static void hist_browser__update_nr_entries(struct hist_browser *hb); |
| 40 | 42 | ||
| 41 | static struct rb_node *hists__filter_entries(struct rb_node *nd, | 43 | static struct rb_node *hists__filter_entries(struct rb_node *nd, |
| @@ -390,7 +392,7 @@ static int hist_browser__run(struct hist_browser *browser, | |||
| 390 | browser->b.entries = &browser->hists->entries; | 392 | browser->b.entries = &browser->hists->entries; |
| 391 | browser->b.nr_entries = hist_browser__nr_entries(browser); | 393 | browser->b.nr_entries = hist_browser__nr_entries(browser); |
| 392 | 394 | ||
| 393 | hists__browser_title(browser->hists, title, sizeof(title)); | 395 | hists__browser_title(browser->hists, hbt, title, sizeof(title)); |
| 394 | 396 | ||
| 395 | if (ui_browser__show(&browser->b, title, | 397 | if (ui_browser__show(&browser->b, title, |
| 396 | "Press '?' for help on key bindings") < 0) | 398 | "Press '?' for help on key bindings") < 0) |
| @@ -417,7 +419,8 @@ static int hist_browser__run(struct hist_browser *browser, | |||
| 417 | ui_browser__warn_lost_events(&browser->b); | 419 | ui_browser__warn_lost_events(&browser->b); |
| 418 | } | 420 | } |
| 419 | 421 | ||
| 420 | hists__browser_title(browser->hists, title, sizeof(title)); | 422 | hists__browser_title(browser->hists, |
| 423 | hbt, title, sizeof(title)); | ||
| 421 | ui_browser__show_title(&browser->b, title); | 424 | ui_browser__show_title(&browser->b, title); |
| 422 | continue; | 425 | continue; |
| 423 | } | 426 | } |
| @@ -1204,7 +1207,15 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser | |||
| 1204 | return browser->he_selection->thread; | 1207 | return browser->he_selection->thread; |
| 1205 | } | 1208 | } |
| 1206 | 1209 | ||
| 1207 | static int hists__browser_title(struct hists *hists, char *bf, size_t size) | 1210 | /* Check whether the browser is for 'top' or 'report' */ |
| 1211 | static inline bool is_report_browser(void *timer) | ||
| 1212 | { | ||
| 1213 | return timer == NULL; | ||
| 1214 | } | ||
| 1215 | |||
| 1216 | static int hists__browser_title(struct hists *hists, | ||
| 1217 | struct hist_browser_timer *hbt, | ||
| 1218 | char *bf, size_t size) | ||
| 1208 | { | 1219 | { |
| 1209 | char unit; | 1220 | char unit; |
| 1210 | int printed; | 1221 | int printed; |
| @@ -1229,12 +1240,14 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size) | |||
| 1229 | ev_name = buf; | 1240 | ev_name = buf; |
| 1230 | 1241 | ||
| 1231 | for_each_group_member(pos, evsel) { | 1242 | for_each_group_member(pos, evsel) { |
| 1243 | struct hists *pos_hists = evsel__hists(pos); | ||
| 1244 | |||
| 1232 | if (symbol_conf.filter_relative) { | 1245 | if (symbol_conf.filter_relative) { |
| 1233 | nr_samples += pos->hists.stats.nr_non_filtered_samples; | 1246 | nr_samples += pos_hists->stats.nr_non_filtered_samples; |
| 1234 | nr_events += pos->hists.stats.total_non_filtered_period; | 1247 | nr_events += pos_hists->stats.total_non_filtered_period; |
| 1235 | } else { | 1248 | } else { |
| 1236 | nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; | 1249 | nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE]; |
| 1237 | nr_events += pos->hists.stats.total_period; | 1250 | nr_events += pos_hists->stats.total_period; |
| 1238 | } | 1251 | } |
| 1239 | } | 1252 | } |
| 1240 | } | 1253 | } |
| @@ -1256,6 +1269,13 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size) | |||
| 1256 | if (dso) | 1269 | if (dso) |
| 1257 | printed += scnprintf(bf + printed, size - printed, | 1270 | printed += scnprintf(bf + printed, size - printed, |
| 1258 | ", DSO: %s", dso->short_name); | 1271 | ", DSO: %s", dso->short_name); |
| 1272 | if (!is_report_browser(hbt)) { | ||
| 1273 | struct perf_top *top = hbt->arg; | ||
| 1274 | |||
| 1275 | if (top->zero) | ||
| 1276 | printed += scnprintf(bf + printed, size - printed, " [z]"); | ||
| 1277 | } | ||
| 1278 | |||
| 1259 | return printed; | 1279 | return printed; |
| 1260 | } | 1280 | } |
| 1261 | 1281 | ||
| @@ -1267,12 +1287,6 @@ static inline void free_popup_options(char **options, int n) | |||
| 1267 | zfree(&options[i]); | 1287 | zfree(&options[i]); |
| 1268 | } | 1288 | } |
| 1269 | 1289 | ||
| 1270 | /* Check whether the browser is for 'top' or 'report' */ | ||
| 1271 | static inline bool is_report_browser(void *timer) | ||
| 1272 | { | ||
| 1273 | return timer == NULL; | ||
| 1274 | } | ||
| 1275 | |||
| 1276 | /* | 1290 | /* |
| 1277 | * Only runtime switching of perf data file will make "input_name" point | 1291 | * Only runtime switching of perf data file will make "input_name" point |
| 1278 | * to a malloced buffer. So add "is_input_name_malloced" flag to decide | 1292 | * to a malloced buffer. So add "is_input_name_malloced" flag to decide |
| @@ -1387,7 +1401,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
| 1387 | float min_pcnt, | 1401 | float min_pcnt, |
| 1388 | struct perf_session_env *env) | 1402 | struct perf_session_env *env) |
| 1389 | { | 1403 | { |
| 1390 | struct hists *hists = &evsel->hists; | 1404 | struct hists *hists = evsel__hists(evsel); |
| 1391 | struct hist_browser *browser = hist_browser__new(hists); | 1405 | struct hist_browser *browser = hist_browser__new(hists); |
| 1392 | struct branch_info *bi; | 1406 | struct branch_info *bi; |
| 1393 | struct pstack *fstack; | 1407 | struct pstack *fstack; |
| @@ -1802,8 +1816,9 @@ static void perf_evsel_menu__write(struct ui_browser *browser, | |||
| 1802 | struct perf_evsel_menu *menu = container_of(browser, | 1816 | struct perf_evsel_menu *menu = container_of(browser, |
| 1803 | struct perf_evsel_menu, b); | 1817 | struct perf_evsel_menu, b); |
| 1804 | struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); | 1818 | struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); |
| 1819 | struct hists *hists = evsel__hists(evsel); | ||
| 1805 | bool current_entry = ui_browser__is_current_entry(browser, row); | 1820 | bool current_entry = ui_browser__is_current_entry(browser, row); |
| 1806 | unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; | 1821 | unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE]; |
| 1807 | const char *ev_name = perf_evsel__name(evsel); | 1822 | const char *ev_name = perf_evsel__name(evsel); |
| 1808 | char bf[256], unit; | 1823 | char bf[256], unit; |
| 1809 | const char *warn = " "; | 1824 | const char *warn = " "; |
| @@ -1818,7 +1833,8 @@ static void perf_evsel_menu__write(struct ui_browser *browser, | |||
| 1818 | ev_name = perf_evsel__group_name(evsel); | 1833 | ev_name = perf_evsel__group_name(evsel); |
| 1819 | 1834 | ||
| 1820 | for_each_group_member(pos, evsel) { | 1835 | for_each_group_member(pos, evsel) { |
| 1821 | nr_events += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE]; | 1836 | struct hists *pos_hists = evsel__hists(pos); |
| 1837 | nr_events += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE]; | ||
| 1822 | } | 1838 | } |
| 1823 | } | 1839 | } |
| 1824 | 1840 | ||
| @@ -1827,7 +1843,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser, | |||
| 1827 | unit, unit == ' ' ? "" : " ", ev_name); | 1843 | unit, unit == ' ' ? "" : " ", ev_name); |
| 1828 | slsmg_printf("%s", bf); | 1844 | slsmg_printf("%s", bf); |
| 1829 | 1845 | ||
| 1830 | nr_events = evsel->hists.stats.nr_events[PERF_RECORD_LOST]; | 1846 | nr_events = hists->stats.nr_events[PERF_RECORD_LOST]; |
| 1831 | if (nr_events != 0) { | 1847 | if (nr_events != 0) { |
| 1832 | menu->lost_events = true; | 1848 | menu->lost_events = true; |
| 1833 | if (!current_entry) | 1849 | if (!current_entry) |
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index f3fa4258b256..fc654fb77ace 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c | |||
| @@ -319,7 +319,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, | |||
| 319 | gtk_container_add(GTK_CONTAINER(window), vbox); | 319 | gtk_container_add(GTK_CONTAINER(window), vbox); |
| 320 | 320 | ||
| 321 | evlist__for_each(evlist, pos) { | 321 | evlist__for_each(evlist, pos) { |
| 322 | struct hists *hists = &pos->hists; | 322 | struct hists *hists = evsel__hists(pos); |
| 323 | const char *evname = perf_evsel__name(pos); | 323 | const char *evname = perf_evsel__name(pos); |
| 324 | GtkWidget *scrolled_window; | 324 | GtkWidget *scrolled_window; |
| 325 | GtkWidget *tab_label; | 325 | GtkWidget *tab_label; |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 36437527dbb3..7dabde14ea54 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
| @@ -478,7 +478,7 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
| 478 | 478 | ||
| 479 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); | 479 | pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); |
| 480 | 480 | ||
| 481 | if (addr < sym->start || addr > sym->end) | 481 | if (addr < sym->start || addr >= sym->end) |
| 482 | return -ERANGE; | 482 | return -ERANGE; |
| 483 | 483 | ||
| 484 | offset = addr - sym->start; | 484 | offset = addr - sym->start; |
| @@ -836,7 +836,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
| 836 | end = map__rip_2objdump(map, sym->end); | 836 | end = map__rip_2objdump(map, sym->end); |
| 837 | 837 | ||
| 838 | offset = line_ip - start; | 838 | offset = line_ip - start; |
| 839 | if ((u64)line_ip < start || (u64)line_ip > end) | 839 | if ((u64)line_ip < start || (u64)line_ip >= end) |
| 840 | offset = -1; | 840 | offset = -1; |
| 841 | else | 841 | else |
| 842 | parsed_line = tmp2 + 1; | 842 | parsed_line = tmp2 + 1; |
| @@ -966,7 +966,7 @@ fallback: | |||
| 966 | kce.kcore_filename = symfs_filename; | 966 | kce.kcore_filename = symfs_filename; |
| 967 | kce.addr = map__rip_2objdump(map, sym->start); | 967 | kce.addr = map__rip_2objdump(map, sym->start); |
| 968 | kce.offs = sym->start; | 968 | kce.offs = sym->start; |
| 969 | kce.len = sym->end + 1 - sym->start; | 969 | kce.len = sym->end - sym->start; |
| 970 | if (!kcore_extract__create(&kce)) { | 970 | if (!kcore_extract__create(&kce)) { |
| 971 | delete_extract = true; | 971 | delete_extract = true; |
| 972 | strlcpy(symfs_filename, kce.extract_filename, | 972 | strlcpy(symfs_filename, kce.extract_filename, |
| @@ -987,7 +987,7 @@ fallback: | |||
| 987 | disassembler_style ? "-M " : "", | 987 | disassembler_style ? "-M " : "", |
| 988 | disassembler_style ? disassembler_style : "", | 988 | disassembler_style ? disassembler_style : "", |
| 989 | map__rip_2objdump(map, sym->start), | 989 | map__rip_2objdump(map, sym->start), |
| 990 | map__rip_2objdump(map, sym->end+1), | 990 | map__rip_2objdump(map, sym->end), |
| 991 | symbol_conf.annotate_asm_raw ? "" : "--no-show-raw", | 991 | symbol_conf.annotate_asm_raw ? "" : "--no-show-raw", |
| 992 | symbol_conf.annotate_src ? "-S" : "", | 992 | symbol_conf.annotate_src ? "-S" : "", |
| 993 | symfs_filename, filename); | 993 | symfs_filename, filename); |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 2a1f5a46543a..94cfefddf4db 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
| @@ -65,6 +65,8 @@ struct callchain_param { | |||
| 65 | enum chain_key key; | 65 | enum chain_key key; |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | extern struct callchain_param callchain_param; | ||
| 69 | |||
| 68 | struct callchain_list { | 70 | struct callchain_list { |
| 69 | u64 ip; | 71 | u64 ip; |
| 70 | struct map_symbol ms; | 72 | struct map_symbol ms; |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 7eb7107731ec..5699e7e2a790 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
| @@ -190,6 +190,32 @@ enum perf_user_event_type { /* above any possible kernel type */ | |||
| 190 | PERF_RECORD_HEADER_MAX | 190 | PERF_RECORD_HEADER_MAX |
| 191 | }; | 191 | }; |
| 192 | 192 | ||
| 193 | /* | ||
| 194 | * The kernel collects the number of events it couldn't send in a stretch and | ||
| 195 | * when possible sends this number in a PERF_RECORD_LOST event. The number of | ||
| 196 | * such "chunks" of lost events is stored in .nr_events[PERF_EVENT_LOST] while | ||
| 197 | * total_lost tells exactly how many events the kernel in fact lost, i.e. it is | ||
| 198 | * the sum of all struct lost_event.lost fields reported. | ||
| 199 | * | ||
| 200 | * The total_period is needed because by default auto-freq is used, so | ||
| 201 | * multipling nr_events[PERF_EVENT_SAMPLE] by a frequency isn't possible to get | ||
| 202 | * the total number of low level events, it is necessary to to sum all struct | ||
| 203 | * sample_event.period and stash the result in total_period. | ||
| 204 | */ | ||
| 205 | struct events_stats { | ||
| 206 | u64 total_period; | ||
| 207 | u64 total_non_filtered_period; | ||
| 208 | u64 total_lost; | ||
| 209 | u64 total_invalid_chains; | ||
| 210 | u32 nr_events[PERF_RECORD_HEADER_MAX]; | ||
| 211 | u32 nr_non_filtered_samples; | ||
| 212 | u32 nr_lost_warned; | ||
| 213 | u32 nr_unknown_events; | ||
| 214 | u32 nr_invalid_chains; | ||
| 215 | u32 nr_unknown_id; | ||
| 216 | u32 nr_unprocessable_samples; | ||
| 217 | }; | ||
| 218 | |||
| 193 | struct attr_event { | 219 | struct attr_event { |
| 194 | struct perf_event_header header; | 220 | struct perf_event_header header; |
| 195 | struct perf_event_attr attr; | 221 | struct perf_event_attr attr; |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3cebc9a8d52e..3c9e77d6b4c2 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -1003,6 +1003,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) | |||
| 1003 | 1003 | ||
| 1004 | out_delete_threads: | 1004 | out_delete_threads: |
| 1005 | thread_map__delete(evlist->threads); | 1005 | thread_map__delete(evlist->threads); |
| 1006 | evlist->threads = NULL; | ||
| 1006 | return -1; | 1007 | return -1; |
| 1007 | } | 1008 | } |
| 1008 | 1009 | ||
| @@ -1175,11 +1176,51 @@ void perf_evlist__close(struct perf_evlist *evlist) | |||
| 1175 | } | 1176 | } |
| 1176 | } | 1177 | } |
| 1177 | 1178 | ||
| 1179 | static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) | ||
| 1180 | { | ||
| 1181 | int err = -ENOMEM; | ||
| 1182 | |||
| 1183 | /* | ||
| 1184 | * Try reading /sys/devices/system/cpu/online to get | ||
| 1185 | * an all cpus map. | ||
| 1186 | * | ||
| 1187 | * FIXME: -ENOMEM is the best we can do here, the cpu_map | ||
| 1188 | * code needs an overhaul to properly forward the | ||
| 1189 | * error, and we may not want to do that fallback to a | ||
| 1190 | * default cpu identity map :-\ | ||
| 1191 | */ | ||
| 1192 | evlist->cpus = cpu_map__new(NULL); | ||
| 1193 | if (evlist->cpus == NULL) | ||
| 1194 | goto out; | ||
| 1195 | |||
| 1196 | evlist->threads = thread_map__new_dummy(); | ||
| 1197 | if (evlist->threads == NULL) | ||
| 1198 | goto out_free_cpus; | ||
| 1199 | |||
| 1200 | err = 0; | ||
| 1201 | out: | ||
| 1202 | return err; | ||
| 1203 | out_free_cpus: | ||
| 1204 | cpu_map__delete(evlist->cpus); | ||
| 1205 | evlist->cpus = NULL; | ||
| 1206 | goto out; | ||
| 1207 | } | ||
| 1208 | |||
| 1178 | int perf_evlist__open(struct perf_evlist *evlist) | 1209 | int perf_evlist__open(struct perf_evlist *evlist) |
| 1179 | { | 1210 | { |
| 1180 | struct perf_evsel *evsel; | 1211 | struct perf_evsel *evsel; |
| 1181 | int err; | 1212 | int err; |
| 1182 | 1213 | ||
| 1214 | /* | ||
| 1215 | * Default: one fd per CPU, all threads, aka systemwide | ||
| 1216 | * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL | ||
| 1217 | */ | ||
| 1218 | if (evlist->threads == NULL && evlist->cpus == NULL) { | ||
| 1219 | err = perf_evlist__create_syswide_maps(evlist); | ||
| 1220 | if (err < 0) | ||
| 1221 | goto out_err; | ||
| 1222 | } | ||
| 1223 | |||
| 1183 | perf_evlist__update_id_pos(evlist); | 1224 | perf_evlist__update_id_pos(evlist); |
| 1184 | 1225 | ||
| 1185 | evlist__for_each(evlist, evsel) { | 1226 | evlist__for_each(evlist, evsel) { |
| @@ -1276,8 +1317,14 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar | |||
| 1276 | sigaction(SIGUSR1, &act, NULL); | 1317 | sigaction(SIGUSR1, &act, NULL); |
| 1277 | } | 1318 | } |
| 1278 | 1319 | ||
| 1279 | if (target__none(target)) | 1320 | if (target__none(target)) { |
| 1321 | if (evlist->threads == NULL) { | ||
| 1322 | fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n", | ||
| 1323 | __func__, __LINE__); | ||
| 1324 | goto out_close_pipes; | ||
| 1325 | } | ||
| 1280 | evlist->threads->map[0] = evlist->workload.pid; | 1326 | evlist->threads->map[0] = evlist->workload.pid; |
| 1327 | } | ||
| 1281 | 1328 | ||
| 1282 | close(child_ready_pipe[1]); | 1329 | close(child_ready_pipe[1]); |
| 1283 | close(go_pipe[0]); | 1330 | close(go_pipe[0]); |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index bd312b01e876..649b0c597283 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -117,6 +117,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, | |||
| 117 | void *ucontext)); | 117 | void *ucontext)); |
| 118 | int perf_evlist__start_workload(struct perf_evlist *evlist); | 118 | int perf_evlist__start_workload(struct perf_evlist *evlist); |
| 119 | 119 | ||
| 120 | struct option; | ||
| 121 | |||
| 120 | int perf_evlist__parse_mmap_pages(const struct option *opt, | 122 | int perf_evlist__parse_mmap_pages(const struct option *opt, |
| 121 | const char *str, | 123 | const char *str, |
| 122 | int unset); | 124 | int unset); |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index e0868a901c4a..2f9e68025ede 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #include <linux/perf_event.h> | 15 | #include <linux/perf_event.h> |
| 16 | #include <sys/resource.h> | 16 | #include <sys/resource.h> |
| 17 | #include "asm/bug.h" | 17 | #include "asm/bug.h" |
| 18 | #include "callchain.h" | ||
| 19 | #include "cgroup.h" | ||
| 18 | #include "evsel.h" | 20 | #include "evsel.h" |
| 19 | #include "evlist.h" | 21 | #include "evlist.h" |
| 20 | #include "util.h" | 22 | #include "util.h" |
| @@ -32,6 +34,48 @@ static struct { | |||
| 32 | bool cloexec; | 34 | bool cloexec; |
| 33 | } perf_missing_features; | 35 | } perf_missing_features; |
| 34 | 36 | ||
| 37 | static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused) | ||
| 38 | { | ||
| 39 | return 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | static void perf_evsel__no_extra_fini(struct perf_evsel *evsel __maybe_unused) | ||
| 43 | { | ||
| 44 | } | ||
| 45 | |||
| 46 | static struct { | ||
| 47 | size_t size; | ||
| 48 | int (*init)(struct perf_evsel *evsel); | ||
| 49 | void (*fini)(struct perf_evsel *evsel); | ||
| 50 | } perf_evsel__object = { | ||
| 51 | .size = sizeof(struct perf_evsel), | ||
| 52 | .init = perf_evsel__no_extra_init, | ||
| 53 | .fini = perf_evsel__no_extra_fini, | ||
| 54 | }; | ||
| 55 | |||
| 56 | int perf_evsel__object_config(size_t object_size, | ||
| 57 | int (*init)(struct perf_evsel *evsel), | ||
| 58 | void (*fini)(struct perf_evsel *evsel)) | ||
| 59 | { | ||
| 60 | |||
| 61 | if (object_size == 0) | ||
| 62 | goto set_methods; | ||
| 63 | |||
| 64 | if (perf_evsel__object.size > object_size) | ||
| 65 | return -EINVAL; | ||
| 66 | |||
| 67 | perf_evsel__object.size = object_size; | ||
| 68 | |||
| 69 | set_methods: | ||
| 70 | if (init != NULL) | ||
| 71 | perf_evsel__object.init = init; | ||
| 72 | |||
| 73 | if (fini != NULL) | ||
| 74 | perf_evsel__object.fini = fini; | ||
| 75 | |||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 35 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 79 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
| 36 | 80 | ||
| 37 | int __perf_evsel__sample_size(u64 sample_type) | 81 | int __perf_evsel__sample_size(u64 sample_type) |
| @@ -116,16 +160,6 @@ void perf_evsel__calc_id_pos(struct perf_evsel *evsel) | |||
| 116 | evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type); | 160 | evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type); |
| 117 | } | 161 | } |
| 118 | 162 | ||
| 119 | void hists__init(struct hists *hists) | ||
| 120 | { | ||
| 121 | memset(hists, 0, sizeof(*hists)); | ||
| 122 | hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; | ||
| 123 | hists->entries_in = &hists->entries_in_array[0]; | ||
| 124 | hists->entries_collapsed = RB_ROOT; | ||
| 125 | hists->entries = RB_ROOT; | ||
| 126 | pthread_mutex_init(&hists->lock, NULL); | ||
| 127 | } | ||
| 128 | |||
| 129 | void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, | 163 | void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, |
| 130 | enum perf_event_sample_format bit) | 164 | enum perf_event_sample_format bit) |
| 131 | { | 165 | { |
| @@ -168,14 +202,14 @@ void perf_evsel__init(struct perf_evsel *evsel, | |||
| 168 | evsel->unit = ""; | 202 | evsel->unit = ""; |
| 169 | evsel->scale = 1.0; | 203 | evsel->scale = 1.0; |
| 170 | INIT_LIST_HEAD(&evsel->node); | 204 | INIT_LIST_HEAD(&evsel->node); |
| 171 | hists__init(&evsel->hists); | 205 | perf_evsel__object.init(evsel); |
| 172 | evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); | 206 | evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); |
| 173 | perf_evsel__calc_id_pos(evsel); | 207 | perf_evsel__calc_id_pos(evsel); |
| 174 | } | 208 | } |
| 175 | 209 | ||
| 176 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) | 210 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) |
| 177 | { | 211 | { |
| 178 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); | 212 | struct perf_evsel *evsel = zalloc(perf_evsel__object.size); |
| 179 | 213 | ||
| 180 | if (evsel != NULL) | 214 | if (evsel != NULL) |
| 181 | perf_evsel__init(evsel, attr, idx); | 215 | perf_evsel__init(evsel, attr, idx); |
| @@ -185,7 +219,7 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) | |||
| 185 | 219 | ||
| 186 | struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) | 220 | struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) |
| 187 | { | 221 | { |
| 188 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); | 222 | struct perf_evsel *evsel = zalloc(perf_evsel__object.size); |
| 189 | 223 | ||
| 190 | if (evsel != NULL) { | 224 | if (evsel != NULL) { |
| 191 | struct perf_event_attr attr = { | 225 | struct perf_event_attr attr = { |
| @@ -692,7 +726,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) | |||
| 692 | } | 726 | } |
| 693 | } | 727 | } |
| 694 | 728 | ||
| 695 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | 729 | static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) |
| 696 | { | 730 | { |
| 697 | int cpu, thread; | 731 | int cpu, thread; |
| 698 | 732 | ||
| @@ -780,13 +814,13 @@ int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus) | |||
| 780 | return evsel->counts != NULL ? 0 : -ENOMEM; | 814 | return evsel->counts != NULL ? 0 : -ENOMEM; |
| 781 | } | 815 | } |
| 782 | 816 | ||
| 783 | void perf_evsel__free_fd(struct perf_evsel *evsel) | 817 | static void perf_evsel__free_fd(struct perf_evsel *evsel) |
| 784 | { | 818 | { |
| 785 | xyarray__delete(evsel->fd); | 819 | xyarray__delete(evsel->fd); |
| 786 | evsel->fd = NULL; | 820 | evsel->fd = NULL; |
| 787 | } | 821 | } |
| 788 | 822 | ||
| 789 | void perf_evsel__free_id(struct perf_evsel *evsel) | 823 | static void perf_evsel__free_id(struct perf_evsel *evsel) |
| 790 | { | 824 | { |
| 791 | xyarray__delete(evsel->sample_id); | 825 | xyarray__delete(evsel->sample_id); |
| 792 | evsel->sample_id = NULL; | 826 | evsel->sample_id = NULL; |
| @@ -817,16 +851,17 @@ void perf_evsel__exit(struct perf_evsel *evsel) | |||
| 817 | assert(list_empty(&evsel->node)); | 851 | assert(list_empty(&evsel->node)); |
| 818 | perf_evsel__free_fd(evsel); | 852 | perf_evsel__free_fd(evsel); |
| 819 | perf_evsel__free_id(evsel); | 853 | perf_evsel__free_id(evsel); |
| 820 | } | ||
| 821 | |||
| 822 | void perf_evsel__delete(struct perf_evsel *evsel) | ||
| 823 | { | ||
| 824 | perf_evsel__exit(evsel); | ||
| 825 | close_cgroup(evsel->cgrp); | 854 | close_cgroup(evsel->cgrp); |
| 826 | zfree(&evsel->group_name); | 855 | zfree(&evsel->group_name); |
| 827 | if (evsel->tp_format) | 856 | if (evsel->tp_format) |
| 828 | pevent_free_format(evsel->tp_format); | 857 | pevent_free_format(evsel->tp_format); |
| 829 | zfree(&evsel->name); | 858 | zfree(&evsel->name); |
| 859 | perf_evsel__object.fini(evsel); | ||
| 860 | } | ||
| 861 | |||
| 862 | void perf_evsel__delete(struct perf_evsel *evsel) | ||
| 863 | { | ||
| 864 | perf_evsel__exit(evsel); | ||
| 830 | free(evsel); | 865 | free(evsel); |
| 831 | } | 866 | } |
| 832 | 867 | ||
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 7bc314be6a7b..163c5604e5d1 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
| @@ -7,8 +7,6 @@ | |||
| 7 | #include <linux/perf_event.h> | 7 | #include <linux/perf_event.h> |
| 8 | #include <linux/types.h> | 8 | #include <linux/types.h> |
| 9 | #include "xyarray.h" | 9 | #include "xyarray.h" |
| 10 | #include "cgroup.h" | ||
| 11 | #include "hist.h" | ||
| 12 | #include "symbol.h" | 10 | #include "symbol.h" |
| 13 | 11 | ||
| 14 | struct perf_counts_values { | 12 | struct perf_counts_values { |
| @@ -43,6 +41,8 @@ struct perf_sample_id { | |||
| 43 | u64 period; | 41 | u64 period; |
| 44 | }; | 42 | }; |
| 45 | 43 | ||
| 44 | struct cgroup_sel; | ||
| 45 | |||
| 46 | /** struct perf_evsel - event selector | 46 | /** struct perf_evsel - event selector |
| 47 | * | 47 | * |
| 48 | * @name - Can be set to retain the original event name passed by the user, | 48 | * @name - Can be set to retain the original event name passed by the user, |
| @@ -66,7 +66,6 @@ struct perf_evsel { | |||
| 66 | struct perf_counts *prev_raw_counts; | 66 | struct perf_counts *prev_raw_counts; |
| 67 | int idx; | 67 | int idx; |
| 68 | u32 ids; | 68 | u32 ids; |
| 69 | struct hists hists; | ||
| 70 | char *name; | 69 | char *name; |
| 71 | double scale; | 70 | double scale; |
| 72 | const char *unit; | 71 | const char *unit; |
| @@ -100,13 +99,16 @@ union u64_swap { | |||
| 100 | u32 val32[2]; | 99 | u32 val32[2]; |
| 101 | }; | 100 | }; |
| 102 | 101 | ||
| 103 | #define hists_to_evsel(h) container_of(h, struct perf_evsel, hists) | ||
| 104 | |||
| 105 | struct cpu_map; | 102 | struct cpu_map; |
| 103 | struct target; | ||
| 106 | struct thread_map; | 104 | struct thread_map; |
| 107 | struct perf_evlist; | 105 | struct perf_evlist; |
| 108 | struct record_opts; | 106 | struct record_opts; |
| 109 | 107 | ||
| 108 | int perf_evsel__object_config(size_t object_size, | ||
| 109 | int (*init)(struct perf_evsel *evsel), | ||
| 110 | void (*fini)(struct perf_evsel *evsel)); | ||
| 111 | |||
| 110 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); | 112 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); |
| 111 | 113 | ||
| 112 | static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr) | 114 | static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr) |
| @@ -153,12 +155,9 @@ const char *perf_evsel__name(struct perf_evsel *evsel); | |||
| 153 | const char *perf_evsel__group_name(struct perf_evsel *evsel); | 155 | const char *perf_evsel__group_name(struct perf_evsel *evsel); |
| 154 | int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size); | 156 | int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size); |
| 155 | 157 | ||
| 156 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); | ||
| 157 | int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); | 158 | int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); |
| 158 | int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus); | 159 | int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus); |
| 159 | void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus); | 160 | void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus); |
| 160 | void perf_evsel__free_fd(struct perf_evsel *evsel); | ||
| 161 | void perf_evsel__free_id(struct perf_evsel *evsel); | ||
| 162 | void perf_evsel__free_counts(struct perf_evsel *evsel); | 161 | void perf_evsel__free_counts(struct perf_evsel *evsel); |
| 163 | void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads); | 162 | void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads); |
| 164 | 163 | ||
| @@ -281,8 +280,6 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel, | |||
| 281 | return __perf_evsel__read(evsel, ncpus, nthreads, true); | 280 | return __perf_evsel__read(evsel, ncpus, nthreads, true); |
| 282 | } | 281 | } |
| 283 | 282 | ||
| 284 | void hists__init(struct hists *hists); | ||
| 285 | |||
| 286 | int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, | 283 | int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, |
| 287 | struct perf_sample *sample); | 284 | struct perf_sample *sample); |
| 288 | 285 | ||
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 86569fa3651d..6e88b9e395df 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #include "hist.h" | 3 | #include "hist.h" |
| 4 | #include "session.h" | 4 | #include "session.h" |
| 5 | #include "sort.h" | 5 | #include "sort.h" |
| 6 | #include "evlist.h" | ||
| 6 | #include "evsel.h" | 7 | #include "evsel.h" |
| 7 | #include "annotate.h" | 8 | #include "annotate.h" |
| 8 | #include <math.h> | 9 | #include <math.h> |
| @@ -14,13 +15,6 @@ static bool hists__filter_entry_by_thread(struct hists *hists, | |||
| 14 | static bool hists__filter_entry_by_symbol(struct hists *hists, | 15 | static bool hists__filter_entry_by_symbol(struct hists *hists, |
| 15 | struct hist_entry *he); | 16 | struct hist_entry *he); |
| 16 | 17 | ||
| 17 | struct callchain_param callchain_param = { | ||
| 18 | .mode = CHAIN_GRAPH_REL, | ||
| 19 | .min_percent = 0.5, | ||
| 20 | .order = ORDER_CALLEE, | ||
| 21 | .key = CCKEY_FUNCTION | ||
| 22 | }; | ||
| 23 | |||
| 24 | u16 hists__col_len(struct hists *hists, enum hist_column col) | 18 | u16 hists__col_len(struct hists *hists, enum hist_column col) |
| 25 | { | 19 | { |
| 26 | return hists->col_len[col]; | 20 | return hists->col_len[col]; |
| @@ -516,6 +510,7 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al | |||
| 516 | { | 510 | { |
| 517 | u64 cost; | 511 | u64 cost; |
| 518 | struct mem_info *mi = iter->priv; | 512 | struct mem_info *mi = iter->priv; |
| 513 | struct hists *hists = evsel__hists(iter->evsel); | ||
| 519 | struct hist_entry *he; | 514 | struct hist_entry *he; |
| 520 | 515 | ||
| 521 | if (mi == NULL) | 516 | if (mi == NULL) |
| @@ -532,7 +527,7 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al | |||
| 532 | * and this is indirectly achieved by passing period=weight here | 527 | * and this is indirectly achieved by passing period=weight here |
| 533 | * and the he_stat__add_period() function. | 528 | * and the he_stat__add_period() function. |
| 534 | */ | 529 | */ |
| 535 | he = __hists__add_entry(&iter->evsel->hists, al, iter->parent, NULL, mi, | 530 | he = __hists__add_entry(hists, al, iter->parent, NULL, mi, |
| 536 | cost, cost, 0, true); | 531 | cost, cost, 0, true); |
| 537 | if (!he) | 532 | if (!he) |
| 538 | return -ENOMEM; | 533 | return -ENOMEM; |
| @@ -546,13 +541,14 @@ iter_finish_mem_entry(struct hist_entry_iter *iter, | |||
| 546 | struct addr_location *al __maybe_unused) | 541 | struct addr_location *al __maybe_unused) |
| 547 | { | 542 | { |
| 548 | struct perf_evsel *evsel = iter->evsel; | 543 | struct perf_evsel *evsel = iter->evsel; |
| 544 | struct hists *hists = evsel__hists(evsel); | ||
| 549 | struct hist_entry *he = iter->he; | 545 | struct hist_entry *he = iter->he; |
| 550 | int err = -EINVAL; | 546 | int err = -EINVAL; |
| 551 | 547 | ||
| 552 | if (he == NULL) | 548 | if (he == NULL) |
| 553 | goto out; | 549 | goto out; |
| 554 | 550 | ||
| 555 | hists__inc_nr_samples(&evsel->hists, he->filtered); | 551 | hists__inc_nr_samples(hists, he->filtered); |
| 556 | 552 | ||
| 557 | err = hist_entry__append_callchain(he, iter->sample); | 553 | err = hist_entry__append_callchain(he, iter->sample); |
| 558 | 554 | ||
| @@ -618,6 +614,7 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a | |||
| 618 | { | 614 | { |
| 619 | struct branch_info *bi; | 615 | struct branch_info *bi; |
| 620 | struct perf_evsel *evsel = iter->evsel; | 616 | struct perf_evsel *evsel = iter->evsel; |
| 617 | struct hists *hists = evsel__hists(evsel); | ||
| 621 | struct hist_entry *he = NULL; | 618 | struct hist_entry *he = NULL; |
| 622 | int i = iter->curr; | 619 | int i = iter->curr; |
| 623 | int err = 0; | 620 | int err = 0; |
| @@ -631,12 +628,12 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a | |||
| 631 | * The report shows the percentage of total branches captured | 628 | * The report shows the percentage of total branches captured |
| 632 | * and not events sampled. Thus we use a pseudo period of 1. | 629 | * and not events sampled. Thus we use a pseudo period of 1. |
| 633 | */ | 630 | */ |
| 634 | he = __hists__add_entry(&evsel->hists, al, iter->parent, &bi[i], NULL, | 631 | he = __hists__add_entry(hists, al, iter->parent, &bi[i], NULL, |
| 635 | 1, 1, 0, true); | 632 | 1, 1, 0, true); |
| 636 | if (he == NULL) | 633 | if (he == NULL) |
| 637 | return -ENOMEM; | 634 | return -ENOMEM; |
| 638 | 635 | ||
| 639 | hists__inc_nr_samples(&evsel->hists, he->filtered); | 636 | hists__inc_nr_samples(hists, he->filtered); |
| 640 | 637 | ||
| 641 | out: | 638 | out: |
| 642 | iter->he = he; | 639 | iter->he = he; |
| @@ -668,7 +665,7 @@ iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location | |||
| 668 | struct perf_sample *sample = iter->sample; | 665 | struct perf_sample *sample = iter->sample; |
| 669 | struct hist_entry *he; | 666 | struct hist_entry *he; |
| 670 | 667 | ||
| 671 | he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, | 668 | he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL, |
| 672 | sample->period, sample->weight, | 669 | sample->period, sample->weight, |
| 673 | sample->transaction, true); | 670 | sample->transaction, true); |
| 674 | if (he == NULL) | 671 | if (he == NULL) |
| @@ -691,7 +688,7 @@ iter_finish_normal_entry(struct hist_entry_iter *iter, | |||
| 691 | 688 | ||
| 692 | iter->he = NULL; | 689 | iter->he = NULL; |
| 693 | 690 | ||
| 694 | hists__inc_nr_samples(&evsel->hists, he->filtered); | 691 | hists__inc_nr_samples(evsel__hists(evsel), he->filtered); |
| 695 | 692 | ||
| 696 | return hist_entry__append_callchain(he, sample); | 693 | return hist_entry__append_callchain(he, sample); |
| 697 | } | 694 | } |
| @@ -724,12 +721,13 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter, | |||
| 724 | struct addr_location *al) | 721 | struct addr_location *al) |
| 725 | { | 722 | { |
| 726 | struct perf_evsel *evsel = iter->evsel; | 723 | struct perf_evsel *evsel = iter->evsel; |
| 724 | struct hists *hists = evsel__hists(evsel); | ||
| 727 | struct perf_sample *sample = iter->sample; | 725 | struct perf_sample *sample = iter->sample; |
| 728 | struct hist_entry **he_cache = iter->priv; | 726 | struct hist_entry **he_cache = iter->priv; |
| 729 | struct hist_entry *he; | 727 | struct hist_entry *he; |
| 730 | int err = 0; | 728 | int err = 0; |
| 731 | 729 | ||
| 732 | he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, | 730 | he = __hists__add_entry(hists, al, iter->parent, NULL, NULL, |
| 733 | sample->period, sample->weight, | 731 | sample->period, sample->weight, |
| 734 | sample->transaction, true); | 732 | sample->transaction, true); |
| 735 | if (he == NULL) | 733 | if (he == NULL) |
| @@ -746,7 +744,7 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter, | |||
| 746 | */ | 744 | */ |
| 747 | callchain_cursor_commit(&callchain_cursor); | 745 | callchain_cursor_commit(&callchain_cursor); |
| 748 | 746 | ||
| 749 | hists__inc_nr_samples(&evsel->hists, he->filtered); | 747 | hists__inc_nr_samples(hists, he->filtered); |
| 750 | 748 | ||
| 751 | return err; | 749 | return err; |
| 752 | } | 750 | } |
| @@ -802,7 +800,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter, | |||
| 802 | } | 800 | } |
| 803 | } | 801 | } |
| 804 | 802 | ||
| 805 | he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, | 803 | he = __hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL, |
| 806 | sample->period, sample->weight, | 804 | sample->period, sample->weight, |
| 807 | sample->transaction, false); | 805 | sample->transaction, false); |
| 808 | if (he == NULL) | 806 | if (he == NULL) |
| @@ -1408,6 +1406,21 @@ int hists__link(struct hists *leader, struct hists *other) | |||
| 1408 | return 0; | 1406 | return 0; |
| 1409 | } | 1407 | } |
| 1410 | 1408 | ||
| 1409 | |||
| 1410 | size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp) | ||
| 1411 | { | ||
| 1412 | struct perf_evsel *pos; | ||
| 1413 | size_t ret = 0; | ||
| 1414 | |||
| 1415 | evlist__for_each(evlist, pos) { | ||
| 1416 | ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); | ||
| 1417 | ret += events_stats__fprintf(&evsel__hists(pos)->stats, fp); | ||
| 1418 | } | ||
| 1419 | |||
| 1420 | return ret; | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | |||
| 1411 | u64 hists__total_period(struct hists *hists) | 1424 | u64 hists__total_period(struct hists *hists) |
| 1412 | { | 1425 | { |
| 1413 | return symbol_conf.filter_relative ? hists->stats.total_non_filtered_period : | 1426 | return symbol_conf.filter_relative ? hists->stats.total_non_filtered_period : |
| @@ -1434,3 +1447,31 @@ int perf_hist_config(const char *var, const char *value) | |||
| 1434 | 1447 | ||
| 1435 | return 0; | 1448 | return 0; |
| 1436 | } | 1449 | } |
| 1450 | |||
| 1451 | static int hists_evsel__init(struct perf_evsel *evsel) | ||
| 1452 | { | ||
| 1453 | struct hists *hists = evsel__hists(evsel); | ||
| 1454 | |||
| 1455 | memset(hists, 0, sizeof(*hists)); | ||
| 1456 | hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; | ||
| 1457 | hists->entries_in = &hists->entries_in_array[0]; | ||
| 1458 | hists->entries_collapsed = RB_ROOT; | ||
| 1459 | hists->entries = RB_ROOT; | ||
| 1460 | pthread_mutex_init(&hists->lock, NULL); | ||
| 1461 | return 0; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | /* | ||
| 1465 | * XXX We probably need a hists_evsel__exit() to free the hist_entries | ||
| 1466 | * stored in the rbtree... | ||
| 1467 | */ | ||
| 1468 | |||
| 1469 | int hists__init(void) | ||
| 1470 | { | ||
| 1471 | int err = perf_evsel__object_config(sizeof(struct hists_evsel), | ||
| 1472 | hists_evsel__init, NULL); | ||
| 1473 | if (err) | ||
| 1474 | fputs("FATAL ERROR: Couldn't setup hists class\n", stderr); | ||
| 1475 | |||
| 1476 | return err; | ||
| 1477 | } | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 8c9c70e18cbb..d0ef9a19a744 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -4,12 +4,11 @@ | |||
| 4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 5 | #include <pthread.h> | 5 | #include <pthread.h> |
| 6 | #include "callchain.h" | 6 | #include "callchain.h" |
| 7 | #include "evsel.h" | ||
| 7 | #include "header.h" | 8 | #include "header.h" |
| 8 | #include "color.h" | 9 | #include "color.h" |
| 9 | #include "ui/progress.h" | 10 | #include "ui/progress.h" |
| 10 | 11 | ||
| 11 | extern struct callchain_param callchain_param; | ||
| 12 | |||
| 13 | struct hist_entry; | 12 | struct hist_entry; |
| 14 | struct addr_location; | 13 | struct addr_location; |
| 15 | struct symbol; | 14 | struct symbol; |
| @@ -23,32 +22,6 @@ enum hist_filter { | |||
| 23 | HIST_FILTER__HOST, | 22 | HIST_FILTER__HOST, |
| 24 | }; | 23 | }; |
| 25 | 24 | ||
| 26 | /* | ||
| 27 | * The kernel collects the number of events it couldn't send in a stretch and | ||
| 28 | * when possible sends this number in a PERF_RECORD_LOST event. The number of | ||
| 29 | * such "chunks" of lost events is stored in .nr_events[PERF_EVENT_LOST] while | ||
| 30 | * total_lost tells exactly how many events the kernel in fact lost, i.e. it is | ||
| 31 | * the sum of all struct lost_event.lost fields reported. | ||
| 32 | * | ||
| 33 | * The total_period is needed because by default auto-freq is used, so | ||
| 34 | * multipling nr_events[PERF_EVENT_SAMPLE] by a frequency isn't possible to get | ||
| 35 | * the total number of low level events, it is necessary to to sum all struct | ||
| 36 | * sample_event.period and stash the result in total_period. | ||
| 37 | */ | ||
| 38 | struct events_stats { | ||
| 39 | u64 total_period; | ||
| 40 | u64 total_non_filtered_period; | ||
| 41 | u64 total_lost; | ||
| 42 | u64 total_invalid_chains; | ||
| 43 | u32 nr_events[PERF_RECORD_HEADER_MAX]; | ||
| 44 | u32 nr_non_filtered_samples; | ||
| 45 | u32 nr_lost_warned; | ||
| 46 | u32 nr_unknown_events; | ||
| 47 | u32 nr_invalid_chains; | ||
| 48 | u32 nr_unknown_id; | ||
| 49 | u32 nr_unprocessable_samples; | ||
| 50 | }; | ||
| 51 | |||
| 52 | enum hist_column { | 25 | enum hist_column { |
| 53 | HISTC_SYMBOL, | 26 | HISTC_SYMBOL, |
| 54 | HISTC_DSO, | 27 | HISTC_DSO, |
| @@ -165,6 +138,7 @@ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); | |||
| 165 | 138 | ||
| 166 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | 139 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, |
| 167 | int max_cols, float min_pcnt, FILE *fp); | 140 | int max_cols, float min_pcnt, FILE *fp); |
| 141 | size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp); | ||
| 168 | 142 | ||
| 169 | void hists__filter_by_dso(struct hists *hists); | 143 | void hists__filter_by_dso(struct hists *hists); |
| 170 | void hists__filter_by_thread(struct hists *hists); | 144 | void hists__filter_by_thread(struct hists *hists); |
| @@ -185,6 +159,25 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *he); | |||
| 185 | void hists__match(struct hists *leader, struct hists *other); | 159 | void hists__match(struct hists *leader, struct hists *other); |
| 186 | int hists__link(struct hists *leader, struct hists *other); | 160 | int hists__link(struct hists *leader, struct hists *other); |
| 187 | 161 | ||
| 162 | struct hists_evsel { | ||
| 163 | struct perf_evsel evsel; | ||
| 164 | struct hists hists; | ||
| 165 | }; | ||
| 166 | |||
| 167 | static inline struct perf_evsel *hists_to_evsel(struct hists *hists) | ||
| 168 | { | ||
| 169 | struct hists_evsel *hevsel = container_of(hists, struct hists_evsel, hists); | ||
| 170 | return &hevsel->evsel; | ||
| 171 | } | ||
| 172 | |||
| 173 | static inline struct hists *evsel__hists(struct perf_evsel *evsel) | ||
| 174 | { | ||
| 175 | struct hists_evsel *hevsel = (struct hists_evsel *)evsel; | ||
| 176 | return &hevsel->hists; | ||
| 177 | } | ||
| 178 | |||
| 179 | int hists__init(void); | ||
| 180 | |||
| 188 | struct perf_hpp { | 181 | struct perf_hpp { |
| 189 | char *buf; | 182 | char *buf; |
| 190 | size_t size; | 183 | size_t size; |
diff --git a/tools/perf/util/include/linux/string.h b/tools/perf/util/include/linux/string.h index 97a800738226..6f19c548ecc0 100644 --- a/tools/perf/util/include/linux/string.h +++ b/tools/perf/util/include/linux/string.h | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | #include <string.h> | 1 | #include <string.h> |
| 2 | 2 | ||
| 3 | void *memdup(const void *src, size_t len); | 3 | void *memdup(const void *src, size_t len); |
| 4 | int str_append(char **s, int *len, const char *a); | ||
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index b7d477fbda02..34fc7c8672e4 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
| @@ -13,12 +13,18 @@ | |||
| 13 | #include <symbol/kallsyms.h> | 13 | #include <symbol/kallsyms.h> |
| 14 | #include "unwind.h" | 14 | #include "unwind.h" |
| 15 | 15 | ||
| 16 | static void dsos__init(struct dsos *dsos) | ||
| 17 | { | ||
| 18 | INIT_LIST_HEAD(&dsos->head); | ||
| 19 | dsos->root = RB_ROOT; | ||
| 20 | } | ||
| 21 | |||
| 16 | int machine__init(struct machine *machine, const char *root_dir, pid_t pid) | 22 | int machine__init(struct machine *machine, const char *root_dir, pid_t pid) |
| 17 | { | 23 | { |
| 18 | map_groups__init(&machine->kmaps); | 24 | map_groups__init(&machine->kmaps); |
| 19 | RB_CLEAR_NODE(&machine->rb_node); | 25 | RB_CLEAR_NODE(&machine->rb_node); |
| 20 | INIT_LIST_HEAD(&machine->user_dsos.head); | 26 | dsos__init(&machine->user_dsos); |
| 21 | INIT_LIST_HEAD(&machine->kernel_dsos.head); | 27 | dsos__init(&machine->kernel_dsos); |
| 22 | 28 | ||
| 23 | machine->threads = RB_ROOT; | 29 | machine->threads = RB_ROOT; |
| 24 | INIT_LIST_HEAD(&machine->dead_threads); | 30 | INIT_LIST_HEAD(&machine->dead_threads); |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index b7090596ac50..2137c4596ec7 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
| @@ -556,7 +556,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, | |||
| 556 | 556 | ||
| 557 | int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter) | 557 | int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter) |
| 558 | { | 558 | { |
| 559 | if (ams->addr < ams->map->start || ams->addr > ams->map->end) { | 559 | if (ams->addr < ams->map->start || ams->addr >= ams->map->end) { |
| 560 | if (ams->map->groups == NULL) | 560 | if (ams->map->groups == NULL) |
| 561 | return -1; | 561 | return -1; |
| 562 | ams->map = map_groups__find(ams->map->groups, ams->map->type, | 562 | ams->map = map_groups__find(ams->map->groups, ams->map->type, |
| @@ -664,7 +664,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, | |||
| 664 | goto move_map; | 664 | goto move_map; |
| 665 | } | 665 | } |
| 666 | 666 | ||
| 667 | before->end = map->start - 1; | 667 | before->end = map->start; |
| 668 | map_groups__insert(mg, before); | 668 | map_groups__insert(mg, before); |
| 669 | if (verbose >= 2) | 669 | if (verbose >= 2) |
| 670 | map__fprintf(before, fp); | 670 | map__fprintf(before, fp); |
| @@ -678,7 +678,7 @@ int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, | |||
| 678 | goto move_map; | 678 | goto move_map; |
| 679 | } | 679 | } |
| 680 | 680 | ||
| 681 | after->start = map->end + 1; | 681 | after->start = map->end; |
| 682 | map_groups__insert(mg, after); | 682 | map_groups__insert(mg, after); |
| 683 | if (verbose >= 2) | 683 | if (verbose >= 2) |
| 684 | map__fprintf(after, fp); | 684 | map__fprintf(after, fp); |
| @@ -752,7 +752,7 @@ struct map *maps__find(struct rb_root *maps, u64 ip) | |||
| 752 | m = rb_entry(parent, struct map, rb_node); | 752 | m = rb_entry(parent, struct map, rb_node); |
| 753 | if (ip < m->start) | 753 | if (ip < m->start) |
| 754 | p = &(*p)->rb_left; | 754 | p = &(*p)->rb_left; |
| 755 | else if (ip > m->end) | 755 | else if (ip >= m->end) |
| 756 | p = &(*p)->rb_right; | 756 | p = &(*p)->rb_right; |
| 757 | else | 757 | else |
| 758 | return m; | 758 | return m; |
diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index 706ce1a66169..fd4be94125fb 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | #include <linux/list.h> | 1 | #include <linux/list.h> |
| 2 | #include <linux/compiler.h> | 2 | #include <linux/compiler.h> |
| 3 | #include <linux/string.h> | ||
| 3 | #include "ordered-events.h" | 4 | #include "ordered-events.h" |
| 4 | #include "evlist.h" | 5 | #include "evlist.h" |
| 5 | #include "session.h" | 6 | #include "session.h" |
| @@ -57,11 +58,45 @@ static void queue_event(struct ordered_events *oe, struct ordered_event *new) | |||
| 57 | } | 58 | } |
| 58 | } | 59 | } |
| 59 | 60 | ||
| 61 | static union perf_event *__dup_event(struct ordered_events *oe, | ||
| 62 | union perf_event *event) | ||
| 63 | { | ||
| 64 | union perf_event *new_event = NULL; | ||
| 65 | |||
| 66 | if (oe->cur_alloc_size < oe->max_alloc_size) { | ||
| 67 | new_event = memdup(event, event->header.size); | ||
| 68 | if (new_event) | ||
| 69 | oe->cur_alloc_size += event->header.size; | ||
| 70 | } | ||
| 71 | |||
| 72 | return new_event; | ||
| 73 | } | ||
| 74 | |||
| 75 | static union perf_event *dup_event(struct ordered_events *oe, | ||
| 76 | union perf_event *event) | ||
| 77 | { | ||
| 78 | return oe->copy_on_queue ? __dup_event(oe, event) : event; | ||
| 79 | } | ||
| 80 | |||
| 81 | static void free_dup_event(struct ordered_events *oe, union perf_event *event) | ||
| 82 | { | ||
| 83 | if (oe->copy_on_queue) { | ||
| 84 | oe->cur_alloc_size -= event->header.size; | ||
| 85 | free(event); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 60 | #define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) | 89 | #define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) |
| 61 | static struct ordered_event *alloc_event(struct ordered_events *oe) | 90 | static struct ordered_event *alloc_event(struct ordered_events *oe, |
| 91 | union perf_event *event) | ||
| 62 | { | 92 | { |
| 63 | struct list_head *cache = &oe->cache; | 93 | struct list_head *cache = &oe->cache; |
| 64 | struct ordered_event *new = NULL; | 94 | struct ordered_event *new = NULL; |
| 95 | union perf_event *new_event; | ||
| 96 | |||
| 97 | new_event = dup_event(oe, event); | ||
| 98 | if (!new_event) | ||
| 99 | return NULL; | ||
| 65 | 100 | ||
| 66 | if (!list_empty(cache)) { | 101 | if (!list_empty(cache)) { |
| 67 | new = list_entry(cache->next, struct ordered_event, list); | 102 | new = list_entry(cache->next, struct ordered_event, list); |
| @@ -74,8 +109,10 @@ static struct ordered_event *alloc_event(struct ordered_events *oe) | |||
| 74 | size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); | 109 | size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); |
| 75 | 110 | ||
| 76 | oe->buffer = malloc(size); | 111 | oe->buffer = malloc(size); |
| 77 | if (!oe->buffer) | 112 | if (!oe->buffer) { |
| 113 | free_dup_event(oe, new_event); | ||
| 78 | return NULL; | 114 | return NULL; |
| 115 | } | ||
| 79 | 116 | ||
| 80 | pr("alloc size %" PRIu64 "B (+%zu), max %" PRIu64 "B\n", | 117 | pr("alloc size %" PRIu64 "B (+%zu), max %" PRIu64 "B\n", |
| 81 | oe->cur_alloc_size, size, oe->max_alloc_size); | 118 | oe->cur_alloc_size, size, oe->max_alloc_size); |
| @@ -90,15 +127,17 @@ static struct ordered_event *alloc_event(struct ordered_events *oe) | |||
| 90 | pr("allocation limit reached %" PRIu64 "B\n", oe->max_alloc_size); | 127 | pr("allocation limit reached %" PRIu64 "B\n", oe->max_alloc_size); |
| 91 | } | 128 | } |
| 92 | 129 | ||
| 130 | new->event = new_event; | ||
| 93 | return new; | 131 | return new; |
| 94 | } | 132 | } |
| 95 | 133 | ||
| 96 | struct ordered_event * | 134 | struct ordered_event * |
| 97 | ordered_events__new(struct ordered_events *oe, u64 timestamp) | 135 | ordered_events__new(struct ordered_events *oe, u64 timestamp, |
| 136 | union perf_event *event) | ||
| 98 | { | 137 | { |
| 99 | struct ordered_event *new; | 138 | struct ordered_event *new; |
| 100 | 139 | ||
| 101 | new = alloc_event(oe); | 140 | new = alloc_event(oe, event); |
| 102 | if (new) { | 141 | if (new) { |
| 103 | new->timestamp = timestamp; | 142 | new->timestamp = timestamp; |
| 104 | queue_event(oe, new); | 143 | queue_event(oe, new); |
| @@ -111,6 +150,7 @@ void ordered_events__delete(struct ordered_events *oe, struct ordered_event *eve | |||
| 111 | { | 150 | { |
| 112 | list_move(&event->list, &oe->cache); | 151 | list_move(&event->list, &oe->cache); |
| 113 | oe->nr_events--; | 152 | oe->nr_events--; |
| 153 | free_dup_event(oe, event->event); | ||
| 114 | } | 154 | } |
| 115 | 155 | ||
| 116 | static int __ordered_events__flush(struct perf_session *s, | 156 | static int __ordered_events__flush(struct perf_session *s, |
| @@ -240,6 +280,7 @@ void ordered_events__free(struct ordered_events *oe) | |||
| 240 | 280 | ||
| 241 | event = list_entry(oe->to_free.next, struct ordered_event, list); | 281 | event = list_entry(oe->to_free.next, struct ordered_event, list); |
| 242 | list_del(&event->list); | 282 | list_del(&event->list); |
| 283 | free_dup_event(oe, event->event); | ||
| 243 | free(event); | 284 | free(event); |
| 244 | } | 285 | } |
| 245 | } | 286 | } |
diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h index 3b2f20542a01..7b8f9b011f38 100644 --- a/tools/perf/util/ordered-events.h +++ b/tools/perf/util/ordered-events.h | |||
| @@ -34,9 +34,11 @@ struct ordered_events { | |||
| 34 | int buffer_idx; | 34 | int buffer_idx; |
| 35 | unsigned int nr_events; | 35 | unsigned int nr_events; |
| 36 | enum oe_flush last_flush_type; | 36 | enum oe_flush last_flush_type; |
| 37 | bool copy_on_queue; | ||
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | struct ordered_event *ordered_events__new(struct ordered_events *oe, u64 timestamp); | 40 | struct ordered_event *ordered_events__new(struct ordered_events *oe, u64 timestamp, |
| 41 | union perf_event *event); | ||
| 40 | void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event); | 42 | void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event); |
| 41 | int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, | 43 | int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, |
| 42 | enum oe_flush how); | 44 | enum oe_flush how); |
| @@ -48,4 +50,10 @@ void ordered_events__set_alloc_size(struct ordered_events *oe, u64 size) | |||
| 48 | { | 50 | { |
| 49 | oe->max_alloc_size = size; | 51 | oe->max_alloc_size = size; |
| 50 | } | 52 | } |
| 53 | |||
| 54 | static inline | ||
| 55 | void ordered_events__set_copy_on_queue(struct ordered_events *oe, bool copy) | ||
| 56 | { | ||
| 57 | oe->copy_on_queue = copy; | ||
| 58 | } | ||
| 51 | #endif /* __ORDERED_EVENTS_H */ | 59 | #endif /* __ORDERED_EVENTS_H */ |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d76aa30cb1fb..c659a3ca1283 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include "parse-options.h" | 6 | #include "parse-options.h" |
| 7 | #include "parse-events.h" | 7 | #include "parse-events.h" |
| 8 | #include "exec_cmd.h" | 8 | #include "exec_cmd.h" |
| 9 | #include "linux/string.h" | 9 | #include "string.h" |
| 10 | #include "symbol.h" | 10 | #include "symbol.h" |
| 11 | #include "cache.h" | 11 | #include "cache.h" |
| 12 | #include "header.h" | 12 | #include "header.h" |
| @@ -30,6 +30,15 @@ extern int parse_events_debug; | |||
| 30 | #endif | 30 | #endif |
| 31 | int parse_events_parse(void *data, void *scanner); | 31 | int parse_events_parse(void *data, void *scanner); |
| 32 | 32 | ||
| 33 | static struct perf_pmu_event_symbol *perf_pmu_events_list; | ||
| 34 | /* | ||
| 35 | * The variable indicates the number of supported pmu event symbols. | ||
| 36 | * 0 means not initialized and ready to init | ||
| 37 | * -1 means failed to init, don't try anymore | ||
| 38 | * >0 is the number of supported pmu event symbols | ||
| 39 | */ | ||
| 40 | static int perf_pmu_events_list_num; | ||
| 41 | |||
| 33 | static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = { | 42 | static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = { |
| 34 | [PERF_COUNT_HW_CPU_CYCLES] = { | 43 | [PERF_COUNT_HW_CPU_CYCLES] = { |
| 35 | .symbol = "cpu-cycles", | 44 | .symbol = "cpu-cycles", |
| @@ -863,30 +872,111 @@ int parse_events_name(struct list_head *list, char *name) | |||
| 863 | return 0; | 872 | return 0; |
| 864 | } | 873 | } |
| 865 | 874 | ||
| 866 | static int parse_events__scanner(const char *str, void *data, int start_token); | 875 | static int |
| 876 | comp_pmu(const void *p1, const void *p2) | ||
| 877 | { | ||
| 878 | struct perf_pmu_event_symbol *pmu1 = (struct perf_pmu_event_symbol *) p1; | ||
| 879 | struct perf_pmu_event_symbol *pmu2 = (struct perf_pmu_event_symbol *) p2; | ||
| 867 | 880 | ||
| 868 | static int parse_events_fixup(int ret, const char *str, void *data, | 881 | return strcmp(pmu1->symbol, pmu2->symbol); |
| 869 | int start_token) | 882 | } |
| 883 | |||
| 884 | static void perf_pmu__parse_cleanup(void) | ||
| 870 | { | 885 | { |
| 871 | char *o = strdup(str); | 886 | if (perf_pmu_events_list_num > 0) { |
| 872 | char *s = NULL; | 887 | struct perf_pmu_event_symbol *p; |
| 873 | char *t = o; | 888 | int i; |
| 874 | char *p; | 889 | |
| 890 | for (i = 0; i < perf_pmu_events_list_num; i++) { | ||
| 891 | p = perf_pmu_events_list + i; | ||
| 892 | free(p->symbol); | ||
| 893 | } | ||
| 894 | free(perf_pmu_events_list); | ||
| 895 | perf_pmu_events_list = NULL; | ||
| 896 | perf_pmu_events_list_num = 0; | ||
| 897 | } | ||
| 898 | } | ||
| 899 | |||
| 900 | #define SET_SYMBOL(str, stype) \ | ||
| 901 | do { \ | ||
| 902 | p->symbol = str; \ | ||
| 903 | if (!p->symbol) \ | ||
| 904 | goto err; \ | ||
| 905 | p->type = stype; \ | ||
| 906 | } while (0) | ||
| 907 | |||
| 908 | /* | ||
| 909 | * Read the pmu events list from sysfs | ||
| 910 | * Save it into perf_pmu_events_list | ||
| 911 | */ | ||
| 912 | static void perf_pmu__parse_init(void) | ||
| 913 | { | ||
| 914 | |||
| 915 | struct perf_pmu *pmu = NULL; | ||
| 916 | struct perf_pmu_alias *alias; | ||
| 875 | int len = 0; | 917 | int len = 0; |
| 876 | 918 | ||
| 877 | if (!o) | 919 | pmu = perf_pmu__find("cpu"); |
| 878 | return ret; | 920 | if ((pmu == NULL) || list_empty(&pmu->aliases)) { |
| 879 | while ((p = strsep(&t, ",")) != NULL) { | 921 | perf_pmu_events_list_num = -1; |
| 880 | if (s) | 922 | return; |
| 881 | str_append(&s, &len, ","); | ||
| 882 | str_append(&s, &len, "cpu/"); | ||
| 883 | str_append(&s, &len, p); | ||
| 884 | str_append(&s, &len, "/"); | ||
| 885 | } | 923 | } |
| 886 | free(o); | 924 | list_for_each_entry(alias, &pmu->aliases, list) { |
| 887 | if (!s) | 925 | if (strchr(alias->name, '-')) |
| 888 | return -ENOMEM; | 926 | len++; |
| 889 | return parse_events__scanner(s, data, start_token); | 927 | len++; |
| 928 | } | ||
| 929 | perf_pmu_events_list = malloc(sizeof(struct perf_pmu_event_symbol) * len); | ||
| 930 | if (!perf_pmu_events_list) | ||
| 931 | return; | ||
| 932 | perf_pmu_events_list_num = len; | ||
| 933 | |||
| 934 | len = 0; | ||
| 935 | list_for_each_entry(alias, &pmu->aliases, list) { | ||
| 936 | struct perf_pmu_event_symbol *p = perf_pmu_events_list + len; | ||
| 937 | char *tmp = strchr(alias->name, '-'); | ||
| 938 | |||
| 939 | if (tmp != NULL) { | ||
| 940 | SET_SYMBOL(strndup(alias->name, tmp - alias->name), | ||
| 941 | PMU_EVENT_SYMBOL_PREFIX); | ||
| 942 | p++; | ||
| 943 | SET_SYMBOL(strdup(++tmp), PMU_EVENT_SYMBOL_SUFFIX); | ||
| 944 | len += 2; | ||
| 945 | } else { | ||
| 946 | SET_SYMBOL(strdup(alias->name), PMU_EVENT_SYMBOL); | ||
| 947 | len++; | ||
| 948 | } | ||
| 949 | } | ||
| 950 | qsort(perf_pmu_events_list, len, | ||
| 951 | sizeof(struct perf_pmu_event_symbol), comp_pmu); | ||
| 952 | |||
| 953 | return; | ||
| 954 | err: | ||
| 955 | perf_pmu__parse_cleanup(); | ||
| 956 | } | ||
| 957 | |||
| 958 | enum perf_pmu_event_symbol_type | ||
| 959 | perf_pmu__parse_check(const char *name) | ||
| 960 | { | ||
| 961 | struct perf_pmu_event_symbol p, *r; | ||
| 962 | |||
| 963 | /* scan kernel pmu events from sysfs if needed */ | ||
| 964 | if (perf_pmu_events_list_num == 0) | ||
| 965 | perf_pmu__parse_init(); | ||
| 966 | /* | ||
| 967 | * name "cpu" could be prefix of cpu-cycles or cpu// events. | ||
| 968 | * cpu-cycles has been handled by hardcode. | ||
| 969 | * So it must be cpu// events, not kernel pmu event. | ||
| 970 | */ | ||
| 971 | if ((perf_pmu_events_list_num <= 0) || !strcmp(name, "cpu")) | ||
| 972 | return PMU_EVENT_SYMBOL_ERR; | ||
| 973 | |||
| 974 | p.symbol = strdup(name); | ||
| 975 | r = bsearch(&p, perf_pmu_events_list, | ||
| 976 | (size_t) perf_pmu_events_list_num, | ||
| 977 | sizeof(struct perf_pmu_event_symbol), comp_pmu); | ||
| 978 | free(p.symbol); | ||
| 979 | return r ? r->type : PMU_EVENT_SYMBOL_ERR; | ||
| 890 | } | 980 | } |
| 891 | 981 | ||
| 892 | static int parse_events__scanner(const char *str, void *data, int start_token) | 982 | static int parse_events__scanner(const char *str, void *data, int start_token) |
| @@ -909,8 +999,6 @@ static int parse_events__scanner(const char *str, void *data, int start_token) | |||
| 909 | parse_events__flush_buffer(buffer, scanner); | 999 | parse_events__flush_buffer(buffer, scanner); |
| 910 | parse_events__delete_buffer(buffer, scanner); | 1000 | parse_events__delete_buffer(buffer, scanner); |
| 911 | parse_events_lex_destroy(scanner); | 1001 | parse_events_lex_destroy(scanner); |
| 912 | if (ret && !strchr(str, '/')) | ||
| 913 | ret = parse_events_fixup(ret, str, data, start_token); | ||
| 914 | return ret; | 1002 | return ret; |
| 915 | } | 1003 | } |
| 916 | 1004 | ||
| @@ -945,6 +1033,7 @@ int parse_events(struct perf_evlist *evlist, const char *str) | |||
| 945 | int ret; | 1033 | int ret; |
| 946 | 1034 | ||
| 947 | ret = parse_events__scanner(str, &data, PE_START_EVENTS); | 1035 | ret = parse_events__scanner(str, &data, PE_START_EVENTS); |
| 1036 | perf_pmu__parse_cleanup(); | ||
| 948 | if (!ret) { | 1037 | if (!ret) { |
| 949 | int entries = data.idx - evlist->nr_entries; | 1038 | int entries = data.idx - evlist->nr_entries; |
| 950 | perf_evlist__splice_list_tail(evlist, &data.list, entries); | 1039 | perf_evlist__splice_list_tail(evlist, &data.list, entries); |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index df094b4ed5ed..db2cf78ff0f3 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
| @@ -35,6 +35,18 @@ extern int parse_filter(const struct option *opt, const char *str, int unset); | |||
| 35 | 35 | ||
| 36 | #define EVENTS_HELP_MAX (128*1024) | 36 | #define EVENTS_HELP_MAX (128*1024) |
| 37 | 37 | ||
| 38 | enum perf_pmu_event_symbol_type { | ||
| 39 | PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */ | ||
| 40 | PMU_EVENT_SYMBOL, /* normal style PMU event */ | ||
| 41 | PMU_EVENT_SYMBOL_PREFIX, /* prefix of pre-suf style event */ | ||
| 42 | PMU_EVENT_SYMBOL_SUFFIX, /* suffix of pre-suf style event */ | ||
| 43 | }; | ||
| 44 | |||
| 45 | struct perf_pmu_event_symbol { | ||
| 46 | char *symbol; | ||
| 47 | enum perf_pmu_event_symbol_type type; | ||
| 48 | }; | ||
| 49 | |||
| 38 | enum { | 50 | enum { |
| 39 | PARSE_EVENTS__TERM_TYPE_NUM, | 51 | PARSE_EVENTS__TERM_TYPE_NUM, |
| 40 | PARSE_EVENTS__TERM_TYPE_STR, | 52 | PARSE_EVENTS__TERM_TYPE_STR, |
| @@ -95,6 +107,8 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx, | |||
| 95 | void *ptr, char *type); | 107 | void *ptr, char *type); |
| 96 | int parse_events_add_pmu(struct list_head *list, int *idx, | 108 | int parse_events_add_pmu(struct list_head *list, int *idx, |
| 97 | char *pmu , struct list_head *head_config); | 109 | char *pmu , struct list_head *head_config); |
| 110 | enum perf_pmu_event_symbol_type | ||
| 111 | perf_pmu__parse_check(const char *name); | ||
| 98 | void parse_events__set_leader(char *name, struct list_head *list); | 112 | void parse_events__set_leader(char *name, struct list_head *list); |
| 99 | void parse_events_update_lists(struct list_head *list_event, | 113 | void parse_events_update_lists(struct list_head *list_event, |
| 100 | struct list_head *list_all); | 114 | struct list_head *list_all); |
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 343299575b30..906630bbf8eb 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l | |||
| @@ -51,6 +51,24 @@ static int str(yyscan_t scanner, int token) | |||
| 51 | return token; | 51 | return token; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | static int pmu_str_check(yyscan_t scanner) | ||
| 55 | { | ||
| 56 | YYSTYPE *yylval = parse_events_get_lval(scanner); | ||
| 57 | char *text = parse_events_get_text(scanner); | ||
| 58 | |||
| 59 | yylval->str = strdup(text); | ||
| 60 | switch (perf_pmu__parse_check(text)) { | ||
| 61 | case PMU_EVENT_SYMBOL_PREFIX: | ||
| 62 | return PE_PMU_EVENT_PRE; | ||
| 63 | case PMU_EVENT_SYMBOL_SUFFIX: | ||
| 64 | return PE_PMU_EVENT_SUF; | ||
| 65 | case PMU_EVENT_SYMBOL: | ||
| 66 | return PE_KERNEL_PMU_EVENT; | ||
| 67 | default: | ||
| 68 | return PE_NAME; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 54 | static int sym(yyscan_t scanner, int type, int config) | 72 | static int sym(yyscan_t scanner, int type, int config) |
| 55 | { | 73 | { |
| 56 | YYSTYPE *yylval = parse_events_get_lval(scanner); | 74 | YYSTYPE *yylval = parse_events_get_lval(scanner); |
| @@ -178,6 +196,16 @@ alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_AL | |||
| 178 | emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } | 196 | emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } |
| 179 | dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); } | 197 | dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); } |
| 180 | 198 | ||
| 199 | /* | ||
| 200 | * We have to handle the kernel PMU event cycles-ct/cycles-t/mem-loads/mem-stores separately. | ||
| 201 | * Because the prefix cycles is mixed up with cpu-cycles. | ||
| 202 | * loads and stores are mixed up with cache event | ||
| 203 | */ | ||
| 204 | cycles-ct { return str(yyscanner, PE_KERNEL_PMU_EVENT); } | ||
| 205 | cycles-t { return str(yyscanner, PE_KERNEL_PMU_EVENT); } | ||
| 206 | mem-loads { return str(yyscanner, PE_KERNEL_PMU_EVENT); } | ||
| 207 | mem-stores { return str(yyscanner, PE_KERNEL_PMU_EVENT); } | ||
| 208 | |||
| 181 | L1-dcache|l1-d|l1d|L1-data | | 209 | L1-dcache|l1-d|l1d|L1-data | |
| 182 | L1-icache|l1-i|l1i|L1-instruction | | 210 | L1-icache|l1-i|l1i|L1-instruction | |
| 183 | LLC|L2 | | 211 | LLC|L2 | |
| @@ -199,7 +227,7 @@ r{num_raw_hex} { return raw(yyscanner); } | |||
| 199 | {num_hex} { return value(yyscanner, 16); } | 227 | {num_hex} { return value(yyscanner, 16); } |
| 200 | 228 | ||
| 201 | {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } | 229 | {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } |
| 202 | {name} { return str(yyscanner, PE_NAME); } | 230 | {name} { return pmu_str_check(yyscanner); } |
| 203 | "/" { BEGIN(config); return '/'; } | 231 | "/" { BEGIN(config); return '/'; } |
| 204 | - { return '-'; } | 232 | - { return '-'; } |
| 205 | , { BEGIN(event); return ','; } | 233 | , { BEGIN(event); return ','; } |
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 55fab6ad609a..93c4c9fbc922 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
| @@ -47,6 +47,7 @@ static inc_group_count(struct list_head *list, | |||
| 47 | %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT | 47 | %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT |
| 48 | %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP | 48 | %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP |
| 49 | %token PE_ERROR | 49 | %token PE_ERROR |
| 50 | %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT | ||
| 50 | %type <num> PE_VALUE | 51 | %type <num> PE_VALUE |
| 51 | %type <num> PE_VALUE_SYM_HW | 52 | %type <num> PE_VALUE_SYM_HW |
| 52 | %type <num> PE_VALUE_SYM_SW | 53 | %type <num> PE_VALUE_SYM_SW |
| @@ -58,6 +59,7 @@ static inc_group_count(struct list_head *list, | |||
| 58 | %type <str> PE_MODIFIER_EVENT | 59 | %type <str> PE_MODIFIER_EVENT |
| 59 | %type <str> PE_MODIFIER_BP | 60 | %type <str> PE_MODIFIER_BP |
| 60 | %type <str> PE_EVENT_NAME | 61 | %type <str> PE_EVENT_NAME |
| 62 | %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT | ||
| 61 | %type <num> value_sym | 63 | %type <num> value_sym |
| 62 | %type <head> event_config | 64 | %type <head> event_config |
| 63 | %type <term> event_term | 65 | %type <term> event_term |
| @@ -220,6 +222,44 @@ PE_NAME '/' '/' | |||
| 220 | ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL)); | 222 | ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, NULL)); |
| 221 | $$ = list; | 223 | $$ = list; |
| 222 | } | 224 | } |
| 225 | | | ||
| 226 | PE_KERNEL_PMU_EVENT sep_dc | ||
| 227 | { | ||
| 228 | struct parse_events_evlist *data = _data; | ||
| 229 | struct list_head *head; | ||
| 230 | struct parse_events_term *term; | ||
| 231 | struct list_head *list; | ||
| 232 | |||
| 233 | ALLOC_LIST(head); | ||
| 234 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, | ||
| 235 | $1, 1)); | ||
| 236 | list_add_tail(&term->list, head); | ||
| 237 | |||
| 238 | ALLOC_LIST(list); | ||
| 239 | ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); | ||
| 240 | parse_events__free_terms(head); | ||
| 241 | $$ = list; | ||
| 242 | } | ||
| 243 | | | ||
| 244 | PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc | ||
| 245 | { | ||
| 246 | struct parse_events_evlist *data = _data; | ||
| 247 | struct list_head *head; | ||
| 248 | struct parse_events_term *term; | ||
| 249 | struct list_head *list; | ||
| 250 | char pmu_name[128]; | ||
| 251 | snprintf(&pmu_name, 128, "%s-%s", $1, $3); | ||
| 252 | |||
| 253 | ALLOC_LIST(head); | ||
| 254 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, | ||
| 255 | &pmu_name, 1)); | ||
| 256 | list_add_tail(&term->list, head); | ||
| 257 | |||
| 258 | ALLOC_LIST(list); | ||
| 259 | ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); | ||
| 260 | parse_events__free_terms(head); | ||
| 261 | $$ = list; | ||
| 262 | } | ||
| 223 | 263 | ||
| 224 | value_sym: | 264 | value_sym: |
| 225 | PE_VALUE_SYM_HW | 265 | PE_VALUE_SYM_HW |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 93a41ca96b8e..e243ad962a4d 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
| @@ -12,16 +12,6 @@ | |||
| 12 | #include "parse-events.h" | 12 | #include "parse-events.h" |
| 13 | #include "cpumap.h" | 13 | #include "cpumap.h" |
| 14 | 14 | ||
| 15 | #define UNIT_MAX_LEN 31 /* max length for event unit name */ | ||
| 16 | |||
| 17 | struct perf_pmu_alias { | ||
| 18 | char *name; | ||
| 19 | struct list_head terms; /* HEAD struct parse_events_term -> list */ | ||
| 20 | struct list_head list; /* ELEM */ | ||
| 21 | char unit[UNIT_MAX_LEN+1]; | ||
| 22 | double scale; | ||
| 23 | }; | ||
| 24 | |||
| 25 | struct perf_pmu_format { | 15 | struct perf_pmu_format { |
| 26 | char *name; | 16 | char *name; |
| 27 | int value; | 17 | int value; |
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index fe90a012c003..fe9dfbee8eed 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h | |||
| @@ -30,6 +30,16 @@ struct perf_pmu_info { | |||
| 30 | double scale; | 30 | double scale; |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | #define UNIT_MAX_LEN 31 /* max length for event unit name */ | ||
| 34 | |||
| 35 | struct perf_pmu_alias { | ||
| 36 | char *name; | ||
| 37 | struct list_head terms; /* HEAD struct parse_events_term -> list */ | ||
| 38 | struct list_head list; /* ELEM */ | ||
| 39 | char unit[UNIT_MAX_LEN+1]; | ||
| 40 | double scale; | ||
| 41 | }; | ||
| 42 | |||
| 33 | struct perf_pmu *perf_pmu__find(const char *name); | 43 | struct perf_pmu *perf_pmu__find(const char *name); |
| 34 | int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, | 44 | int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, |
| 35 | struct list_head *head_terms); | 45 | struct list_head *head_terms); |
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 56ba07cce549..496f21cadd97 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | 28 | ||
| 29 | #include "../../perf.h" | 29 | #include "../../perf.h" |
| 30 | #include "../debug.h" | 30 | #include "../debug.h" |
| 31 | #include "../callchain.h" | ||
| 31 | #include "../evsel.h" | 32 | #include "../evsel.h" |
| 32 | #include "../util.h" | 33 | #include "../util.h" |
| 33 | #include "../event.h" | 34 | #include "../event.h" |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 883406f4b381..6702ac28754b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -532,17 +532,16 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event, | |||
| 532 | return -EINVAL; | 532 | return -EINVAL; |
| 533 | } | 533 | } |
| 534 | 534 | ||
| 535 | new = ordered_events__new(oe, timestamp); | 535 | new = ordered_events__new(oe, timestamp, event); |
| 536 | if (!new) { | 536 | if (!new) { |
| 537 | ordered_events__flush(s, tool, OE_FLUSH__HALF); | 537 | ordered_events__flush(s, tool, OE_FLUSH__HALF); |
| 538 | new = ordered_events__new(oe, timestamp); | 538 | new = ordered_events__new(oe, timestamp, event); |
| 539 | } | 539 | } |
| 540 | 540 | ||
| 541 | if (!new) | 541 | if (!new) |
| 542 | return -ENOMEM; | 542 | return -ENOMEM; |
| 543 | 543 | ||
| 544 | new->file_offset = file_offset; | 544 | new->file_offset = file_offset; |
| 545 | new->event = event; | ||
| 546 | return 0; | 545 | return 0; |
| 547 | } | 546 | } |
| 548 | 547 | ||
| @@ -813,22 +812,6 @@ int perf_session__deliver_event(struct perf_session *session, | |||
| 813 | dump_event(session, event, file_offset, sample); | 812 | dump_event(session, event, file_offset, sample); |
| 814 | 813 | ||
| 815 | evsel = perf_evlist__id2evsel(session->evlist, sample->id); | 814 | evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
| 816 | if (evsel != NULL && event->header.type != PERF_RECORD_SAMPLE) { | ||
| 817 | /* | ||
| 818 | * XXX We're leaving PERF_RECORD_SAMPLE unnacounted here | ||
| 819 | * because the tools right now may apply filters, discarding | ||
| 820 | * some of the samples. For consistency, in the future we | ||
| 821 | * should have something like nr_filtered_samples and remove | ||
| 822 | * the sample->period from total_sample_period, etc, KISS for | ||
| 823 | * now tho. | ||
| 824 | * | ||
| 825 | * Also testing against NULL allows us to handle files without | ||
| 826 | * attr.sample_id_all and/or without PERF_SAMPLE_ID. In the | ||
| 827 | * future probably it'll be a good idea to restrict event | ||
| 828 | * processing via perf_session to files with both set. | ||
| 829 | */ | ||
| 830 | hists__inc_nr_events(&evsel->hists, event->header.type); | ||
| 831 | } | ||
| 832 | 815 | ||
| 833 | machine = perf_session__find_machine_for_cpumode(session, event, | 816 | machine = perf_session__find_machine_for_cpumode(session, event, |
| 834 | sample); | 817 | sample); |
| @@ -1391,16 +1374,9 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *session, FILE *fp | |||
| 1391 | 1374 | ||
| 1392 | size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) | 1375 | size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) |
| 1393 | { | 1376 | { |
| 1394 | struct perf_evsel *pos; | ||
| 1395 | size_t ret = fprintf(fp, "Aggregated stats:\n"); | 1377 | size_t ret = fprintf(fp, "Aggregated stats:\n"); |
| 1396 | 1378 | ||
| 1397 | ret += events_stats__fprintf(&session->stats, fp); | 1379 | ret += events_stats__fprintf(&session->stats, fp); |
| 1398 | |||
| 1399 | evlist__for_each(session->evlist, pos) { | ||
| 1400 | ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); | ||
| 1401 | ret += events_stats__fprintf(&pos->hists.stats, fp); | ||
| 1402 | } | ||
| 1403 | |||
| 1404 | return ret; | 1380 | return ret; |
| 1405 | } | 1381 | } |
| 1406 | 1382 | ||
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index ffb440462008..a4be851f1a90 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #define __PERF_SESSION_H | 2 | #define __PERF_SESSION_H |
| 3 | 3 | ||
| 4 | #include "trace-event.h" | 4 | #include "trace-event.h" |
| 5 | #include "hist.h" | ||
| 6 | #include "event.h" | 5 | #include "event.h" |
| 7 | #include "header.h" | 6 | #include "header.h" |
| 8 | #include "machine.h" | 7 | #include "machine.h" |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 289df9d1e65a..4906cd81cb56 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
| @@ -1218,7 +1218,7 @@ static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, | |||
| 1218 | hse = container_of(fmt, struct hpp_sort_entry, hpp); | 1218 | hse = container_of(fmt, struct hpp_sort_entry, hpp); |
| 1219 | 1219 | ||
| 1220 | if (!len) | 1220 | if (!len) |
| 1221 | len = hists__col_len(&evsel->hists, hse->se->se_width_idx); | 1221 | len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx); |
| 1222 | 1222 | ||
| 1223 | return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, fmt->name); | 1223 | return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, fmt->name); |
| 1224 | } | 1224 | } |
| @@ -1233,7 +1233,7 @@ static int __sort__hpp_width(struct perf_hpp_fmt *fmt, | |||
| 1233 | hse = container_of(fmt, struct hpp_sort_entry, hpp); | 1233 | hse = container_of(fmt, struct hpp_sort_entry, hpp); |
| 1234 | 1234 | ||
| 1235 | if (!len) | 1235 | if (!len) |
| 1236 | len = hists__col_len(&evsel->hists, hse->se->se_width_idx); | 1236 | len = hists__col_len(evsel__hists(evsel), hse->se->se_width_idx); |
| 1237 | 1237 | ||
| 1238 | return len; | 1238 | return len; |
| 1239 | } | 1239 | } |
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index d87767f76903..6afd6106ceb5 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
| @@ -357,27 +357,3 @@ void *memdup(const void *src, size_t len) | |||
| 357 | 357 | ||
| 358 | return p; | 358 | return p; |
| 359 | } | 359 | } |
| 360 | |||
| 361 | /** | ||
| 362 | * str_append - reallocate string and append another | ||
| 363 | * @s: pointer to string pointer | ||
| 364 | * @len: pointer to len (initialized) | ||
| 365 | * @a: string to append. | ||
| 366 | */ | ||
| 367 | int str_append(char **s, int *len, const char *a) | ||
| 368 | { | ||
| 369 | int olen = *s ? strlen(*s) : 0; | ||
| 370 | int nlen = olen + strlen(a) + 1; | ||
| 371 | if (*len < nlen) { | ||
| 372 | *len = *len * 2; | ||
| 373 | if (*len < nlen) | ||
| 374 | *len = nlen; | ||
| 375 | *s = realloc(*s, *len); | ||
| 376 | if (!*s) | ||
| 377 | return -ENOMEM; | ||
| 378 | if (olen == 0) | ||
| 379 | **s = 0; | ||
| 380 | } | ||
| 381 | strcat(*s, a); | ||
| 382 | return 0; | ||
| 383 | } | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index be84f7a9838b..078331140d8c 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -186,7 +186,7 @@ void symbols__fixup_end(struct rb_root *symbols) | |||
| 186 | curr = rb_entry(nd, struct symbol, rb_node); | 186 | curr = rb_entry(nd, struct symbol, rb_node); |
| 187 | 187 | ||
| 188 | if (prev->end == prev->start && prev->end != curr->start) | 188 | if (prev->end == prev->start && prev->end != curr->start) |
| 189 | prev->end = curr->start - 1; | 189 | prev->end = curr->start; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | /* Last entry */ | 192 | /* Last entry */ |
| @@ -207,7 +207,7 @@ void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) | |||
| 207 | for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { | 207 | for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { |
| 208 | prev = curr; | 208 | prev = curr; |
| 209 | curr = rb_entry(nd, struct map, rb_node); | 209 | curr = rb_entry(nd, struct map, rb_node); |
| 210 | prev->end = curr->start - 1; | 210 | prev->end = curr->start; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /* | 213 | /* |
| @@ -229,7 +229,7 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name) | |||
| 229 | sym = ((void *)sym) + symbol_conf.priv_size; | 229 | sym = ((void *)sym) + symbol_conf.priv_size; |
| 230 | 230 | ||
| 231 | sym->start = start; | 231 | sym->start = start; |
| 232 | sym->end = len ? start + len - 1 : start; | 232 | sym->end = len ? start + len : start; |
| 233 | sym->binding = binding; | 233 | sym->binding = binding; |
| 234 | sym->namelen = namelen - 1; | 234 | sym->namelen = namelen - 1; |
| 235 | 235 | ||
| @@ -325,7 +325,7 @@ static struct symbol *symbols__find(struct rb_root *symbols, u64 ip) | |||
| 325 | 325 | ||
| 326 | if (ip < s->start) | 326 | if (ip < s->start) |
| 327 | n = n->rb_left; | 327 | n = n->rb_left; |
| 328 | else if (ip > s->end) | 328 | else if (ip >= s->end) |
| 329 | n = n->rb_right; | 329 | n = n->rb_right; |
| 330 | else | 330 | else |
| 331 | return s; | 331 | return s; |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index bec4b7bd09de..eb2c19bf8d90 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -95,7 +95,7 @@ void symbols__delete(struct rb_root *symbols); | |||
| 95 | 95 | ||
| 96 | static inline size_t symbol__size(const struct symbol *sym) | 96 | static inline size_t symbol__size(const struct symbol *sym) |
| 97 | { | 97 | { |
| 98 | return sym->end - sym->start + 1; | 98 | return sym->end - sym->start; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | struct strlist; | 101 | struct strlist; |
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index a9df7f2c6dc9..2b7b2d91c016 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include "util.h" | 7 | #include "util.h" |
| 8 | #include "debug.h" | 8 | #include "debug.h" |
| 9 | #include "comm.h" | 9 | #include "comm.h" |
| 10 | #include "unwind.h" | ||
| 10 | 11 | ||
| 11 | int thread__init_map_groups(struct thread *thread, struct machine *machine) | 12 | int thread__init_map_groups(struct thread *thread, struct machine *machine) |
| 12 | { | 13 | { |
| @@ -37,6 +38,9 @@ struct thread *thread__new(pid_t pid, pid_t tid) | |||
| 37 | thread->cpu = -1; | 38 | thread->cpu = -1; |
| 38 | INIT_LIST_HEAD(&thread->comm_list); | 39 | INIT_LIST_HEAD(&thread->comm_list); |
| 39 | 40 | ||
| 41 | if (unwind__prepare_access(thread) < 0) | ||
| 42 | goto err_thread; | ||
| 43 | |||
| 40 | comm_str = malloc(32); | 44 | comm_str = malloc(32); |
| 41 | if (!comm_str) | 45 | if (!comm_str) |
| 42 | goto err_thread; | 46 | goto err_thread; |
| @@ -48,6 +52,7 @@ struct thread *thread__new(pid_t pid, pid_t tid) | |||
| 48 | goto err_thread; | 52 | goto err_thread; |
| 49 | 53 | ||
| 50 | list_add(&comm->list, &thread->comm_list); | 54 | list_add(&comm->list, &thread->comm_list); |
| 55 | |||
| 51 | } | 56 | } |
| 52 | 57 | ||
| 53 | return thread; | 58 | return thread; |
| @@ -69,6 +74,7 @@ void thread__delete(struct thread *thread) | |||
| 69 | list_del(&comm->list); | 74 | list_del(&comm->list); |
| 70 | comm__free(comm); | 75 | comm__free(comm); |
| 71 | } | 76 | } |
| 77 | unwind__finish_access(thread); | ||
| 72 | 78 | ||
| 73 | free(thread); | 79 | free(thread); |
| 74 | } | 80 | } |
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 5d3215912105..f93b9734735b 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c | |||
| @@ -214,6 +214,17 @@ out_free_threads: | |||
| 214 | goto out; | 214 | goto out; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | struct thread_map *thread_map__new_dummy(void) | ||
| 218 | { | ||
| 219 | struct thread_map *threads = malloc(sizeof(*threads) + sizeof(pid_t)); | ||
| 220 | |||
| 221 | if (threads != NULL) { | ||
| 222 | threads->map[0] = -1; | ||
| 223 | threads->nr = 1; | ||
| 224 | } | ||
| 225 | return threads; | ||
| 226 | } | ||
| 227 | |||
| 217 | static struct thread_map *thread_map__new_by_tid_str(const char *tid_str) | 228 | static struct thread_map *thread_map__new_by_tid_str(const char *tid_str) |
| 218 | { | 229 | { |
| 219 | struct thread_map *threads = NULL, *nt; | 230 | struct thread_map *threads = NULL, *nt; |
| @@ -224,14 +235,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str) | |||
| 224 | struct strlist *slist; | 235 | struct strlist *slist; |
| 225 | 236 | ||
| 226 | /* perf-stat expects threads to be generated even if tid not given */ | 237 | /* perf-stat expects threads to be generated even if tid not given */ |
| 227 | if (!tid_str) { | 238 | if (!tid_str) |
| 228 | threads = malloc(sizeof(*threads) + sizeof(pid_t)); | 239 | return thread_map__new_dummy(); |
| 229 | if (threads != NULL) { | ||
| 230 | threads->map[0] = -1; | ||
| 231 | threads->nr = 1; | ||
| 232 | } | ||
| 233 | return threads; | ||
| 234 | } | ||
| 235 | 240 | ||
| 236 | slist = strlist__new(false, tid_str); | 241 | slist = strlist__new(false, tid_str); |
| 237 | if (!slist) | 242 | if (!slist) |
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index 0cd8b3108084..95313f43cc0f 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h | |||
| @@ -9,6 +9,7 @@ struct thread_map { | |||
| 9 | pid_t map[]; | 9 | pid_t map[]; |
| 10 | }; | 10 | }; |
| 11 | 11 | ||
| 12 | struct thread_map *thread_map__new_dummy(void); | ||
| 12 | struct thread_map *thread_map__new_by_pid(pid_t pid); | 13 | struct thread_map *thread_map__new_by_pid(pid_t pid); |
| 13 | struct thread_map *thread_map__new_by_tid(pid_t tid); | 14 | struct thread_map *thread_map__new_by_tid(pid_t tid); |
| 14 | struct thread_map *thread_map__new_by_uid(uid_t uid); | 15 | struct thread_map *thread_map__new_by_uid(uid_t uid); |
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 92b56db52471..e060386165c5 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
| 25 | #include <libunwind.h> | 25 | #include <libunwind.h> |
| 26 | #include <libunwind-ptrace.h> | 26 | #include <libunwind-ptrace.h> |
| 27 | #include "callchain.h" | ||
| 27 | #include "thread.h" | 28 | #include "thread.h" |
| 28 | #include "session.h" | 29 | #include "session.h" |
| 29 | #include "perf_regs.h" | 30 | #include "perf_regs.h" |
| @@ -525,12 +526,12 @@ static unw_accessors_t accessors = { | |||
| 525 | .get_proc_name = get_proc_name, | 526 | .get_proc_name = get_proc_name, |
| 526 | }; | 527 | }; |
| 527 | 528 | ||
| 528 | static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | 529 | int unwind__prepare_access(struct thread *thread) |
| 529 | void *arg, int max_stack) | ||
| 530 | { | 530 | { |
| 531 | unw_addr_space_t addr_space; | 531 | unw_addr_space_t addr_space; |
| 532 | unw_cursor_t c; | 532 | |
| 533 | int ret; | 533 | if (callchain_param.record_mode != CALLCHAIN_DWARF) |
| 534 | return 0; | ||
| 534 | 535 | ||
| 535 | addr_space = unw_create_addr_space(&accessors, 0); | 536 | addr_space = unw_create_addr_space(&accessors, 0); |
| 536 | if (!addr_space) { | 537 | if (!addr_space) { |
| @@ -538,6 +539,33 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | |||
| 538 | return -ENOMEM; | 539 | return -ENOMEM; |
| 539 | } | 540 | } |
| 540 | 541 | ||
| 542 | thread__set_priv(thread, addr_space); | ||
| 543 | |||
| 544 | return 0; | ||
| 545 | } | ||
| 546 | |||
| 547 | void unwind__finish_access(struct thread *thread) | ||
| 548 | { | ||
| 549 | unw_addr_space_t addr_space; | ||
| 550 | |||
| 551 | if (callchain_param.record_mode != CALLCHAIN_DWARF) | ||
| 552 | return; | ||
| 553 | |||
| 554 | addr_space = thread__priv(thread); | ||
| 555 | unw_destroy_addr_space(addr_space); | ||
| 556 | } | ||
| 557 | |||
| 558 | static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | ||
| 559 | void *arg, int max_stack) | ||
| 560 | { | ||
| 561 | unw_addr_space_t addr_space; | ||
| 562 | unw_cursor_t c; | ||
| 563 | int ret; | ||
| 564 | |||
| 565 | addr_space = thread__priv(ui->thread); | ||
| 566 | if (addr_space == NULL) | ||
| 567 | return -1; | ||
| 568 | |||
| 541 | ret = unw_init_remote(&c, addr_space, ui); | 569 | ret = unw_init_remote(&c, addr_space, ui); |
| 542 | if (ret) | 570 | if (ret) |
| 543 | display_error(ret); | 571 | display_error(ret); |
| @@ -549,7 +577,6 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | |||
| 549 | ret = ip ? entry(ip, ui->thread, ui->machine, cb, arg) : 0; | 577 | ret = ip ? entry(ip, ui->thread, ui->machine, cb, arg) : 0; |
| 550 | } | 578 | } |
| 551 | 579 | ||
| 552 | unw_destroy_addr_space(addr_space); | ||
| 553 | return ret; | 580 | return ret; |
| 554 | } | 581 | } |
| 555 | 582 | ||
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index f03061260b4e..c17c4855bdbc 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 5 | #include "event.h" | 5 | #include "event.h" |
| 6 | #include "symbol.h" | 6 | #include "symbol.h" |
| 7 | #include "thread.h" | ||
| 7 | 8 | ||
| 8 | struct unwind_entry { | 9 | struct unwind_entry { |
| 9 | struct map *map; | 10 | struct map *map; |
| @@ -21,6 +22,15 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, | |||
| 21 | /* libunwind specific */ | 22 | /* libunwind specific */ |
| 22 | #ifdef HAVE_LIBUNWIND_SUPPORT | 23 | #ifdef HAVE_LIBUNWIND_SUPPORT |
| 23 | int libunwind__arch_reg_id(int regnum); | 24 | int libunwind__arch_reg_id(int regnum); |
| 25 | int unwind__prepare_access(struct thread *thread); | ||
| 26 | void unwind__finish_access(struct thread *thread); | ||
| 27 | #else | ||
| 28 | static inline int unwind__prepare_access(struct thread *thread __maybe_unused) | ||
| 29 | { | ||
| 30 | return 0; | ||
| 31 | } | ||
| 32 | |||
| 33 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} | ||
| 24 | #endif | 34 | #endif |
| 25 | #else | 35 | #else |
| 26 | static inline int | 36 | static inline int |
| @@ -33,5 +43,12 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused, | |||
| 33 | { | 43 | { |
| 34 | return 0; | 44 | return 0; |
| 35 | } | 45 | } |
| 46 | |||
| 47 | static inline int unwind__prepare_access(struct thread *thread __maybe_unused) | ||
| 48 | { | ||
| 49 | return 0; | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} | ||
| 36 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ | 53 | #endif /* HAVE_DWARF_UNWIND_SUPPORT */ |
| 37 | #endif /* __UNWIND_H */ | 54 | #endif /* __UNWIND_H */ |
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 24e8d871b74e..d5eab3f3323f 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
| @@ -14,6 +14,14 @@ | |||
| 14 | #include <byteswap.h> | 14 | #include <byteswap.h> |
| 15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 16 | #include <unistd.h> | 16 | #include <unistd.h> |
| 17 | #include "callchain.h" | ||
| 18 | |||
| 19 | struct callchain_param callchain_param = { | ||
| 20 | .mode = CHAIN_GRAPH_REL, | ||
| 21 | .min_percent = 0.5, | ||
| 22 | .order = ORDER_CALLEE, | ||
| 23 | .key = CCKEY_FUNCTION | ||
| 24 | }; | ||
| 17 | 25 | ||
| 18 | /* | 26 | /* |
| 19 | * XXX We need to find a better place for these things... | 27 | * XXX We need to find a better place for these things... |
