xref: /openbmc/linux/tools/perf/util/python.c (revision c819e2cf)
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