On Tue, 2022-03-01 at 21:57 -0500, Hongzhan Chen via Xenomai wrote:
> For cobalt thread, there is special struct param_ex data stored in
> data record, we need to parse and print its content out correctly
> to hint user.
> 
> Signed-off-by: Hongzhan Chen <[email protected]>
> ---
>  configure.ac                                  |  17 +-
>  tracing/Makefile.am                           |  13 +-
>  tracing/libtraceevent/Makefile.am             |  10 +
>  tracing/libtraceevent/README                  |  30 +++
>  .../plugin_xenomai_schedparams.c              | 201 ++++++++++++++++++
>  5 files changed, 268 insertions(+), 3 deletions(-)
>  create mode 100644 tracing/libtraceevent/Makefile.am
>  create mode 100644 tracing/libtraceevent/README
>  create mode 100644 tracing/libtraceevent/plugin_xenomai_schedparams.c
> 
> diff --git a/configure.ac b/configure.ac
> index b8e9ca143..5858b3b22 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -829,7 +829,7 @@ AC_MSG_RESULT($XENO_DEMO_DIR)
>  xeno_build_kernelshark=false
>  AC_MSG_CHECKING(build kernelshark plugins)
>  AC_ARG_WITH(kernelshark,
> -    AS_HELP_STRING([--with-kernelshark],[build kernelshark related plugins]),
> +    AS_HELP_STRING([--with-kernelshark],[build kernelshark related plugins 
> including libtraceevent plugin]),
>      [
>       case "$withval" in
>       "" | y | ye | yes) xeno_build_kernelshark=true;;
> @@ -840,6 +840,20 @@ AC_MSG_RESULT($xeno_build_kernelshark)
>  
>  AM_CONDITIONAL([BUILD_KERNELSHARK], [test x$xeno_build_kernelshark = xtrue])
>  
> +xeno_build_libtraceevent=false
> +AC_MSG_CHECKING(build libtraceevent plugin)
> +AC_ARG_WITH(libtraceevent,
> +    AS_HELP_STRING([--with-libtraceevent],[build libtraceevent plugin]),
> +    [
> +     case "$withval" in
> +     "" | y | ye | yes) xeno_build_libtraceevent=true;;
> +     n | no) xeno_build_libtraceevent=false;;
> +     esac
> +    ], [xeno_build_libtraceevent=false])
> +AC_MSG_RESULT($xeno_build_libtraceevent)
> +
> +AM_CONDITIONAL([BUILD_LIBTRACEEVENT], [test x$xeno_build_libtraceevent = 
> xtrue])
> +
>  AC_MSG_CHECKING([for test source generation])
>  AC_RUN_IFELSE([AC_LANG_PROGRAM([[ ]], [[ ]])],
>      [AC_MSG_RESULT(ok)], [AC_MSG_RESULT(failed)], 
> [AC_MSG_RESULT(untestable)])
> @@ -959,6 +973,7 @@ AC_CONFIG_FILES([ \
>       scripts/xeno \
>       tracing/Makefile \
>       tracing/kernelshark/Makefile \
> +     tracing/libtraceevent/Makefile \
>       lib/Makefile \
>       lib/boilerplate/Makefile \
>       lib/boilerplate/init/Makefile \
> diff --git a/tracing/Makefile.am b/tracing/Makefile.am
> index 7925ae9c6..1351a98d2 100644
> --- a/tracing/Makefile.am
> +++ b/tracing/Makefile.am
> @@ -1,7 +1,16 @@
>  if BUILD_KERNELSHARK
>  SUBDIRS =            \
> -     kernelshark
> +     kernelshark     \
> +     libtraceevent
> +else
> +
> +if BUILD_LIBTRACEEVENT
> +SUBDIRS =            \
> +     libtraceevent
> +endif
> +
>  endif
>  
>  DIST_SUBDIRS =               \
> -     kernelshark
> +     kernelshark     \
> +     libtraceevent
> diff --git a/tracing/libtraceevent/Makefile.am 
> b/tracing/libtraceevent/Makefile.am
> new file mode 100644
> index 000000000..e6ae6f319
> --- /dev/null
> +++ b/tracing/libtraceevent/Makefile.am
> @@ -0,0 +1,10 @@
> +
> +lib_LTLIBRARIES = libplugin_xenomai_schedparams.la
> +
> +TRACEEVENR_INCLUDS ?= /usr/local/include/traceevent
> +
> +libplugin_xenomai_schedparams_la_SOURCES =   \
> +     plugin_xenomai_schedparams.c
> +
> +libplugin_xenomai_schedparams_la_CPPFLAGS =  \
> +     -I$(TRACEEVENR_INCLUDS)
> diff --git a/tracing/libtraceevent/README b/tracing/libtraceevent/README
> new file mode 100644
> index 000000000..c15088b02
> --- /dev/null
> +++ b/tracing/libtraceevent/README
> @@ -0,0 +1,30 @@
> +
> +What is it?
> +=============
> +
> +  It is Xenomai plugin on libtracevent to parse struct param_ex
> +  out correctly for trace log.
> +
> +How to compile?
> +================================
> +
> +Preparation:
> +
> +  - GIT clone:
> +
> +      https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git
> +
> +  - build and install libtraceevent:
> +
> +      make;
> +      sudo make install
> +
> +How to use built lib?
> +===============================
> +
> +  Please copy built libplugin_xenomai_schedparams.so to
> +  /usr/local/lib/traceevent/plugins/ or
> +  /usr/local/lib64/traceevent/plugins/ depending on your system.
> +  While libtracevent and its plugins is installed correctly, the plugins
> +  would be loaded automatically by other module such as libtracecmd after
> +  corresponding tracing tool run such as kernelshark or tracecmd.
> diff --git a/tracing/libtraceevent/plugin_xenomai_schedparams.c 
> b/tracing/libtraceevent/plugin_xenomai_schedparams.c
> new file mode 100644
> index 000000000..731e525ba
> --- /dev/null
> +++ b/tracing/libtraceevent/plugin_xenomai_schedparams.c
> @@ -0,0 +1,201 @@
> +// SPDX-License-Identifier: LGPL-2.1
> +/*
> + * Copyright (C) 2021 Intel Inc, Hongzhan Chen <[email protected]>
> + */
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <linux/sched.h>
> +
> +#include "event-parse.h"
> +#include "trace-seq.h"
> +
> +
> +#define SCHED_SPORADIC               10
> +#define SCHED_TP             11
> +#define SCHED_QUOTA          12
> +
> +#define SCHED_COBALT         42
> +#define SCHED_WEAK           43
> +
> +struct __sched_ss_param {
> +     int __sched_low_priority;
> +     struct timespec __sched_repl_period;
> +     struct timespec __sched_init_budget;
> +     int __sched_max_repl;
> +};
> +
> +struct __sched_rr_param {
> +     struct timespec __sched_rr_quantum;
> +};
> +
> +struct __sched_tp_param {
> +     int __sched_partition;
> +};
> +
> +struct __sched_quota_param {
> +     int __sched_group;
> +};
> +
> +struct sched_param_ex {
> +     int sched_priority;
> +     union {
> +             struct __sched_ss_param ss;
> +             struct __sched_rr_param rr;
> +             struct __sched_tp_param tp;
> +             struct __sched_quota_param quota;
> +     } sched_u;
> +};
> +
> +#define sched_quota_group    sched_u.quota.__sched_group
> +#define sched_tp_partition   sched_u.tp.__sched_partition
> +#define sched_ss_low_priority        sched_u.ss.__sched_low_priority
> +#define sched_ss_repl_period sched_u.ss.__sched_repl_period
> +#define sched_ss_init_budget sched_u.ss.__sched_init_budget
> +#define sched_ss_max_repl    sched_u.ss.__sched_max_repl

Why can't you include the xenomai header that actually already defines
such types and their helpers? I might overlook something, but it looks
like a redefinition to me which might break as soon as we have to touch
such types inside Xenomai. Everything around sched_param_ex is y2038
affected for example, so there might be the need to change...

> +
> +static void write_policy(struct trace_seq *p, int policy)
> +{
> +     trace_seq_printf(p, "policy=");
> +
> +     switch (policy) {
> +     case SCHED_QUOTA:
> +             trace_seq_printf(p, "quota ");
> +             break;
> +     case SCHED_TP:
> +             trace_seq_printf(p, "tp ");
> +             break;
> +     case SCHED_NORMAL:
> +             trace_seq_printf(p, "normal ");
> +             break;
> +     case SCHED_SPORADIC:
> +             trace_seq_printf(p, "sporadic ");
> +             break;
> +     case SCHED_RR:
> +             trace_seq_printf(p, "rr ");
> +             break;
> +     case SCHED_FIFO:
> +             trace_seq_printf(p, "fifo ");
> +             break;
> +     case SCHED_COBALT:
> +             trace_seq_printf(p, "cobalt ");
> +             break;
> +     case SCHED_WEAK:
> +             trace_seq_printf(p, "weak ");
> +             break;
> +     default:
> +             trace_seq_printf(p, "unknown ");
> +             break;
> +     }
> +}
> +
> +/* save param */
> +static void write_param(struct tep_format_field *field,
> +                             struct tep_record *record,
> +                             struct trace_seq *p, int policy)
> +{
> +     int offset;
> +     struct sched_param_ex *params;
> +
> +     offset = field->offset;
> +
> +     if (!strncmp(field->type, "__data_loc", 10)) {
> +             unsigned long long v;
> +
> +             if (tep_read_number_field(field, record->data, &v)) {
> +                     trace_seq_printf(p, "invalid_data_loc");
> +                     return;
> +             }
> +             offset = v & 0xffff;
> +
> +     }
> +
> +     params = (struct sched_param_ex *)((char *)record->data + offset);
> +
> +     trace_seq_printf(p, "param: { ");
> +
> +     switch (policy) {
> +     case SCHED_QUOTA:
> +             trace_seq_printf(p, "priority=%d, group=%d",
> +                              params->sched_priority,
> +                              params->sched_quota_group);
> +             break;
> +     case SCHED_TP:
> +             trace_seq_printf(p, "priority=%d, partition=%d",
> +                              params->sched_priority,
> +                              params->sched_tp_partition);
> +             break;
> +     case SCHED_NORMAL:
> +             break;
> +     case SCHED_SPORADIC:
> +             trace_seq_printf(p, "priority=%d, low_priority=%d, ",
> +                              params->sched_priority,
> +                              params->sched_ss_low_priority);
> +
> +             trace_seq_printf(p, "budget=(%ld.%09ld), period=(%ld.%09ld), ",
> +                              params->sched_ss_init_budget.tv_sec,
> +                              params->sched_ss_init_budget.tv_nsec);
> +
> +             trace_seq_printf(p, "maxrepl=%d",
> +                              params->sched_ss_max_repl);
> +             break;
> +     case SCHED_RR:
> +     case SCHED_FIFO:
> +     case SCHED_COBALT:
> +     case SCHED_WEAK:
> +     default:
> +             trace_seq_printf(p, "priority=%d", params->sched_priority);
> +             break;
> +     }
> +     trace_seq_printf(p, " }");
> +     trace_seq_putc(p, '\0');
> +
> +}
> +
> +static int cobalt_schedparam_handler(struct trace_seq *s,
> +                             struct tep_record *record,
> +                             struct tep_event *event, void *context)
> +{
> +     struct tep_format_field *field;
> +     unsigned long long val;
> +
> +     if (tep_get_field_val(s, event, "pth", record, &val, 1))
> +             return trace_seq_putc(s, '!');
> +     trace_seq_puts(s, "pth: ");
> +     trace_seq_printf(s, "0x%08llx ", val);
> +
> +     if (tep_get_field_val(s, event, "policy", record, &val, 1) == 0)
> +             write_policy(s, val);
> +
> +     field = tep_find_field(event, "param_ex");
> +     if (field)
> +             write_param(field, record, s, val);
> +
> +     return 0;
> +}
> +
> +int TEP_PLUGIN_LOADER(struct tep_handle *tep)
> +{
> +     tep_register_event_handler(tep, -1, "cobalt_posix", 
> "cobalt_pthread_setschedparam",
> +                                     cobalt_schedparam_handler, NULL);
> +
> +     tep_register_event_handler(tep, -1, "cobalt_posix", 
> "cobalt_pthread_getschedparam",
> +                                     cobalt_schedparam_handler, NULL);
> +
> +     tep_register_event_handler(tep, -1, "cobalt_posix", 
> "cobalt_pthread_create",
> +                                     cobalt_schedparam_handler, NULL);
> +
> +     return 0;
> +}
> +
> +void TEP_PLUGIN_UNLOADER(struct tep_handle *tep)
> +{
> +     tep_unregister_event_handler(tep, -1, "cobalt_posix", 
> "cobalt_pthread_setschedparam",
> +                                     cobalt_schedparam_handler, NULL);
> +
> +     tep_unregister_event_handler(tep, -1, "cobalt_posix", 
> "cobalt_pthread_getschedparam",
> +                                     cobalt_schedparam_handler, NULL);
> +
> +     tep_unregister_event_handler(tep, -1, "cobalt_posix", 
> "cobalt_pthread_create",
> +                                     cobalt_schedparam_handler, NULL);
> +}

Reply via email to