1 #include <Python.h> 2 #include <structmember.h> 3 #include <inttypes.h> 4 #include <poll.h> 5 #include "evlist.h" 6 #include "evsel.h" 7 #include "event.h" 8 #include "cpumap.h" 9 #include "thread_map.h" 10 11 /* 12 * Support debug printing even though util/debug.c is not linked. That means 13 * implementing 'verbose' and 'eprintf'. 14 */ 15 int verbose; 16 17 int eprintf(int level, int var, const char *fmt, ...) 18 { 19 va_list args; 20 int ret = 0; 21 22 if (var >= level) { 23 va_start(args, fmt); 24 ret = vfprintf(stderr, fmt, args); 25 va_end(args); 26 } 27 28 return ret; 29 } 30 31 /* Define PyVarObject_HEAD_INIT for python 2.5 */ 32 #ifndef PyVarObject_HEAD_INIT 33 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, 34 #endif 35 36 PyMODINIT_FUNC initperf(void); 37 38 #define member_def(type, member, ptype, help) \ 39 { #member, ptype, \ 40 offsetof(struct pyrf_event, event) + offsetof(struct type, member), \ 41 0, help } 42 43 #define sample_member_def(name, member, ptype, help) \ 44 { #name, ptype, \ 45 offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \ 46 0, help } 47 48 struct pyrf_event { 49 PyObject_HEAD 50 struct perf_sample sample; 51 union perf_event event; 52 }; 53 54 #define sample_members \ 55 sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \ 56 sample_member_def(sample_pid, pid, T_INT, "event pid"), \ 57 sample_member_def(sample_tid, tid, T_INT, "event tid"), \ 58 sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \ 59 sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \ 60 sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \ 61 sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \ 62 sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \ 63 sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"), 64 65 static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object."); 66 67 static PyMemberDef pyrf_mmap_event__members[] = { 68 sample_members 69 member_def(perf_event_header, type, T_UINT, "event type"), 70 member_def(perf_event_header, misc, T_UINT, "event misc"), 71 member_def(mmap_event, pid, T_UINT, "event pid"), 72 member_def(mmap_event, tid, T_UINT, "event tid"), 73 member_def(mmap_event, start, T_ULONGLONG, "start of the map"), 74 member_def(mmap_event, len, T_ULONGLONG, "map length"), 75 member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"), 76 member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"), 77 { .name = NULL, }, 78 }; 79 80 static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent) 81 { 82 PyObject *ret; 83 char *s; 84 85 if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", " 86 "length: %#" PRIx64 ", offset: %#" PRIx64 ", " 87 "filename: %s }", 88 pevent->event.mmap.pid, pevent->event.mmap.tid, 89 pevent->event.mmap.start, pevent->event.mmap.len, 90 pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) { 91 ret = PyErr_NoMemory(); 92 } else { 93 ret = PyString_FromString(s); 94 free(s); 95 } 96 return ret; 97 } 98 99 static PyTypeObject pyrf_mmap_event__type = { 100 PyVarObject_HEAD_INIT(NULL, 0) 101 .tp_name = "perf.mmap_event", 102 .tp_basicsize = sizeof(struct pyrf_event), 103 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 104 .tp_doc = pyrf_mmap_event__doc, 105 .tp_members = pyrf_mmap_event__members, 106 .tp_repr = (reprfunc)pyrf_mmap_event__repr, 107 }; 108 109 static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object."); 110 111 static PyMemberDef pyrf_task_event__members[] = { 112 sample_members 113 member_def(perf_event_header, type, T_UINT, "event type"), 114 member_def(fork_event, pid, T_UINT, "event pid"), 115 member_def(fork_event, ppid, T_UINT, "event ppid"), 116 member_def(fork_event, tid, T_UINT, "event tid"), 117 member_def(fork_event, ptid, T_UINT, "event ptid"), 118 member_def(fork_event, time, T_ULONGLONG, "timestamp"), 119 { .name = NULL, }, 120 }; 121 122 static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent) 123 { 124 return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, " 125 "ptid: %u, time: %" PRIu64 "}", 126 pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit", 127 pevent->event.fork.pid, 128 pevent->event.fork.ppid, 129 pevent->event.fork.tid, 130 pevent->event.fork.ptid, 131 pevent->event.fork.time); 132 } 133 134 static PyTypeObject pyrf_task_event__type = { 135 PyVarObject_HEAD_INIT(NULL, 0) 136 .tp_name = "perf.task_event", 137 .tp_basicsize = sizeof(struct pyrf_event), 138 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 139 .tp_doc = pyrf_task_event__doc, 140 .tp_members = pyrf_task_event__members, 141 .tp_repr = (reprfunc)pyrf_task_event__repr, 142 }; 143 144 static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object."); 145 146 static PyMemberDef pyrf_comm_event__members[] = { 147 sample_members 148 member_def(perf_event_header, type, T_UINT, "event type"), 149 member_def(comm_event, pid, T_UINT, "event pid"), 150 member_def(comm_event, tid, T_UINT, "event tid"), 151 member_def(comm_event, comm, T_STRING_INPLACE, "process name"), 152 { .name = NULL, }, 153 }; 154 155 static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent) 156 { 157 return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }", 158 pevent->event.comm.pid, 159 pevent->event.comm.tid, 160 pevent->event.comm.comm); 161 } 162 163 static PyTypeObject pyrf_comm_event__type = { 164 PyVarObject_HEAD_INIT(NULL, 0) 165 .tp_name = "perf.comm_event", 166 .tp_basicsize = sizeof(struct pyrf_event), 167 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 168 .tp_doc = pyrf_comm_event__doc, 169 .tp_members = pyrf_comm_event__members, 170 .tp_repr = (reprfunc)pyrf_comm_event__repr, 171 }; 172 173 static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object."); 174 175 static PyMemberDef pyrf_throttle_event__members[] = { 176 sample_members 177 member_def(perf_event_header, type, T_UINT, "event type"), 178 member_def(throttle_event, time, T_ULONGLONG, "timestamp"), 179 member_def(throttle_event, id, T_ULONGLONG, "event id"), 180 member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"), 181 { .name = NULL, }, 182 }; 183 184 static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent) 185 { 186 struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1); 187 188 return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64 189 ", stream_id: %" PRIu64 " }", 190 pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un", 191 te->time, te->id, te->stream_id); 192 } 193 194 static PyTypeObject pyrf_throttle_event__type = { 195 PyVarObject_HEAD_INIT(NULL, 0) 196 .tp_name = "perf.throttle_event", 197 .tp_basicsize = sizeof(struct pyrf_event), 198 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 199 .tp_doc = pyrf_throttle_event__doc, 200 .tp_members = pyrf_throttle_event__members, 201 .tp_repr = (reprfunc)pyrf_throttle_event__repr, 202 }; 203 204 static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); 205 206 static PyMemberDef pyrf_lost_event__members[] = { 207 sample_members 208 member_def(lost_event, id, T_ULONGLONG, "event id"), 209 member_def(lost_event, lost, T_ULONGLONG, "number of lost events"), 210 { .name = NULL, }, 211 }; 212 213 static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent) 214 { 215 PyObject *ret; 216 char *s; 217 218 if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", " 219 "lost: %#" PRIx64 " }", 220 pevent->event.lost.id, pevent->event.lost.lost) < 0) { 221 ret = PyErr_NoMemory(); 222 } else { 223 ret = PyString_FromString(s); 224 free(s); 225 } 226 return ret; 227 } 228 229 static PyTypeObject pyrf_lost_event__type = { 230 PyVarObject_HEAD_INIT(NULL, 0) 231 .tp_name = "perf.lost_event", 232 .tp_basicsize = sizeof(struct pyrf_event), 233 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 234 .tp_doc = pyrf_lost_event__doc, 235 .tp_members = pyrf_lost_event__members, 236 .tp_repr = (reprfunc)pyrf_lost_event__repr, 237 }; 238 239 static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object."); 240 241 static PyMemberDef pyrf_read_event__members[] = { 242 sample_members 243 member_def(read_event, pid, T_UINT, "event pid"), 244 member_def(read_event, tid, T_UINT, "event tid"), 245 { .name = NULL, }, 246 }; 247 248 static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent) 249 { 250 return PyString_FromFormat("{ type: read, pid: %u, tid: %u }", 251 pevent->event.read.pid, 252 pevent->event.read.tid); 253 /* 254 * FIXME: return the array of read values, 255 * making this method useful ;-) 256 */ 257 } 258 259 static PyTypeObject pyrf_read_event__type = { 260 PyVarObject_HEAD_INIT(NULL, 0) 261 .tp_name = "perf.read_event", 262 .tp_basicsize = sizeof(struct pyrf_event), 263 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 264 .tp_doc = pyrf_read_event__doc, 265 .tp_members = pyrf_read_event__members, 266 .tp_repr = (reprfunc)pyrf_read_event__repr, 267 }; 268 269 static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object."); 270 271 static PyMemberDef pyrf_sample_event__members[] = { 272 sample_members 273 member_def(perf_event_header, type, T_UINT, "event type"), 274 { .name = NULL, }, 275 }; 276 277 static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) 278 { 279 PyObject *ret; 280 char *s; 281 282 if (asprintf(&s, "{ type: sample }") < 0) { 283 ret = PyErr_NoMemory(); 284 } else { 285 ret = PyString_FromString(s); 286 free(s); 287 } 288 return ret; 289 } 290 291 static PyTypeObject pyrf_sample_event__type = { 292 PyVarObject_HEAD_INIT(NULL, 0) 293 .tp_name = "perf.sample_event", 294 .tp_basicsize = sizeof(struct pyrf_event), 295 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 296 .tp_doc = pyrf_sample_event__doc, 297 .tp_members = pyrf_sample_event__members, 298 .tp_repr = (reprfunc)pyrf_sample_event__repr, 299 }; 300 301 static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object."); 302 303 static PyMemberDef pyrf_context_switch_event__members[] = { 304 sample_members 305 member_def(perf_event_header, type, T_UINT, "event type"), 306 member_def(context_switch_event, next_prev_pid, T_UINT, "next/prev pid"), 307 member_def(context_switch_event, next_prev_tid, T_UINT, "next/prev tid"), 308 { .name = NULL, }, 309 }; 310 311 static PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent) 312 { 313 PyObject *ret; 314 char *s; 315 316 if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }", 317 pevent->event.context_switch.next_prev_pid, 318 pevent->event.context_switch.next_prev_tid, 319 !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) { 320 ret = PyErr_NoMemory(); 321 } else { 322 ret = PyString_FromString(s); 323 free(s); 324 } 325 return ret; 326 } 327 328 static PyTypeObject pyrf_context_switch_event__type = { 329 PyVarObject_HEAD_INIT(NULL, 0) 330 .tp_name = "perf.context_switch_event", 331 .tp_basicsize = sizeof(struct pyrf_event), 332 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 333 .tp_doc = pyrf_context_switch_event__doc, 334 .tp_members = pyrf_context_switch_event__members, 335 .tp_repr = (reprfunc)pyrf_context_switch_event__repr, 336 }; 337 338 static int pyrf_event__setup_types(void) 339 { 340 int err; 341 pyrf_mmap_event__type.tp_new = 342 pyrf_task_event__type.tp_new = 343 pyrf_comm_event__type.tp_new = 344 pyrf_lost_event__type.tp_new = 345 pyrf_read_event__type.tp_new = 346 pyrf_sample_event__type.tp_new = 347 pyrf_context_switch_event__type.tp_new = 348 pyrf_throttle_event__type.tp_new = PyType_GenericNew; 349 err = PyType_Ready(&pyrf_mmap_event__type); 350 if (err < 0) 351 goto out; 352 err = PyType_Ready(&pyrf_lost_event__type); 353 if (err < 0) 354 goto out; 355 err = PyType_Ready(&pyrf_task_event__type); 356 if (err < 0) 357 goto out; 358 err = PyType_Ready(&pyrf_comm_event__type); 359 if (err < 0) 360 goto out; 361 err = PyType_Ready(&pyrf_throttle_event__type); 362 if (err < 0) 363 goto out; 364 err = PyType_Ready(&pyrf_read_event__type); 365 if (err < 0) 366 goto out; 367 err = PyType_Ready(&pyrf_sample_event__type); 368 if (err < 0) 369 goto out; 370 err = PyType_Ready(&pyrf_context_switch_event__type); 371 if (err < 0) 372 goto out; 373 out: 374 return err; 375 } 376 377 static PyTypeObject *pyrf_event__type[] = { 378 [PERF_RECORD_MMAP] = &pyrf_mmap_event__type, 379 [PERF_RECORD_LOST] = &pyrf_lost_event__type, 380 [PERF_RECORD_COMM] = &pyrf_comm_event__type, 381 [PERF_RECORD_EXIT] = &pyrf_task_event__type, 382 [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type, 383 [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type, 384 [PERF_RECORD_FORK] = &pyrf_task_event__type, 385 [PERF_RECORD_READ] = &pyrf_read_event__type, 386 [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type, 387 [PERF_RECORD_SWITCH] = &pyrf_context_switch_event__type, 388 [PERF_RECORD_SWITCH_CPU_WIDE] = &pyrf_context_switch_event__type, 389 }; 390 391 static PyObject *pyrf_event__new(union perf_event *event) 392 { 393 struct pyrf_event *pevent; 394 PyTypeObject *ptype; 395 396 if ((event->header.type < PERF_RECORD_MMAP || 397 event->header.type > PERF_RECORD_SAMPLE) && 398 !(event->header.type == PERF_RECORD_SWITCH || 399 event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)) 400 return NULL; 401 402 ptype = pyrf_event__type[event->header.type]; 403 pevent = PyObject_New(struct pyrf_event, ptype); 404 if (pevent != NULL) 405 memcpy(&pevent->event, event, event->header.size); 406 return (PyObject *)pevent; 407 } 408 409 struct pyrf_cpu_map { 410 PyObject_HEAD 411 412 struct cpu_map *cpus; 413 }; 414 415 static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, 416 PyObject *args, PyObject *kwargs) 417 { 418 static char *kwlist[] = { "cpustr", NULL }; 419 char *cpustr = NULL; 420 421 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", 422 kwlist, &cpustr)) 423 return -1; 424 425 pcpus->cpus = cpu_map__new(cpustr); 426 if (pcpus->cpus == NULL) 427 return -1; 428 return 0; 429 } 430 431 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus) 432 { 433 cpu_map__put(pcpus->cpus); 434 pcpus->ob_type->tp_free((PyObject*)pcpus); 435 } 436 437 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj) 438 { 439 struct pyrf_cpu_map *pcpus = (void *)obj; 440 441 return pcpus->cpus->nr; 442 } 443 444 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i) 445 { 446 struct pyrf_cpu_map *pcpus = (void *)obj; 447 448 if (i >= pcpus->cpus->nr) 449 return NULL; 450 451 return Py_BuildValue("i", pcpus->cpus->map[i]); 452 } 453 454 static PySequenceMethods pyrf_cpu_map__sequence_methods = { 455 .sq_length = pyrf_cpu_map__length, 456 .sq_item = pyrf_cpu_map__item, 457 }; 458 459 static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object."); 460 461 static PyTypeObject pyrf_cpu_map__type = { 462 PyVarObject_HEAD_INIT(NULL, 0) 463 .tp_name = "perf.cpu_map", 464 .tp_basicsize = sizeof(struct pyrf_cpu_map), 465 .tp_dealloc = (destructor)pyrf_cpu_map__delete, 466 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 467 .tp_doc = pyrf_cpu_map__doc, 468 .tp_as_sequence = &pyrf_cpu_map__sequence_methods, 469 .tp_init = (initproc)pyrf_cpu_map__init, 470 }; 471 472 static int pyrf_cpu_map__setup_types(void) 473 { 474 pyrf_cpu_map__type.tp_new = PyType_GenericNew; 475 return PyType_Ready(&pyrf_cpu_map__type); 476 } 477 478 struct pyrf_thread_map { 479 PyObject_HEAD 480 481 struct thread_map *threads; 482 }; 483 484 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, 485 PyObject *args, PyObject *kwargs) 486 { 487 static char *kwlist[] = { "pid", "tid", "uid", NULL }; 488 int pid = -1, tid = -1, uid = UINT_MAX; 489 490 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii", 491 kwlist, &pid, &tid, &uid)) 492 return -1; 493 494 pthreads->threads = thread_map__new(pid, tid, uid); 495 if (pthreads->threads == NULL) 496 return -1; 497 return 0; 498 } 499 500 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads) 501 { 502 thread_map__put(pthreads->threads); 503 pthreads->ob_type->tp_free((PyObject*)pthreads); 504 } 505 506 static Py_ssize_t pyrf_thread_map__length(PyObject *obj) 507 { 508 struct pyrf_thread_map *pthreads = (void *)obj; 509 510 return pthreads->threads->nr; 511 } 512 513 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i) 514 { 515 struct pyrf_thread_map *pthreads = (void *)obj; 516 517 if (i >= pthreads->threads->nr) 518 return NULL; 519 520 return Py_BuildValue("i", pthreads->threads->map[i]); 521 } 522 523 static PySequenceMethods pyrf_thread_map__sequence_methods = { 524 .sq_length = pyrf_thread_map__length, 525 .sq_item = pyrf_thread_map__item, 526 }; 527 528 static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object."); 529 530 static PyTypeObject pyrf_thread_map__type = { 531 PyVarObject_HEAD_INIT(NULL, 0) 532 .tp_name = "perf.thread_map", 533 .tp_basicsize = sizeof(struct pyrf_thread_map), 534 .tp_dealloc = (destructor)pyrf_thread_map__delete, 535 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 536 .tp_doc = pyrf_thread_map__doc, 537 .tp_as_sequence = &pyrf_thread_map__sequence_methods, 538 .tp_init = (initproc)pyrf_thread_map__init, 539 }; 540 541 static int pyrf_thread_map__setup_types(void) 542 { 543 pyrf_thread_map__type.tp_new = PyType_GenericNew; 544 return PyType_Ready(&pyrf_thread_map__type); 545 } 546 547 struct pyrf_evsel { 548 PyObject_HEAD 549 550 struct perf_evsel evsel; 551 }; 552 553 static int pyrf_evsel__init(struct pyrf_evsel *pevsel, 554 PyObject *args, PyObject *kwargs) 555 { 556 struct perf_event_attr attr = { 557 .type = PERF_TYPE_HARDWARE, 558 .config = PERF_COUNT_HW_CPU_CYCLES, 559 .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID, 560 }; 561 static char *kwlist[] = { 562 "type", 563 "config", 564 "sample_freq", 565 "sample_period", 566 "sample_type", 567 "read_format", 568 "disabled", 569 "inherit", 570 "pinned", 571 "exclusive", 572 "exclude_user", 573 "exclude_kernel", 574 "exclude_hv", 575 "exclude_idle", 576 "mmap", 577 "context_switch", 578 "comm", 579 "freq", 580 "inherit_stat", 581 "enable_on_exec", 582 "task", 583 "watermark", 584 "precise_ip", 585 "mmap_data", 586 "sample_id_all", 587 "wakeup_events", 588 "bp_type", 589 "bp_addr", 590 "bp_len", 591 NULL 592 }; 593 u64 sample_period = 0; 594 u32 disabled = 0, 595 inherit = 0, 596 pinned = 0, 597 exclusive = 0, 598 exclude_user = 0, 599 exclude_kernel = 0, 600 exclude_hv = 0, 601 exclude_idle = 0, 602 mmap = 0, 603 context_switch = 0, 604 comm = 0, 605 freq = 1, 606 inherit_stat = 0, 607 enable_on_exec = 0, 608 task = 0, 609 watermark = 0, 610 precise_ip = 0, 611 mmap_data = 0, 612 sample_id_all = 1; 613 int idx = 0; 614 615 if (!PyArg_ParseTupleAndKeywords(args, kwargs, 616 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist, 617 &attr.type, &attr.config, &attr.sample_freq, 618 &sample_period, &attr.sample_type, 619 &attr.read_format, &disabled, &inherit, 620 &pinned, &exclusive, &exclude_user, 621 &exclude_kernel, &exclude_hv, &exclude_idle, 622 &mmap, &context_switch, &comm, &freq, &inherit_stat, 623 &enable_on_exec, &task, &watermark, 624 &precise_ip, &mmap_data, &sample_id_all, 625 &attr.wakeup_events, &attr.bp_type, 626 &attr.bp_addr, &attr.bp_len, &idx)) 627 return -1; 628 629 /* union... */ 630 if (sample_period != 0) { 631 if (attr.sample_freq != 0) 632 return -1; /* FIXME: throw right exception */ 633 attr.sample_period = sample_period; 634 } 635 636 /* Bitfields */ 637 attr.disabled = disabled; 638 attr.inherit = inherit; 639 attr.pinned = pinned; 640 attr.exclusive = exclusive; 641 attr.exclude_user = exclude_user; 642 attr.exclude_kernel = exclude_kernel; 643 attr.exclude_hv = exclude_hv; 644 attr.exclude_idle = exclude_idle; 645 attr.mmap = mmap; 646 attr.context_switch = context_switch; 647 attr.comm = comm; 648 attr.freq = freq; 649 attr.inherit_stat = inherit_stat; 650 attr.enable_on_exec = enable_on_exec; 651 attr.task = task; 652 attr.watermark = watermark; 653 attr.precise_ip = precise_ip; 654 attr.mmap_data = mmap_data; 655 attr.sample_id_all = sample_id_all; 656 657 perf_evsel__init(&pevsel->evsel, &attr, idx); 658 return 0; 659 } 660 661 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel) 662 { 663 perf_evsel__exit(&pevsel->evsel); 664 pevsel->ob_type->tp_free((PyObject*)pevsel); 665 } 666 667 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, 668 PyObject *args, PyObject *kwargs) 669 { 670 struct perf_evsel *evsel = &pevsel->evsel; 671 struct cpu_map *cpus = NULL; 672 struct thread_map *threads = NULL; 673 PyObject *pcpus = NULL, *pthreads = NULL; 674 int group = 0, inherit = 0; 675 static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL }; 676 677 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, 678 &pcpus, &pthreads, &group, &inherit)) 679 return NULL; 680 681 if (pthreads != NULL) 682 threads = ((struct pyrf_thread_map *)pthreads)->threads; 683 684 if (pcpus != NULL) 685 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 686 687 evsel->attr.inherit = inherit; 688 /* 689 * This will group just the fds for this single evsel, to group 690 * multiple events, use evlist.open(). 691 */ 692 if (perf_evsel__open(evsel, cpus, threads) < 0) { 693 PyErr_SetFromErrno(PyExc_OSError); 694 return NULL; 695 } 696 697 Py_INCREF(Py_None); 698 return Py_None; 699 } 700 701 static PyMethodDef pyrf_evsel__methods[] = { 702 { 703 .ml_name = "open", 704 .ml_meth = (PyCFunction)pyrf_evsel__open, 705 .ml_flags = METH_VARARGS | METH_KEYWORDS, 706 .ml_doc = PyDoc_STR("open the event selector file descriptor table.") 707 }, 708 { .ml_name = NULL, } 709 }; 710 711 static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object."); 712 713 static PyTypeObject pyrf_evsel__type = { 714 PyVarObject_HEAD_INIT(NULL, 0) 715 .tp_name = "perf.evsel", 716 .tp_basicsize = sizeof(struct pyrf_evsel), 717 .tp_dealloc = (destructor)pyrf_evsel__delete, 718 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 719 .tp_doc = pyrf_evsel__doc, 720 .tp_methods = pyrf_evsel__methods, 721 .tp_init = (initproc)pyrf_evsel__init, 722 }; 723 724 static int pyrf_evsel__setup_types(void) 725 { 726 pyrf_evsel__type.tp_new = PyType_GenericNew; 727 return PyType_Ready(&pyrf_evsel__type); 728 } 729 730 struct pyrf_evlist { 731 PyObject_HEAD 732 733 struct perf_evlist evlist; 734 }; 735 736 static int pyrf_evlist__init(struct pyrf_evlist *pevlist, 737 PyObject *args, PyObject *kwargs __maybe_unused) 738 { 739 PyObject *pcpus = NULL, *pthreads = NULL; 740 struct cpu_map *cpus; 741 struct thread_map *threads; 742 743 if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads)) 744 return -1; 745 746 threads = ((struct pyrf_thread_map *)pthreads)->threads; 747 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 748 perf_evlist__init(&pevlist->evlist, cpus, threads); 749 return 0; 750 } 751 752 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist) 753 { 754 perf_evlist__exit(&pevlist->evlist); 755 pevlist->ob_type->tp_free((PyObject*)pevlist); 756 } 757 758 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, 759 PyObject *args, PyObject *kwargs) 760 { 761 struct perf_evlist *evlist = &pevlist->evlist; 762 static char *kwlist[] = { "pages", "overwrite", NULL }; 763 int pages = 128, overwrite = false; 764 765 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, 766 &pages, &overwrite)) 767 return NULL; 768 769 if (perf_evlist__mmap(evlist, pages, overwrite) < 0) { 770 PyErr_SetFromErrno(PyExc_OSError); 771 return NULL; 772 } 773 774 Py_INCREF(Py_None); 775 return Py_None; 776 } 777 778 static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist, 779 PyObject *args, PyObject *kwargs) 780 { 781 struct perf_evlist *evlist = &pevlist->evlist; 782 static char *kwlist[] = { "timeout", NULL }; 783 int timeout = -1, n; 784 785 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout)) 786 return NULL; 787 788 n = perf_evlist__poll(evlist, timeout); 789 if (n < 0) { 790 PyErr_SetFromErrno(PyExc_OSError); 791 return NULL; 792 } 793 794 return Py_BuildValue("i", n); 795 } 796 797 static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist, 798 PyObject *args __maybe_unused, 799 PyObject *kwargs __maybe_unused) 800 { 801 struct perf_evlist *evlist = &pevlist->evlist; 802 PyObject *list = PyList_New(0); 803 int i; 804 805 for (i = 0; i < evlist->pollfd.nr; ++i) { 806 PyObject *file; 807 FILE *fp = fdopen(evlist->pollfd.entries[i].fd, "r"); 808 809 if (fp == NULL) 810 goto free_list; 811 812 file = PyFile_FromFile(fp, "perf", "r", NULL); 813 if (file == NULL) 814 goto free_list; 815 816 if (PyList_Append(list, file) != 0) { 817 Py_DECREF(file); 818 goto free_list; 819 } 820 821 Py_DECREF(file); 822 } 823 824 return list; 825 free_list: 826 return PyErr_NoMemory(); 827 } 828 829 830 static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, 831 PyObject *args, 832 PyObject *kwargs __maybe_unused) 833 { 834 struct perf_evlist *evlist = &pevlist->evlist; 835 PyObject *pevsel; 836 struct perf_evsel *evsel; 837 838 if (!PyArg_ParseTuple(args, "O", &pevsel)) 839 return NULL; 840 841 Py_INCREF(pevsel); 842 evsel = &((struct pyrf_evsel *)pevsel)->evsel; 843 evsel->idx = evlist->nr_entries; 844 perf_evlist__add(evlist, evsel); 845 846 return Py_BuildValue("i", evlist->nr_entries); 847 } 848 849 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, 850 PyObject *args, PyObject *kwargs) 851 { 852 struct perf_evlist *evlist = &pevlist->evlist; 853 union perf_event *event; 854 int sample_id_all = 1, cpu; 855 static char *kwlist[] = { "cpu", "sample_id_all", NULL }; 856 int err; 857 858 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, 859 &cpu, &sample_id_all)) 860 return NULL; 861 862 event = perf_evlist__mmap_read(evlist, cpu); 863 if (event != NULL) { 864 PyObject *pyevent = pyrf_event__new(event); 865 struct pyrf_event *pevent = (struct pyrf_event *)pyevent; 866 867 perf_evlist__mmap_consume(evlist, cpu); 868 869 if (pyevent == NULL) 870 return PyErr_NoMemory(); 871 872 err = perf_evlist__parse_sample(evlist, event, &pevent->sample); 873 if (err) 874 return PyErr_Format(PyExc_OSError, 875 "perf: can't parse sample, err=%d", err); 876 return pyevent; 877 } 878 879 Py_INCREF(Py_None); 880 return Py_None; 881 } 882 883 static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist, 884 PyObject *args, PyObject *kwargs) 885 { 886 struct perf_evlist *evlist = &pevlist->evlist; 887 int group = 0; 888 static char *kwlist[] = { "group", NULL }; 889 890 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group)) 891 return NULL; 892 893 if (group) 894 perf_evlist__set_leader(evlist); 895 896 if (perf_evlist__open(evlist) < 0) { 897 PyErr_SetFromErrno(PyExc_OSError); 898 return NULL; 899 } 900 901 Py_INCREF(Py_None); 902 return Py_None; 903 } 904 905 static PyMethodDef pyrf_evlist__methods[] = { 906 { 907 .ml_name = "mmap", 908 .ml_meth = (PyCFunction)pyrf_evlist__mmap, 909 .ml_flags = METH_VARARGS | METH_KEYWORDS, 910 .ml_doc = PyDoc_STR("mmap the file descriptor table.") 911 }, 912 { 913 .ml_name = "open", 914 .ml_meth = (PyCFunction)pyrf_evlist__open, 915 .ml_flags = METH_VARARGS | METH_KEYWORDS, 916 .ml_doc = PyDoc_STR("open the file descriptors.") 917 }, 918 { 919 .ml_name = "poll", 920 .ml_meth = (PyCFunction)pyrf_evlist__poll, 921 .ml_flags = METH_VARARGS | METH_KEYWORDS, 922 .ml_doc = PyDoc_STR("poll the file descriptor table.") 923 }, 924 { 925 .ml_name = "get_pollfd", 926 .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd, 927 .ml_flags = METH_VARARGS | METH_KEYWORDS, 928 .ml_doc = PyDoc_STR("get the poll file descriptor table.") 929 }, 930 { 931 .ml_name = "add", 932 .ml_meth = (PyCFunction)pyrf_evlist__add, 933 .ml_flags = METH_VARARGS | METH_KEYWORDS, 934 .ml_doc = PyDoc_STR("adds an event selector to the list.") 935 }, 936 { 937 .ml_name = "read_on_cpu", 938 .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu, 939 .ml_flags = METH_VARARGS | METH_KEYWORDS, 940 .ml_doc = PyDoc_STR("reads an event.") 941 }, 942 { .ml_name = NULL, } 943 }; 944 945 static Py_ssize_t pyrf_evlist__length(PyObject *obj) 946 { 947 struct pyrf_evlist *pevlist = (void *)obj; 948 949 return pevlist->evlist.nr_entries; 950 } 951 952 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i) 953 { 954 struct pyrf_evlist *pevlist = (void *)obj; 955 struct perf_evsel *pos; 956 957 if (i >= pevlist->evlist.nr_entries) 958 return NULL; 959 960 evlist__for_each(&pevlist->evlist, pos) { 961 if (i-- == 0) 962 break; 963 } 964 965 return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel)); 966 } 967 968 static PySequenceMethods pyrf_evlist__sequence_methods = { 969 .sq_length = pyrf_evlist__length, 970 .sq_item = pyrf_evlist__item, 971 }; 972 973 static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object."); 974 975 static PyTypeObject pyrf_evlist__type = { 976 PyVarObject_HEAD_INIT(NULL, 0) 977 .tp_name = "perf.evlist", 978 .tp_basicsize = sizeof(struct pyrf_evlist), 979 .tp_dealloc = (destructor)pyrf_evlist__delete, 980 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 981 .tp_as_sequence = &pyrf_evlist__sequence_methods, 982 .tp_doc = pyrf_evlist__doc, 983 .tp_methods = pyrf_evlist__methods, 984 .tp_init = (initproc)pyrf_evlist__init, 985 }; 986 987 static int pyrf_evlist__setup_types(void) 988 { 989 pyrf_evlist__type.tp_new = PyType_GenericNew; 990 return PyType_Ready(&pyrf_evlist__type); 991 } 992 993 #define PERF_CONST(name) { #name, PERF_##name } 994 995 static struct { 996 const char *name; 997 int value; 998 } perf__constants[] = { 999 PERF_CONST(TYPE_HARDWARE), 1000 PERF_CONST(TYPE_SOFTWARE), 1001 PERF_CONST(TYPE_TRACEPOINT), 1002 PERF_CONST(TYPE_HW_CACHE), 1003 PERF_CONST(TYPE_RAW), 1004 PERF_CONST(TYPE_BREAKPOINT), 1005 1006 PERF_CONST(COUNT_HW_CPU_CYCLES), 1007 PERF_CONST(COUNT_HW_INSTRUCTIONS), 1008 PERF_CONST(COUNT_HW_CACHE_REFERENCES), 1009 PERF_CONST(COUNT_HW_CACHE_MISSES), 1010 PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS), 1011 PERF_CONST(COUNT_HW_BRANCH_MISSES), 1012 PERF_CONST(COUNT_HW_BUS_CYCLES), 1013 PERF_CONST(COUNT_HW_CACHE_L1D), 1014 PERF_CONST(COUNT_HW_CACHE_L1I), 1015 PERF_CONST(COUNT_HW_CACHE_LL), 1016 PERF_CONST(COUNT_HW_CACHE_DTLB), 1017 PERF_CONST(COUNT_HW_CACHE_ITLB), 1018 PERF_CONST(COUNT_HW_CACHE_BPU), 1019 PERF_CONST(COUNT_HW_CACHE_OP_READ), 1020 PERF_CONST(COUNT_HW_CACHE_OP_WRITE), 1021 PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH), 1022 PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS), 1023 PERF_CONST(COUNT_HW_CACHE_RESULT_MISS), 1024 1025 PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND), 1026 PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND), 1027 1028 PERF_CONST(COUNT_SW_CPU_CLOCK), 1029 PERF_CONST(COUNT_SW_TASK_CLOCK), 1030 PERF_CONST(COUNT_SW_PAGE_FAULTS), 1031 PERF_CONST(COUNT_SW_CONTEXT_SWITCHES), 1032 PERF_CONST(COUNT_SW_CPU_MIGRATIONS), 1033 PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN), 1034 PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ), 1035 PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS), 1036 PERF_CONST(COUNT_SW_EMULATION_FAULTS), 1037 PERF_CONST(COUNT_SW_DUMMY), 1038 1039 PERF_CONST(SAMPLE_IP), 1040 PERF_CONST(SAMPLE_TID), 1041 PERF_CONST(SAMPLE_TIME), 1042 PERF_CONST(SAMPLE_ADDR), 1043 PERF_CONST(SAMPLE_READ), 1044 PERF_CONST(SAMPLE_CALLCHAIN), 1045 PERF_CONST(SAMPLE_ID), 1046 PERF_CONST(SAMPLE_CPU), 1047 PERF_CONST(SAMPLE_PERIOD), 1048 PERF_CONST(SAMPLE_STREAM_ID), 1049 PERF_CONST(SAMPLE_RAW), 1050 1051 PERF_CONST(FORMAT_TOTAL_TIME_ENABLED), 1052 PERF_CONST(FORMAT_TOTAL_TIME_RUNNING), 1053 PERF_CONST(FORMAT_ID), 1054 PERF_CONST(FORMAT_GROUP), 1055 1056 PERF_CONST(RECORD_MMAP), 1057 PERF_CONST(RECORD_LOST), 1058 PERF_CONST(RECORD_COMM), 1059 PERF_CONST(RECORD_EXIT), 1060 PERF_CONST(RECORD_THROTTLE), 1061 PERF_CONST(RECORD_UNTHROTTLE), 1062 PERF_CONST(RECORD_FORK), 1063 PERF_CONST(RECORD_READ), 1064 PERF_CONST(RECORD_SAMPLE), 1065 PERF_CONST(RECORD_MMAP2), 1066 PERF_CONST(RECORD_AUX), 1067 PERF_CONST(RECORD_ITRACE_START), 1068 PERF_CONST(RECORD_LOST_SAMPLES), 1069 PERF_CONST(RECORD_SWITCH), 1070 PERF_CONST(RECORD_SWITCH_CPU_WIDE), 1071 1072 PERF_CONST(RECORD_MISC_SWITCH_OUT), 1073 { .name = NULL, }, 1074 }; 1075 1076 static PyMethodDef perf__methods[] = { 1077 { .ml_name = NULL, } 1078 }; 1079 1080 PyMODINIT_FUNC initperf(void) 1081 { 1082 PyObject *obj; 1083 int i; 1084 PyObject *dict, *module = Py_InitModule("perf", perf__methods); 1085 1086 if (module == NULL || 1087 pyrf_event__setup_types() < 0 || 1088 pyrf_evlist__setup_types() < 0 || 1089 pyrf_evsel__setup_types() < 0 || 1090 pyrf_thread_map__setup_types() < 0 || 1091 pyrf_cpu_map__setup_types() < 0) 1092 return; 1093 1094 /* The page_size is placed in util object. */ 1095 page_size = sysconf(_SC_PAGE_SIZE); 1096 1097 Py_INCREF(&pyrf_evlist__type); 1098 PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type); 1099 1100 Py_INCREF(&pyrf_evsel__type); 1101 PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type); 1102 1103 Py_INCREF(&pyrf_thread_map__type); 1104 PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type); 1105 1106 Py_INCREF(&pyrf_cpu_map__type); 1107 PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type); 1108 1109 dict = PyModule_GetDict(module); 1110 if (dict == NULL) 1111 goto error; 1112 1113 for (i = 0; perf__constants[i].name != NULL; i++) { 1114 obj = PyInt_FromLong(perf__constants[i].value); 1115 if (obj == NULL) 1116 goto error; 1117 PyDict_SetItemString(dict, perf__constants[i].name, obj); 1118 Py_DECREF(obj); 1119 } 1120 1121 error: 1122 if (PyErr_Occurred()) 1123 PyErr_SetString(PyExc_ImportError, "perf: Init failed!"); 1124 } 1125 1126 /* 1127 * Dummy, to avoid dragging all the test_attr infrastructure in the python 1128 * binding. 1129 */ 1130 void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, 1131 int fd, int group_fd, unsigned long flags) 1132 { 1133 } 1134