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