[v13,4/4] eal: add PMU support to tracing library
Checks
Commit Message
In order to profile app one needs to store significant amount of samples
somewhere for an analysis later on. Since trace library supports
storing data in a CTF format lets take advantage of that and add a
dedicated PMU tracepoint.
Signed-off-by: Tomasz Duszynski <tduszynski@marvell.com>
---
app/test/test_trace_perf.c | 4 ++
doc/guides/prog_guide/profile_app.rst | 5 ++
doc/guides/prog_guide/trace_lib.rst | 32 +++++++++++++
lib/eal/common/eal_common_trace.c | 7 ++-
lib/eal/common/eal_common_trace_points.c | 5 ++
lib/eal/include/rte_eal_trace.h | 9 ++++
lib/eal/meson.build | 2 +-
lib/eal/version.map | 3 ++
lib/pmu/rte_pmu.c | 61 ++++++++++++++++++++++++
lib/pmu/rte_pmu.h | 18 +++++++
lib/pmu/version.map | 1 +
11 files changed, 145 insertions(+), 2 deletions(-)
Comments
> From: Tomasz Duszynski [mailto:tduszynski@marvell.com]
> Sent: Wednesday, 9 October 2024 13.23
>
> +PMU tracepoint
> +--------------
> +
> +Performance monitoring unit (PMU) event values can be read from
> hardware
> +registers using predefined ``rte_pmu_read`` tracepoint.
> +
> +Tracing is enabled via ``--trace`` EAL option by passing both
> expression
> +matching PMU tracepoint name i.e ``lib.eal.pmu.read`` and expression
> +``e=ev1[,ev2,...]`` matching particular events::
> +
> + --trace='.*pmu.read\|e=cpu_cycles,l1d_cache'
> +
> +Event names are available under
> ``/sys/bus/event_source/devices/PMU/events``
> +directory, where ``PMU`` is a placeholder for either a ``cpu`` or a
> directory
> +containing ``cpus``.
> +
> +In contrary to other tracepoints this does not need any extra
> variables
> +added to source files. Instead, caller passes index which follows the
> order of
> +events specified via ``--trace`` parameter. In the following example
> index ``0``
> +corresponds to ``cpu_cyclces`` while index ``1`` corresponds to
> ``l1d_cache``.
> +
> +.. code-block:: c
> +
> + ...
> + rte_eal_trace_pmu_read(0);
> + rte_eal_trace_pmu_read(1);
> + ...
> +
> +PMU tracing support must be explicitly enabled using the
> ``enable_trace_fp``
> +option for meson build.
> +
> +int
> +rte_pmu_add_events_by_pattern(const char *pattern)
> +{
> + regmatch_t rmatch;
> + char buf[BUFSIZ];
> + unsigned int num;
> + regex_t reg;
> + int ret;
> +
> + /* events are matched against occurrences of e=ev1[,ev2,..]
> pattern */
> + ret = regcomp(®, "e=([_[:alnum:]-],?)+", REG_EXTENDED);
> + if (ret)
> + return -EINVAL;
> +
> + for (;;) {
> + if (regexec(®, pattern, 1, &rmatch, 0))
> + break;
> +
> + num = rmatch.rm_eo - rmatch.rm_so;
> + if (num > sizeof(buf))
> + num = sizeof(buf);
> +
> + /* skip e= pattern prefix */
> + memcpy(buf, pattern + rmatch.rm_so + 2, num - 2);
> + buf[num - 2] = '\0';
> + ret = add_events(buf);
> + if (ret)
> + break;
> +
> + pattern += rmatch.rm_eo;
> + }
> +
> + regfree(®);
> +
> + return ret;
> +}
This --trace parameter takes a regex, but the --log-level parameter takes a globbing pattern (and a regex, for backwards compatibility, I assume).
This --trace parameter should behave like the --log-level parameter, or if not able to parse both, use globbing pattern, not regex.
Check the --trace parameter parser here:
https://elixir.bootlin.com/dpdk/v24.07/source/lib/eal/common/eal_common_options.c#L1409
On Wed, 9 Oct 2024 14:50:02 +0200
Morten Brørup <mb@smartsharesystems.com> wrote:
> > From: Tomasz Duszynski [mailto:tduszynski@marvell.com]
> > Sent: Wednesday, 9 October 2024 13.23
> >
> > +PMU tracepoint
> > +--------------
> > +
> > +Performance monitoring unit (PMU) event values can be read from
> > hardware
> > +registers using predefined ``rte_pmu_read`` tracepoint.
> > +
> > +Tracing is enabled via ``--trace`` EAL option by passing both
> > expression
> > +matching PMU tracepoint name i.e ``lib.eal.pmu.read`` and expression
> > +``e=ev1[,ev2,...]`` matching particular events::
> > +
> > + --trace='.*pmu.read\|e=cpu_cycles,l1d_cache'
> > +
> > +Event names are available under
> > ``/sys/bus/event_source/devices/PMU/events``
> > +directory, where ``PMU`` is a placeholder for either a ``cpu`` or a
> > directory
> > +containing ``cpus``.
> > +
> > +In contrary to other tracepoints this does not need any extra
> > variables
> > +added to source files. Instead, caller passes index which follows the
> > order of
> > +events specified via ``--trace`` parameter. In the following example
> > index ``0``
> > +corresponds to ``cpu_cyclces`` while index ``1`` corresponds to
> > ``l1d_cache``.
> > +
> > +.. code-block:: c
> > +
> > + ...
> > + rte_eal_trace_pmu_read(0);
> > + rte_eal_trace_pmu_read(1);
> > + ...
> > +
> > +PMU tracing support must be explicitly enabled using the
> > ``enable_trace_fp``
> > +option for meson build.
> > +
>
>
> > +int
> > +rte_pmu_add_events_by_pattern(const char *pattern)
> > +{
> > + regmatch_t rmatch;
> > + char buf[BUFSIZ];
> > + unsigned int num;
> > + regex_t reg;
> > + int ret;
> > +
> > + /* events are matched against occurrences of e=ev1[,ev2,..]
> > pattern */
> > + ret = regcomp(®, "e=([_[:alnum:]-],?)+", REG_EXTENDED);
> > + if (ret)
> > + return -EINVAL;
> > +
> > + for (;;) {
> > + if (regexec(®, pattern, 1, &rmatch, 0))
> > + break;
> > +
> > + num = rmatch.rm_eo - rmatch.rm_so;
> > + if (num > sizeof(buf))
> > + num = sizeof(buf);
> > +
> > + /* skip e= pattern prefix */
> > + memcpy(buf, pattern + rmatch.rm_so + 2, num - 2);
> > + buf[num - 2] = '\0';
> > + ret = add_events(buf);
> > + if (ret)
> > + break;
> > +
> > + pattern += rmatch.rm_eo;
> > + }
> > +
> > + regfree(®);
> > +
> > + return ret;
> > +}
>
> This --trace parameter takes a regex, but the --log-level parameter takes a globbing pattern (and a regex, for backwards compatibility, I assume).
>
> This --trace parameter should behave like the --log-level parameter, or if not able to parse both, use globbing pattern, not regex.
>
> Check the --trace parameter parser here:
> https://elixir.bootlin.com/dpdk/v24.07/source/lib/eal/common/eal_common_options.c#L1409
The log level has two API's one takes regex and one takes file glob pattern.
The original one was the regex, but everybody (including the documentation) got regex wrong when the log level format had periods
in it. The glob match was more intuitive, and that is what is recommended.
For tracing if you want to use regex then function should be named with _regexp(
For extra bonus points, having both a regex and glob version (with pattern) would be great.
>On Wed, 9 Oct 2024 14:50:02 +0200
>Morten Brørup <mb@smartsharesystems.com> wrote:
>
>> > From: Tomasz Duszynski [mailto:tduszynski@marvell.com]
>> > Sent: Wednesday, 9 October 2024 13.23
>> >
>> > +PMU tracepoint
>> > +--------------
>> > +
>> > +Performance monitoring unit (PMU) event values can be read from
>> > hardware
>> > +registers using predefined ``rte_pmu_read`` tracepoint.
>> > +
>> > +Tracing is enabled via ``--trace`` EAL option by passing both
>> > expression
>> > +matching PMU tracepoint name i.e ``lib.eal.pmu.read`` and
>> > +expression ``e=ev1[,ev2,...]`` matching particular events::
>> > +
>> > + --trace='.*pmu.read\|e=cpu_cycles,l1d_cache'
>> > +
>> > +Event names are available under
>> > ``/sys/bus/event_source/devices/PMU/events``
>> > +directory, where ``PMU`` is a placeholder for either a ``cpu`` or a
>> > directory
>> > +containing ``cpus``.
>> > +
>> > +In contrary to other tracepoints this does not need any extra
>> > variables
>> > +added to source files. Instead, caller passes index which follows
>> > +the
>> > order of
>> > +events specified via ``--trace`` parameter. In the following
>> > +example
>> > index ``0``
>> > +corresponds to ``cpu_cyclces`` while index ``1`` corresponds to
>> > ``l1d_cache``.
>> > +
>> > +.. code-block:: c
>> > +
>> > + ...
>> > + rte_eal_trace_pmu_read(0);
>> > + rte_eal_trace_pmu_read(1);
>> > + ...
>> > +
>> > +PMU tracing support must be explicitly enabled using the
>> > ``enable_trace_fp``
>> > +option for meson build.
>> > +
>>
>>
>> > +int
>> > +rte_pmu_add_events_by_pattern(const char *pattern) {
>> > + regmatch_t rmatch;
>> > + char buf[BUFSIZ];
>> > + unsigned int num;
>> > + regex_t reg;
>> > + int ret;
>> > +
>> > + /* events are matched against occurrences of e=ev1[,ev2,..]
>> > pattern */
>> > + ret = regcomp(®, "e=([_[:alnum:]-],?)+", REG_EXTENDED);
>> > + if (ret)
>> > + return -EINVAL;
>> > +
>> > + for (;;) {
>> > + if (regexec(®, pattern, 1, &rmatch, 0))
>> > + break;
>> > +
>> > + num = rmatch.rm_eo - rmatch.rm_so;
>> > + if (num > sizeof(buf))
>> > + num = sizeof(buf);
>> > +
>> > + /* skip e= pattern prefix */
>> > + memcpy(buf, pattern + rmatch.rm_so + 2, num - 2);
>> > + buf[num - 2] = '\0';
>> > + ret = add_events(buf);
>> > + if (ret)
>> > + break;
>> > +
>> > + pattern += rmatch.rm_eo;
>> > + }
>> > +
>> > + regfree(®);
>> > +
>> > + return ret;
>> > +}
>>
>> This --trace parameter takes a regex, but the --log-level parameter takes a globbing pattern (and
>a regex, for backwards compatibility, I assume).
>>
>> This --trace parameter should behave like the --log-level parameter, or if not able to parse
>both, use globbing pattern, not regex.
>>
>> Check the --trace parameter parser here:
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__elixir.bootlin.co
>> m_dpdk_v24.07_source_lib_eal_common_eal-5Fcommon-5Foptions.c-23L1409
Just in case, I'll stress that --trace parameter is inherited from tracing library and that itself takes a regex.
Checked both documentation and sources for any discrepancies but there are none.
That means there has never been any compatibility with --log-level behavior and I don't think that patch
should straight things out.
Maybe addressing that separately would be more sensible.
>
>The log level has two API's one takes regex and one takes file glob pattern.
>The original one was the regex, but everybody (including the documentation) got regex wrong when
>the log level format had periods in it. The glob match was more intuitive, and that is what is
>recommended.
>
Thanks for providing more context.
>For tracing if you want to use regex then function should be named with _regexp( For extra bonus
>points, having both a regex and glob version (with pattern) would be great.
Adding extra suffix is fine. glob match lacks some syntax used for specifying events to read, which is \| (OR). Checked the link from Morten
and seems regex matching is turned on whenever log-level contains a coma. Unfortunately I treat coma as event delimiter so presumably
syntax would need to be changed.
Maybe something like '.*pmu.read:cpu_cycles;l1d_cache,*some_other_unrelated tp*' would be more appropriate if making --trace similar to --log-level is the way to go.
> From: Tomasz Duszynski [mailto:tduszynski@marvell.com]
> Sent: Thursday, 10 October 2024 09.24
>
> >On Wed, 9 Oct 2024 14:50:02 +0200
> >Morten Brørup <mb@smartsharesystems.com> wrote:
> >
> >> > From: Tomasz Duszynski [mailto:tduszynski@marvell.com]
> >> > Sent: Wednesday, 9 October 2024 13.23
> >> >
> >> > +PMU tracepoint
> >> > +--------------
> >> > +
> >> > +Performance monitoring unit (PMU) event values can be read from
> >> > hardware
> >> > +registers using predefined ``rte_pmu_read`` tracepoint.
> >> > +
> >> > +Tracing is enabled via ``--trace`` EAL option by passing both
> >> > expression
> >> > +matching PMU tracepoint name i.e ``lib.eal.pmu.read`` and
> >> > +expression ``e=ev1[,ev2,...]`` matching particular events::
> >> > +
> >> > + --trace='.*pmu.read\|e=cpu_cycles,l1d_cache'
> >> > +
> >> > +Event names are available under
> >> > ``/sys/bus/event_source/devices/PMU/events``
> >> > +directory, where ``PMU`` is a placeholder for either a ``cpu`` or
> a
> >> > directory
> >> > +containing ``cpus``.
> >> > +
> >> > +In contrary to other tracepoints this does not need any extra
> >> > variables
> >> > +added to source files. Instead, caller passes index which follows
> >> > +the
> >> > order of
> >> > +events specified via ``--trace`` parameter. In the following
> >> > +example
> >> > index ``0``
> >> > +corresponds to ``cpu_cyclces`` while index ``1`` corresponds to
> >> > ``l1d_cache``.
> >> > +
> >> > +.. code-block:: c
> >> > +
> >> > + ...
> >> > + rte_eal_trace_pmu_read(0);
> >> > + rte_eal_trace_pmu_read(1);
> >> > + ...
> >> > +
> >> > +PMU tracing support must be explicitly enabled using the
> >> > ``enable_trace_fp``
> >> > +option for meson build.
> >> > +
> >>
> >>
> >> > +int
> >> > +rte_pmu_add_events_by_pattern(const char *pattern) {
> >> > + regmatch_t rmatch;
> >> > + char buf[BUFSIZ];
> >> > + unsigned int num;
> >> > + regex_t reg;
> >> > + int ret;
> >> > +
> >> > + /* events are matched against occurrences of e=ev1[,ev2,..]
> >> > pattern */
> >> > + ret = regcomp(®, "e=([_[:alnum:]-],?)+", REG_EXTENDED);
> >> > + if (ret)
> >> > + return -EINVAL;
> >> > +
> >> > + for (;;) {
> >> > + if (regexec(®, pattern, 1, &rmatch, 0))
> >> > + break;
> >> > +
> >> > + num = rmatch.rm_eo - rmatch.rm_so;
> >> > + if (num > sizeof(buf))
> >> > + num = sizeof(buf);
> >> > +
> >> > + /* skip e= pattern prefix */
> >> > + memcpy(buf, pattern + rmatch.rm_so + 2, num - 2);
> >> > + buf[num - 2] = '\0';
> >> > + ret = add_events(buf);
> >> > + if (ret)
> >> > + break;
> >> > +
> >> > + pattern += rmatch.rm_eo;
> >> > + }
> >> > +
> >> > + regfree(®);
> >> > +
> >> > + return ret;
> >> > +}
> >>
> >> This --trace parameter takes a regex, but the --log-level parameter
> takes a globbing pattern (and
> >a regex, for backwards compatibility, I assume).
> >>
> >> This --trace parameter should behave like the --log-level parameter,
> or if not able to parse
> >both, use globbing pattern, not regex.
> >>
> >> Check the --trace parameter parser here:
> >> https://urldefense.proofpoint.com/v2/url?u=https-
> 3A__elixir.bootlin.co
> >> m_dpdk_v24.07_source_lib_eal_common_eal-5Fcommon-5Foptions.c-23L1409
>
> Just in case, I'll stress that --trace parameter is inherited from
> tracing library and that itself takes a regex.
> Checked both documentation and sources for any discrepancies but there
> are none.
>
> That means there has never been any compatibility with --log-level
> behavior and I don't think that patch
> should straight things out.
>
> Maybe addressing that separately would be more sensible.
>
> >
> >The log level has two API's one takes regex and one takes file glob
> pattern.
> >The original one was the regex, but everybody (including the
> documentation) got regex wrong when
> >the log level format had periods in it. The glob match was more
> intuitive, and that is what is
> >recommended.
> >
>
> Thanks for providing more context.
>
> >For tracing if you want to use regex then function should be named
> with _regexp( For extra bonus
> >points, having both a regex and glob version (with pattern) would be
> great.
>
> Adding extra suffix is fine. glob match lacks some syntax used for
> specifying events to read, which is \| (OR). Checked the link from
> Morten
> and seems regex matching is turned on whenever log-level contains a
> coma. Unfortunately I treat coma as event delimiter so presumably
> syntax would need to be changed.
>
> Maybe something like
> '.*pmu.read:cpu_cycles;l1d_cache,*some_other_unrelated tp*' would be
> more appropriate if making --trace similar to --log-level is the way to
> go.
<rant>
It's unfortunate that the parameter formats passed though various means (command line, telemetry, ...) have evolved by piling on more and more, rather than making a proper design, like the other APIs.
</rant>
Since this patch is related to trace, you should let trace conventions take precedence over log conventions.
Please ignore my feedback about using log conventions.
Sorry about the noise. ;-)
@@ -114,6 +114,8 @@ worker_fn_##func(void *arg) \
#define GENERIC_DOUBLE rte_eal_trace_generic_double(3.66666)
#define GENERIC_STR rte_eal_trace_generic_str("hello world")
#define VOID_FP app_dpdk_test_fp()
+/* 0 corresponds first event passed via --trace= */
+#define READ_PMU rte_eal_trace_pmu_read(0)
WORKER_DEFINE(GENERIC_VOID)
WORKER_DEFINE(GENERIC_U64)
@@ -122,6 +124,7 @@ WORKER_DEFINE(GENERIC_FLOAT)
WORKER_DEFINE(GENERIC_DOUBLE)
WORKER_DEFINE(GENERIC_STR)
WORKER_DEFINE(VOID_FP)
+WORKER_DEFINE(READ_PMU)
static void
run_test(const char *str, lcore_function_t f, struct test_data *data, size_t sz)
@@ -174,6 +177,7 @@ test_trace_perf(void)
run_test("double", worker_fn_GENERIC_DOUBLE, data, sz);
run_test("string", worker_fn_GENERIC_STR, data, sz);
run_test("void_fp", worker_fn_VOID_FP, data, sz);
+ run_test("read_pmu", worker_fn_READ_PMU, data, sz);
rte_free(data);
return TEST_SUCCESS;
@@ -36,6 +36,11 @@ As of now implementation imposes certain limitations:
* Each EAL lcore measures same group of events
+Alternatively tracing library can be used which offers dedicated tracepoint
+``rte_eal_trace_pmu_event()``.
+
+Refer to :doc:`../prog_guide/trace_lib` for more details.
+
Profiling on x86
----------------
@@ -46,6 +46,7 @@ DPDK tracing library features
trace format and is compatible with ``LTTng``.
For detailed information, refer to
`Common Trace Format <https://diamon.org/ctf/>`_.
+- Support reading PMU events on ARM64 and x86-64 (Intel)
How to add a tracepoint?
------------------------
@@ -139,6 +140,37 @@ the user must use ``RTE_TRACE_POINT_FP`` instead of ``RTE_TRACE_POINT``.
``RTE_TRACE_POINT_FP`` is compiled out by default and it can be enabled using
the ``enable_trace_fp`` option for meson build.
+PMU tracepoint
+--------------
+
+Performance monitoring unit (PMU) event values can be read from hardware
+registers using predefined ``rte_pmu_read`` tracepoint.
+
+Tracing is enabled via ``--trace`` EAL option by passing both expression
+matching PMU tracepoint name i.e ``lib.eal.pmu.read`` and expression
+``e=ev1[,ev2,...]`` matching particular events::
+
+ --trace='.*pmu.read\|e=cpu_cycles,l1d_cache'
+
+Event names are available under ``/sys/bus/event_source/devices/PMU/events``
+directory, where ``PMU`` is a placeholder for either a ``cpu`` or a directory
+containing ``cpus``.
+
+In contrary to other tracepoints this does not need any extra variables
+added to source files. Instead, caller passes index which follows the order of
+events specified via ``--trace`` parameter. In the following example index ``0``
+corresponds to ``cpu_cyclces`` while index ``1`` corresponds to ``l1d_cache``.
+
+.. code-block:: c
+
+ ...
+ rte_eal_trace_pmu_read(0);
+ rte_eal_trace_pmu_read(1);
+ ...
+
+PMU tracing support must be explicitly enabled using the ``enable_trace_fp``
+option for meson build.
+
Event record mode
-----------------
@@ -12,6 +12,7 @@
#include <rte_errno.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
+#include <rte_pmu.h>
#include <rte_string_fns.h>
#include "eal_trace.h"
@@ -72,8 +73,11 @@ eal_trace_init(void)
goto free_meta;
/* Apply global configurations */
- STAILQ_FOREACH(arg, &trace.args, next)
+ STAILQ_FOREACH(arg, &trace.args, next) {
trace_args_apply(arg->val);
+ if (rte_pmu_init() == 0)
+ rte_pmu_add_events_by_pattern(arg->val);
+ }
rte_trace_mode_set(trace.mode);
@@ -89,6 +93,7 @@ eal_trace_init(void)
void
eal_trace_fini(void)
{
+ rte_pmu_fini();
trace_mem_free();
trace_metadata_destroy();
eal_trace_args_free();
@@ -100,3 +100,8 @@ RTE_TRACE_POINT_REGISTER(rte_eal_trace_intr_enable,
lib.eal.intr.enable)
RTE_TRACE_POINT_REGISTER(rte_eal_trace_intr_disable,
lib.eal.intr.disable)
+
+#ifdef RTE_EXEC_ENV_LINUX
+RTE_TRACE_POINT_REGISTER(rte_eal_trace_pmu_read,
+ lib.eal.pmu.read)
+#endif
@@ -15,6 +15,7 @@
extern "C" {
#endif
+#include <rte_pmu.h>
#include <rte_trace_point.h>
/* Generic */
@@ -127,6 +128,14 @@ RTE_TRACE_POINT(
#define RTE_EAL_TRACE_GENERIC_FUNC rte_eal_trace_generic_func(__func__)
+RTE_TRACE_POINT_FP(
+ rte_eal_trace_pmu_read,
+ RTE_TRACE_POINT_ARGS(unsigned int index),
+ uint64_t val;
+ val = rte_pmu_read(index);
+ rte_trace_point_emit_u64(val);
+)
+
#ifdef __cplusplus
}
#endif
@@ -14,7 +14,7 @@ subdir(exec_env)
subdir(arch_subdir)
-deps += ['log', 'kvargs']
+deps += ['log', 'kvargs', 'pmu']
if not is_windows
deps += ['telemetry']
endif
@@ -396,6 +396,9 @@ EXPERIMENTAL {
# added in 24.03
rte_vfio_get_device_info; # WINDOWS_NO_EXPORT
+
+ # added in 24.11
+ __rte_eal_trace_pmu_read; # WINDOWS_NO_EXPORT
};
INTERNAL {
@@ -403,6 +403,67 @@ rte_pmu_add_event(const char *name)
return event->index;
}
+static int
+add_events(const char *pattern)
+{
+ char *token, *copy;
+ int ret = 0;
+
+ copy = strdup(pattern);
+ if (copy == NULL)
+ return -ENOMEM;
+
+ token = strtok(copy, ",");
+ while (token) {
+ ret = rte_pmu_add_event(token);
+ if (ret < 0)
+ break;
+
+ token = strtok(NULL, ",");
+ }
+
+ free(copy);
+
+ return ret >= 0 ? 0 : ret;
+}
+
+int
+rte_pmu_add_events_by_pattern(const char *pattern)
+{
+ regmatch_t rmatch;
+ char buf[BUFSIZ];
+ unsigned int num;
+ regex_t reg;
+ int ret;
+
+ /* events are matched against occurrences of e=ev1[,ev2,..] pattern */
+ ret = regcomp(®, "e=([_[:alnum:]-],?)+", REG_EXTENDED);
+ if (ret)
+ return -EINVAL;
+
+ for (;;) {
+ if (regexec(®, pattern, 1, &rmatch, 0))
+ break;
+
+ num = rmatch.rm_eo - rmatch.rm_so;
+ if (num > sizeof(buf))
+ num = sizeof(buf);
+
+ /* skip e= pattern prefix */
+ memcpy(buf, pattern + rmatch.rm_so + 2, num - 2);
+ buf[num - 2] = '\0';
+ ret = add_events(buf);
+ if (ret)
+ break;
+
+ pattern += rmatch.rm_eo;
+ }
+
+ regfree(®);
+
+ return ret;
+}
+
int
rte_pmu_init(void)
{
@@ -175,6 +175,20 @@ __rte_experimental
int
rte_pmu_add_event(const char *name);
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Add events matching pattern to the group of enabled events.
+ *
+ * @param pattern
+ * Pattern e=ev1[,ev2,...] matching events, where evX is a placeholder for an event listed under
+ * /sys/bus/event_source/devices/pmu/events.
+ */
+__rte_experimental
+int
+rte_pmu_add_events_by_pattern(const char *pattern);
+
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice
@@ -221,6 +235,10 @@ static inline void rte_pmu_fini(void) { }
__rte_experimental
static inline int rte_pmu_add_event(const char *name __rte_unused) { return -ENOTSUP; }
+__rte_experimental
+static inline int
+rte_pmu_add_events_by_pattern(const char *pattern __rte_unused) { return -ENOTSUP; }
+
__rte_experimental
static inline uint64_t rte_pmu_read(unsigned int index __rte_unused) { return UINT64_MAX; }
@@ -6,6 +6,7 @@ EXPERIMENTAL {
per_lcore__event_group;
rte_pmu;
rte_pmu_add_event;
+ rte_pmu_add_events_by_pattern;
rte_pmu_fini;
rte_pmu_init;
rte_pmu_read;