-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Performance monitoring plugin intel_pmu #2276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The intel_pmu plugin collects information about system performance counters using kernel Linux perf interface. Signed-off-by: Serhiy Pshyk <serhiyx.pshyk@intel.com>
Signed-off-by: Serhiy Pshyk <serhiyx.pshyk@intel.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @serhiyx,
thank you very much for your patch! It looks great and I have almost exclusively coding style nits.
Best regards,
—octo
src/collectd.conf.pod
Outdated
|
||
=over 4 | ||
|
||
=item B<HWCacheEvents> B<false>|B<true> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Configuration options with this functionality are usually called ReportFoo
, for example ReportNumCpu
of the CPU plugin.
src/collectd.conf.pod
Outdated
- branch-loads | ||
- branch-load-misses | ||
|
||
=item B<KernelPMUEvents> B<false>|B<true> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dito: ReportKernelPMUEvents
src/collectd.conf.pod
Outdated
- branch-misses | ||
- bus-cycles | ||
|
||
=item B<SWEvents> B<false>|B<true> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dito: ReportSWEvents
; please consider expanding "SW" to "Software" to make this option easier to read.
src/collectd.conf.pod
Outdated
|
||
=item B<HWSpecificEvents> I<events> | ||
|
||
This field is a list of comma separated event names. To be able to monitor all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comma separated
Config options can take multiple arguments. Please take a list of strings instead of a single string that is then parsed inside the plugin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored this functionality to use list of strings provided by config parser. But some subparsing routine is still needed as each entry can contain multiple event names to create group of events.
src/collectd.conf.pod
Outdated
- alignment-faults | ||
- emulation-faults | ||
|
||
=item B<HWSpecificEvents> I<events> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the boolean options all having the form "Report… true|false", I'd suggest to rename this option to HardwareEvents.
src/intel_pmu.c
Outdated
return (0); | ||
} | ||
|
||
static int pmu_parse_events(struct eventlist *el, char *events) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned above: the config parser can give you a list of strings – please use that instead of implementing your own (sub-)parsing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored this function to receive list of strings provided by config parser. But some subparsing routine is still needed as each entry can contain multiple event names to create group of events.
src/intel_pmu.c
Outdated
": Events list is empty. No events were setup for monitoring."); | ||
} | ||
|
||
return (0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please unify this style. Both, return foo;
and return (foo);
are okay, just use the same everywhere in the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, with #2277, please remove all parenthesis from this PR.
src/intel_pmu.c
Outdated
|
||
for (s = strtok_r(events, ",", &tmp); s; s = strtok_r(NULL, ",", &tmp)) { | ||
bool group_leader = false, end_group = false; | ||
int len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a size_t
.
src/intel_pmu.c
Outdated
|
||
ret = read_all_events(g_ctx.event_list); | ||
if (ret != 0) { | ||
DEBUG(PMU_PLUGIN ": Failed to read values of all events."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be an ERROR()
since you abort and return prematurely.
src/intel_pmu.c
Outdated
|
||
ret = pmu_dispatch_data(); | ||
if (ret != 0) { | ||
DEBUG(PMU_PLUGIN ": Failed to dispatch event values."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dito: Use ERROR()
here.
Change-Id: I6ec3cb1602b96e76b75339a79e7768b39b2c323a Signed-off-by: Serhiy Pshyk <serhiyx.pshyk@intel.com>
contrib/systemd.collectd.service
Outdated
# Environment=XDG_CACHE_HOME=/opt | ||
# | ||
# By default, the HOME directory is chosen: | ||
Environment= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of getting this from the environment, would it be possible to turn this into a config option settable in collectd.conf?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This environment variable is not used by the plugin itself. It is used inside jevents library that is used by the plugin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And there's no way to pass this to jevents except from the environment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is possible. Will rework the solution to use config option and get rid of using of environment variable..
configure.ac
Outdated
# --with-libjevents {{{ | ||
with_libjevents_cppflags="" | ||
with_libjevents_ldflags="" | ||
AC_ARG_WITH(libjevents, [AS_HELP_STRING([--with-libjevents@<:@=PREFIX@:>@], [Path to libjevents.])], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please keep the same code style as the rest of configure.ac
configure.ac
Outdated
fi | ||
if test "x$with_libjevents" = "xyes" | ||
then | ||
SAVE_CPPFLAGS="$CPPFLAGS" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AC_CHECK_LIB doesn't use CPPFLAGS, so no need to save them.
configure.ac
Outdated
SAVE_LDFLAGS="$LDFLAGS" | ||
SAVE_LIBS="$LIBS" | ||
F438 | CPPFLAGS="$CPPFLAGS -fPIC" | |
LDFLAGS="$LDFLAGS -shared" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting -fPIC and -shared is not needed, you're creating an executable, not a library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I want to create shared object that is linked with jevents library just to check if jevents was compiled with -fPIC. I've added this logic to avoid errors during collectd installation/compilation - if collectd is compiled on the system with jevents installed we check if jevents version is suitable for us and if not just disable intel_pmu plugin during configure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's more trouble than it's worth, you've already a note in the README that jevents should be position independent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Will remove this.
configure.ac
Outdated
} | ||
]] | ||
)], | ||
[with_libjevents="yes"], [with_libjevents="no (could not link to libjevents. Check jevents is compiled with -fPIC.)"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this. If libjevents is not compiled with -fPIC, it is not a shared library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default jevents library is compiled without -fPIC. But this flag is required when jevents library is linked with pmu plugin (intel_pmu.so) to avoid the following error:
/usr/bin/ld: /usr/local/lib64/libjevents.a(cache.o): relocation R_X86_64_32S against
.bss' can not be used when making a shared object; recompile with -fPIC`
configure.ac
Outdated
BUILD_WITH_LIBJEVENTS_CPPFLAGS="$with_libjevents_cppflags" | ||
BUILD_WITH_LIBJEVENTS_LDFLAGS="$with_libjevents_ldflags" | ||
BUILD_WITH_LIBJEVENTS_LIBS="-ljevents" | ||
AC_SUBST(BUILD_WITH_LIBJEVENTS_CPPFLAGS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should not use AC_SUBST in a conditional statement. Please move it below the fi.
- cleanup of configure.ac - add config option EventList to avoid dependency on environment variables Change-Id: I987095b6e71bcf05103e773793c0a40c815f729b Signed-off-by: Serhiy Pshyk <serhiyx.pshyk@intel.com>
@@ -240,7 +245,7 @@ Features | |||
|
|||
- netapp | |||
Plugin to query performance values from a NetApp storage system using the | |||
“Manage ONTAP” SDK provided by NetApp. | |||
“Manage ONTAP” SDK provided by NetApp. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What changed on this line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
must have been fixed by my editor. no-break space symbol (c2a0) was changed to space symbol (20).
Should I revert this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, nice one. No problem, please leave it in, I prefer spaces anyway :)
configure.ac
Outdated
AC_ARG_WITH([libjevents], | ||
[AS_HELP_STRING([--with-libjevents@<:@=PREFIX@:>@], [Path to libjevents.])], | ||
[ | ||
if test "x$withval" != "xno" && test "x$withval" != "xyes" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put if and then on the same line please.
configure.ac
Outdated
SAVE_CPPFLAGS="$CPPFLAGS" | ||
CPPFLAGS="$CPPFLAGS $with_libjevents_cppflags" | ||
|
||
AC_CHECK_HEADERS(jevents.h, [with_libjevents="yes"], [with_libjevents="no (jevents.h not found)"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please quote all the arguments.
configure.ac
Outdated
SAVE_LDFLAGS="$LDFLAGS" | ||
LDFLAGS="$LDFLAGS $with_libjevents_ldflags" | ||
|
||
AC_CHECK_LIB(jevents, json_events, [with_libjevents="yes"], [with_libjevents="no (Can't find libjevents)"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please quote all the arguments, and break this long line.
configure.ac
Outdated
BUILD_WITH_LIBJEVENTS_LDFLAGS="$with_libjevents_ldflags" | ||
BUILD_WITH_LIBJEVENTS_LIBS="-ljevents" | ||
fi | ||
AC_SUBST(BUILD_WITH_LIBJEVENTS_CPPFLAGS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please quote the argument.
Change-Id: Ie69b921a253f418ac7b87248faa29d9d35c647a0 Signed-off-by: Serhiy Pshyk <serhiyx.pshyk@intel.com>
Makefile.am
Outdated
if BUILD_PLUGIN_INTEL_PMU | ||
pkglib_LTLIBRARIES += intel_pmu.la | ||
intel_pmu_la_SOURCES = src/intel_pmu.c | ||
intel_pmu_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBJEVENTS_CPPFLAGS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BUILD_WITH_LIBJEVENTS_CPPFLAGS should be added to intel_pmu_la_CPPFLAGS.
src/intel_pmu.c
Outdated
DEBUG(PMU_PLUGIN ": size : %d", e->attr.size); | ||
} | ||
|
||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to return from a void function.
src/intel_pmu.c
Outdated
DEBUG(PMU_PLUGIN ": hardware_events[%zu]: %s", i, g_ctx.hw_events[i]); | ||
} | ||
|
||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to return from a void function.
src/intel_pmu.c
Outdated
} | ||
|
||
static int pmu_config(oconfig_item_t *ci) { | ||
int ret = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you reduce the scope by moving this into the for loop?
src/intel_pmu.c
Outdated
ret = cf_util_get_boolean(child, &g_ctx.sw_events); | ||
} else { | ||
ERROR(PMU_PLUGIN ": Unknown configuration parameter \"%s\".", child->key); | ||
ret = (-1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for the braces.
src/intel_pmu.c
Outdated
plugin_dispatch_values(&vl); | ||
} | ||
|
||
static int pmu_dispatch_data(void) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function always returns 0, make it void?
src/intel_pmu.c
Outdated
} | ||
|
||
ret = pmu_dispatch_data(); | ||
if (ret != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a no-op, pmu_dispatch_data always returns 0.
src/intel_pmu.c
Outdated
ret = read_all_events(g_ctx.event_list); | ||
if (ret != 0) { | ||
ERROR(PMU_PLUGIN ": Failed to read values of all events."); | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not return an error?
src/intel_pmu.c
Outdated
ret = pmu_dispatch_data(); | ||
if (ret != 0) { | ||
ERROR(PMU_PLUGIN ": Failed to dispatch event values."); | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not return an error?
src/intel_pmu.c
Outdated
e->attr.type = type; | ||
e->attr.config = events[i].config; | ||
e->attr.size = PERF_ATTR_SIZE_VER0; | ||
e->next = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a no-op, the struct has already been zeroed by calloc.
src/intel_pmu.c
Outdated
} | ||
|
||
static int pmu_add_events(struct eventlist *el, uint32_t type, | ||
event_info_t *events, int count) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
count should be size_t.
@serhiyx I left a few more review comments. Once these are resolved I think this is good to go in. Feel free to also add yourself to AUTHORS if you want to. |
Change-Id: I172ad8535edda429cd58e0d6198aa19af76151eb Signed-off-by: Serhiy Pshyk <serhiyx.pshyk@intel.com>
@octo I think this is good to go in, and think all your remarks have been addressed. Do you want to merge this? |
Thank you very much for your great work, @serhiyx! |
The intel_pmu plugin reads performance counters provided by the Linux kernel perf interface. The plugin uses jevents library to resolve named events to perf events and access perf interface.