cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

plugin_sched_switch.c (3667B)


      1// SPDX-License-Identifier: LGPL-2.1
      2/*
      3 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
      4 */
      5#include <stdio.h>
      6#include <stdlib.h>
      7#include <string.h>
      8
      9#include "event-parse.h"
     10#include "trace-seq.h"
     11
     12static void write_state(struct trace_seq *s, int val)
     13{
     14	const char states[] = "SDTtZXxW";
     15	int found = 0;
     16	int i;
     17
     18	for (i = 0; i < (sizeof(states) - 1); i++) {
     19		if (!(val & (1 << i)))
     20			continue;
     21
     22		if (found)
     23			trace_seq_putc(s, '|');
     24
     25		found = 1;
     26		trace_seq_putc(s, states[i]);
     27	}
     28
     29	if (!found)
     30		trace_seq_putc(s, 'R');
     31}
     32
     33static void write_and_save_comm(struct tep_format_field *field,
     34				struct tep_record *record,
     35				struct trace_seq *s, int pid)
     36{
     37	const char *comm;
     38	int len;
     39
     40	comm = (char *)(record->data + field->offset);
     41	len = s->len;
     42	trace_seq_printf(s, "%.*s",
     43			 field->size, comm);
     44
     45	/* make sure the comm has a \0 at the end. */
     46	trace_seq_terminate(s);
     47	comm = &s->buffer[len];
     48
     49	/* Help out the comm to ids. This will handle dups */
     50	tep_register_comm(field->event->tep, comm, pid);
     51}
     52
     53static int sched_wakeup_handler(struct trace_seq *s,
     54				struct tep_record *record,
     55				struct tep_event *event, void *context)
     56{
     57	struct tep_format_field *field;
     58	unsigned long long val;
     59
     60	if (tep_get_field_val(s, event, "pid", record, &val, 1))
     61		return trace_seq_putc(s, '!');
     62
     63	field = tep_find_any_field(event, "comm");
     64	if (field) {
     65		write_and_save_comm(field, record, s, val);
     66		trace_seq_putc(s, ':');
     67	}
     68	trace_seq_printf(s, "%lld", val);
     69
     70	if (tep_get_field_val(s, event, "prio", record, &val, 0) == 0)
     71		trace_seq_printf(s, " [%lld]", val);
     72
     73	if (tep_get_field_val(s, event, "success", record, &val, 1) == 0)
     74		trace_seq_printf(s, " success=%lld", val);
     75
     76	if (tep_get_field_val(s, event, "target_cpu", record, &val, 0) == 0)
     77		trace_seq_printf(s, " CPU:%03llu", val);
     78
     79	return 0;
     80}
     81
     82static int sched_switch_handler(struct trace_seq *s,
     83				struct tep_record *record,
     84				struct tep_event *event, void *context)
     85{
     86	struct tep_format_field *field;
     87	unsigned long long val;
     88
     89	if (tep_get_field_val(s, event, "prev_pid", record, &val, 1))
     90		return trace_seq_putc(s, '!');
     91
     92	field = tep_find_any_field(event, "prev_comm");
     93	if (field) {
     94		write_and_save_comm(field, record, s, val);
     95		trace_seq_putc(s, ':');
     96	}
     97	trace_seq_printf(s, "%lld ", val);
     98
     99	if (tep_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
    100		trace_seq_printf(s, "[%d] ", (int) val);
    101
    102	if (tep_get_field_val(s,  event, "prev_state", record, &val, 0) == 0)
    103		write_state(s, val);
    104
    105	trace_seq_puts(s, " ==> ");
    106
    107	if (tep_get_field_val(s, event, "next_pid", record, &val, 1))
    108		return trace_seq_putc(s, '!');
    109
    110	field = tep_find_any_field(event, "next_comm");
    111	if (field) {
    112		write_and_save_comm(field, record, s, val);
    113		trace_seq_putc(s, ':');
    114	}
    115	trace_seq_printf(s, "%lld", val);
    116
    117	if (tep_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
    118		trace_seq_printf(s, " [%d]", (int) val);
    119
    120	return 0;
    121}
    122
    123int TEP_PLUGIN_LOADER(struct tep_handle *tep)
    124{
    125	tep_register_event_handler(tep, -1, "sched", "sched_switch",
    126				   sched_switch_handler, NULL);
    127
    128	tep_register_event_handler(tep, -1, "sched", "sched_wakeup",
    129				   sched_wakeup_handler, NULL);
    130
    131	tep_register_event_handler(tep, -1, "sched", "sched_wakeup_new",
    132				   sched_wakeup_handler, NULL);
    133	return 0;
    134}
    135
    136void TEP_PLUGIN_UNLOADER(struct tep_handle *tep)
    137{
    138	tep_unregister_event_handler(tep, -1, "sched", "sched_switch",
    139				     sched_switch_handler, NULL);
    140
    141	tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup",
    142				     sched_wakeup_handler, NULL);
    143
    144	tep_unregister_event_handler(tep, -1, "sched", "sched_wakeup_new",
    145				     sched_wakeup_handler, NULL);
    146}