~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/python.c

Version: ~ [ linux-5.5-rc7 ] ~ [ linux-5.4.13 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.97 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.166 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.210 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.210 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp