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