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