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

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

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

~ [ 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