Commit 3b4991dc authored by Gautam Menghani's avatar Gautam Menghani Committed by Arnaldo Carvalho de Melo
Browse files

perf python: Add support for 'struct perf_counts_values' to return counter data



Add support for the perf_counts_values struct to enable the python
bindings to read and return the counter data.

Committer notes:

Use T_ULONG instead of Py_T_ULONG, as all the other PyMemberDef arrays,
fixing the build with older python3 versions.

Use { .name = NULL, } to finish the new PyMemberDef
pyrf_counts_values_members array, again as the other arrays to please
some clang versions, ditto for PyGetSetDef.

Signed-off-by: default avatarGautam Menghani <gautam@linux.ibm.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20250519195148.1708988-5-irogers@google.com


Signed-off-by: default avatarIan Rogers <irogers@google.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 0589aff4
Loading
Loading
Loading
Loading
+91 −1
Original line number Diff line number Diff line
@@ -626,6 +626,92 @@ static int pyrf_thread_map__setup_types(void)
	return PyType_Ready(&pyrf_thread_map__type);
}

struct pyrf_counts_values {
	PyObject_HEAD

	struct perf_counts_values values;
};

static const char pyrf_counts_values__doc[] = PyDoc_STR("perf counts values object.");

static void pyrf_counts_values__delete(struct pyrf_counts_values *pcounts_values)
{
	Py_TYPE(pcounts_values)->tp_free((PyObject *)pcounts_values);
}

#define counts_values_member_def(member, ptype, help) \
	{ #member, ptype, \
	  offsetof(struct pyrf_counts_values, values.member), \
	  0, help }

static PyMemberDef pyrf_counts_values_members[] = {
	counts_values_member_def(val, T_ULONG, "Value of event"),
	counts_values_member_def(ena, T_ULONG, "Time for which enabled"),
	counts_values_member_def(run, T_ULONG, "Time for which running"),
	counts_values_member_def(id, T_ULONG, "Unique ID for an event"),
	counts_values_member_def(lost, T_ULONG, "Num of lost samples"),
	{ .name = NULL, },
};

static PyObject *pyrf_counts_values_get_values(struct pyrf_counts_values *self, void *closure)
{
	PyObject *vals = PyList_New(5);

	if (!vals)
		return NULL;
	for (int i = 0; i < 5; i++)
		PyList_SetItem(vals, i, PyLong_FromLong(self->values.values[i]));

	return vals;
}

static int pyrf_counts_values_set_values(struct pyrf_counts_values *self, PyObject *list,
					 void *closure)
{
	Py_ssize_t size;
	PyObject *item = NULL;

	if (!PyList_Check(list)) {
		PyErr_SetString(PyExc_TypeError, "Value assigned must be a list");
		return -1;
	}

	size = PyList_Size(list);
	for (Py_ssize_t i = 0; i < size; i++) {
		item = PyList_GetItem(list, i);
		if (!PyLong_Check(item)) {
			PyErr_SetString(PyExc_TypeError, "List members should be numbers");
			return -1;
		}
		self->values.values[i] = PyLong_AsLong(item);
	}

	return 0;
}

static PyGetSetDef pyrf_counts_values_getset[] = {
	{"values", (getter)pyrf_counts_values_get_values, (setter)pyrf_counts_values_set_values,
		"Name field", NULL},
	{ .name = NULL, },
};

static PyTypeObject pyrf_counts_values__type = {
	PyVarObject_HEAD_INIT(NULL, 0)
	.tp_name	= "perf.counts_values",
	.tp_basicsize	= sizeof(struct pyrf_counts_values),
	.tp_dealloc	= (destructor)pyrf_counts_values__delete,
	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
	.tp_doc		= pyrf_counts_values__doc,
	.tp_members	= pyrf_counts_values_members,
	.tp_getset	= pyrf_counts_values_getset,
};

static int pyrf_counts_values__setup_types(void)
{
	pyrf_counts_values__type.tp_new = PyType_GenericNew;
	return PyType_Ready(&pyrf_counts_values__type);
}

struct pyrf_evsel {
	PyObject_HEAD

@@ -1475,7 +1561,8 @@ PyMODINIT_FUNC PyInit_perf(void)
	    pyrf_evlist__setup_types() < 0 ||
	    pyrf_evsel__setup_types() < 0 ||
	    pyrf_thread_map__setup_types() < 0 ||
	    pyrf_cpu_map__setup_types() < 0)
	    pyrf_cpu_map__setup_types() < 0 ||
	    pyrf_counts_values__setup_types() < 0)
		return module;

	/* The page_size is placed in util object. */
@@ -1520,6 +1607,9 @@ PyMODINIT_FUNC PyInit_perf(void)
	Py_INCREF(&pyrf_cpu_map__type);
	PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);

	Py_INCREF(&pyrf_counts_values__type);
	PyModule_AddObject(module, "counts_values", (PyObject *)&pyrf_counts_values__type);

	dict = PyModule_GetDict(module);
	if (dict == NULL)
		goto error;