Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: LGPL-2.1
0002 /*
0003  * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
0004  */
0005 #include <stdio.h>
0006 #include <stdlib.h>
0007 #include <string.h>
0008 
0009 #include "event-parse.h"
0010 #include "trace-seq.h"
0011 
0012 static void write_state(struct trace_seq *s, int val)
0013 {
0014     const char states[] = "SDTtZXxW";
0015     int found = 0;
0016     int i;
0017 
0018     for (i = 0; i < (sizeof(states) - 1); i++) {
0019         if (!(val & (1 << i)))
0020             continue;
0021 
0022         if (found)
0023             trace_seq_putc(s, '|');
0024 
0025         found = 1;
0026         trace_seq_putc(s, states[i]);
0027     }
0028 
0029     if (!found)
0030         trace_seq_putc(s, 'R');
0031 }
0032 
0033 static void write_and_save_comm(struct tep_format_field *field,
0034                 struct tep_record *record,
0035                 struct trace_seq *s, int pid)
0036 {
0037     const char *comm;
0038     int len;
0039 
0040     comm = (char *)(record->data + field->offset);
0041     len = s->len;
0042     trace_seq_printf(s, "%.*s",
0043              field->size, comm);
0044 
0045     /* make sure the comm has a \0 at the end. */
0046     trace_seq_terminate(s);
0047     comm = &s->buffer[len];
0048 
0049     /* Help out the comm to ids. This will handle dups */
0050     tep_register_comm(field->event->tep, comm, pid);
0051 }
0052 
0053 static int sched_wakeup_handler(struct trace_seq *s,
0054                 struct tep_record *record,
0055                 struct tep_event *event, void *context)
0056 {
0057     struct tep_format_field *field;
0058     unsigned long long val;
0059 
0060     if (tep_get_field_val(s, event, "pid", record, &val, 1))
0061         return trace_seq_putc(s, '!');
0062 
0063     field = tep_find_any_field(event, "comm");
0064     if (field) {
0065         write_and_save_comm(field, record, s, val);
0066         trace_seq_putc(s, ':');
0067     }
0068     trace_seq_printf(s, "%lld", val);
0069 
0070     if (tep_get_field_val(s, event, "prio", record, &val, 0) == 0)
0071         trace_seq_printf(s, " [%lld]", val);
0072 
0073     if (tep_get_field_val(s, event, "success", record, &val, 1) == 0)
0074         trace_seq_printf(s, " success=%lld", val);
0075 
0076     if (tep_get_field_val(s, event, "target_cpu", record, &val, 0) == 0)
0077         trace_seq_printf(s, " CPU:%03llu", val);
0078 
0079     return 0;
0080 }
0081 
0082 static int sched_switch_handler(struct trace_seq *s,
0083                 struct tep_record *record,
0084                 struct tep_event *event, void *context)
0085 {
0086     struct tep_format_field *field;
0087     unsigned long long val;
0088 
0089     if (tep_get_field_val(s, event, "prev_pid", record, &val, 1))
0090         return trace_seq_putc(s, '!');
0091 
0092     field = tep_find_any_field(event, "prev_comm");
0093     if (field) {
0094         write_and_save_comm(field, record, s, val);
0095         trace_seq_putc(s, ':');
0096     }
0097     trace_seq_printf(s, "%lld ", val);
0098 
0099     if (tep_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
0100         trace_seq_printf(s, "[%d] ", (int) val);
0101 
0102     if (tep_get_field_val(s,  event, "prev_state", record, &val, 0) == 0)
0103         write_state(s, val);
0104 
0105     trace_seq_puts(s, " ==> ");
0106 
0107     if (tep_get_field_val(s, event, "next_pid", record, &val, 1))
0108         return trace_seq_putc(s, '!');
0109 
0110     field = tep_find_any_field(event, "next_comm");
0111     if (field) {
0112         write_and_save_comm(field, record, s, val);
0113         trace_seq_putc(s, ':');
0114     }
0115     trace_seq_printf(s, "%lld", val);
0116 
0117     if (tep_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
0118         trace_seq_printf(s, " [%d]", (int) val);
0119 
0120     return 0;
0121 }
0122 
0123 int TEP_PLUGIN_LOADER(struct tep_handle *tep)
0124 {
0125     tep_register_event_handler(tep, -1, "sched", "sched_switch",
0126                    sched_switch_handler, NULL);
0127 
0128     tep_register_event_handler(tep, -1, "sched", "sched_wakeup",
0129                    sched_wakeup_handler, NULL);
0130 
0131     tep_register_event_handler(tep, -1, "sched", "sched_wakeup_new",
0132                    sched_wakeup_handler, NULL);
0133     return 0;
0134 }
0135 
0136 void TEP_PLUGIN_UNLOADER(struct tep_handle *tep)
0137 {
0138     tep_unregister_event_handler(tep, -1, "sched", "sched_switch",
0139                      sched_switch_handler, NULL);
0140 
0141     tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup",
0142                      sched_wakeup_handler, NULL);
0143 
0144     tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup_new",
0145                      sched_wakeup_handler, NULL);
0146 }