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