1 // SPDX-License-Identifier: GPL-2.0 2 #include <Python.h> 3 #include <structmember.h> 4 #include <inttypes.h> 5 #include <poll.h> 6 #include <linux/err.h> 7 #include <perf/cpumap.h> 8 #include <traceevent/event-parse.h> 9 #include <perf/mmap.h> 10 #include "evlist.h" 11 #include "callchain.h" 12 #include "evsel.h" 13 #include "event.h" 14 #include "print_binary.h" 15 #include "thread_map.h" 16 #include "trace-event.h" 17 #include "mmap.h" 18 #include "stat.h" 19 #include "metricgroup.h" 20 #include "util/env.h" 21 #include <internal/lib.h> 22 #include "util.h" 23 24 #if PY_MAJOR_VERSION < 3 25 #define _PyUnicode_FromString(arg) \ 26 PyString_FromString(arg) 27 #define _PyUnicode_AsString(arg) \ 28 PyString_AsString(arg) 29 #define _PyUnicode_FromFormat(...) \ 30 PyString_FromFormat(__VA_ARGS__) 31 #define _PyLong_FromLong(arg) \ 32 PyInt_FromLong(arg) 33 34 #else 35 36 #define _PyUnicode_FromString(arg) \ 37 PyUnicode_FromString(arg) 38 #define _PyUnicode_FromFormat(...) \ 39 PyUnicode_FromFormat(__VA_ARGS__) 40 #define _PyLong_FromLong(arg) \ 41 PyLong_FromLong(arg) 42 #endif 43 44 #ifndef Py_TYPE 45 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) 46 #endif 47 48 /* 49 * Provide these two so that we don't have to link against callchain.c and 50 * start dragging hist.c, etc. 51 */ 52 struct callchain_param callchain_param; 53 54 int parse_callchain_record(const char *arg __maybe_unused, 55 struct callchain_param *param __maybe_unused) 56 { 57 return 0; 58 } 59 60 /* 61 * Add this one here not to drag util/env.c 62 */ 63 struct perf_env perf_env; 64 65 /* 66 * Add this one here not to drag util/stat-shadow.c 67 */ 68 void perf_stat__collect_metric_expr(struct evlist *evsel_list) 69 { 70 } 71 72 /* 73 * This one is needed not to drag the PMU bandwagon, jevents generated 74 * pmu_sys_event_tables, etc and evsel__find_pmu() is used so far just for 75 * doing per PMU perf_event_attr.exclude_guest handling, not really needed, so 76 * far, for the perf python binding known usecases, revisit if this become 77 * necessary. 78 */ 79 struct perf_pmu *evsel__find_pmu(struct evsel *evsel __maybe_unused) 80 { 81 return NULL; 82 } 83 84 /* 85 * Add this one here not to drag util/metricgroup.c 86 */ 87 int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp, 88 struct rblist *new_metric_events, 89 struct rblist *old_metric_events) 90 { 91 return 0; 92 } 93 94 /* 95 * XXX: All these evsel destructors need some better mechanism, like a linked 96 * list of destructors registered when the relevant code indeed is used instead 97 * of having more and more calls in perf_evsel__delete(). -- acme 98 * 99 * For now, add some more: 100 * 101 * Not to drag the BPF bandwagon... 102 */ 103 void bpf_counter__destroy(struct evsel *evsel); 104 int bpf_counter__install_pe(struct evsel *evsel, int cpu, int fd); 105 int bpf_counter__disable(struct evsel *evsel); 106 107 void bpf_counter__destroy(struct evsel *evsel __maybe_unused) 108 { 109 } 110 111 int bpf_counter__install_pe(struct evsel *evsel __maybe_unused, int cpu __maybe_unused, int fd __maybe_unused) 112 { 113 return 0; 114 } 115 116 int bpf_counter__disable(struct evsel *evsel __maybe_unused) 117 { 118 return 0; 119 } 120 121 /* 122 * Support debug printing even though util/debug.c is not linked. That means 123 * implementing 'verbose' and 'eprintf'. 124 */ 125 int verbose; 126 int debug_peo_args; 127 128 int eprintf(int level, int var, const char *fmt, ...); 129 130 int eprintf(int level, int var, const char *fmt, ...) 131 { 132 va_list args; 133 int ret = 0; 134 135 if (var >= level) { 136 va_start(args, fmt); 137 ret = vfprintf(stderr, fmt, args); 138 va_end(args); 139 } 140 141 return ret; 142 } 143 144 /* Define PyVarObject_HEAD_INIT for python 2.5 */ 145 #ifndef PyVarObject_HEAD_INIT 146 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, 147 #endif 148 149 #if PY_MAJOR_VERSION < 3 150 PyMODINIT_FUNC initperf(void); 151 #else 152 PyMODINIT_FUNC PyInit_perf(void); 153 #endif 154 155 #define member_def(type, member, ptype, help) \ 156 { #member, ptype, \ 157 offsetof(struct pyrf_event, event) + offsetof(struct type, member), \ 158 0, help } 159 160 #define sample_member_def(name, member, ptype, help) \ 161 { #name, ptype, \ 162 offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \ 163 0, help } 164 165 struct pyrf_event { 166 PyObject_HEAD 167 struct evsel *evsel; 168 struct perf_sample sample; 169 union perf_event event; 170 }; 171 172 #define sample_members \ 173 sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \ 174 sample_member_def(sample_pid, pid, T_INT, "event pid"), \ 175 sample_member_def(sample_tid, tid, T_INT, "event tid"), \ 176 sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \ 177 sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \ 178 sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \ 179 sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \ 180 sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \ 181 sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"), 182 183 static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object."); 184 185 static PyMemberDef pyrf_mmap_event__members[] = { 186 sample_members 187 member_def(perf_event_header, type, T_UINT, "event type"), 188 member_def(perf_event_header, misc, T_UINT, "event misc"), 189 member_def(perf_record_mmap, pid, T_UINT, "event pid"), 190 member_def(perf_record_mmap, tid, T_UINT, "event tid"), 191 member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"), 192 member_def(perf_record_mmap, len, T_ULONGLONG, "map length"), 193 member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"), 194 member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"), 195 { .name = NULL, }, 196 }; 197 198 static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent) 199 { 200 PyObject *ret; 201 char *s; 202 203 if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", " 204 "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", " 205 "filename: %s }", 206 pevent->event.mmap.pid, pevent->event.mmap.tid, 207 pevent->event.mmap.start, pevent->event.mmap.len, 208 pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) { 209 ret = PyErr_NoMemory(); 210 } else { 211 ret = _PyUnicode_FromString(s); 212 free(s); 213 } 214 return ret; 215 } 216 217 static PyTypeObject pyrf_mmap_event__type = { 218 PyVarObject_HEAD_INIT(NULL, 0) 219 .tp_name = "perf.mmap_event", 220 .tp_basicsize = sizeof(struct pyrf_event), 221 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 222 .tp_doc = pyrf_mmap_event__doc, 223 .tp_members = pyrf_mmap_event__members, 224 .tp_repr = (reprfunc)pyrf_mmap_event__repr, 225 }; 226 227 static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object."); 228 229 static PyMemberDef pyrf_task_event__members[] = { 230 sample_members 231 member_def(perf_event_header, type, T_UINT, "event type"), 232 member_def(perf_record_fork, pid, T_UINT, "event pid"), 233 member_def(perf_record_fork, ppid, T_UINT, "event ppid"), 234 member_def(perf_record_fork, tid, T_UINT, "event tid"), 235 member_def(perf_record_fork, ptid, T_UINT, "event ptid"), 236 member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"), 237 { .name = NULL, }, 238 }; 239 240 static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent) 241 { 242 return _PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, " 243 "ptid: %u, time: %" PRI_lu64 "}", 244 pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit", 245 pevent->event.fork.pid, 246 pevent->event.fork.ppid, 247 pevent->event.fork.tid, 248 pevent->event.fork.ptid, 249 pevent->event.fork.time); 250 } 251 252 static PyTypeObject pyrf_task_event__type = { 253 PyVarObject_HEAD_INIT(NULL, 0) 254 .tp_name = "perf.task_event", 255 .tp_basicsize = sizeof(struct pyrf_event), 256 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 257 .tp_doc = pyrf_task_event__doc, 258 .tp_members = pyrf_task_event__members, 259 .tp_repr = (reprfunc)pyrf_task_event__repr, 260 }; 261 262 static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object."); 263 264 static PyMemberDef pyrf_comm_event__members[] = { 265 sample_members 266 member_def(perf_event_header, type, T_UINT, "event type"), 267 member_def(perf_record_comm, pid, T_UINT, "event pid"), 268 member_def(perf_record_comm, tid, T_UINT, "event tid"), 269 member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"), 270 { .name = NULL, }, 271 }; 272 273 static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent) 274 { 275 return _PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }", 276 pevent->event.comm.pid, 277 pevent->event.comm.tid, 278 pevent->event.comm.comm); 279 } 280 281 static PyTypeObject pyrf_comm_event__type = { 282 PyVarObject_HEAD_INIT(NULL, 0) 283 .tp_name = "perf.comm_event", 284 .tp_basicsize = sizeof(struct pyrf_event), 285 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 286 .tp_doc = pyrf_comm_event__doc, 287 .tp_members = pyrf_comm_event__members, 288 .tp_repr = (reprfunc)pyrf_comm_event__repr, 289 }; 290 291 static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object."); 292 293 static PyMemberDef pyrf_throttle_event__members[] = { 294 sample_members 295 member_def(perf_event_header, type, T_UINT, "event type"), 296 member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"), 297 member_def(perf_record_throttle, id, T_ULONGLONG, "event id"), 298 member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"), 299 { .name = NULL, }, 300 }; 301 302 static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent) 303 { 304 struct perf_record_throttle *te = (struct perf_record_throttle *)(&pevent->event.header + 1); 305 306 return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64 307 ", stream_id: %" PRI_lu64 " }", 308 pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un", 309 te->time, te->id, te->stream_id); 310 } 311 312 static PyTypeObject pyrf_throttle_event__type = { 313 PyVarObject_HEAD_INIT(NULL, 0) 314 .tp_name = "perf.throttle_event", 315 .tp_basicsize = sizeof(struct pyrf_event), 316 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 317 .tp_doc = pyrf_throttle_event__doc, 318 .tp_members = pyrf_throttle_event__members, 319 .tp_repr = (reprfunc)pyrf_throttle_event__repr, 320 }; 321 322 static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); 323 324 static PyMemberDef pyrf_lost_event__members[] = { 325 sample_members 326 member_def(perf_record_lost, id, T_ULONGLONG, "event id"), 327 member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"), 328 { .name = NULL, }, 329 }; 330 331 static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent) 332 { 333 PyObject *ret; 334 char *s; 335 336 if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", " 337 "lost: %#" PRI_lx64 " }", 338 pevent->event.lost.id, pevent->event.lost.lost) < 0) { 339 ret = PyErr_NoMemory(); 340 } else { 341 ret = _PyUnicode_FromString(s); 342 free(s); 343 } 344 return ret; 345 } 346 347 static PyTypeObject pyrf_lost_event__type = { 348 PyVarObject_HEAD_INIT(NULL, 0) 349 .tp_name = "perf.lost_event", 350 .tp_basicsize = sizeof(struct pyrf_event), 351 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 352 .tp_doc = pyrf_lost_event__doc, 353 .tp_members = pyrf_lost_event__members, 354 .tp_repr = (reprfunc)pyrf_lost_event__repr, 355 }; 356 357 static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object."); 358 359 static PyMemberDef pyrf_read_event__members[] = { 360 sample_members 361 member_def(perf_record_read, pid, T_UINT, "event pid"), 362 member_def(perf_record_read, tid, T_UINT, "event tid"), 363 { .name = NULL, }, 364 }; 365 366 static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent) 367 { 368 return _PyUnicode_FromFormat("{ type: read, pid: %u, tid: %u }", 369 pevent->event.read.pid, 370 pevent->event.read.tid); 371 /* 372 * FIXME: return the array of read values, 373 * making this method useful ;-) 374 */ 375 } 376 377 static PyTypeObject pyrf_read_event__type = { 378 PyVarObject_HEAD_INIT(NULL, 0) 379 .tp_name = "perf.read_event", 380 .tp_basicsize = sizeof(struct pyrf_event), 381 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 382 .tp_doc = pyrf_read_event__doc, 383 .tp_members = pyrf_read_event__members, 384 .tp_repr = (reprfunc)pyrf_read_event__repr, 385 }; 386 387 static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object."); 388 389 static PyMemberDef pyrf_sample_event__members[] = { 390 sample_members 391 member_def(perf_event_header, type, T_UINT, "event type"), 392 { .name = NULL, }, 393 }; 394 395 static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) 396 { 397 PyObject *ret; 398 char *s; 399 400 if (asprintf(&s, "{ type: sample }") < 0) { 401 ret = PyErr_NoMemory(); 402 } else { 403 ret = _PyUnicode_FromString(s); 404 free(s); 405 } 406 return ret; 407 } 408 409 static bool is_tracepoint(struct pyrf_event *pevent) 410 { 411 return pevent->evsel->core.attr.type == PERF_TYPE_TRACEPOINT; 412 } 413 414 static PyObject* 415 tracepoint_field(struct pyrf_event *pe, struct tep_format_field *field) 416 { 417 struct tep_handle *pevent = field->event->tep; 418 void *data = pe->sample.raw_data; 419 PyObject *ret = NULL; 420 unsigned long long val; 421 unsigned int offset, len; 422 423 if (field->flags & TEP_FIELD_IS_ARRAY) { 424 offset = field->offset; 425 len = field->size; 426 if (field->flags & TEP_FIELD_IS_DYNAMIC) { 427 val = tep_read_number(pevent, data + offset, len); 428 offset = val; 429 len = offset >> 16; 430 offset &= 0xffff; 431 if (field->flags & TEP_FIELD_IS_RELATIVE) 432 offset += field->offset + field->size; 433 } 434 if (field->flags & TEP_FIELD_IS_STRING && 435 is_printable_array(data + offset, len)) { 436 ret = _PyUnicode_FromString((char *)data + offset); 437 } else { 438 ret = PyByteArray_FromStringAndSize((const char *) data + offset, len); 439 field->flags &= ~TEP_FIELD_IS_STRING; 440 } 441 } else { 442 val = tep_read_number(pevent, data + field->offset, 443 field->size); 444 if (field->flags & TEP_FIELD_IS_POINTER) 445 ret = PyLong_FromUnsignedLong((unsigned long) val); 446 else if (field->flags & TEP_FIELD_IS_SIGNED) 447 ret = PyLong_FromLong((long) val); 448 else 449 ret = PyLong_FromUnsignedLong((unsigned long) val); 450 } 451 452 return ret; 453 } 454 455 static PyObject* 456 get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name) 457 { 458 const char *str = _PyUnicode_AsString(PyObject_Str(attr_name)); 459 struct evsel *evsel = pevent->evsel; 460 struct tep_format_field *field; 461 462 if (!evsel->tp_format) { 463 struct tep_event *tp_format; 464 465 tp_format = trace_event__tp_format_id(evsel->core.attr.config); 466 if (IS_ERR_OR_NULL(tp_format)) 467 return NULL; 468 469 evsel->tp_format = tp_format; 470 } 471 472 field = tep_find_any_field(evsel->tp_format, str); 473 if (!field) 474 return NULL; 475 476 return tracepoint_field(pevent, field); 477 } 478 479 static PyObject* 480 pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name) 481 { 482 PyObject *obj = NULL; 483 484 if (is_tracepoint(pevent)) 485 obj = get_tracepoint_field(pevent, attr_name); 486 487 return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name); 488 } 489 490 static PyTypeObject pyrf_sample_event__type = { 491 PyVarObject_HEAD_INIT(NULL, 0) 492 .tp_name = "perf.sample_event", 493 .tp_basicsize = sizeof(struct pyrf_event), 494 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 495 .tp_doc = pyrf_sample_event__doc, 496 .tp_members = pyrf_sample_event__members, 497 .tp_repr = (reprfunc)pyrf_sample_event__repr, 498 .tp_getattro = (getattrofunc) pyrf_sample_event__getattro, 499 }; 500 501 static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object."); 502 503 static PyMemberDef pyrf_context_switch_event__members[] = { 504 sample_members 505 member_def(perf_event_header, type, T_UINT, "event type"), 506 member_def(perf_record_switch, next_prev_pid, T_UINT, "next/prev pid"), 507 member_def(perf_record_switch, next_prev_tid, T_UINT, "next/prev tid"), 508 { .name = NULL, }, 509 }; 510 511 static PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent) 512 { 513 PyObject *ret; 514 char *s; 515 516 if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }", 517 pevent->event.context_switch.next_prev_pid, 518 pevent->event.context_switch.next_prev_tid, 519 !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) { 520 ret = PyErr_NoMemory(); 521 } else { 522 ret = _PyUnicode_FromString(s); 523 free(s); 524 } 525 return ret; 526 } 527 528 static PyTypeObject pyrf_context_switch_event__type = { 529 PyVarObject_HEAD_INIT(NULL, 0) 530 .tp_name = "perf.context_switch_event", 531 .tp_basicsize = sizeof(struct pyrf_event), 532 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 533 .tp_doc = pyrf_context_switch_event__doc, 534 .tp_members = pyrf_context_switch_event__members, 535 .tp_repr = (reprfunc)pyrf_context_switch_event__repr, 536 }; 537 538 static int pyrf_event__setup_types(void) 539 { 540 int err; 541 pyrf_mmap_event__type.tp_new = 542 pyrf_task_event__type.tp_new = 543 pyrf_comm_event__type.tp_new = 544 pyrf_lost_event__type.tp_new = 545 pyrf_read_event__type.tp_new = 546 pyrf_sample_event__type.tp_new = 547 pyrf_context_switch_event__type.tp_new = 548 pyrf_throttle_event__type.tp_new = PyType_GenericNew; 549 err = PyType_Ready(&pyrf_mmap_event__type); 550 if (err < 0) 551 goto out; 552 err = PyType_Ready(&pyrf_lost_event__type); 553 if (err < 0) 554 goto out; 555 err = PyType_Ready(&pyrf_task_event__type); 556 if (err < 0) 557 goto out; 558 err = PyType_Ready(&pyrf_comm_event__type); 559 if (err < 0) 560 goto out; 561 err = PyType_Ready(&pyrf_throttle_event__type); 562 if (err < 0) 563 goto out; 564 err = PyType_Ready(&pyrf_read_event__type); 565 if (err < 0) 566 goto out; 567 err = PyType_Ready(&pyrf_sample_event__type); 568 if (err < 0) 569 goto out; 570 err = PyType_Ready(&pyrf_context_switch_event__type); 571 if (err < 0) 572 goto out; 573 out: 574 return err; 575 } 576 577 static PyTypeObject *pyrf_event__type[] = { 578 [PERF_RECORD_MMAP] = &pyrf_mmap_event__type, 579 [PERF_RECORD_LOST] = &pyrf_lost_event__type, 580 [PERF_RECORD_COMM] = &pyrf_comm_event__type, 581 [PERF_RECORD_EXIT] = &pyrf_task_event__type, 582 [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type, 583 [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type, 584 [PERF_RECORD_FORK] = &pyrf_task_event__type, 585 [PERF_RECORD_READ] = &pyrf_read_event__type, 586 [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type, 587 [PERF_RECORD_SWITCH] = &pyrf_context_switch_event__type, 588 [PERF_RECORD_SWITCH_CPU_WIDE] = &pyrf_context_switch_event__type, 589 }; 590 591 static PyObject *pyrf_event__new(union perf_event *event) 592 { 593 struct pyrf_event *pevent; 594 PyTypeObject *ptype; 595 596 if ((event->header.type < PERF_RECORD_MMAP || 597 event->header.type > PERF_RECORD_SAMPLE) && 598 !(event->header.type == PERF_RECORD_SWITCH || 599 event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)) 600 return NULL; 601 602 ptype = pyrf_event__type[event->header.type]; 603 pevent = PyObject_New(struct pyrf_event, ptype); 604 if (pevent != NULL) 605 memcpy(&pevent->event, event, event->header.size); 606 return (PyObject *)pevent; 607 } 608 609 struct pyrf_cpu_map { 610 PyObject_HEAD 611 612 struct perf_cpu_map *cpus; 613 }; 614 615 static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, 616 PyObject *args, PyObject *kwargs) 617 { 618 static char *kwlist[] = { "cpustr", NULL }; 619 char *cpustr = NULL; 620 621 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", 622 kwlist, &cpustr)) 623 return -1; 624 625 pcpus->cpus = perf_cpu_map__new(cpustr); 626 if (pcpus->cpus == NULL) 627 return -1; 628 return 0; 629 } 630 631 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus) 632 { 633 perf_cpu_map__put(pcpus->cpus); 634 Py_TYPE(pcpus)->tp_free((PyObject*)pcpus); 635 } 636 637 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj) 638 { 639 struct pyrf_cpu_map *pcpus = (void *)obj; 640 641 return perf_cpu_map__nr(pcpus->cpus); 642 } 643 644 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i) 645 { 646 struct pyrf_cpu_map *pcpus = (void *)obj; 647 648 if (i >= perf_cpu_map__nr(pcpus->cpus)) 649 return NULL; 650 651 return Py_BuildValue("i", perf_cpu_map__cpu(pcpus->cpus, i).cpu); 652 } 653 654 static PySequenceMethods pyrf_cpu_map__sequence_methods = { 655 .sq_length = pyrf_cpu_map__length, 656 .sq_item = pyrf_cpu_map__item, 657 }; 658 659 static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object."); 660 661 static PyTypeObject pyrf_cpu_map__type = { 662 PyVarObject_HEAD_INIT(NULL, 0) 663 .tp_name = "perf.cpu_map", 664 .tp_basicsize = sizeof(struct pyrf_cpu_map), 665 .tp_dealloc = (destructor)pyrf_cpu_map__delete, 666 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 667 .tp_doc = pyrf_cpu_map__doc, 668 .tp_as_sequence = &pyrf_cpu_map__sequence_methods, 669 .tp_init = (initproc)pyrf_cpu_map__init, 670 }; 671 672 static int pyrf_cpu_map__setup_types(void) 673 { 674 pyrf_cpu_map__type.tp_new = PyType_GenericNew; 675 return PyType_Ready(&pyrf_cpu_map__type); 676 } 677 678 struct pyrf_thread_map { 679 PyObject_HEAD 680 681 struct perf_thread_map *threads; 682 }; 683 684 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, 685 PyObject *args, PyObject *kwargs) 686 { 687 static char *kwlist[] = { "pid", "tid", "uid", NULL }; 688 int pid = -1, tid = -1, uid = UINT_MAX; 689 690 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii", 691 kwlist, &pid, &tid, &uid)) 692 return -1; 693 694 pthreads->threads = thread_map__new(pid, tid, uid); 695 if (pthreads->threads == NULL) 696 return -1; 697 return 0; 698 } 699 700 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads) 701 { 702 perf_thread_map__put(pthreads->threads); 703 Py_TYPE(pthreads)->tp_free((PyObject*)pthreads); 704 } 705 706 static Py_ssize_t pyrf_thread_map__length(PyObject *obj) 707 { 708 struct pyrf_thread_map *pthreads = (void *)obj; 709 710 return pthreads->threads->nr; 711 } 712 713 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i) 714 { 715 struct pyrf_thread_map *pthreads = (void *)obj; 716 717 if (i >= pthreads->threads->nr) 718 return NULL; 719 720 return Py_BuildValue("i", pthreads->threads->map[i]); 721 } 722 723 static PySequenceMethods pyrf_thread_map__sequence_methods = { 724 .sq_length = pyrf_thread_map__length, 725 .sq_item = pyrf_thread_map__item, 726 }; 727 728 static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object."); 729 730 static PyTypeObject pyrf_thread_map__type = { 731 PyVarObject_HEAD_INIT(NULL, 0) 732 .tp_name = "perf.thread_map", 733 .tp_basicsize = sizeof(struct pyrf_thread_map), 734 .tp_dealloc = (destructor)pyrf_thread_map__delete, 735 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 736 .tp_doc = pyrf_thread_map__doc, 737 .tp_as_sequence = &pyrf_thread_map__sequence_methods, 738 .tp_init = (initproc)pyrf_thread_map__init, 739 }; 740 741 static int pyrf_thread_map__setup_types(void) 742 { 743 pyrf_thread_map__type.tp_new = PyType_GenericNew; 744 return PyType_Ready(&pyrf_thread_map__type); 745 } 746 747 struct pyrf_evsel { 748 PyObject_HEAD 749 750 struct evsel evsel; 751 }; 752 753 static int pyrf_evsel__init(struct pyrf_evsel *pevsel, 754 PyObject *args, PyObject *kwargs) 755 { 756 struct perf_event_attr attr = { 757 .type = PERF_TYPE_HARDWARE, 758 .config = PERF_COUNT_HW_CPU_CYCLES, 759 .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID, 760 }; 761 static char *kwlist[] = { 762 "type", 763 "config", 764 "sample_freq", 765 "sample_period", 766 "sample_type", 767 "read_format", 768 "disabled", 769 "inherit", 770 "pinned", 771 "exclusive", 772 "exclude_user", 773 "exclude_kernel", 774 "exclude_hv", 775 "exclude_idle", 776 "mmap", 777 "context_switch", 778 "comm", 779 "freq", 780 "inherit_stat", 781 "enable_on_exec", 782 "task", 783 "watermark", 784 "precise_ip", 785 "mmap_data", 786 "sample_id_all", 787 "wakeup_events", 788 "bp_type", 789 "bp_addr", 790 "bp_len", 791 NULL 792 }; 793 u64 sample_period = 0; 794 u32 disabled = 0, 795 inherit = 0, 796 pinned = 0, 797 exclusive = 0, 798 exclude_user = 0, 799 exclude_kernel = 0, 800 exclude_hv = 0, 801 exclude_idle = 0, 802 mmap = 0, 803 context_switch = 0, 804 comm = 0, 805 freq = 1, 806 inherit_stat = 0, 807 enable_on_exec = 0, 808 task = 0, 809 watermark = 0, 810 precise_ip = 0, 811 mmap_data = 0, 812 sample_id_all = 1; 813 int idx = 0; 814 815 if (!PyArg_ParseTupleAndKeywords(args, kwargs, 816 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist, 817 &attr.type, &attr.config, &attr.sample_freq, 818 &sample_period, &attr.sample_type, 819 &attr.read_format, &disabled, &inherit, 820 &pinned, &exclusive, &exclude_user, 821 &exclude_kernel, &exclude_hv, &exclude_idle, 822 &mmap, &context_switch, &comm, &freq, &inherit_stat, 823 &enable_on_exec, &task, &watermark, 824 &precise_ip, &mmap_data, &sample_id_all, 825 &attr.wakeup_events, &attr.bp_type, 826 &attr.bp_addr, &attr.bp_len, &idx)) 827 return -1; 828 829 /* union... */ 830 if (sample_period != 0) { 831 if (attr.sample_freq != 0) 832 return -1; /* FIXME: throw right exception */ 833 attr.sample_period = sample_period; 834 } 835 836 /* Bitfields */ 837 attr.disabled = disabled; 838 attr.inherit = inherit; 839 attr.pinned = pinned; 840 attr.exclusive = exclusive; 841 attr.exclude_user = exclude_user; 842 attr.exclude_kernel = exclude_kernel; 843 attr.exclude_hv = exclude_hv; 844 attr.exclude_idle = exclude_idle; 845 attr.mmap = mmap; 846 attr.context_switch = context_switch; 847 attr.comm = comm; 848 attr.freq = freq; 849 attr.inherit_stat = inherit_stat; 850 attr.enable_on_exec = enable_on_exec; 851 attr.task = task; 852 attr.watermark = watermark; 853 attr.precise_ip = precise_ip; 854 attr.mmap_data = mmap_data; 855 attr.sample_id_all = sample_id_all; 856 attr.size = sizeof(attr); 857 858 evsel__init(&pevsel->evsel, &attr, idx); 859 return 0; 860 } 861 862 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel) 863 { 864 evsel__exit(&pevsel->evsel); 865 Py_TYPE(pevsel)->tp_free((PyObject*)pevsel); 866 } 867 868 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, 869 PyObject *args, PyObject *kwargs) 870 { 871 struct evsel *evsel = &pevsel->evsel; 872 struct perf_cpu_map *cpus = NULL; 873 struct perf_thread_map *threads = NULL; 874 PyObject *pcpus = NULL, *pthreads = NULL; 875 int group = 0, inherit = 0; 876 static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL }; 877 878 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, 879 &pcpus, &pthreads, &group, &inherit)) 880 return NULL; 881 882 if (pthreads != NULL) 883 threads = ((struct pyrf_thread_map *)pthreads)->threads; 884 885 if (pcpus != NULL) 886 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 887 888 evsel->core.attr.inherit = inherit; 889 /* 890 * This will group just the fds for this single evsel, to group 891 * multiple events, use evlist.open(). 892 */ 893 if (evsel__open(evsel, cpus, threads) < 0) { 894 PyErr_SetFromErrno(PyExc_OSError); 895 return NULL; 896 } 897 898 Py_INCREF(Py_None); 899 return Py_None; 900 } 901 902 static PyMethodDef pyrf_evsel__methods[] = { 903 { 904 .ml_name = "open", 905 .ml_meth = (PyCFunction)pyrf_evsel__open, 906 .ml_flags = METH_VARARGS | METH_KEYWORDS, 907 .ml_doc = PyDoc_STR("open the event selector file descriptor table.") 908 }, 909 { .ml_name = NULL, } 910 }; 911 912 static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object."); 913 914 static PyTypeObject pyrf_evsel__type = { 915 PyVarObject_HEAD_INIT(NULL, 0) 916 .tp_name = "perf.evsel", 917 .tp_basicsize = sizeof(struct pyrf_evsel), 918 .tp_dealloc = (destructor)pyrf_evsel__delete, 919 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 920 .tp_doc = pyrf_evsel__doc, 921 .tp_methods = pyrf_evsel__methods, 922 .tp_init = (initproc)pyrf_evsel__init, 923 }; 924 925 static int pyrf_evsel__setup_types(void) 926 { 927 pyrf_evsel__type.tp_new = PyType_GenericNew; 928 return PyType_Ready(&pyrf_evsel__type); 929 } 930 931 struct pyrf_evlist { 932 PyObject_HEAD 933 934 struct evlist evlist; 935 }; 936 937 static int pyrf_evlist__init(struct pyrf_evlist *pevlist, 938 PyObject *args, PyObject *kwargs __maybe_unused) 939 { 940 PyObject *pcpus = NULL, *pthreads = NULL; 941 struct perf_cpu_map *cpus; 942 struct perf_thread_map *threads; 943 944 if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads)) 945 return -1; 946 947 threads = ((struct pyrf_thread_map *)pthreads)->threads; 948 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 949 evlist__init(&pevlist->evlist, cpus, threads); 950 return 0; 951 } 952 953 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist) 954 { 955 evlist__exit(&pevlist->evlist); 956 Py_TYPE(pevlist)->tp_free((PyObject*)pevlist); 957 } 958 959 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, 960 PyObject *args, PyObject *kwargs) 961 { 962 struct evlist *evlist = &pevlist->evlist; 963 static char *kwlist[] = { "pages", "overwrite", NULL }; 964 int pages = 128, overwrite = false; 965 966 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, 967 &pages, &overwrite)) 968 return NULL; 969 970 if (evlist__mmap(evlist, pages) < 0) { 971 PyErr_SetFromErrno(PyExc_OSError); 972 return NULL; 973 } 974 975 Py_INCREF(Py_None); 976 return Py_None; 977 } 978 979 static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist, 980 PyObject *args, PyObject *kwargs) 981 { 982 struct evlist *evlist = &pevlist->evlist; 983 static char *kwlist[] = { "timeout", NULL }; 984 int timeout = -1, n; 985 986 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout)) 987 return NULL; 988 989 n = evlist__poll(evlist, timeout); 990 if (n < 0) { 991 PyErr_SetFromErrno(PyExc_OSError); 992 return NULL; 993 } 994 995 return Py_BuildValue("i", n); 996 } 997 998 static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist, 999 PyObject *args __maybe_unused, 1000 PyObject *kwargs __maybe_unused) 1001 { 1002 struct evlist *evlist = &pevlist->evlist; 1003 PyObject *list = PyList_New(0); 1004 int i; 1005 1006 for (i = 0; i < evlist->core.pollfd.nr; ++i) { 1007 PyObject *file; 1008 #if PY_MAJOR_VERSION < 3 1009 FILE *fp = fdopen(evlist->core.pollfd.entries[i].fd, "r"); 1010 1011 if (fp == NULL) 1012 goto free_list; 1013 1014 file = PyFile_FromFile(fp, "perf", "r", NULL); 1015 #else 1016 file = PyFile_FromFd(evlist->core.pollfd.entries[i].fd, "perf", "r", -1, 1017 NULL, NULL, NULL, 0); 1018 #endif 1019 if (file == NULL) 1020 goto free_list; 1021 1022 if (PyList_Append(list, file) != 0) { 1023 Py_DECREF(file); 1024 goto free_list; 1025 } 1026 1027 Py_DECREF(file); 1028 } 1029 1030 return list; 1031 free_list: 1032 return PyErr_NoMemory(); 1033 } 1034 1035 1036 static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, 1037 PyObject *args, 1038 PyObject *kwargs __maybe_unused) 1039 { 1040 struct evlist *evlist = &pevlist->evlist; 1041 PyObject *pevsel; 1042 struct evsel *evsel; 1043 1044 if (!PyArg_ParseTuple(args, "O", &pevsel)) 1045 return NULL; 1046 1047 Py_INCREF(pevsel); 1048 evsel = &((struct pyrf_evsel *)pevsel)->evsel; 1049 evsel->core.idx = evlist->core.nr_entries; 1050 evlist__add(evlist, evsel); 1051 1052 return Py_BuildValue("i", evlist->core.nr_entries); 1053 } 1054 1055 static struct mmap *get_md(struct evlist *evlist, int cpu) 1056 { 1057 int i; 1058 1059 for (i = 0; i < evlist->core.nr_mmaps; i++) { 1060 struct mmap *md = &evlist->mmap[i]; 1061 1062 if (md->core.cpu.cpu == cpu) 1063 return md; 1064 } 1065 1066 return NULL; 1067 } 1068 1069 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, 1070 PyObject *args, PyObject *kwargs) 1071 { 1072 struct evlist *evlist = &pevlist->evlist; 1073 union perf_event *event; 1074 int sample_id_all = 1, cpu; 1075 static char *kwlist[] = { "cpu", "sample_id_all", NULL }; 1076 struct mmap *md; 1077 int err; 1078 1079 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, 1080 &cpu, &sample_id_all)) 1081 return NULL; 1082 1083 md = get_md(evlist, cpu); 1084 if (!md) 1085 return NULL; 1086 1087 if (perf_mmap__read_init(&md->core) < 0) 1088 goto end; 1089 1090 event = perf_mmap__read_event(&md->core); 1091 if (event != NULL) { 1092 PyObject *pyevent = pyrf_event__new(event); 1093 struct pyrf_event *pevent = (struct pyrf_event *)pyevent; 1094 struct evsel *evsel; 1095 1096 if (pyevent == NULL) 1097 return PyErr_NoMemory(); 1098 1099 evsel = evlist__event2evsel(evlist, event); 1100 if (!evsel) { 1101 Py_INCREF(Py_None); 1102 return Py_None; 1103 } 1104 1105 pevent->evsel = evsel; 1106 1107 err = evsel__parse_sample(evsel, event, &pevent->sample); 1108 1109 /* Consume the even only after we parsed it out. */ 1110 perf_mmap__consume(&md->core); 1111 1112 if (err) 1113 return PyErr_Format(PyExc_OSError, 1114 "perf: can't parse sample, err=%d", err); 1115 return pyevent; 1116 } 1117 end: 1118 Py_INCREF(Py_None); 1119 return Py_None; 1120 } 1121 1122 static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist, 1123 PyObject *args, PyObject *kwargs) 1124 { 1125 struct evlist *evlist = &pevlist->evlist; 1126 int group = 0; 1127 static char *kwlist[] = { "group", NULL }; 1128 1129 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group)) 1130 return NULL; 1131 1132 if (group) 1133 evlist__set_leader(evlist); 1134 1135 if (evlist__open(evlist) < 0) { 1136 PyErr_SetFromErrno(PyExc_OSError); 1137 return NULL; 1138 } 1139 1140 Py_INCREF(Py_None); 1141 return Py_None; 1142 } 1143 1144 static PyMethodDef pyrf_evlist__methods[] = { 1145 { 1146 .ml_name = "mmap", 1147 .ml_meth = (PyCFunction)pyrf_evlist__mmap, 1148 .ml_flags = METH_VARARGS | METH_KEYWORDS, 1149 .ml_doc = PyDoc_STR("mmap the file descriptor table.") 1150 }, 1151 { 1152 .ml_name = "open", 1153 .ml_meth = (PyCFunction)pyrf_evlist__open, 1154 .ml_flags = METH_VARARGS | METH_KEYWORDS, 1155 .ml_doc = PyDoc_STR("open the file descriptors.") 1156 }, 1157 { 1158 .ml_name = "poll", 1159 .ml_meth = (PyCFunction)pyrf_evlist__poll, 1160 .ml_flags = METH_VARARGS | METH_KEYWORDS, 1161 .ml_doc = PyDoc_STR("poll the file descriptor table.") 1162 }, 1163 { 1164 .ml_name = "get_pollfd", 1165 .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd, 1166 .ml_flags = METH_VARARGS | METH_KEYWORDS, 1167 .ml_doc = PyDoc_STR("get the poll file descriptor table.") 1168 }, 1169 { 1170 .ml_name = "add", 1171 .ml_meth = (PyCFunction)pyrf_evlist__add, 1172 .ml_flags = METH_VARARGS | METH_KEYWORDS, 1173 .ml_doc = PyDoc_STR("adds an event selector to the list.") 1174 }, 1175 { 1176 .ml_name = "read_on_cpu", 1177 .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu, 1178 .ml_flags = METH_VARARGS | METH_KEYWORDS, 1179 .ml_doc = PyDoc_STR("reads an event.") 1180 }, 1181 { .ml_name = NULL, } 1182 }; 1183 1184 static Py_ssize_t pyrf_evlist__length(PyObject *obj) 1185 { 1186 struct pyrf_evlist *pevlist = (void *)obj; 1187 1188 return pevlist->evlist.core.nr_entries; 1189 } 1190 1191 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i) 1192 { 1193 struct pyrf_evlist *pevlist = (void *)obj; 1194 struct evsel *pos; 1195 1196 if (i >= pevlist->evlist.core.nr_entries) 1197 return NULL; 1198 1199 evlist__for_each_entry(&pevlist->evlist, pos) { 1200 if (i-- == 0) 1201 break; 1202 } 1203 1204 return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel)); 1205 } 1206 1207 static PySequenceMethods pyrf_evlist__sequence_methods = { 1208 .sq_length = pyrf_evlist__length, 1209 .sq_item = pyrf_evlist__item, 1210 }; 1211 1212 static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object."); 1213 1214 static PyTypeObject pyrf_evlist__type = { 1215 PyVarObject_HEAD_INIT(NULL, 0) 1216 .tp_name = "perf.evlist", 1217 .tp_basicsize = sizeof(struct pyrf_evlist), 1218 .tp_dealloc = (destructor)pyrf_evlist__delete, 1219 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 1220 .tp_as_sequence = &pyrf_evlist__sequence_methods, 1221 .tp_doc = pyrf_evlist__doc, 1222 .tp_methods = pyrf_evlist__methods, 1223 .tp_init = (initproc)pyrf_evlist__init, 1224 }; 1225 1226 static int pyrf_evlist__setup_types(void) 1227 { 1228 pyrf_evlist__type.tp_new = PyType_GenericNew; 1229 return PyType_Ready(&pyrf_evlist__type); 1230 } 1231 1232 #define PERF_CONST(name) { #name, PERF_##name } 1233 1234 static struct { 1235 const char *name; 1236 int value; 1237 } perf__constants[] = { 1238 PERF_CONST(TYPE_HARDWARE), 1239 PERF_CONST(TYPE_SOFTWARE), 1240 PERF_CONST(TYPE_TRACEPOINT), 1241 PERF_CONST(TYPE_HW_CACHE), 1242 PERF_CONST(TYPE_RAW), 1243 PERF_CONST(TYPE_BREAKPOINT), 1244 1245 PERF_CONST(COUNT_HW_CPU_CYCLES), 1246 PERF_CONST(COUNT_HW_INSTRUCTIONS), 1247 PERF_CONST(COUNT_HW_CACHE_REFERENCES), 1248 PERF_CONST(COUNT_HW_CACHE_MISSES), 1249 PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS), 1250 PERF_CONST(COUNT_HW_BRANCH_MISSES), 1251 PERF_CONST(COUNT_HW_BUS_CYCLES), 1252 PERF_CONST(COUNT_HW_CACHE_L1D), 1253 PERF_CONST(COUNT_HW_CACHE_L1I), 1254 PERF_CONST(COUNT_HW_CACHE_LL), 1255 PERF_CONST(COUNT_HW_CACHE_DTLB), 1256 PERF_CONST(COUNT_HW_CACHE_ITLB), 1257 PERF_CONST(COUNT_HW_CACHE_BPU), 1258 PERF_CONST(COUNT_HW_CACHE_OP_READ), 1259 PERF_CONST(COUNT_HW_CACHE_OP_WRITE), 1260 PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH), 1261 PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS), 1262 PERF_CONST(COUNT_HW_CACHE_RESULT_MISS), 1263 1264 PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND), 1265 PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND), 1266 1267 PERF_CONST(COUNT_SW_CPU_CLOCK), 1268 PERF_CONST(COUNT_SW_TASK_CLOCK), 1269 PERF_CONST(COUNT_SW_PAGE_FAULTS), 1270 PERF_CONST(COUNT_SW_CONTEXT_SWITCHES), 1271 PERF_CONST(COUNT_SW_CPU_MIGRATIONS), 1272 PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN), 1273 PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ), 1274 PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS), 1275 PERF_CONST(COUNT_SW_EMULATION_FAULTS), 1276 PERF_CONST(COUNT_SW_DUMMY), 1277 1278 PERF_CONST(SAMPLE_IP), 1279 PERF_CONST(SAMPLE_TID), 1280 PERF_CONST(SAMPLE_TIME), 1281 PERF_CONST(SAMPLE_ADDR), 1282 PERF_CONST(SAMPLE_READ), 1283 PERF_CONST(SAMPLE_CALLCHAIN), 1284 PERF_CONST(SAMPLE_ID), 1285 PERF_CONST(SAMPLE_CPU), 1286 PERF_CONST(SAMPLE_PERIOD), 1287 PERF_CONST(SAMPLE_STREAM_ID), 1288 PERF_CONST(SAMPLE_RAW), 1289 1290 PERF_CONST(FORMAT_TOTAL_TIME_ENABLED), 1291 PERF_CONST(FORMAT_TOTAL_TIME_RUNNING), 1292 PERF_CONST(FORMAT_ID), 1293 PERF_CONST(FORMAT_GROUP), 1294 1295 PERF_CONST(RECORD_MMAP), 1296 PERF_CONST(RECORD_LOST), 1297 PERF_CONST(RECORD_COMM), 1298 PERF_CONST(RECORD_EXIT), 1299 PERF_CONST(RECORD_THROTTLE), 1300 PERF_CONST(RECORD_UNTHROTTLE), 1301 PERF_CONST(RECORD_FORK), 1302 PERF_CONST(RECORD_READ), 1303 PERF_CONST(RECORD_SAMPLE), 1304 PERF_CONST(RECORD_MMAP2), 1305 PERF_CONST(RECORD_AUX), 1306 PERF_CONST(RECORD_ITRACE_START), 1307 PERF_CONST(RECORD_LOST_SAMPLES), 1308 PERF_CONST(RECORD_SWITCH), 1309 PERF_CONST(RECORD_SWITCH_CPU_WIDE), 1310 1311 PERF_CONST(RECORD_MISC_SWITCH_OUT), 1312 { .name = NULL, }, 1313 }; 1314 1315 static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel, 1316 PyObject *args, PyObject *kwargs) 1317 { 1318 struct tep_event *tp_format; 1319 static char *kwlist[] = { "sys", "name", NULL }; 1320 char *sys = NULL; 1321 char *name = NULL; 1322 1323 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss", kwlist, 1324 &sys, &name)) 1325 return NULL; 1326 1327 tp_format = trace_event__tp_format(sys, name); 1328 if (IS_ERR(tp_format)) 1329 return _PyLong_FromLong(-1); 1330 1331 return _PyLong_FromLong(tp_format->id); 1332 } 1333 1334 static PyMethodDef perf__methods[] = { 1335 { 1336 .ml_name = "tracepoint", 1337 .ml_meth = (PyCFunction) pyrf__tracepoint, 1338 .ml_flags = METH_VARARGS | METH_KEYWORDS, 1339 .ml_doc = PyDoc_STR("Get tracepoint config.") 1340 }, 1341 { .ml_name = NULL, } 1342 }; 1343 1344 #if PY_MAJOR_VERSION < 3 1345 PyMODINIT_FUNC initperf(void) 1346 #else 1347 PyMODINIT_FUNC PyInit_perf(void) 1348 #endif 1349 { 1350 PyObject *obj; 1351 int i; 1352 PyObject *dict; 1353 #if PY_MAJOR_VERSION < 3 1354 PyObject *module = Py_InitModule("perf", perf__methods); 1355 #else 1356 static struct PyModuleDef moduledef = { 1357 PyModuleDef_HEAD_INIT, 1358 "perf", /* m_name */ 1359 "", /* m_doc */ 1360 -1, /* m_size */ 1361 perf__methods, /* m_methods */ 1362 NULL, /* m_reload */ 1363 NULL, /* m_traverse */ 1364 NULL, /* m_clear */ 1365 NULL, /* m_free */ 1366 }; 1367 PyObject *module = PyModule_Create(&moduledef); 1368 #endif 1369 1370 if (module == NULL || 1371 pyrf_event__setup_types() < 0 || 1372 pyrf_evlist__setup_types() < 0 || 1373 pyrf_evsel__setup_types() < 0 || 1374 pyrf_thread_map__setup_types() < 0 || 1375 pyrf_cpu_map__setup_types() < 0) 1376 #if PY_MAJOR_VERSION < 3 1377 return; 1378 #else 1379 return module; 1380 #endif 1381 1382 /* The page_size is placed in util object. */ 1383 page_size = sysconf(_SC_PAGE_SIZE); 1384 1385 Py_INCREF(&pyrf_evlist__type); 1386 PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type); 1387 1388 Py_INCREF(&pyrf_evsel__type); 1389 PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type); 1390 1391 Py_INCREF(&pyrf_mmap_event__type); 1392 PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__type); 1393 1394 Py_INCREF(&pyrf_lost_event__type); 1395 PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__type); 1396 1397 Py_INCREF(&pyrf_comm_event__type); 1398 PyModule_AddObject(module, "comm_event", (PyObject *)&pyrf_comm_event__type); 1399 1400 Py_INCREF(&pyrf_task_event__type); 1401 PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type); 1402 1403 Py_INCREF(&pyrf_throttle_event__type); 1404 PyModule_AddObject(module, "throttle_event", (PyObject *)&pyrf_throttle_event__type); 1405 1406 Py_INCREF(&pyrf_task_event__type); 1407 PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type); 1408 1409 Py_INCREF(&pyrf_read_event__type); 1410 PyModule_AddObject(module, "read_event", (PyObject *)&pyrf_read_event__type); 1411 1412 Py_INCREF(&pyrf_sample_event__type); 1413 PyModule_AddObject(module, "sample_event", (PyObject *)&pyrf_sample_event__type); 1414 1415 Py_INCREF(&pyrf_context_switch_event__type); 1416 PyModule_AddObject(module, "switch_event", (PyObject *)&pyrf_context_switch_event__type); 1417 1418 Py_INCREF(&pyrf_thread_map__type); 1419 PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type); 1420 1421 Py_INCREF(&pyrf_cpu_map__type); 1422 PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type); 1423 1424 dict = PyModule_GetDict(module); 1425 if (dict == NULL) 1426 goto error; 1427 1428 for (i = 0; perf__constants[i].name != NULL; i++) { 1429 obj = _PyLong_FromLong(perf__constants[i].value); 1430 if (obj == NULL) 1431 goto error; 1432 PyDict_SetItemString(dict, perf__constants[i].name, obj); 1433 Py_DECREF(obj); 1434 } 1435 1436 error: 1437 if (PyErr_Occurred()) 1438 PyErr_SetString(PyExc_ImportError, "perf: Init failed!"); 1439 #if PY_MAJOR_VERSION >= 3 1440 return module; 1441 #endif 1442 } 1443 1444 /* 1445 * Dummy, to avoid dragging all the test_attr infrastructure in the python 1446 * binding. 1447 */ 1448 void test_attr__open(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu, 1449 int fd, int group_fd, unsigned long flags) 1450 { 1451 } 1452