diff options
Diffstat (limited to 'include/linux/perf_counter.h')
| -rw-r--r-- | include/linux/perf_counter.h | 728 |
1 files changed, 728 insertions, 0 deletions
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h new file mode 100644 index 000000000000..89698d8aba5c --- /dev/null +++ b/include/linux/perf_counter.h | |||
| @@ -0,0 +1,728 @@ | |||
| 1 | /* | ||
| 2 | * Performance counters: | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009, Thomas Gleixner <tglx@linutronix.de> | ||
| 5 | * Copyright (C) 2008-2009, Red Hat, Inc., Ingo Molnar | ||
| 6 | * Copyright (C) 2008-2009, Red Hat, Inc., Peter Zijlstra | ||
| 7 | * | ||
| 8 | * Data type definitions, declarations, prototypes. | ||
| 9 | * | ||
| 10 | * Started by: Thomas Gleixner and Ingo Molnar | ||
| 11 | * | ||
| 12 | * For licencing details see kernel-base/COPYING | ||
| 13 | */ | ||
| 14 | #ifndef _LINUX_PERF_COUNTER_H | ||
| 15 | #define _LINUX_PERF_COUNTER_H | ||
| 16 | |||
| 17 | #include <linux/types.h> | ||
| 18 | #include <linux/ioctl.h> | ||
| 19 | #include <asm/byteorder.h> | ||
| 20 | |||
| 21 | /* | ||
| 22 | * User-space ABI bits: | ||
| 23 | */ | ||
| 24 | |||
| 25 | /* | ||
| 26 | * attr.type | ||
| 27 | */ | ||
| 28 | enum perf_type_id { | ||
| 29 | PERF_TYPE_HARDWARE = 0, | ||
| 30 | PERF_TYPE_SOFTWARE = 1, | ||
| 31 | PERF_TYPE_TRACEPOINT = 2, | ||
| 32 | PERF_TYPE_HW_CACHE = 3, | ||
| 33 | PERF_TYPE_RAW = 4, | ||
| 34 | |||
| 35 | PERF_TYPE_MAX, /* non-ABI */ | ||
| 36 | }; | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Generalized performance counter event types, used by the | ||
| 40 | * attr.event_id parameter of the sys_perf_counter_open() | ||
| 41 | * syscall: | ||
| 42 | */ | ||
| 43 | enum perf_hw_id { | ||
| 44 | /* | ||
| 45 | * Common hardware events, generalized by the kernel: | ||
| 46 | */ | ||
| 47 | PERF_COUNT_HW_CPU_CYCLES = 0, | ||
| 48 | PERF_COUNT_HW_INSTRUCTIONS = 1, | ||
| 49 | PERF_COUNT_HW_CACHE_REFERENCES = 2, | ||
| 50 | PERF_COUNT_HW_CACHE_MISSES = 3, | ||
| 51 | PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4, | ||
| 52 | PERF_COUNT_HW_BRANCH_MISSES = 5, | ||
| 53 | PERF_COUNT_HW_BUS_CYCLES = 6, | ||
| 54 | |||
| 55 | PERF_COUNT_HW_MAX, /* non-ABI */ | ||
| 56 | }; | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Generalized hardware cache counters: | ||
| 60 | * | ||
| 61 | * { L1-D, L1-I, LLC, ITLB, DTLB, BPU } x | ||
| 62 | * { read, write, prefetch } x | ||
| 63 | * { accesses, misses } | ||
| 64 | */ | ||
| 65 | enum perf_hw_cache_id { | ||
| 66 | PERF_COUNT_HW_CACHE_L1D = 0, | ||
| 67 | PERF_COUNT_HW_CACHE_L1I = 1, | ||
| 68 | PERF_COUNT_HW_CACHE_LL = 2, | ||
| 69 | PERF_COUNT_HW_CACHE_DTLB = 3, | ||
| 70 | PERF_COUNT_HW_CACHE_ITLB = 4, | ||
| 71 | PERF_COUNT_HW_CACHE_BPU = 5, | ||
| 72 | |||
| 73 | PERF_COUNT_HW_CACHE_MAX, /* non-ABI */ | ||
| 74 | }; | ||
| 75 | |||
| 76 | enum perf_hw_cache_op_id { | ||
| 77 | PERF_COUNT_HW_CACHE_OP_READ = 0, | ||
| 78 | PERF_COUNT_HW_CACHE_OP_WRITE = 1, | ||
| 79 | PERF_COUNT_HW_CACHE_OP_PREFETCH = 2, | ||
| 80 | |||
| 81 | PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */ | ||
| 82 | }; | ||
| 83 | |||
| 84 | enum perf_hw_cache_op_result_id { | ||
| 85 | PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0, | ||
| 86 | PERF_COUNT_HW_CACHE_RESULT_MISS = 1, | ||
| 87 | |||
| 88 | PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */ | ||
| 89 | }; | ||
| 90 | |||
| 91 | /* | ||
| 92 | * Special "software" counters provided by the kernel, even if the hardware | ||
| 93 | * does not support performance counters. These counters measure various | ||
| 94 | * physical and sw events of the kernel (and allow the profiling of them as | ||
| 95 | * well): | ||
| 96 | */ | ||
| 97 | enum perf_sw_ids { | ||
| 98 | PERF_COUNT_SW_CPU_CLOCK = 0, | ||
| 99 | PERF_COUNT_SW_TASK_CLOCK = 1, | ||
| 100 | PERF_COUNT_SW_PAGE_FAULTS = 2, | ||
| 101 | PERF_COUNT_SW_CONTEXT_SWITCHES = 3, | ||
| 102 | PERF_COUNT_SW_CPU_MIGRATIONS = 4, | ||
| 103 | PERF_COUNT_SW_PAGE_FAULTS_MIN = 5, | ||
| 104 | PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6, | ||
| 105 | |||
| 106 | PERF_COUNT_SW_MAX, /* non-ABI */ | ||
| 107 | }; | ||
| 108 | |||
| 109 | /* | ||
| 110 | * Bits that can be set in attr.sample_type to request information | ||
| 111 | * in the overflow packets. | ||
| 112 | */ | ||
| 113 | enum perf_counter_sample_format { | ||
| 114 | PERF_SAMPLE_IP = 1U << 0, | ||
| 115 | PERF_SAMPLE_TID = 1U << 1, | ||
| 116 | PERF_SAMPLE_TIME = 1U << 2, | ||
| 117 | PERF_SAMPLE_ADDR = 1U << 3, | ||
| 118 | PERF_SAMPLE_GROUP = 1U << 4, | ||
| 119 | PERF_SAMPLE_CALLCHAIN = 1U << 5, | ||
| 120 | PERF_SAMPLE_ID = 1U << 6, | ||
| 121 | PERF_SAMPLE_CPU = 1U << 7, | ||
| 122 | PERF_SAMPLE_PERIOD = 1U << 8, | ||
| 123 | |||
| 124 | PERF_SAMPLE_MAX = 1U << 9, /* non-ABI */ | ||
| 125 | }; | ||
| 126 | |||
| 127 | /* | ||
| 128 | * Bits that can be set in attr.read_format to request that | ||
| 129 | * reads on the counter should return the indicated quantities, | ||
| 130 | * in increasing order of bit value, after the counter value. | ||
| 131 | */ | ||
| 132 | enum perf_counter_read_format { | ||
| 133 | PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0, | ||
| 134 | PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1, | ||
| 135 | PERF_FORMAT_ID = 1U << 2, | ||
| 136 | |||
| 137 | PERF_FORMAT_MAX = 1U << 3, /* non-ABI */ | ||
| 138 | }; | ||
| 139 | |||
| 140 | #define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */ | ||
| 141 | |||
| 142 | /* | ||
| 143 | * Hardware event to monitor via a performance monitoring counter: | ||
| 144 | */ | ||
| 145 | struct perf_counter_attr { | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Major type: hardware/software/tracepoint/etc. | ||
| 149 | */ | ||
| 150 | __u32 type; | ||
| 151 | |||
| 152 | /* | ||
| 153 | * Size of the attr structure, for fwd/bwd compat. | ||
| 154 | */ | ||
| 155 | __u32 size; | ||
| 156 | |||
| 157 | /* | ||
| 158 | * Type specific configuration information. | ||
| 159 | */ | ||
| 160 | __u64 config; | ||
| 161 | |||
| 162 | union { | ||
| 163 | __u64 sample_period; | ||
| 164 | __u64 sample_freq; | ||
| 165 | }; | ||
| 166 | |||
| 167 | __u64 sample_type; | ||
| 168 | __u64 read_format; | ||
| 169 | |||
| 170 | __u64 disabled : 1, /* off by default */ | ||
| 171 | inherit : 1, /* children inherit it */ | ||
| 172 | pinned : 1, /* must always be on PMU */ | ||
| 173 | exclusive : 1, /* only group on PMU */ | ||
| 174 | exclude_user : 1, /* don't count user */ | ||
| 175 | exclude_kernel : 1, /* ditto kernel */ | ||
| 176 | exclude_hv : 1, /* ditto hypervisor */ | ||
| 177 | exclude_idle : 1, /* don't count when idle */ | ||
| 178 | mmap : 1, /* include mmap data */ | ||
| 179 | comm : 1, /* include comm data */ | ||
| 180 | freq : 1, /* use freq, not period */ | ||
| 181 | |||
| 182 | __reserved_1 : 53; | ||
| 183 | |||
| 184 | __u32 wakeup_events; /* wakeup every n events */ | ||
| 185 | __u32 __reserved_2; | ||
| 186 | |||
| 187 | __u64 __reserved_3; | ||
| 188 | }; | ||
| 189 | |||
| 190 | /* | ||
| 191 | * Ioctls that can be done on a perf counter fd: | ||
| 192 | */ | ||
| 193 | #define PERF_COUNTER_IOC_ENABLE _IO ('$', 0) | ||
| 194 | #define PERF_COUNTER_IOC_DISABLE _IO ('$', 1) | ||
| 195 | #define PERF_COUNTER_IOC_REFRESH _IO ('$', 2) | ||
| 196 | #define PERF_COUNTER_IOC_RESET _IO ('$', 3) | ||
| 197 | #define PERF_COUNTER_IOC_PERIOD _IOW('$', 4, u64) | ||
| 198 | |||
| 199 | enum perf_counter_ioc_flags { | ||
| 200 | PERF_IOC_FLAG_GROUP = 1U << 0, | ||
| 201 | }; | ||
| 202 | |||
| 203 | /* | ||
| 204 | * Structure of the page that can be mapped via mmap | ||
| 205 | */ | ||
| 206 | struct perf_counter_mmap_page { | ||
| 207 | __u32 version; /* version number of this structure */ | ||
| 208 | __u32 compat_version; /* lowest version this is compat with */ | ||
| 209 | |||
| 210 | /* | ||
| 211 | * Bits needed to read the hw counters in user-space. | ||
| 212 | * | ||
| 213 | * u32 seq; | ||
| 214 | * s64 count; | ||
| 215 | * | ||
| 216 | * do { | ||
| 217 | * seq = pc->lock; | ||
| 218 | * | ||
| 219 | * barrier() | ||
| 220 | * if (pc->index) { | ||
| 221 | * count = pmc_read(pc->index - 1); | ||
| 222 | * count += pc->offset; | ||
| 223 | * } else | ||
| 224 | * goto regular_read; | ||
| 225 | * | ||
| 226 | * barrier(); | ||
| 227 | * } while (pc->lock != seq); | ||
| 228 | * | ||
| 229 | * NOTE: for obvious reason this only works on self-monitoring | ||
| 230 | * processes. | ||
| 231 | */ | ||
| 232 | __u32 lock; /* seqlock for synchronization */ | ||
| 233 | __u32 index; /* hardware counter identifier */ | ||
| 234 | __s64 offset; /* add to hardware counter value */ | ||
| 235 | |||
| 236 | /* | ||
| 237 | * Control data for the mmap() data buffer. | ||
| 238 | * | ||
| 239 | * User-space reading the @data_head value should issue an rmb(), on | ||
| 240 | * SMP capable platforms, after reading this value -- see | ||
| 241 | * perf_counter_wakeup(). | ||
| 242 | * | ||
| 243 | * When the mapping is PROT_WRITE the @data_tail value should be | ||
| 244 | * written by userspace to reflect the last read data. In this case | ||
| 245 | * the kernel will not over-write unread data. | ||
| 246 | */ | ||
| 247 | __u64 data_head; /* head in the data section */ | ||
| 248 | __u64 data_tail; /* user-space written tail */ | ||
| 249 | }; | ||
| 250 | |||
| 251 | #define PERF_EVENT_MISC_CPUMODE_MASK (3 << 0) | ||
| 252 | #define PERF_EVENT_MISC_CPUMODE_UNKNOWN (0 << 0) | ||
| 253 | #define PERF_EVENT_MISC_KERNEL (1 << 0) | ||
| 254 | #define PERF_EVENT_MISC_USER (2 << 0) | ||
| 255 | #define PERF_EVENT_MISC_HYPERVISOR (3 << 0) | ||
| 256 | #define PERF_EVENT_MISC_OVERFLOW (1 << 2) | ||
| 257 | |||
| 258 | struct perf_event_header { | ||
| 259 | __u32 type; | ||
| 260 | __u16 misc; | ||
| 261 | __u16 size; | ||
| 262 | }; | ||
| 263 | |||
| 264 | enum perf_event_type { | ||
| 265 | |||
| 266 | /* | ||
| 267 | * The MMAP events record the PROT_EXEC mappings so that we can | ||
| 268 | * correlate userspace IPs to code. They have the following structure: | ||
| 269 | * | ||
| 270 | * struct { | ||
| 271 | * struct perf_event_header header; | ||
| 272 | * | ||
| 273 | * u32 pid, tid; | ||
| 274 | * u64 addr; | ||
| 275 | * u64 len; | ||
| 276 | * u64 pgoff; | ||
| 277 | * char filename[]; | ||
| 278 | * }; | ||
| 279 | */ | ||
| 280 | PERF_EVENT_MMAP = 1, | ||
| 281 | |||
| 282 | /* | ||
| 283 | * struct { | ||
| 284 | * struct perf_event_header header; | ||
| 285 | * u64 id; | ||
| 286 | * u64 lost; | ||
| 287 | * }; | ||
| 288 | */ | ||
| 289 | PERF_EVENT_LOST = 2, | ||
| 290 | |||
| 291 | /* | ||
| 292 | * struct { | ||
| 293 | * struct perf_event_header header; | ||
| 294 | * | ||
| 295 | * u32 pid, tid; | ||
| 296 | * char comm[]; | ||
| 297 | * }; | ||
| 298 | */ | ||
| 299 | PERF_EVENT_COMM = 3, | ||
| 300 | |||
| 301 | /* | ||
| 302 | * struct { | ||
| 303 | * struct perf_event_header header; | ||
| 304 | * u64 time; | ||
| 305 | * u64 id; | ||
| 306 | * u64 sample_period; | ||
| 307 | * }; | ||
| 308 | */ | ||
| 309 | PERF_EVENT_PERIOD = 4, | ||
| 310 | |||
| 311 | /* | ||
| 312 | * struct { | ||
| 313 | * struct perf_event_header header; | ||
| 314 | * u64 time; | ||
| 315 | * u64 id; | ||
| 316 | * }; | ||
| 317 | */ | ||
| 318 | PERF_EVENT_THROTTLE = 5, | ||
| 319 | PERF_EVENT_UNTHROTTLE = 6, | ||
| 320 | |||
| 321 | /* | ||
| 322 | * struct { | ||
| 323 | * struct perf_event_header header; | ||
| 324 | * u32 pid, ppid; | ||
| 325 | * }; | ||
| 326 | */ | ||
| 327 | PERF_EVENT_FORK = 7, | ||
| 328 | |||
| 329 | /* | ||
| 330 | * When header.misc & PERF_EVENT_MISC_OVERFLOW the event_type field | ||
| 331 | * will be PERF_SAMPLE_* | ||
| 332 | * | ||
| 333 | * struct { | ||
| 334 | * struct perf_event_header header; | ||
| 335 | * | ||
| 336 | * { u64 ip; } && PERF_SAMPLE_IP | ||
| 337 | * { u32 pid, tid; } && PERF_SAMPLE_TID | ||
| 338 | * { u64 time; } && PERF_SAMPLE_TIME | ||
| 339 | * { u64 addr; } && PERF_SAMPLE_ADDR | ||
| 340 | * { u64 config; } && PERF_SAMPLE_CONFIG | ||
| 341 | * { u32 cpu, res; } && PERF_SAMPLE_CPU | ||
| 342 | * | ||
| 343 | * { u64 nr; | ||
| 344 | * { u64 id, val; } cnt[nr]; } && PERF_SAMPLE_GROUP | ||
| 345 | * | ||
| 346 | * { u64 nr, | ||
| 347 | * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN | ||
| 348 | * }; | ||
| 349 | */ | ||
| 350 | }; | ||
| 351 | |||
| 352 | enum perf_callchain_context { | ||
| 353 | PERF_CONTEXT_HV = (__u64)-32, | ||
| 354 | PERF_CONTEXT_KERNEL = (__u64)-128, | ||
| 355 | PERF_CONTEXT_USER = (__u64)-512, | ||
| 356 | |||
| 357 | PERF_CONTEXT_GUEST = (__u64)-2048, | ||
| 358 | PERF_CONTEXT_GUEST_KERNEL = (__u64)-2176, | ||
| 359 | PERF_CONTEXT_GUEST_USER = (__u64)-2560, | ||
| 360 | |||
| 361 | PERF_CONTEXT_MAX = (__u64)-4095, | ||
| 362 | }; | ||
| 363 | |||
| 364 | #ifdef __KERNEL__ | ||
| 365 | /* | ||
| 366 | * Kernel-internal data types and definitions: | ||
| 367 | */ | ||
| 368 | |||
| 369 | #ifdef CONFIG_PERF_COUNTERS | ||
| 370 | # include <asm/perf_counter.h> | ||
| 371 | #endif | ||
| 372 | |||
| 373 | #include <linux/list.h> | ||
| 374 | #include <linux/mutex.h> | ||
| 375 | #include <linux/rculist.h> | ||
| 376 | #include <linux/rcupdate.h> | ||
| 377 | #include <linux/spinlock.h> | ||
| 378 | #include <linux/hrtimer.h> | ||
| 379 | #include <linux/fs.h> | ||
| 380 | #include <linux/pid_namespace.h> | ||
| 381 | #include <asm/atomic.h> | ||
| 382 | |||
| 383 | #define PERF_MAX_STACK_DEPTH 255 | ||
| 384 | |||
| 385 | struct perf_callchain_entry { | ||
| 386 | __u64 nr; | ||
| 387 | __u64 ip[PERF_MAX_STACK_DEPTH]; | ||
| 388 | }; | ||
| 389 | |||
| 390 | struct task_struct; | ||
| 391 | |||
| 392 | /** | ||
| 393 | * struct hw_perf_counter - performance counter hardware details: | ||
| 394 | */ | ||
| 395 | struct hw_perf_counter { | ||
| 396 | #ifdef CONFIG_PERF_COUNTERS | ||
| 397 | union { | ||
| 398 | struct { /* hardware */ | ||
| 399 | u64 config; | ||
| 400 | unsigned long config_base; | ||
| 401 | unsigned long counter_base; | ||
| 402 | int idx; | ||
| 403 | }; | ||
| 404 | union { /* software */ | ||
| 405 | atomic64_t count; | ||
| 406 | struct hrtimer hrtimer; | ||
| 407 | }; | ||
| 408 | }; | ||
| 409 | atomic64_t prev_count; | ||
| 410 | u64 sample_period; | ||
| 411 | u64 last_period; | ||
| 412 | atomic64_t period_left; | ||
| 413 | u64 interrupts; | ||
| 414 | |||
| 415 | u64 freq_count; | ||
| 416 | u64 freq_interrupts; | ||
| 417 | u64 freq_stamp; | ||
| 418 | #endif | ||
| 419 | }; | ||
| 420 | |||
| 421 | struct perf_counter; | ||
| 422 | |||
| 423 | /** | ||
| 424 | * struct pmu - generic performance monitoring unit | ||
| 425 | */ | ||
| 426 | struct pmu { | ||
| 427 | int (*enable) (struct perf_counter *counter); | ||
| 428 | void (*disable) (struct perf_counter *counter); | ||
| 429 | void (*read) (struct perf_counter *counter); | ||
| 430 | void (*unthrottle) (struct perf_counter *counter); | ||
| 431 | }; | ||
| 432 | |||
| 433 | /** | ||
| 434 | * enum perf_counter_active_state - the states of a counter | ||
| 435 | */ | ||
| 436 | enum perf_counter_active_state { | ||
| 437 | PERF_COUNTER_STATE_ERROR = -2, | ||
| 438 | PERF_COUNTER_STATE_OFF = -1, | ||
| 439 | PERF_COUNTER_STATE_INACTIVE = 0, | ||
| 440 | PERF_COUNTER_STATE_ACTIVE = 1, | ||
| 441 | }; | ||
| 442 | |||
| 443 | struct file; | ||
| 444 | |||
| 445 | struct perf_mmap_data { | ||
| 446 | struct rcu_head rcu_head; | ||
| 447 | int nr_pages; /* nr of data pages */ | ||
| 448 | int writable; /* are we writable */ | ||
| 449 | int nr_locked; /* nr pages mlocked */ | ||
| 450 | |||
| 451 | atomic_t poll; /* POLL_ for wakeups */ | ||
| 452 | atomic_t events; /* event limit */ | ||
| 453 | |||
| 454 | atomic_long_t head; /* write position */ | ||
| 455 | atomic_long_t done_head; /* completed head */ | ||
| 456 | |||
| 457 | atomic_t lock; /* concurrent writes */ | ||
| 458 | atomic_t wakeup; /* needs a wakeup */ | ||
| 459 | atomic_t lost; /* nr records lost */ | ||
| 460 | |||
| 461 | struct perf_counter_mmap_page *user_page; | ||
| 462 | void *data_pages[0]; | ||
| 463 | }; | ||
| 464 | |||
| 465 | struct perf_pending_entry { | ||
| 466 | struct perf_pending_entry *next; | ||
| 467 | void (*func)(struct perf_pending_entry *); | ||
| 468 | }; | ||
| 469 | |||
| 470 | /** | ||
| 471 | * struct perf_counter - performance counter kernel representation: | ||
| 472 | */ | ||
| 473 | struct perf_counter { | ||
| 474 | #ifdef CONFIG_PERF_COUNTERS | ||
| 475 | struct list_head list_entry; | ||
| 476 | struct list_head event_entry; | ||
| 477 | struct list_head sibling_list; | ||
| 478 | int nr_siblings; | ||
| 479 | struct perf_counter *group_leader; | ||
| 480 | const struct pmu *pmu; | ||
| 481 | |||
| 482 | enum perf_counter_active_state state; | ||
| 483 | atomic64_t count; | ||
| 484 | |||
| 485 | /* | ||
| 486 | * These are the total time in nanoseconds that the counter | ||
| 487 | * has been enabled (i.e. eligible to run, and the task has | ||
| 488 | * been scheduled in, if this is a per-task counter) | ||
| 489 | * and running (scheduled onto the CPU), respectively. | ||
| 490 | * | ||
| 491 | * They are computed from tstamp_enabled, tstamp_running and | ||
| 492 | * tstamp_stopped when the counter is in INACTIVE or ACTIVE state. | ||
| 493 | */ | ||
| 494 | u64 total_time_enabled; | ||
| 495 | u64 total_time_running; | ||
| 496 | |||
| 497 | /* | ||
| 498 | * These are timestamps used for computing total_time_enabled | ||
| 499 | * and total_time_running when the counter is in INACTIVE or | ||
| 500 | * ACTIVE state, measured in nanoseconds from an arbitrary point | ||
| 501 | * in time. | ||
| 502 | * tstamp_enabled: the notional time when the counter was enabled | ||
| 503 | * tstamp_running: the notional time when the counter was scheduled on | ||
| 504 | * tstamp_stopped: in INACTIVE state, the notional time when the | ||
| 505 | * counter was scheduled off. | ||
| 506 | */ | ||
| 507 | u64 tstamp_enabled; | ||
| 508 | u64 tstamp_running; | ||
| 509 | u64 tstamp_stopped; | ||
| 510 | |||
| 511 | struct perf_counter_attr attr; | ||
| 512 | struct hw_perf_counter hw; | ||
| 513 | |||
| 514 | struct perf_counter_context *ctx; | ||
| 515 | struct file *filp; | ||
| 516 | |||
| 517 | /* | ||
| 518 | * These accumulate total time (in nanoseconds) that children | ||
| 519 | * counters have been enabled and running, respectively. | ||
| 520 | */ | ||
| 521 | atomic64_t child_total_time_enabled; | ||
| 522 | atomic64_t child_total_time_running; | ||
| 523 | |||
| 524 | /* | ||
| 525 | * Protect attach/detach and child_list: | ||
| 526 | */ | ||
| 527 | struct mutex child_mutex; | ||
| 528 | struct list_head child_list; | ||
| 529 | struct perf_counter *parent; | ||
| 530 | |||
| 531 | int oncpu; | ||
| 532 | int cpu; | ||
| 533 | |||
| 534 | struct list_head owner_entry; | ||
| 535 | struct task_struct *owner; | ||
| 536 | |||
| 537 | /* mmap bits */ | ||
| 538 | struct mutex mmap_mutex; | ||
| 539 | atomic_t mmap_count; | ||
| 540 | struct perf_mmap_data *data; | ||
| 541 | |||
| 542 | /* poll related */ | ||
| 543 | wait_queue_head_t waitq; | ||
| 544 | struct fasync_struct *fasync; | ||
| 545 | |||
| 546 | /* delayed work for NMIs and such */ | ||
| 547 | int pending_wakeup; | ||
| 548 | int pending_kill; | ||
| 549 | int pending_disable; | ||
| 550 | struct perf_pending_entry pending; | ||
| 551 | |||
| 552 | atomic_t event_limit; | ||
| 553 | |||
| 554 | void (*destroy)(struct perf_counter *); | ||
| 555 | struct rcu_head rcu_head; | ||
| 556 | |||
| 557 | struct pid_namespace *ns; | ||
| 558 | u64 id; | ||
| 559 | #endif | ||
| 560 | }; | ||
| 561 | |||
| 562 | /** | ||
| 563 | * struct perf_counter_context - counter context structure | ||
| 564 | * | ||
| 565 | * Used as a container for task counters and CPU counters as well: | ||
| 566 | */ | ||
| 567 | struct perf_counter_context { | ||
| 568 | /* | ||
| 569 | * Protect the states of the counters in the list, | ||
| 570 | * nr_active, and the list: | ||
| 571 | */ | ||
| 572 | spinlock_t lock; | ||
| 573 | /* | ||
| 574 | * Protect the list of counters. Locking either mutex or lock | ||
| 575 | * is sufficient to ensure the list doesn't change; to change | ||
| 576 | * the list you need to lock both the mutex and the spinlock. | ||
| 577 | */ | ||
| 578 | struct mutex mutex; | ||
| 579 | |||
| 580 | struct list_head counter_list; | ||
| 581 | struct list_head event_list; | ||
| 582 | int nr_counters; | ||
| 583 | int nr_active; | ||
| 584 | int is_active; | ||
| 585 | atomic_t refcount; | ||
| 586 | struct task_struct *task; | ||
| 587 | |||
| 588 | /* | ||
| 589 | * Context clock, runs when context enabled. | ||
| 590 | */ | ||
| 591 | u64 time; | ||
| 592 | u64 timestamp; | ||
| 593 | |||
| 594 | /* | ||
| 595 | * These fields let us detect when two contexts have both | ||
| 596 | * been cloned (inherited) from a common ancestor. | ||
| 597 | */ | ||
| 598 | struct perf_counter_context *parent_ctx; | ||
| 599 | u64 parent_gen; | ||
| 600 | u64 generation; | ||
| 601 | int pin_count; | ||
| 602 | struct rcu_head rcu_head; | ||
| 603 | }; | ||
| 604 | |||
| 605 | /** | ||
| 606 | * struct perf_counter_cpu_context - per cpu counter context structure | ||
| 607 | */ | ||
| 608 | struct perf_cpu_context { | ||
| 609 | struct perf_counter_context ctx; | ||
| 610 | struct perf_counter_context *task_ctx; | ||
| 611 | int active_oncpu; | ||
| 612 | int max_pertask; | ||
| 613 | int exclusive; | ||
| 614 | |||
| 615 | /* | ||
| 616 | * Recursion avoidance: | ||
| 617 | * | ||
| 618 | * task, softirq, irq, nmi context | ||
| 619 | */ | ||
| 620 | int recursion[4]; | ||
| 621 | }; | ||
| 622 | |||
| 623 | #ifdef CONFIG_PERF_COUNTERS | ||
| 624 | |||
| 625 | /* | ||
| 626 | * Set by architecture code: | ||
| 627 | */ | ||
| 628 | extern int perf_max_counters; | ||
| 629 | |||
| 630 | extern const struct pmu *hw_perf_counter_init(struct perf_counter *counter); | ||
| 631 | |||
| 632 | extern void perf_counter_task_sched_in(struct task_struct *task, int cpu); | ||
| 633 | extern void perf_counter_task_sched_out(struct task_struct *task, | ||
| 634 | struct task_struct *next, int cpu); | ||
| 635 | extern void perf_counter_task_tick(struct task_struct *task, int cpu); | ||
| 636 | extern int perf_counter_init_task(struct task_struct *child); | ||
| 637 | extern void perf_counter_exit_task(struct task_struct *child); | ||
| 638 | extern void perf_counter_free_task(struct task_struct *task); | ||
| 639 | extern void set_perf_counter_pending(void); | ||
| 640 | extern void perf_counter_do_pending(void); | ||
| 641 | extern void perf_counter_print_debug(void); | ||
| 642 | extern void __perf_disable(void); | ||
| 643 | extern bool __perf_enable(void); | ||
| 644 | extern void perf_disable(void); | ||
| 645 | extern void perf_enable(void); | ||
| 646 | extern int perf_counter_task_disable(void); | ||
| 647 | extern int perf_counter_task_enable(void); | ||
| 648 | extern int hw_perf_group_sched_in(struct perf_counter *group_leader, | ||
| 649 | struct perf_cpu_context *cpuctx, | ||
| 650 | struct perf_counter_context *ctx, int cpu); | ||
| 651 | extern void perf_counter_update_userpage(struct perf_counter *counter); | ||
| 652 | |||
| 653 | struct perf_sample_data { | ||
| 654 | struct pt_regs *regs; | ||
| 655 | u64 addr; | ||
| 656 | u64 period; | ||
| 657 | }; | ||
| 658 | |||
| 659 | extern int perf_counter_overflow(struct perf_counter *counter, int nmi, | ||
| 660 | struct perf_sample_data *data); | ||
| 661 | |||
| 662 | /* | ||
| 663 | * Return 1 for a software counter, 0 for a hardware counter | ||
| 664 | */ | ||
| 665 | static inline int is_software_counter(struct perf_counter *counter) | ||
| 666 | { | ||
| 667 | return (counter->attr.type != PERF_TYPE_RAW) && | ||
| 668 | (counter->attr.type != PERF_TYPE_HARDWARE) && | ||
| 669 | (counter->attr.type != PERF_TYPE_HW_CACHE); | ||
| 670 | } | ||
| 671 | |||
| 672 | extern void perf_swcounter_event(u32, u64, int, struct pt_regs *, u64); | ||
| 673 | |||
| 674 | extern void __perf_counter_mmap(struct vm_area_struct *vma); | ||
| 675 | |||
| 676 | static inline void perf_counter_mmap(struct vm_area_struct *vma) | ||
| 677 | { | ||
| 678 | if (vma->vm_flags & VM_EXEC) | ||
| 679 | __perf_counter_mmap(vma); | ||
| 680 | } | ||
| 681 | |||
| 682 | extern void perf_counter_comm(struct task_struct *tsk); | ||
| 683 | extern void perf_counter_fork(struct task_struct *tsk); | ||
| 684 | |||
| 685 | extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs); | ||
| 686 | |||
| 687 | extern int sysctl_perf_counter_paranoid; | ||
| 688 | extern int sysctl_perf_counter_mlock; | ||
| 689 | extern int sysctl_perf_counter_sample_rate; | ||
| 690 | |||
| 691 | extern void perf_counter_init(void); | ||
| 692 | |||
| 693 | #ifndef perf_misc_flags | ||
| 694 | #define perf_misc_flags(regs) (user_mode(regs) ? PERF_EVENT_MISC_USER : \ | ||
| 695 | PERF_EVENT_MISC_KERNEL) | ||
| 696 | #define perf_instruction_pointer(regs) instruction_pointer(regs) | ||
| 697 | #endif | ||
| 698 | |||
| 699 | #else | ||
| 700 | static inline void | ||
| 701 | perf_counter_task_sched_in(struct task_struct *task, int cpu) { } | ||
| 702 | static inline void | ||
| 703 | perf_counter_task_sched_out(struct task_struct *task, | ||
| 704 | struct task_struct *next, int cpu) { } | ||
| 705 | static inline void | ||
| 706 | perf_counter_task_tick(struct task_struct *task, int cpu) { } | ||
| 707 | static inline int perf_counter_init_task(struct task_struct *child) { return 0; } | ||
| 708 | static inline void perf_counter_exit_task(struct task_struct *child) { } | ||
| 709 | static inline void perf_counter_free_task(struct task_struct *task) { } | ||
| 710 | static inline void perf_counter_do_pending(void) { } | ||
| 711 | static inline void perf_counter_print_debug(void) { } | ||
| 712 | static inline void perf_disable(void) { } | ||
| 713 | static inline void perf_enable(void) { } | ||
| 714 | static inline int perf_counter_task_disable(void) { return -EINVAL; } | ||
| 715 | static inline int perf_counter_task_enable(void) { return -EINVAL; } | ||
| 716 | |||
| 717 | static inline void | ||
| 718 | perf_swcounter_event(u32 event, u64 nr, int nmi, | ||
| 719 | struct pt_regs *regs, u64 addr) { } | ||
| 720 | |||
| 721 | static inline void perf_counter_mmap(struct vm_area_struct *vma) { } | ||
| 722 | static inline void perf_counter_comm(struct task_struct *tsk) { } | ||
| 723 | static inline void perf_counter_fork(struct task_struct *tsk) { } | ||
| 724 | static inline void perf_counter_init(void) { } | ||
| 725 | #endif | ||
| 726 | |||
| 727 | #endif /* __KERNEL__ */ | ||
| 728 | #endif /* _LINUX_PERF_COUNTER_H */ | ||
