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 <hongzhan.c...@intel.com>
---
 configure.ac                                  |  17 +-
 tracing/Makefile.am                           |  13 +-
 tracing/libtraceevent/Makefile.am             |  11 ++
 tracing/libtraceevent/README                  |  30 ++++
 .../plugin_xenomai_schedparams.c              | 158 ++++++++++++++++++
 5 files changed, 226 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..3a5345feb
--- /dev/null
+++ b/tracing/libtraceevent/Makefile.am
@@ -0,0 +1,11 @@
+
+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)                 \
+       -I$(top_srcdir)/include
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..01234fe5f
--- /dev/null
+++ b/tracing/libtraceevent/plugin_xenomai_schedparams.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * Copyright (C) 2021 Intel Inc, Hongzhan Chen <hongzhan.c...@intel.com>
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <linux/sched.h>
+#include <cobalt/uapi/sched.h>
+#include <sched.h>
+#include "event-parse.h"
+#include "trace-seq.h"
+
+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);
+}
-- 
2.17.1


Reply via email to