lkml.org 
[lkml]   [2013]   [Dec]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 17/28] tools lib traceevent: Add sched_switch plugin
    Date
    Backporting sched_switch plugin.

    Backported from Steven Rostedt's trace-cmd repo (HEAD 0f2c2fb):
    git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/trace-cmd.git

    This plugin adds fields resolving for
    sched:sched_switch tracepoint event.

    The diff of 'perf script' output generated by old and new code:
    (data was generated by 'perf record -e sched:sched_switch -a')

    --- script.sched_switch.old
    +++ script.sched_switch.new
    - perf 577 [002] 30965.311852: sched:sched_switch: prev_comm=perf prev_pid=577 prev_prio=120 prev_state=S ==> next_comm=swapper/2 next_pid=0 next_prio=120
    + perf 577 [002] 30965.311852: sched:sched_switch: perf:577 [120] S ==> swapper/2:0 [120]

    Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
    Signed-off-by: Jiri Olsa <jolsa@redhat.com>
    Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
    Cc: Frederic Weisbecker <fweisbec@gmail.com>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: David Ahern <dsahern@gmail.com>
    ---
    tools/lib/traceevent/Makefile | 1 +
    tools/lib/traceevent/plugin_sched_switch.c | 148 +++++++++++++++++++++++++++++
    2 files changed, 149 insertions(+)
    create mode 100644 tools/lib/traceevent/plugin_sched_switch.c

    diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
    index d0e0ca1..1c319a8 100644
    --- a/tools/lib/traceevent/Makefile
    +++ b/tools/lib/traceevent/Makefile
    @@ -217,6 +217,7 @@ PLUGIN_OBJS += plugin_hrtimer.o
    PLUGIN_OBJS += plugin_kmem.o
    PLUGIN_OBJS += plugin_kvm.o
    PLUGIN_OBJS += plugin_mac80211.o
    +PLUGIN_OBJS += plugin_sched_switch.o

    PLUGINS := $(PLUGIN_OBJS:.o=.so)

    diff --git a/tools/lib/traceevent/plugin_sched_switch.c b/tools/lib/traceevent/plugin_sched_switch.c
    new file mode 100644
    index 0000000..fea3724
    --- /dev/null
    +++ b/tools/lib/traceevent/plugin_sched_switch.c
    @@ -0,0 +1,148 @@
    +/*
    + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
    + *
    + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU Lesser General Public
    + * License as published by the Free Software Foundation;
    + * version 2.1 of the License (not later!)
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    + * GNU Lesser General Public License for more details.
    + *
    + * You should have received a copy of the GNU Lesser General Public
    + * License along with this program; if not, see <http://www.gnu.org/licenses>
    + *
    + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + */
    +#include <stdio.h>
    +#include <stdlib.h>
    +#include <string.h>
    +
    +#include "event-parse.h"
    +
    +static void write_state(struct trace_seq *s, int val)
    +{
    + const char states[] = "SDTtZXxW";
    + int found = 0;
    + int i;
    +
    + for (i = 0; i < (sizeof(states) - 1); i++) {
    + if (!(val & (1 << i)))
    + continue;
    +
    + if (found)
    + trace_seq_putc(s, '|');
    +
    + found = 1;
    + trace_seq_putc(s, states[i]);
    + }
    +
    + if (!found)
    + trace_seq_putc(s, 'R');
    +}
    +
    +static void write_and_save_comm(struct format_field *field,
    + struct pevent_record *record,
    + struct trace_seq *s, int pid)
    +{
    + const char *comm;
    + int len;
    +
    + comm = (char *)(record->data + field->offset);
    + len = s->len;
    + trace_seq_printf(s, "%.*s",
    + field->size, comm);
    +
    + /* make sure the comm has a \0 at the end. */
    + trace_seq_terminate(s);
    + comm = &s->buffer[len];
    +
    + /* Help out the comm to ids. This will handle dups */
    + pevent_register_comm(field->event->pevent, comm, pid);
    +}
    +
    +static int sched_wakeup_handler(struct trace_seq *s,
    + struct pevent_record *record,
    + struct event_format *event, void *context)
    +{
    + struct format_field *field;
    + unsigned long long val;
    +
    + if (pevent_get_field_val(s, event, "pid", record, &val, 1))
    + return trace_seq_putc(s, '!');
    +
    + field = pevent_find_any_field(event, "comm");
    + if (field) {
    + write_and_save_comm(field, record, s, val);
    + trace_seq_putc(s, ':');
    + }
    + trace_seq_printf(s, "%lld", val);
    +
    + if (pevent_get_field_val(s, event, "prio", record, &val, 0) == 0)
    + trace_seq_printf(s, " [%lld]", val);
    +
    + if (pevent_get_field_val(s, event, "success", record, &val, 1) == 0)
    + trace_seq_printf(s, " success=%lld", val);
    +
    + if (pevent_get_field_val(s, event, "target_cpu", record, &val, 0) == 0)
    + trace_seq_printf(s, " CPU:%03llu", val);
    +
    + return 0;
    +}
    +
    +static int sched_switch_handler(struct trace_seq *s,
    + struct pevent_record *record,
    + struct event_format *event, void *context)
    +{
    + struct format_field *field;
    + unsigned long long val;
    +
    + if (pevent_get_field_val(s, event, "prev_pid", record, &val, 1))
    + return trace_seq_putc(s, '!');
    +
    + field = pevent_find_any_field(event, "prev_comm");
    + if (field) {
    + write_and_save_comm(field, record, s, val);
    + trace_seq_putc(s, ':');
    + }
    + trace_seq_printf(s, "%lld ", val);
    +
    + if (pevent_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
    + trace_seq_printf(s, "[%lld] ", val);
    +
    + if (pevent_get_field_val(s, event, "prev_state", record, &val, 0) == 0)
    + write_state(s, val);
    +
    + trace_seq_puts(s, " ==> ");
    +
    + if (pevent_get_field_val(s, event, "next_pid", record, &val, 1))
    + return trace_seq_putc(s, '!');
    +
    + field = pevent_find_any_field(event, "next_comm");
    + if (field) {
    + write_and_save_comm(field, record, s, val);
    + trace_seq_putc(s, ':');
    + }
    + trace_seq_printf(s, "%lld", val);
    +
    + if (pevent_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
    + trace_seq_printf(s, " [%lld]", val);
    +
    + return 0;
    +}
    +
    +int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
    +{
    + pevent_register_event_handler(pevent, -1, "sched", "sched_switch",
    + sched_switch_handler, NULL);
    +
    + pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup",
    + sched_wakeup_handler, NULL);
    +
    + pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup_new",
    + sched_wakeup_handler, NULL);
    + return 0;
    +}
    --
    1.8.3.1


    \
     
     \ /
      Last update: 2013-12-03 15:01    [W:4.074 / U:0.176 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site