^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * trace_events_synth - synthetic trace events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015, 2020 Tom Zanussi <tom.zanussi@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kallsyms.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/stacktrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/tracefs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* for gfp flag names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/trace_events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <trace/events/mmflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "trace_synth.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #undef ERRORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define ERRORS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) C(BAD_NAME, "Illegal name"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) C(CMD_INCOMPLETE, "Incomplete command"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) C(EVENT_EXISTS, "Event already exists"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) C(TOO_MANY_FIELDS, "Too many fields"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) C(INCOMPLETE_TYPE, "Incomplete type"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) C(INVALID_TYPE, "Invalid type"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) C(INVALID_FIELD, "Invalid field"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) C(CMD_TOO_LONG, "Command too long"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #undef C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define C(a, b) SYNTH_ERR_##a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) enum { ERRORS };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #undef C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define C(a, b) b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const char *err_text[] = { ERRORS };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static char last_cmd[MAX_FILTER_STR_VAL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int errpos(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return err_pos(last_cmd, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static void last_cmd_set(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) strncpy(last_cmd, str, MAX_FILTER_STR_VAL - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static void synth_err(u8 err_type, u8 err_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) tracing_log_err(NULL, "synthetic_events", last_cmd, err_text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) err_type, err_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int create_synth_event(int argc, const char **argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int synth_event_show(struct seq_file *m, struct dyn_event *ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int synth_event_release(struct dyn_event *ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static bool synth_event_is_busy(struct dyn_event *ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static bool synth_event_match(const char *system, const char *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int argc, const char **argv, struct dyn_event *ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static struct dyn_event_operations synth_event_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .create = create_synth_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .show = synth_event_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .is_busy = synth_event_is_busy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .free = synth_event_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .match = synth_event_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static bool is_synth_event(struct dyn_event *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return ev->ops == &synth_event_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static struct synth_event *to_synth_event(struct dyn_event *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return container_of(ev, struct synth_event, devent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static bool synth_event_is_busy(struct dyn_event *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct synth_event *event = to_synth_event(ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return event->ref != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static bool synth_event_match(const char *system, const char *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int argc, const char **argv, struct dyn_event *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct synth_event *sev = to_synth_event(ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return strcmp(sev->name, event) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) (!system || strcmp(system, SYNTH_SYSTEM) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct synth_trace_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct trace_entry ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u64 fields[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int synth_event_define_fields(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct synth_trace_event trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int offset = offsetof(typeof(trace), fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct synth_event *event = call->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned int i, size, n_u64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) char *name, *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) bool is_signed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) size = event->fields[i]->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) is_signed = event->fields[i]->is_signed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) type = event->fields[i]->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) name = event->fields[i]->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = trace_define_field(call, type, name, offset, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) is_signed, FILTER_OTHER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) event->fields[i]->offset = n_u64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (event->fields[i]->is_string && !event->fields[i]->is_dynamic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) offset += STR_VAR_LEN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) offset += sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) n_u64++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) event->n_u64 = n_u64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static bool synth_field_signed(char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (str_has_prefix(type, "u"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (strcmp(type, "gfp_t") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int synth_field_is_string(char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (strstr(type, "char[") != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int synth_field_string_size(char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) char buf[4], *end, *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int size, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) start = strstr(type, "char[");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (start == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) start += sizeof("char[") - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) end = strchr(type, ']');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (!end || end < start || type + strlen(type) > end + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) len = end - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (len > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return 0; /* variable-length string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) strncpy(buf, start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) buf[len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) err = kstrtouint(buf, 0, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (size > STR_VAR_LEN_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int synth_field_size(char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (strcmp(type, "s64") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) size = sizeof(s64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) else if (strcmp(type, "u64") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) size = sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) else if (strcmp(type, "s32") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) size = sizeof(s32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) else if (strcmp(type, "u32") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) size = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) else if (strcmp(type, "s16") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) size = sizeof(s16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) else if (strcmp(type, "u16") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) size = sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) else if (strcmp(type, "s8") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) size = sizeof(s8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) else if (strcmp(type, "u8") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) size = sizeof(u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) else if (strcmp(type, "char") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) size = sizeof(char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) else if (strcmp(type, "unsigned char") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) size = sizeof(unsigned char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) else if (strcmp(type, "int") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) size = sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) else if (strcmp(type, "unsigned int") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) size = sizeof(unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) else if (strcmp(type, "long") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) size = sizeof(long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) else if (strcmp(type, "unsigned long") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) size = sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) else if (strcmp(type, "bool") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) size = sizeof(bool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) else if (strcmp(type, "pid_t") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) size = sizeof(pid_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) else if (strcmp(type, "gfp_t") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) size = sizeof(gfp_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) else if (synth_field_is_string(type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) size = synth_field_string_size(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static const char *synth_field_fmt(char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) const char *fmt = "%llu";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (strcmp(type, "s64") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) fmt = "%lld";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) else if (strcmp(type, "u64") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) fmt = "%llu";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) else if (strcmp(type, "s32") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) fmt = "%d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) else if (strcmp(type, "u32") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) fmt = "%u";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) else if (strcmp(type, "s16") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) fmt = "%d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) else if (strcmp(type, "u16") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) fmt = "%u";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) else if (strcmp(type, "s8") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) fmt = "%d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) else if (strcmp(type, "u8") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) fmt = "%u";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) else if (strcmp(type, "char") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) fmt = "%d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) else if (strcmp(type, "unsigned char") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) fmt = "%u";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) else if (strcmp(type, "int") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) fmt = "%d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) else if (strcmp(type, "unsigned int") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) fmt = "%u";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) else if (strcmp(type, "long") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) fmt = "%ld";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) else if (strcmp(type, "unsigned long") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) fmt = "%lu";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) else if (strcmp(type, "bool") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) fmt = "%d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) else if (strcmp(type, "pid_t") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) fmt = "%d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) else if (strcmp(type, "gfp_t") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) fmt = "%x";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) else if (synth_field_is_string(type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) fmt = "%.*s";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static void print_synth_event_num_val(struct trace_seq *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) char *print_fmt, char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int size, u64 val, char *space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) trace_seq_printf(s, print_fmt, name, (u8)val, space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) trace_seq_printf(s, print_fmt, name, (u16)val, space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) trace_seq_printf(s, print_fmt, name, (u32)val, space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) trace_seq_printf(s, print_fmt, name, val, space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static enum print_line_t print_synth_event(struct trace_iterator *iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct trace_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct trace_array *tr = iter->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct trace_seq *s = &iter->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct synth_trace_event *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct synth_event *se;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) unsigned int i, n_u64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) char print_fmt[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) const char *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) entry = (struct synth_trace_event *)iter->ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) se = container_of(event, struct synth_event, call.event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) trace_seq_printf(s, "%s: ", se->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) for (i = 0, n_u64 = 0; i < se->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (trace_seq_has_overflowed(s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) fmt = synth_field_fmt(se->fields[i]->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* parameter types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (tr && tr->trace_flags & TRACE_ITER_VERBOSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) trace_seq_printf(s, "%s ", fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) snprintf(print_fmt, sizeof(print_fmt), "%%s=%s%%s", fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* parameter values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (se->fields[i]->is_string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (se->fields[i]->is_dynamic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) u32 offset, data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) char *str_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) offset = (u32)entry->fields[n_u64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) data_offset = offset & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) str_field = (char *)entry + data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) trace_seq_printf(s, print_fmt, se->fields[i]->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) STR_VAR_LEN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) str_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) i == se->n_fields - 1 ? "" : " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) n_u64++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) trace_seq_printf(s, print_fmt, se->fields[i]->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) STR_VAR_LEN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) (char *)&entry->fields[n_u64],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) i == se->n_fields - 1 ? "" : " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct trace_print_flags __flags[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) __def_gfpflag_names, {-1, NULL} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) char *space = (i == se->n_fields - 1 ? "" : " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) print_synth_event_num_val(s, print_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) se->fields[i]->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) se->fields[i]->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) entry->fields[n_u64],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (strcmp(se->fields[i]->type, "gfp_t") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) trace_seq_puts(s, " (");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) trace_print_flags_seq(s, "|",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) entry->fields[n_u64],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) __flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) trace_seq_putc(s, ')');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) n_u64++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) trace_seq_putc(s, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return trace_handle_return(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static struct trace_event_functions synth_event_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .trace = print_synth_event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static unsigned int trace_string(struct synth_trace_event *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct synth_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) char *str_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) bool is_dynamic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) unsigned int data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) unsigned int *n_u64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) unsigned int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) char *str_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (is_dynamic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u32 data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) data_offset = offsetof(typeof(*entry), fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) data_offset += event->n_u64 * sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) data_offset += data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) str_field = (char *)entry + data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) len = strlen(str_val) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) strscpy(str_field, str_val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) data_offset |= len << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *(u32 *)&entry->fields[*n_u64] = data_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) (*n_u64)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) str_field = (char *)&entry->fields[*n_u64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) strscpy(str_field, str_val, STR_VAR_LEN_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) (*n_u64) += STR_VAR_LEN_MAX / sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static notrace void trace_event_raw_event_synth(void *__data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) u64 *var_ref_vals,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) unsigned int *var_ref_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) unsigned int i, n_u64, val_idx, len, data_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct trace_event_file *trace_file = __data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct synth_trace_event *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct trace_event_buffer fbuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct trace_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct synth_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int fields_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) event = trace_file->event_call->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (trace_trigger_soft_disabled(trace_file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) fields_size = event->n_u64 * sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) for (i = 0; i < event->n_dynamic_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) unsigned int field_pos = event->dynamic_fields[i]->field_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) char *str_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) val_idx = var_ref_idx[field_pos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) str_val = (char *)(long)var_ref_vals[val_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) len = strlen(str_val) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) fields_size += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * Avoid ring buffer recursion detection, as this event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * is being performed within another event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) buffer = trace_file->tr->array_buffer.buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ring_buffer_nest_start(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) entry = trace_event_buffer_reserve(&fbuffer, trace_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) sizeof(*entry) + fields_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) val_idx = var_ref_idx[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (event->fields[i]->is_string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) char *str_val = (char *)(long)var_ref_vals[val_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) len = trace_string(entry, event, str_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) event->fields[i]->is_dynamic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) data_size, &n_u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) data_size += len; /* only dynamic string increments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct synth_field *field = event->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) u64 val = var_ref_vals[val_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) switch (field->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) *(u8 *)&entry->fields[n_u64] = (u8)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) *(u16 *)&entry->fields[n_u64] = (u16)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) *(u32 *)&entry->fields[n_u64] = (u32)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) entry->fields[n_u64] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) n_u64++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) trace_event_buffer_commit(&fbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ring_buffer_nest_end(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static void free_synth_event_print_fmt(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (call) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) kfree(call->print_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) call->print_fmt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static int __set_synth_event_print_fmt(struct synth_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) char *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) const char *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) int pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* When len=0, we just calculate the needed length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #define LEN_OR_ZERO (len ? len - pos : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) for (i = 0; i < event->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) fmt = synth_field_fmt(event->fields[i]->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) pos += snprintf(buf + pos, LEN_OR_ZERO, "%s=%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) event->fields[i]->name, fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) i == event->n_fields - 1 ? "" : ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) for (i = 0; i < event->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (event->fields[i]->is_string &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) event->fields[i]->is_dynamic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) pos += snprintf(buf + pos, LEN_OR_ZERO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ", __get_str(%s)", event->fields[i]->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pos += snprintf(buf + pos, LEN_OR_ZERO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ", REC->%s", event->fields[i]->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) #undef LEN_OR_ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* return the length of print_fmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static int set_synth_event_print_fmt(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct synth_event *event = call->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) char *print_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* First: called with 0 length to calculate the needed length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) len = __set_synth_event_print_fmt(event, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) print_fmt = kmalloc(len + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (!print_fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* Second: actually write the @print_fmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) __set_synth_event_print_fmt(event, print_fmt, len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) call->print_fmt = print_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static void free_synth_field(struct synth_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) kfree(field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) kfree(field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) kfree(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static struct synth_field *parse_synth_field(int argc, const char **argv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int *consumed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct synth_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) const char *prefix = NULL, *field_type = argv[0], *field_name, *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int len, ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct seq_buf s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) ssize_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (field_type[0] == ';')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) field_type++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (!strcmp(field_type, "unsigned")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (argc < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) synth_err(SYNTH_ERR_INCOMPLETE_TYPE, errpos(field_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) prefix = "unsigned ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) field_type = argv[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) field_name = argv[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) *consumed = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) field_name = argv[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) *consumed = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) field = kzalloc(sizeof(*field), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) len = strlen(field_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) array = strchr(field_name, '[');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) len -= strlen(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) else if (field_name[len - 1] == ';')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) field->name = kmemdup_nul(field_name, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (!field->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (!is_good_name(field->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) synth_err(SYNTH_ERR_BAD_NAME, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (field_type[0] == ';')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) field_type++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) len = strlen(field_type) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) len += strlen(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) len += strlen(prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) field->type = kzalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!field->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) seq_buf_init(&s, field->type, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (prefix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) seq_buf_puts(&s, prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) seq_buf_puts(&s, field_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (array) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) seq_buf_puts(&s, array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (s.buffer[s.len - 1] == ';')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) s.len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) s.buffer[s.len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) size = synth_field_size(field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) synth_err(SYNTH_ERR_INVALID_TYPE, errpos(field_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) } else if (size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (synth_field_is_string(field->type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) len = sizeof("__data_loc ") + strlen(field->type) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) type = kzalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (!type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) seq_buf_init(&s, type, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) seq_buf_puts(&s, "__data_loc ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) seq_buf_puts(&s, field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) s.buffer[s.len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) kfree(field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) field->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) field->is_dynamic = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) size = sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) synth_err(SYNTH_ERR_INVALID_TYPE, errpos(field_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) field->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (synth_field_is_string(field->type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) field->is_string = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) field->is_signed = synth_field_signed(field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) free_synth_field(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) field = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static void free_synth_tracepoint(struct tracepoint *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (!tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) kfree(tp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) kfree(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static struct tracepoint *alloc_synth_tracepoint(char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct tracepoint *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) tp = kzalloc(sizeof(*tp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (!tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) tp->name = kstrdup(name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (!tp->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) kfree(tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct synth_event *find_synth_event(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct dyn_event *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct synth_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) for_each_dyn_event(pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (!is_synth_event(pos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) event = to_synth_event(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (strcmp(event->name, name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) static struct trace_event_fields synth_event_fields_array[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) { .type = TRACE_FUNCTION_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) .define_fields = synth_event_define_fields },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int register_synth_event(struct synth_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct trace_event_call *call = &event->call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) event->call.class = &event->class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) event->class.system = kstrdup(SYNTH_SYSTEM, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (!event->class.system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) event->tp = alloc_synth_tracepoint(event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (IS_ERR(event->tp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ret = PTR_ERR(event->tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) event->tp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) INIT_LIST_HEAD(&call->class->fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) call->event.funcs = &synth_event_funcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) call->class->fields_array = synth_event_fields_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ret = register_trace_event(&call->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) call->flags = TRACE_EVENT_FL_TRACEPOINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) call->class->reg = trace_event_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) call->class->probe = trace_event_raw_event_synth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) call->data = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) call->tp = event->tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ret = trace_add_event_call(call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) pr_warn("Failed to register synthetic event: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) trace_event_name(call));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) ret = set_synth_event_print_fmt(call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) trace_remove_event_call(call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unregister_trace_event(&call->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static int unregister_synth_event(struct synth_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct trace_event_call *call = &event->call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) ret = trace_remove_event_call(call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static void free_synth_event(struct synth_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) for (i = 0; i < event->n_fields; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) free_synth_field(event->fields[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) kfree(event->fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) kfree(event->dynamic_fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) kfree(event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) kfree(event->class.system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) free_synth_tracepoint(event->tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) free_synth_event_print_fmt(&event->call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) kfree(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static struct synth_event *alloc_synth_event(const char *name, int n_fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) struct synth_field **fields)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) unsigned int i, j, n_dynamic_fields = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct synth_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) event = kzalloc(sizeof(*event), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (!event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) event = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) event->name = kstrdup(name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (!event->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) kfree(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) event = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) event->fields = kcalloc(n_fields, sizeof(*event->fields), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (!event->fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) free_synth_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) event = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) for (i = 0; i < n_fields; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (fields[i]->is_dynamic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) n_dynamic_fields++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (n_dynamic_fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) event->dynamic_fields = kcalloc(n_dynamic_fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) sizeof(*event->dynamic_fields),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (!event->dynamic_fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) free_synth_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) event = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) dyn_event_init(&event->devent, &synth_event_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) for (i = 0, j = 0; i < n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) event->fields[i] = fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (fields[i]->is_dynamic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) event->dynamic_fields[j] = fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) event->dynamic_fields[j]->field_pos = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) event->dynamic_fields[j++] = fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) event->n_dynamic_fields++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) event->n_fields = n_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) static int synth_event_check_arg_fn(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct dynevent_arg_pair *arg_pair = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) size = synth_field_size((char *)arg_pair->lhs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (strstr((char *)arg_pair->lhs, "["))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return size ? 0 : -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * synth_event_add_field - Add a new field to a synthetic event cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * @cmd: A pointer to the dynevent_cmd struct representing the new event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * @type: The type of the new field to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * @name: The name of the new field to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * Add a new field to a synthetic event cmd object. Field ordering is in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * the same order the fields are added.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * See synth_field_size() for available types. If field_name contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * [n] the field is considered to be an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * Return: 0 if successful, error otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) int synth_event_add_field(struct dynevent_cmd *cmd, const char *type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct dynevent_arg_pair arg_pair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (cmd->type != DYNEVENT_TYPE_SYNTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (!type || !name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) dynevent_arg_pair_init(&arg_pair, 0, ';');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) arg_pair.lhs = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) arg_pair.rhs = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ret = dynevent_arg_pair_add(cmd, &arg_pair, synth_event_check_arg_fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (++cmd->n_fields > SYNTH_FIELDS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) EXPORT_SYMBOL_GPL(synth_event_add_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * synth_event_add_field_str - Add a new field to a synthetic event cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * @cmd: A pointer to the dynevent_cmd struct representing the new event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * @type_name: The type and name of the new field to add, as a single string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * Add a new field to a synthetic event cmd object, as a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * string. The @type_name string is expected to be of the form 'type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * name', which will be appended by ';'. No sanity checking is done -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * what's passed in is assumed to already be well-formed. Field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * ordering is in the same order the fields are added.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * See synth_field_size() for available types. If field_name contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * [n] the field is considered to be an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * Return: 0 if successful, error otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) int synth_event_add_field_str(struct dynevent_cmd *cmd, const char *type_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) struct dynevent_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (cmd->type != DYNEVENT_TYPE_SYNTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (!type_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) dynevent_arg_init(&arg, ';');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) arg.str = type_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) ret = dynevent_arg_add(cmd, &arg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (++cmd->n_fields > SYNTH_FIELDS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) EXPORT_SYMBOL_GPL(synth_event_add_field_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * synth_event_add_fields - Add multiple fields to a synthetic event cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * @cmd: A pointer to the dynevent_cmd struct representing the new event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * @fields: An array of type/name field descriptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * @n_fields: The number of field descriptions contained in the fields array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * Add a new set of fields to a synthetic event cmd object. The event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * fields that will be defined for the event should be passed in as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * array of struct synth_field_desc, and the number of elements in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * array passed in as n_fields. Field ordering will retain the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * ordering given in the fields array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * See synth_field_size() for available types. If field_name contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * [n] the field is considered to be an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) * Return: 0 if successful, error otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) int synth_event_add_fields(struct dynevent_cmd *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) struct synth_field_desc *fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) unsigned int n_fields)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) for (i = 0; i < n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (fields[i].type == NULL || fields[i].name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) ret = synth_event_add_field(cmd, fields[i].type, fields[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) EXPORT_SYMBOL_GPL(synth_event_add_fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * __synth_event_gen_cmd_start - Start a synthetic event command from arg list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * @cmd: A pointer to the dynevent_cmd struct representing the new event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * @name: The name of the synthetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * @mod: The module creating the event, NULL if not created from a module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * @args: Variable number of arg (pairs), one pair for each field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * NOTE: Users normally won't want to call this function directly, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * rather use the synth_event_gen_cmd_start() wrapper, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * automatically adds a NULL to the end of the arg list. If this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * function is used directly, make sure the last arg in the variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * arg list is NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * Generate a synthetic event command to be executed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * synth_event_gen_cmd_end(). This function can be used to generate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * the complete command or only the first part of it; in the latter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * case, synth_event_add_field(), synth_event_add_field_str(), or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * synth_event_add_fields() can be used to add more fields following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * There should be an even number variable args, each pair consisting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) * of a type followed by a field name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * See synth_field_size() for available types. If field_name contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * [n] the field is considered to be an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * Return: 0 if successful, error otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) int __synth_event_gen_cmd_start(struct dynevent_cmd *cmd, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) struct module *mod, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct dynevent_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) cmd->event_name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) cmd->private_data = mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (cmd->type != DYNEVENT_TYPE_SYNTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) dynevent_arg_init(&arg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) arg.str = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) ret = dynevent_arg_add(cmd, &arg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) va_start(args, mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) const char *type, *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) type = va_arg(args, const char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (!type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) name = va_arg(args, const char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (++cmd->n_fields > SYNTH_FIELDS_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) ret = synth_event_add_field(cmd, type, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) EXPORT_SYMBOL_GPL(__synth_event_gen_cmd_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * synth_event_gen_cmd_array_start - Start synthetic event command from an array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * @cmd: A pointer to the dynevent_cmd struct representing the new event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * @name: The name of the synthetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * @fields: An array of type/name field descriptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * @n_fields: The number of field descriptions contained in the fields array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) * Generate a synthetic event command to be executed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) * synth_event_gen_cmd_end(). This function can be used to generate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * the complete command or only the first part of it; in the latter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) * case, synth_event_add_field(), synth_event_add_field_str(), or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * synth_event_add_fields() can be used to add more fields following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * The event fields that will be defined for the event should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * passed in as an array of struct synth_field_desc, and the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) * elements in the array passed in as n_fields. Field ordering will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) * retain the ordering given in the fields array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * See synth_field_size() for available types. If field_name contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * [n] the field is considered to be an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * Return: 0 if successful, error otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) int synth_event_gen_cmd_array_start(struct dynevent_cmd *cmd, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) struct module *mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) struct synth_field_desc *fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) unsigned int n_fields)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct dynevent_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) cmd->event_name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) cmd->private_data = mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (cmd->type != DYNEVENT_TYPE_SYNTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (n_fields > SYNTH_FIELDS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) dynevent_arg_init(&arg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) arg.str = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) ret = dynevent_arg_add(cmd, &arg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) for (i = 0; i < n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (fields[i].type == NULL || fields[i].name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) ret = synth_event_add_field(cmd, fields[i].type, fields[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) EXPORT_SYMBOL_GPL(synth_event_gen_cmd_array_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) static int save_cmdstr(int argc, const char *name, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) struct seq_buf s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) seq_buf_init(&s, buf, MAX_DYNEVENT_CMD_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) seq_buf_puts(&s, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) for (i = 0; i < argc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) seq_buf_putc(&s, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) seq_buf_puts(&s, argv[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (!seq_buf_buffer_left(&s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) synth_err(SYNTH_ERR_CMD_TOO_LONG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) buf[s.len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) last_cmd_set(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static int __create_synth_event(int argc, const char *name, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct synth_field *field, *fields[SYNTH_FIELDS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct synth_event *event = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) int i, consumed = 0, n_fields = 0, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ret = save_cmdstr(argc, name, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * Argument syntax:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * - Add synthetic event: <event_name> field[;field] ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * - Remove synthetic event: !<event_name> field[;field] ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * where 'field' = type field_name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (name[0] == '\0' || argc < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) synth_err(SYNTH_ERR_CMD_INCOMPLETE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) mutex_lock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (!is_good_name(name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) synth_err(SYNTH_ERR_BAD_NAME, errpos(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) event = find_synth_event(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) synth_err(SYNTH_ERR_EVENT_EXISTS, errpos(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) for (i = 0; i < argc - 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (strcmp(argv[i], ";") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (n_fields == SYNTH_FIELDS_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) field = parse_synth_field(argc - i, &argv[i], &consumed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (IS_ERR(field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ret = PTR_ERR(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) fields[n_fields++] = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) i += consumed - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (i < argc && strcmp(argv[i], ";") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) synth_err(SYNTH_ERR_INVALID_FIELD, errpos(argv[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) event = alloc_synth_event(name, n_fields, fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (IS_ERR(event)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) ret = PTR_ERR(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) event = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) ret = register_synth_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) dyn_event_add(&event->devent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) free_synth_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) mutex_unlock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) for (i = 0; i < n_fields; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) free_synth_field(fields[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) * synth_event_create - Create a new synthetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) * @name: The name of the new sythetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) * @fields: An array of type/name field descriptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) * @n_fields: The number of field descriptions contained in the fields array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) * @mod: The module creating the event, NULL if not created from a module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) * Create a new synthetic event with the given name under the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) * trace/events/synthetic/ directory. The event fields that will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) * defined for the event should be passed in as an array of struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) * synth_field_desc, and the number elements in the array passed in as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) * n_fields. Field ordering will retain the ordering given in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) * fields array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) * If the new synthetic event is being created from a module, the mod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) * param must be non-NULL. This will ensure that the trace buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * won't contain unreadable events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * The new synth event should be deleted using synth_event_delete()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * function. The new synthetic event can be generated from modules or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * other kernel code using trace_synth_event() and related functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * Return: 0 if successful, error otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) int synth_event_create(const char *name, struct synth_field_desc *fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) unsigned int n_fields, struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) struct dynevent_cmd cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) synth_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) ret = synth_event_gen_cmd_array_start(&cmd, name, mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) fields, n_fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) ret = synth_event_gen_cmd_end(&cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) EXPORT_SYMBOL_GPL(synth_event_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) static int destroy_synth_event(struct synth_event *se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) if (se->ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) ret = unregister_synth_event(se);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) dyn_event_remove(&se->devent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) free_synth_event(se);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) * synth_event_delete - Delete a synthetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) * @event_name: The name of the new sythetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) * Delete a synthetic event that was created with synth_event_create().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * Return: 0 if successful, error otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) int synth_event_delete(const char *event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) struct synth_event *se = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct module *mod = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) mutex_lock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) se = find_synth_event(event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (se) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) mod = se->mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) ret = destroy_synth_event(se);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) mutex_unlock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) mutex_lock(&trace_types_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) * It is safest to reset the ring buffer if the module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) * being unloaded registered any events that were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) * used. The only worry is if a new module gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) * loaded, and takes on the same id as the events of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * this module. When printing out the buffer, traced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) * events left over from this module may be passed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) * the new module events and unexpected results may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * occur.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) tracing_reset_all_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) mutex_unlock(&trace_types_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) EXPORT_SYMBOL_GPL(synth_event_delete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) static int create_or_delete_synth_event(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) const char *name = argv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) /* trace_run_command() ensures argc != 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (name[0] == '!') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) ret = synth_event_delete(name + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) ret = __create_synth_event(argc - 1, name, (const char **)argv + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) return ret == -ECANCELED ? -EINVAL : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) static int synth_event_run_command(struct dynevent_cmd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct synth_event *se;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) ret = trace_run_command(cmd->seq.buffer, create_or_delete_synth_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) se = find_synth_event(cmd->event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (WARN_ON(!se))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) se->mod = cmd->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) * synth_event_cmd_init - Initialize a synthetic event command object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) * @cmd: A pointer to the dynevent_cmd struct representing the new event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) * @buf: A pointer to the buffer used to build the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) * @maxlen: The length of the buffer passed in @buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) * Initialize a synthetic event command object. Use this before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * calling any of the other dyenvent_cmd functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) void synth_event_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) dynevent_cmd_init(cmd, buf, maxlen, DYNEVENT_TYPE_SYNTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) synth_event_run_command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) EXPORT_SYMBOL_GPL(synth_event_cmd_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) __synth_event_trace_init(struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) struct synth_event_trace_state *trace_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) memset(trace_state, '\0', sizeof(*trace_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) * Normal event tracing doesn't get called at all unless the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) * ENABLED bit is set (which attaches the probe thus allowing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) * this code to be called, etc). Because this is called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) * directly by the user, we don't have that but we still need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * to honor not logging when disabled. For the iterated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) * trace case, we save the enabed state upon start and just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * ignore the following data calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (!(file->flags & EVENT_FILE_FL_ENABLED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) trace_trigger_soft_disabled(file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) trace_state->disabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) trace_state->event = file->event_call->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) __synth_event_trace_start(struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) struct synth_event_trace_state *trace_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) int dynamic_fields_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) int entry_size, fields_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) fields_size = trace_state->event->n_u64 * sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) fields_size += dynamic_fields_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) * Avoid ring buffer recursion detection, as this event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) * is being performed within another event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) trace_state->buffer = file->tr->array_buffer.buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) ring_buffer_nest_start(trace_state->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) entry_size = sizeof(*trace_state->entry) + fields_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) trace_state->entry = trace_event_buffer_reserve(&trace_state->fbuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) entry_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (!trace_state->entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) ring_buffer_nest_end(trace_state->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) __synth_event_trace_end(struct synth_event_trace_state *trace_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) trace_event_buffer_commit(&trace_state->fbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) ring_buffer_nest_end(trace_state->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) * synth_event_trace - Trace a synthetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) * @file: The trace_event_file representing the synthetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) * @n_vals: The number of values in vals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * @args: Variable number of args containing the event values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * Trace a synthetic event using the values passed in the variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * argument list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * The argument list should be a list 'n_vals' u64 values. The number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) * of vals must match the number of field in the synthetic event, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * must be in the same order as the synthetic event fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) * All vals should be cast to u64, and string vals are just pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) * to strings, cast to u64. Strings will be copied into space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) * reserved in the event for the string, using these pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * Return: 0 on success, err otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) int synth_event_trace(struct trace_event_file *file, unsigned int n_vals, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) unsigned int i, n_u64, len, data_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) struct synth_event_trace_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) ret = __synth_event_trace_init(file, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if (ret == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) ret = 0; /* just disabled, not really an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (state.event->n_dynamic_fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) va_start(args, n_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) for (i = 0; i < state.event->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) u64 val = va_arg(args, u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (state.event->fields[i]->is_string &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) state.event->fields[i]->is_dynamic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) char *str_val = (char *)(long)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) data_size += strlen(str_val) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) ret = __synth_event_trace_start(file, &state, data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (n_vals != state.event->n_fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) data_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) va_start(args, n_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) for (i = 0, n_u64 = 0; i < state.event->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) val = va_arg(args, u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (state.event->fields[i]->is_string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) char *str_val = (char *)(long)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) len = trace_string(state.entry, state.event, str_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) state.event->fields[i]->is_dynamic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) data_size, &n_u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) data_size += len; /* only dynamic string increments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) struct synth_field *field = state.event->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) switch (field->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) *(u8 *)&state.entry->fields[n_u64] = (u8)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) *(u16 *)&state.entry->fields[n_u64] = (u16)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) *(u32 *)&state.entry->fields[n_u64] = (u32)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) state.entry->fields[n_u64] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) n_u64++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) __synth_event_trace_end(&state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) EXPORT_SYMBOL_GPL(synth_event_trace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) * synth_event_trace_array - Trace a synthetic event from an array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) * @file: The trace_event_file representing the synthetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) * @vals: Array of values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) * @n_vals: The number of values in vals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) * Trace a synthetic event using the values passed in as 'vals'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) * The 'vals' array is just an array of 'n_vals' u64. The number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) * vals must match the number of field in the synthetic event, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) * must be in the same order as the synthetic event fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) * All vals should be cast to u64, and string vals are just pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) * to strings, cast to u64. Strings will be copied into space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) * reserved in the event for the string, using these pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) * Return: 0 on success, err otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) int synth_event_trace_array(struct trace_event_file *file, u64 *vals,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) unsigned int n_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) unsigned int i, n_u64, field_pos, len, data_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) struct synth_event_trace_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) char *str_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) ret = __synth_event_trace_init(file, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (ret == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) ret = 0; /* just disabled, not really an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (state.event->n_dynamic_fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) for (i = 0; i < state.event->n_dynamic_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) field_pos = state.event->dynamic_fields[i]->field_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) str_val = (char *)(long)vals[field_pos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) len = strlen(str_val) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) data_size += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) ret = __synth_event_trace_start(file, &state, data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) if (n_vals != state.event->n_fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) data_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) for (i = 0, n_u64 = 0; i < state.event->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (state.event->fields[i]->is_string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) char *str_val = (char *)(long)vals[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) len = trace_string(state.entry, state.event, str_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) state.event->fields[i]->is_dynamic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) data_size, &n_u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) data_size += len; /* only dynamic string increments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) struct synth_field *field = state.event->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) u64 val = vals[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) switch (field->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) *(u8 *)&state.entry->fields[n_u64] = (u8)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) *(u16 *)&state.entry->fields[n_u64] = (u16)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) *(u32 *)&state.entry->fields[n_u64] = (u32)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) state.entry->fields[n_u64] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) n_u64++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) __synth_event_trace_end(&state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) EXPORT_SYMBOL_GPL(synth_event_trace_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) * synth_event_trace_start - Start piecewise synthetic event trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) * @file: The trace_event_file representing the synthetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) * @trace_state: A pointer to object tracking the piecewise trace state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) * Start the trace of a synthetic event field-by-field rather than all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) * at once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) * This function 'opens' an event trace, which means space is reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) * for the event in the trace buffer, after which the event's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) * individual field values can be set through either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) * synth_event_add_next_val() or synth_event_add_val().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) * A pointer to a trace_state object is passed in, which will keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) * track of the current event trace state until the event trace is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) * closed (and the event finally traced) using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) * synth_event_trace_end().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) * Note that synth_event_trace_end() must be called after all values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) * have been added for each event trace, regardless of whether adding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) * all field values succeeded or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) * Note also that for a given event trace, all fields must be added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) * using either synth_event_add_next_val() or synth_event_add_val()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) * but not both together or interleaved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * Return: 0 on success, err otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) int synth_event_trace_start(struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) struct synth_event_trace_state *trace_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) if (!trace_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) ret = __synth_event_trace_init(file, trace_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (ret == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) ret = 0; /* just disabled, not really an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (trace_state->event->n_dynamic_fields)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) ret = __synth_event_trace_start(file, trace_state, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) EXPORT_SYMBOL_GPL(synth_event_trace_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) static int __synth_event_add_val(const char *field_name, u64 val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) struct synth_event_trace_state *trace_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) struct synth_field *field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) struct synth_trace_event *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) struct synth_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) if (!trace_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) /* can't mix add_next_synth_val() with add_synth_val() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) if (field_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) if (trace_state->add_next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) trace_state->add_name = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) if (trace_state->add_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) trace_state->add_next = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if (trace_state->disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) event = trace_state->event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) if (trace_state->add_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) for (i = 0; i < event->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) field = event->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (strcmp(field->name, field_name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) if (trace_state->cur_field >= event->n_fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) field = event->fields[trace_state->cur_field++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) entry = trace_state->entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) if (field->is_string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) char *str_val = (char *)(long)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) char *str_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (field->is_dynamic) { /* add_val can't do dynamic strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) if (!str_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) str_field = (char *)&entry->fields[field->offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) strscpy(str_field, str_val, STR_VAR_LEN_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) switch (field->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) *(u8 *)&trace_state->entry->fields[field->offset] = (u8)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) *(u16 *)&trace_state->entry->fields[field->offset] = (u16)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) *(u32 *)&trace_state->entry->fields[field->offset] = (u32)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) trace_state->entry->fields[field->offset] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) * synth_event_add_next_val - Add the next field's value to an open synth trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) * @val: The value to set the next field to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) * @trace_state: A pointer to object tracking the piecewise trace state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) * Set the value of the next field in an event that's been opened by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) * synth_event_trace_start().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) * The val param should be the value cast to u64. If the value points
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) * to a string, the val param should be a char * cast to u64.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) * This function assumes all the fields in an event are to be set one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) * after another - successive calls to this function are made, one for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) * each field, in the order of the fields in the event, until all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) * fields have been set. If you'd rather set each field individually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) * without regard to ordering, synth_event_add_val() can be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) * instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) * Note however that synth_event_add_next_val() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) * synth_event_add_val() can't be intermixed for a given event trace -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) * one or the other but not both can be used at the same time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) * Note also that synth_event_trace_end() must be called after all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) * values have been added for each event trace, regardless of whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) * adding all field values succeeded or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) * Return: 0 on success, err otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) int synth_event_add_next_val(u64 val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) struct synth_event_trace_state *trace_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) return __synth_event_add_val(NULL, val, trace_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) EXPORT_SYMBOL_GPL(synth_event_add_next_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) * synth_event_add_val - Add a named field's value to an open synth trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) * @field_name: The name of the synthetic event field value to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) * @val: The value to set the next field to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) * @trace_state: A pointer to object tracking the piecewise trace state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) * Set the value of the named field in an event that's been opened by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) * synth_event_trace_start().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) * The val param should be the value cast to u64. If the value points
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) * to a string, the val param should be a char * cast to u64.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) * This function looks up the field name, and if found, sets the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) * to the specified value. This lookup makes this function more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) * expensive than synth_event_add_next_val(), so use that or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) * none-piecewise synth_event_trace() instead if efficiency is more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) * important.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) * Note however that synth_event_add_next_val() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) * synth_event_add_val() can't be intermixed for a given event trace -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) * one or the other but not both can be used at the same time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) * Note also that synth_event_trace_end() must be called after all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) * values have been added for each event trace, regardless of whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) * adding all field values succeeded or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) * Return: 0 on success, err otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) int synth_event_add_val(const char *field_name, u64 val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) struct synth_event_trace_state *trace_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) return __synth_event_add_val(field_name, val, trace_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) EXPORT_SYMBOL_GPL(synth_event_add_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) * synth_event_trace_end - End piecewise synthetic event trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) * @trace_state: A pointer to object tracking the piecewise trace state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) * End the trace of a synthetic event opened by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) * synth_event_trace__start().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) * This function 'closes' an event trace, which basically means that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) * it commits the reserved event and cleans up other loose ends.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) * A pointer to a trace_state object is passed in, which will keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) * track of the current event trace state opened with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) * synth_event_trace_start().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) * Note that this function must be called after all values have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) * added for each event trace, regardless of whether adding all field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) * values succeeded or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) * Return: 0 on success, err otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) int synth_event_trace_end(struct synth_event_trace_state *trace_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) if (!trace_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) __synth_event_trace_end(trace_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) EXPORT_SYMBOL_GPL(synth_event_trace_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) static int create_synth_event(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) const char *name = argv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if (name[0] != 's' || name[1] != ':')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) return -ECANCELED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) name += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) /* This interface accepts group name prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) if (strchr(name, '/')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) len = str_has_prefix(name, SYNTH_SYSTEM "/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) name += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) return __create_synth_event(argc - 1, name, argv + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) static int synth_event_release(struct dyn_event *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) struct synth_event *event = to_synth_event(ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (event->ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) ret = unregister_synth_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) dyn_event_remove(ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) free_synth_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) static int __synth_event_show(struct seq_file *m, struct synth_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) struct synth_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) char *type, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) seq_printf(m, "%s\t", event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) for (i = 0; i < event->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) field = event->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) type = field->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) t = strstr(type, "__data_loc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if (t) { /* __data_loc belongs in format but not event desc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) t += sizeof("__data_loc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) type = t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) /* parameter values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) seq_printf(m, "%s %s%s", type, field->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) i == event->n_fields - 1 ? "" : "; ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) static int synth_event_show(struct seq_file *m, struct dyn_event *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) struct synth_event *event = to_synth_event(ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) seq_printf(m, "s:%s/", event->class.system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) return __synth_event_show(m, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) static int synth_events_seq_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) struct dyn_event *ev = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) if (!is_synth_event(ev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) return __synth_event_show(m, to_synth_event(ev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) static const struct seq_operations synth_events_seq_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) .start = dyn_event_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) .next = dyn_event_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) .stop = dyn_event_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) .show = synth_events_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) static int synth_events_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) ret = security_locked_down(LOCKDOWN_TRACEFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) ret = dyn_events_release_all(&synth_event_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) return seq_open(file, &synth_events_seq_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) static ssize_t synth_events_write(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) const char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) return trace_parse_run_command(file, buffer, count, ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) create_or_delete_synth_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) static const struct file_operations synth_events_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) .open = synth_events_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) .write = synth_events_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) .release = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) * Register dynevent at core_initcall. This allows kernel to setup kprobe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) * events in postcore_initcall without tracefs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) static __init int trace_events_synth_init_early(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) err = dyn_event_register(&synth_event_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) pr_warn("Could not register synth_event_ops\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) core_initcall(trace_events_synth_init_early);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) static __init int trace_events_synth_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) struct dentry *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) err = tracing_init_dentry();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) entry = tracefs_create_file("synthetic_events", 0644, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) NULL, &synth_events_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) pr_warn("Could not create tracefs 'synthetic_events' entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) fs_initcall(trace_events_synth_init);