^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_hist - trace event hist triggers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015 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 "tracing_map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "trace_synth.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define ERRORS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) C(NONE, "No error"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) C(DUPLICATE_VAR, "Variable already defined"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) C(VAR_NOT_UNIQUE, "Variable name not unique, need to use fully qualified name (subsys.event.var) for variable"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) C(TOO_MANY_VARS, "Too many variables defined"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) C(MALFORMED_ASSIGNMENT, "Malformed assignment"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) C(NAMED_MISMATCH, "Named hist trigger doesn't match existing named trigger (includes variables)"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) C(TRIGGER_EEXIST, "Hist trigger already exists"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) C(TRIGGER_ENOENT_CLEAR, "Can't clear or continue a nonexistent hist trigger"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) C(SET_CLOCK_FAIL, "Couldn't set trace_clock"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) C(BAD_FIELD_MODIFIER, "Invalid field modifier"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) C(TOO_MANY_SUBEXPR, "Too many subexpressions (3 max)"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) C(TIMESTAMP_MISMATCH, "Timestamp units in expression don't match"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) C(TOO_MANY_FIELD_VARS, "Too many field variables defined"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) C(EVENT_FILE_NOT_FOUND, "Event file not found"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) C(HIST_NOT_FOUND, "Matching event histogram not found"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) C(HIST_CREATE_FAIL, "Couldn't create histogram for field"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) C(SYNTH_VAR_NOT_FOUND, "Couldn't find synthetic variable"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) C(SYNTH_EVENT_NOT_FOUND,"Couldn't find synthetic event"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) C(SYNTH_TYPE_MISMATCH, "Param type doesn't match synthetic event field type"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) C(SYNTH_COUNT_MISMATCH, "Param count doesn't match synthetic event field count"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) C(FIELD_VAR_PARSE_FAIL, "Couldn't parse field variable"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) C(VAR_CREATE_FIND_FAIL, "Couldn't create or find variable"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) C(ONX_NOT_VAR, "For onmax(x) or onchange(x), x must be a variable"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) C(ONX_VAR_NOT_FOUND, "Couldn't find onmax or onchange variable"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) C(ONX_VAR_CREATE_FAIL, "Couldn't create onmax or onchange variable"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) C(FIELD_VAR_CREATE_FAIL,"Couldn't create field variable"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) C(TOO_MANY_PARAMS, "Too many action params"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) C(PARAM_NOT_FOUND, "Couldn't find param"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) C(INVALID_PARAM, "Invalid action param"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) C(ACTION_NOT_FOUND, "No action found"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) C(NO_SAVE_PARAMS, "No params found for save()"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) C(TOO_MANY_SAVE_ACTIONS,"Can't have more than one save() action per hist"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) C(ACTION_MISMATCH, "Handler doesn't support action"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) C(NO_CLOSING_PAREN, "No closing paren found"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) C(SUBSYS_NOT_FOUND, "Missing subsystem"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) C(INVALID_SUBSYS_EVENT, "Invalid subsystem or event name"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) C(INVALID_REF_KEY, "Using variable references in keys not supported"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) C(VAR_NOT_FOUND, "Couldn't find variable"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) C(FIELD_NOT_FOUND, "Couldn't find field"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) C(EMPTY_ASSIGNMENT, "Empty assignment"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) C(INVALID_SORT_MODIFIER,"Invalid sort modifier"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) C(EMPTY_SORT_FIELD, "Empty sort field"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) C(TOO_MANY_SORT_FIELDS, "Too many sort fields (Max = 2)"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) C(INVALID_SORT_FIELD, "Sort field must be a key or a val"), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) C(INVALID_STR_OPERAND, "String type can not be an operand in expression"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #undef C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define C(a, b) HIST_ERR_##a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) enum { ERRORS };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #undef C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define C(a, b) b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static const char *err_text[] = { ERRORS };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) typedef u64 (*hist_field_fn_t) (struct hist_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) void *event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define HIST_FIELD_OPERANDS_MAX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define HIST_FIELDS_MAX (TRACING_MAP_FIELDS_MAX + TRACING_MAP_VARS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define HIST_ACTIONS_MAX 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) enum field_op_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) FIELD_OP_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) FIELD_OP_PLUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) FIELD_OP_MINUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) FIELD_OP_UNARY_MINUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * A hist_var (histogram variable) contains variable information for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * hist_fields having the HIST_FIELD_FL_VAR or HIST_FIELD_FL_VAR_REF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * flag set. A hist_var has a variable name e.g. ts0, and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * associated with a given histogram trigger, as specified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * hist_data. The hist_var idx is the unique index assigned to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * variable by the hist trigger's tracing_map. The idx is what is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * used to set a variable's value and, by a variable reference, to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * retrieve it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct hist_var {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct hist_field {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct ftrace_event_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) hist_field_fn_t fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned int ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned int is_signed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) const char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct hist_field *operands[HIST_FIELD_OPERANDS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Variable fields contain variable-specific info in var.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct hist_var var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) enum field_op_id operator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) char *system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) char *event_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * The name field is used for EXPR and VAR_REF fields. VAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * fields contain the variable name in var.name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) char *name;
^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) * When a histogram trigger is hit, if it has any references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * to variables, the values of those variables are collected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * into a var_ref_vals array by resolve_var_refs(). The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * current value of each variable is read from the tracing_map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * using the hist field's hist_var.idx and entered into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * var_ref_idx entry i.e. var_ref_vals[var_ref_idx].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned int var_ref_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) bool read_once;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned int var_str_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static u64 hist_field_none(struct hist_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static u64 hist_field_counter(struct hist_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static u64 hist_field_string(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) char *addr = (char *)(event + hist_field->field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return (u64)(unsigned long)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static u64 hist_field_dynstring(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) u32 str_item = *(u32 *)(event + hist_field->field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int str_loc = str_item & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) char *addr = (char *)(event + str_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return (u64)(unsigned long)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static u64 hist_field_pstring(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) char **addr = (char **)(event + hist_field->field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return (u64)(unsigned long)*addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static u64 hist_field_log2(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct hist_field *operand = hist_field->operands[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) u64 val = operand->fn(operand, elt, rbe, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return (u64) ilog2(roundup_pow_of_two(val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static u64 hist_field_plus(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct hist_field *operand1 = hist_field->operands[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct hist_field *operand2 = hist_field->operands[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u64 val1 = operand1->fn(operand1, elt, rbe, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) u64 val2 = operand2->fn(operand2, elt, rbe, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return val1 + val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static u64 hist_field_minus(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct hist_field *operand1 = hist_field->operands[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct hist_field *operand2 = hist_field->operands[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u64 val1 = operand1->fn(operand1, elt, rbe, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) u64 val2 = operand2->fn(operand2, elt, rbe, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return val1 - val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static u64 hist_field_unary_minus(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct hist_field *operand = hist_field->operands[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) s64 sval = (s64)operand->fn(operand, elt, rbe, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u64 val = (u64)-sval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #define DEFINE_HIST_FIELD_FN(type) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static u64 hist_field_##type(struct hist_field *hist_field, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct tracing_map_elt *elt, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct ring_buffer_event *rbe, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) void *event) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) type *addr = (type *)(event + hist_field->field->offset); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return (u64)(unsigned long)*addr; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) DEFINE_HIST_FIELD_FN(s64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) DEFINE_HIST_FIELD_FN(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) DEFINE_HIST_FIELD_FN(s32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) DEFINE_HIST_FIELD_FN(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) DEFINE_HIST_FIELD_FN(s16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) DEFINE_HIST_FIELD_FN(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) DEFINE_HIST_FIELD_FN(s8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) DEFINE_HIST_FIELD_FN(u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define for_each_hist_field(i, hist_data) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) for ((i) = 0; (i) < (hist_data)->n_fields; (i)++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define for_each_hist_val_field(i, hist_data) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) for ((i) = 0; (i) < (hist_data)->n_vals; (i)++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #define for_each_hist_key_field(i, hist_data) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) for ((i) = (hist_data)->n_vals; (i) < (hist_data)->n_fields; (i)++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #define HIST_STACKTRACE_DEPTH 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) #define HIST_STACKTRACE_SIZE (HIST_STACKTRACE_DEPTH * sizeof(unsigned long))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #define HIST_STACKTRACE_SKIP 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #define HITCOUNT_IDX 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #define HIST_KEY_SIZE_MAX (MAX_FILTER_STR_VAL + HIST_STACKTRACE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) enum hist_field_flags {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) HIST_FIELD_FL_HITCOUNT = 1 << 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) HIST_FIELD_FL_KEY = 1 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) HIST_FIELD_FL_STRING = 1 << 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) HIST_FIELD_FL_HEX = 1 << 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) HIST_FIELD_FL_SYM = 1 << 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) HIST_FIELD_FL_SYM_OFFSET = 1 << 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) HIST_FIELD_FL_EXECNAME = 1 << 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) HIST_FIELD_FL_SYSCALL = 1 << 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) HIST_FIELD_FL_STACKTRACE = 1 << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) HIST_FIELD_FL_LOG2 = 1 << 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) HIST_FIELD_FL_TIMESTAMP = 1 << 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) HIST_FIELD_FL_TIMESTAMP_USECS = 1 << 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) HIST_FIELD_FL_VAR = 1 << 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) HIST_FIELD_FL_EXPR = 1 << 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) HIST_FIELD_FL_VAR_REF = 1 << 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) HIST_FIELD_FL_CPU = 1 << 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) HIST_FIELD_FL_ALIAS = 1 << 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct var_defs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) unsigned int n_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) char *name[TRACING_MAP_VARS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) char *expr[TRACING_MAP_VARS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct hist_trigger_attrs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) char *keys_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) char *vals_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) char *sort_key_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) char *clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) bool pause;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) bool cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) bool clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) bool ts_in_usecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) unsigned int map_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) char *assignment_str[TRACING_MAP_VARS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) unsigned int n_assignments;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) char *action_str[HIST_ACTIONS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned int n_actions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct var_defs var_defs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct field_var {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct hist_field *var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct hist_field *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct field_var_hist {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) char *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct hist_trigger_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct hist_field *fields[HIST_FIELDS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned int n_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) unsigned int n_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) unsigned int n_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) unsigned int n_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) unsigned int n_var_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) unsigned int key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct tracing_map_sort_key sort_keys[TRACING_MAP_SORT_KEYS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) unsigned int n_sort_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct trace_event_file *event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct hist_trigger_attrs *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct tracing_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) bool enable_timestamps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) bool remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct hist_field *var_refs[TRACING_MAP_VARS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) unsigned int n_var_refs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct action_data *actions[HIST_ACTIONS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) unsigned int n_actions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct field_var *field_vars[SYNTH_FIELDS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) unsigned int n_field_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned int n_field_var_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct field_var_hist *field_var_hists[SYNTH_FIELDS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned int n_field_var_hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct field_var *save_vars[SYNTH_FIELDS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) unsigned int n_save_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) unsigned int n_save_var_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct action_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) typedef void (*action_fn_t) (struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct tracing_map_elt *elt, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct ring_buffer_event *rbe, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct action_data *data, u64 *var_ref_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) typedef bool (*check_track_val_fn_t) (u64 track_val, u64 var_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) enum handler_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) HANDLER_ONMATCH = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) HANDLER_ONMAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) HANDLER_ONCHANGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) enum action_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ACTION_SAVE = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ACTION_TRACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ACTION_SNAPSHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct action_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) enum handler_id handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) enum action_id action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) char *action_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) action_fn_t fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) unsigned int n_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) char *params[SYNTH_FIELDS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * When a histogram trigger is hit, the values of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * references to variables, including variables being passed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * as parameters to synthetic events, are collected into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * var_ref_vals array. This var_ref_idx array is an array of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * indices into the var_ref_vals array, one for each synthetic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * event param, and is passed to the synthetic event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * invocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) unsigned int var_ref_idx[TRACING_MAP_VARS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct synth_event *synth_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) bool use_trace_keyword;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) char *synth_event_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) char *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) char *event_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) } match_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * var_str contains the $-unstripped variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * name referenced by var_ref, and used when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * printing the action. Because var_ref
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * creation is deferred to create_actions(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * we need a per-action way to save it until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * then, thus var_str.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) char *var_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * var_ref refers to the variable being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * tracked e.g onmax($var).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct hist_field *var_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * track_var contains the 'invisible' tracking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * variable created to keep the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * e.g. max value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct hist_field *track_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) check_track_val_fn_t check_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) action_fn_t save_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) } track_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) };
^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) struct track_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) u64 track_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) bool updated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) unsigned int key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) void *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct tracing_map_elt elt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct action_data *action_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct hist_elt_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) char *comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u64 *var_ref_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) char *field_var_str[SYNTH_FIELDS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct snapshot_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct tracing_map_elt *elt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) void *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static void track_data_free(struct track_data *track_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct hist_elt_data *elt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (!track_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) kfree(track_data->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) elt_data = track_data->elt.private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (elt_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) kfree(elt_data->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) kfree(elt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) kfree(track_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static struct track_data *track_data_alloc(unsigned int key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct action_data *action_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct track_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct hist_elt_data *elt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) data->key = kzalloc(key_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!data->key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) track_data_free(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) data->key_len = key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) data->action_data = action_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) data->hist_data = hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (!elt_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) track_data_free(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) data->elt.private_data = elt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) elt_data->comm = kzalloc(TASK_COMM_LEN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (!elt_data->comm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) track_data_free(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static char last_cmd[MAX_FILTER_STR_VAL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static char last_cmd_loc[MAX_FILTER_STR_VAL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int errpos(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return err_pos(last_cmd, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static void last_cmd_set(struct trace_event_file *file, char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) const char *system = NULL, *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct trace_event_call *call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) strcpy(last_cmd, "hist:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) strncat(last_cmd, str, MAX_FILTER_STR_VAL - 1 - sizeof("hist:"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) call = file->event_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) system = call->class->system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) name = trace_event_name(call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) system = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (system)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) snprintf(last_cmd_loc, MAX_FILTER_STR_VAL, "hist:%s:%s", system, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static void hist_err(struct trace_array *tr, u8 err_type, u8 err_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) tracing_log_err(tr, last_cmd_loc, last_cmd, err_text,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) err_type, err_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static void hist_err_clear(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) last_cmd[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) last_cmd_loc[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) typedef void (*synth_probe_func_t) (void *__data, u64 *var_ref_vals,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) unsigned int *var_ref_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static inline void trace_synth(struct synth_event *event, u64 *var_ref_vals,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) unsigned int *var_ref_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct tracepoint *tp = event->tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (unlikely(atomic_read(&tp->key.enabled) > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct tracepoint_func *probe_func_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) synth_probe_func_t probe_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) void *__data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (!(cpu_online(raw_smp_processor_id())))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) probe_func_ptr = rcu_dereference_sched((tp)->funcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (probe_func_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) probe_func = probe_func_ptr->func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) __data = probe_func_ptr->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) probe_func(__data, var_ref_vals, var_ref_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) } while ((++probe_func_ptr)->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static void action_trace(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct tracing_map_elt *elt, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct ring_buffer_event *rbe, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct action_data *data, u64 *var_ref_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct synth_event *event = data->synth_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) trace_synth(event, var_ref_vals, data->var_ref_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct hist_var_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static u64 hist_field_timestamp(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct hist_trigger_data *hist_data = hist_field->hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) u64 ts = ring_buffer_event_time_stamp(rbe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (hist_data->attrs->ts_in_usecs && trace_clock_in_ns(tr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ts = ns2usecs(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static u64 hist_field_cpu(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) int cpu = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * check_field_for_var_ref - Check if a VAR_REF field references a variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * @hist_field: The VAR_REF field to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * @var_data: The hist trigger that owns the variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * @var_idx: The trigger variable identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * Check the given VAR_REF field to see whether or not it references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * the given variable associated with the given trigger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * Return: The VAR_REF field if it does reference the variable, NULL if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static struct hist_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) check_field_for_var_ref(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct hist_trigger_data *var_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) unsigned int var_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) WARN_ON(!(hist_field && hist_field->flags & HIST_FIELD_FL_VAR_REF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (hist_field && hist_field->var.idx == var_idx &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) hist_field->var.hist_data == var_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * find_var_ref - Check if a trigger has a reference to a trigger variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * @hist_data: The hist trigger that might have a reference to the variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * @var_data: The hist trigger that owns the variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * @var_idx: The trigger variable identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * Check the list of var_refs[] on the first hist trigger to see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * whether any of them are references to the variable on the second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * trigger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * Return: The VAR_REF field referencing the variable if so, NULL if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static struct hist_field *find_var_ref(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct hist_trigger_data *var_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) unsigned int var_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) for (i = 0; i < hist_data->n_var_refs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) hist_field = hist_data->var_refs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (check_field_for_var_ref(hist_field, var_data, var_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * find_any_var_ref - Check if there is a reference to a given trigger variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * @hist_data: The hist trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * @var_idx: The trigger variable identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * Check to see whether the given variable is currently referenced by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * any other trigger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * The trigger the variable is defined on is explicitly excluded - the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * assumption being that a self-reference doesn't prevent a trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * from being removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * Return: The VAR_REF field referencing the variable if so, NULL if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static struct hist_field *find_any_var_ref(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) unsigned int var_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct hist_field *found = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct hist_var_data *var_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) list_for_each_entry(var_data, &tr->hist_vars, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (var_data->hist_data == hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) found = find_var_ref(var_data->hist_data, hist_data, var_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * check_var_refs - Check if there is a reference to any of trigger's variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * @hist_data: The hist trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * A trigger can define one or more variables. If any one of them is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * currently referenced by any other trigger, this function will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * determine that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * Typically used to determine whether or not a trigger can be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * - if there are any references to a trigger's variables, it cannot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * Return: True if there is a reference to any of trigger's variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static bool check_var_refs(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct hist_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) for_each_hist_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (field && field->flags & HIST_FIELD_FL_VAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (find_any_var_ref(hist_data, field->var.idx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) break;
^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) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static struct hist_var_data *find_hist_vars(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct hist_var_data *var_data, *found = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) list_for_each_entry(var_data, &tr->hist_vars, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (var_data->hist_data == hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) found = var_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static bool field_has_hist_vars(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) unsigned int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (level > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (!hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (hist_field->flags & HIST_FIELD_FL_VAR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) hist_field->flags & HIST_FIELD_FL_VAR_REF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct hist_field *operand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) operand = hist_field->operands[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (field_has_hist_vars(operand, level + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static bool has_hist_vars(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) for_each_hist_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) hist_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (field_has_hist_vars(hist_field, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static int save_hist_vars(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct hist_var_data *var_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) var_data = find_hist_vars(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (var_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (tracing_check_open_get_tr(tr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) var_data = kzalloc(sizeof(*var_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (!var_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) trace_array_put(tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) var_data->hist_data = hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) list_add(&var_data->list, &tr->hist_vars);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static void remove_hist_vars(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct hist_var_data *var_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) var_data = find_hist_vars(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (!var_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (WARN_ON(check_var_refs(hist_data)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) list_del(&var_data->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) kfree(var_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) trace_array_put(tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static struct hist_field *find_var_field(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) const char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct hist_field *hist_field, *found = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) for_each_hist_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) hist_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (hist_field && hist_field->flags & HIST_FIELD_FL_VAR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) strcmp(hist_field->var.name, var_name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) found = hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) static struct hist_field *find_var(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) const char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct hist_trigger_data *test_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct event_trigger_data *test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) hist_field = find_var_field(hist_data, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) list_for_each_entry(test, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) test_data = test->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) hist_field = find_var_field(test_data, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return hist_field;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) static struct trace_event_file *find_var_file(struct trace_array *tr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) char *system,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) char *event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct hist_trigger_data *var_hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct hist_var_data *var_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct trace_event_file *file, *found = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (system)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return find_event_file(tr, system, event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) list_for_each_entry(var_data, &tr->hist_vars, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) var_hist_data = var_data->hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) file = var_hist_data->event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (file == found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (find_var_field(var_hist_data, var_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) hist_err(tr, HIST_ERR_VAR_NOT_UNIQUE, errpos(var_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) found = file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) static struct hist_field *find_file_var(struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) const char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) struct hist_trigger_data *test_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct event_trigger_data *test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) list_for_each_entry(test, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) test_data = test->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) hist_field = find_var_field(test_data, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static struct hist_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) find_match_var(struct hist_trigger_data *hist_data, char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct hist_field *hist_field, *found = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct trace_event_file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) for (i = 0; i < hist_data->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct action_data *data = hist_data->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (data->handler == HANDLER_ONMATCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) char *system = data->match_data.event_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) char *event_name = data->match_data.event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) file = find_var_file(tr, system, event_name, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) hist_field = find_file_var(file, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (hist_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) hist_err(tr, HIST_ERR_VAR_NOT_UNIQUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) errpos(var_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) found = hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) static struct hist_field *find_event_var(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) char *system,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) char *event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct hist_field *hist_field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct trace_event_file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (!system || !event_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) hist_field = find_match_var(hist_data, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (IS_ERR(hist_field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) file = find_var_file(tr, system, event_name, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) hist_field = find_file_var(file, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static u64 hist_field_var_ref(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) void *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) struct hist_elt_data *elt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) u64 var_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (WARN_ON_ONCE(!elt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return var_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) elt_data = elt->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) var_val = elt_data->var_ref_vals[hist_field->var_ref_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return var_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static bool resolve_var_refs(struct hist_trigger_data *hist_data, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) u64 *var_ref_vals, bool self)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct hist_trigger_data *var_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct tracing_map_elt *var_elt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) unsigned int i, var_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) bool resolved = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) u64 var_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) for (i = 0; i < hist_data->n_var_refs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) hist_field = hist_data->var_refs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) var_idx = hist_field->var.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) var_data = hist_field->var.hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (var_data == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) resolved = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if ((self && var_data != hist_data) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) (!self && var_data == hist_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) var_elt = tracing_map_lookup(var_data->map, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (!var_elt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) resolved = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (!tracing_map_var_set(var_elt, var_idx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) resolved = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (self || !hist_field->read_once)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) var_val = tracing_map_read_var(var_elt, var_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) var_val = tracing_map_read_var_once(var_elt, var_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) var_ref_vals[i] = var_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return resolved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static const char *hist_field_name(struct hist_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) unsigned int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) const char *field_name = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (level > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return field_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (field->field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) field_name = field->field->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) else if (field->flags & HIST_FIELD_FL_LOG2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) field->flags & HIST_FIELD_FL_ALIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) field_name = hist_field_name(field->operands[0], ++level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) else if (field->flags & HIST_FIELD_FL_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) field_name = "common_cpu";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) else if (field->flags & HIST_FIELD_FL_EXPR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) field->flags & HIST_FIELD_FL_VAR_REF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (field->system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static char full_name[MAX_FILTER_STR_VAL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) strcat(full_name, field->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) strcat(full_name, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) strcat(full_name, field->event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) strcat(full_name, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) strcat(full_name, field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) field_name = full_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) field_name = field->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) } else if (field->flags & HIST_FIELD_FL_TIMESTAMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) field_name = "common_timestamp";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (field_name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) field_name = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return field_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static hist_field_fn_t select_value_fn(int field_size, int field_is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) hist_field_fn_t fn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) switch (field_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (field_is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) fn = hist_field_s64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) fn = hist_field_u64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (field_is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) fn = hist_field_s32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) fn = hist_field_u32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (field_is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) fn = hist_field_s16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) fn = hist_field_u16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (field_is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) fn = hist_field_s8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) fn = hist_field_u8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) static int parse_map_size(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) unsigned long size, map_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) ret = kstrtoul(str, 0, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) map_bits = ilog2(roundup_pow_of_two(size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (map_bits < TRACING_MAP_BITS_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) map_bits > TRACING_MAP_BITS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) ret = map_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) static void destroy_hist_trigger_attrs(struct hist_trigger_attrs *attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (!attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) for (i = 0; i < attrs->n_assignments; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) kfree(attrs->assignment_str[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) for (i = 0; i < attrs->n_actions; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) kfree(attrs->action_str[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) kfree(attrs->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) kfree(attrs->sort_key_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) kfree(attrs->keys_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) kfree(attrs->vals_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) kfree(attrs->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) kfree(attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) static int parse_action(char *str, struct hist_trigger_attrs *attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (attrs->n_actions >= HIST_ACTIONS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if ((str_has_prefix(str, "onmatch(")) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) (str_has_prefix(str, "onmax(")) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) (str_has_prefix(str, "onchange("))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) attrs->action_str[attrs->n_actions] = kstrdup(str, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (!attrs->action_str[attrs->n_actions]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) attrs->n_actions++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) static int parse_assignment(struct trace_array *tr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) char *str, struct hist_trigger_attrs *attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) int len, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if ((len = str_has_prefix(str, "key=")) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) (len = str_has_prefix(str, "keys="))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) attrs->keys_str = kstrdup(str + len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (!attrs->keys_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) } else if ((len = str_has_prefix(str, "val=")) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) (len = str_has_prefix(str, "vals=")) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) (len = str_has_prefix(str, "values="))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) attrs->vals_str = kstrdup(str + len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (!attrs->vals_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) } else if ((len = str_has_prefix(str, "sort="))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) attrs->sort_key_str = kstrdup(str + len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (!attrs->sort_key_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) } else if (str_has_prefix(str, "name=")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) attrs->name = kstrdup(str, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (!attrs->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) } else if ((len = str_has_prefix(str, "clock="))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) str += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) str = strstrip(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) attrs->clock = kstrdup(str, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (!attrs->clock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) } else if ((len = str_has_prefix(str, "size="))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) int map_bits = parse_map_size(str + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (map_bits < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) ret = map_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) attrs->map_bits = map_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) char *assignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (attrs->n_assignments == TRACING_MAP_VARS_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) assignment = kstrdup(str, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (!assignment) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) attrs->assignment_str[attrs->n_assignments++] = assignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static struct hist_trigger_attrs *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) parse_hist_trigger_attrs(struct trace_array *tr, char *trigger_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) struct hist_trigger_attrs *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (!attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) while (trigger_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) char *str = strsep(&trigger_str, ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) char *rhs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) rhs = strchr(str, '=');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (rhs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (!strlen(++rhs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) hist_err(tr, HIST_ERR_EMPTY_ASSIGNMENT, errpos(str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) ret = parse_assignment(tr, str, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) } else if (strcmp(str, "pause") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) attrs->pause = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) else if ((strcmp(str, "cont") == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) (strcmp(str, "continue") == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) attrs->cont = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) else if (strcmp(str, "clear") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) attrs->clear = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) ret = parse_action(str, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (!attrs->keys_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (!attrs->clock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) attrs->clock = kstrdup("global", GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (!attrs->clock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) destroy_hist_trigger_attrs(attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return ERR_PTR(ret);
^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) static inline void save_comm(char *comm, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (!task->pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) strcpy(comm, "<idle>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (WARN_ON_ONCE(task->pid < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) strcpy(comm, "<XXX>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) strncpy(comm, task->comm, TASK_COMM_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) static void hist_elt_data_free(struct hist_elt_data *elt_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) for (i = 0; i < SYNTH_FIELDS_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) kfree(elt_data->field_var_str[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) kfree(elt_data->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) kfree(elt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) static void hist_trigger_elt_data_free(struct tracing_map_elt *elt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) struct hist_elt_data *elt_data = elt->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) hist_elt_data_free(elt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) struct hist_trigger_data *hist_data = elt->map->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) unsigned int size = TASK_COMM_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct hist_elt_data *elt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) struct hist_field *key_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) unsigned int i, n_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (!elt_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) for_each_hist_key_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) key_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (key_field->flags & HIST_FIELD_FL_EXECNAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) elt_data->comm = kzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (!elt_data->comm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) kfree(elt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) n_str = hist_data->n_field_var_str + hist_data->n_save_var_str +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) hist_data->n_var_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (n_str > SYNTH_FIELDS_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) hist_elt_data_free(elt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) BUILD_BUG_ON(STR_VAR_LEN_MAX & (sizeof(u64) - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) size = STR_VAR_LEN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) for (i = 0; i < n_str; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) elt_data->field_var_str[i] = kzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (!elt_data->field_var_str[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) hist_elt_data_free(elt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) elt->private_data = elt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) static void hist_trigger_elt_data_init(struct tracing_map_elt *elt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) struct hist_elt_data *elt_data = elt->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (elt_data->comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) save_comm(elt_data->comm, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) static const struct tracing_map_ops hist_trigger_elt_data_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) .elt_alloc = hist_trigger_elt_data_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) .elt_free = hist_trigger_elt_data_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) .elt_init = hist_trigger_elt_data_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) static const char *get_hist_field_flags(struct hist_field *hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) const char *flags_str = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (hist_field->flags & HIST_FIELD_FL_HEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) flags_str = "hex";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) else if (hist_field->flags & HIST_FIELD_FL_SYM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) flags_str = "sym";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) flags_str = "sym-offset";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) else if (hist_field->flags & HIST_FIELD_FL_EXECNAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) flags_str = "execname";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) else if (hist_field->flags & HIST_FIELD_FL_SYSCALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) flags_str = "syscall";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) else if (hist_field->flags & HIST_FIELD_FL_LOG2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) flags_str = "log2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP_USECS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) flags_str = "usecs";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return flags_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) static void expr_field_str(struct hist_field *field, char *expr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if (field->flags & HIST_FIELD_FL_VAR_REF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) strcat(expr, "$");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) strcat(expr, hist_field_name(field, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (field->flags && !(field->flags & HIST_FIELD_FL_VAR_REF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) const char *flags_str = get_hist_field_flags(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (flags_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) strcat(expr, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) strcat(expr, flags_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) static char *expr_str(struct hist_field *field, unsigned int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) char *expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) if (level > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) expr = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if (!expr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (!field->operands[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) expr_field_str(field, expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) return expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) if (field->operator == FIELD_OP_UNARY_MINUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) char *subexpr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) strcat(expr, "-(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) subexpr = expr_str(field->operands[0], ++level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if (!subexpr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) kfree(expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) strcat(expr, subexpr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) strcat(expr, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) kfree(subexpr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) return expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) expr_field_str(field->operands[0], expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) switch (field->operator) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) case FIELD_OP_MINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) strcat(expr, "-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) case FIELD_OP_PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) strcat(expr, "+");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) kfree(expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) expr_field_str(field->operands[1], expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) return expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) static int contains_operator(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) enum field_op_id field_op = FIELD_OP_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) char *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) op = strpbrk(str, "+-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (!op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return FIELD_OP_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) switch (*op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) case '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) * Unfortunately, the modifier ".sym-offset"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) * can confuse things.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) if (op - str >= 4 && !strncmp(op - 4, ".sym-offset", 11))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) return FIELD_OP_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (*str == '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) field_op = FIELD_OP_UNARY_MINUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) field_op = FIELD_OP_MINUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) case '+':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) field_op = FIELD_OP_PLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return field_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) static void get_hist_field(struct hist_field *hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) hist_field->ref++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) static void __destroy_hist_field(struct hist_field *hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (--hist_field->ref > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) kfree(hist_field->var.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) kfree(hist_field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) kfree(hist_field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) kfree(hist_field->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) kfree(hist_field->event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) kfree(hist_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) static void destroy_hist_field(struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) unsigned int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) if (level > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (!hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (hist_field->flags & HIST_FIELD_FL_VAR_REF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) return; /* var refs will be destroyed separately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) destroy_hist_field(hist_field->operands[i], level + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) __destroy_hist_field(hist_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) struct ftrace_event_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) unsigned long flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) if (field && is_function_field(field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) hist_field = kzalloc(sizeof(struct hist_field), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (!hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) hist_field->ref = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) hist_field->hist_data = hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (flags & HIST_FIELD_FL_EXPR || flags & HIST_FIELD_FL_ALIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) goto out; /* caller will populate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (flags & HIST_FIELD_FL_VAR_REF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) hist_field->fn = hist_field_var_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (flags & HIST_FIELD_FL_HITCOUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) hist_field->fn = hist_field_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) hist_field->size = sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) hist_field->type = kstrdup("u64", GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (!hist_field->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) goto out;
^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 (flags & HIST_FIELD_FL_STACKTRACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) hist_field->fn = hist_field_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (flags & HIST_FIELD_FL_LOG2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) unsigned long fl = flags & ~HIST_FIELD_FL_LOG2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) hist_field->fn = hist_field_log2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) hist_field->size = hist_field->operands[0]->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) hist_field->type = kstrdup(hist_field->operands[0]->type, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (!hist_field->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) if (flags & HIST_FIELD_FL_TIMESTAMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) hist_field->fn = hist_field_timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) hist_field->size = sizeof(u64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) hist_field->type = kstrdup("u64", GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (!hist_field->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) if (flags & HIST_FIELD_FL_CPU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) hist_field->fn = hist_field_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) hist_field->size = sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) hist_field->type = kstrdup("unsigned int", GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) if (!hist_field->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (WARN_ON_ONCE(!field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) /* Pointers to strings are just pointers and dangerous to dereference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (is_string_field(field) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) (field->filter_type != FILTER_PTR_STRING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) flags |= HIST_FIELD_FL_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) hist_field->size = MAX_FILTER_STR_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) hist_field->type = kstrdup(field->type, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (!hist_field->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (field->filter_type == FILTER_STATIC_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) hist_field->fn = hist_field_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) hist_field->size = field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) } else if (field->filter_type == FILTER_DYN_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) hist_field->fn = hist_field_dynstring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) hist_field->fn = hist_field_pstring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) hist_field->size = field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) hist_field->is_signed = field->is_signed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) hist_field->type = kstrdup(field->type, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) if (!hist_field->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) hist_field->fn = select_value_fn(field->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) field->is_signed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (!hist_field->fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) destroy_hist_field(hist_field, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) hist_field->field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) hist_field->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (var_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) hist_field->var.name = kstrdup(var_name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (!hist_field->var.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) destroy_hist_field(hist_field, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) static void destroy_hist_fields(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) for (i = 0; i < HIST_FIELDS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) if (hist_data->fields[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) destroy_hist_field(hist_data->fields[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) hist_data->fields[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) for (i = 0; i < hist_data->n_var_refs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) WARN_ON(!(hist_data->var_refs[i]->flags & HIST_FIELD_FL_VAR_REF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) __destroy_hist_field(hist_data->var_refs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) hist_data->var_refs[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) }
^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) static int init_var_ref(struct hist_field *ref_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) struct hist_field *var_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) char *system, char *event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) ref_field->var.idx = var_field->var.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) ref_field->var.hist_data = var_field->hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) ref_field->size = var_field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) ref_field->is_signed = var_field->is_signed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) ref_field->flags |= var_field->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) ref_field->system = kstrdup(system, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) if (!ref_field->system)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) if (event_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) ref_field->event_name = kstrdup(event_name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) if (!ref_field->event_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) if (var_field->var.name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) ref_field->name = kstrdup(var_field->var.name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) if (!ref_field->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) } else if (var_field->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) ref_field->name = kstrdup(var_field->name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) if (!ref_field->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) ref_field->type = kstrdup(var_field->type, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (!ref_field->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) kfree(ref_field->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) kfree(ref_field->event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) kfree(ref_field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) static int find_var_ref_idx(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) struct hist_field *var_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) struct hist_field *ref_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) for (i = 0; i < hist_data->n_var_refs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) ref_field = hist_data->var_refs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (ref_field->var.idx == var_field->var.idx &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) ref_field->var.hist_data == var_field->hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) return i;
^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) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) * create_var_ref - Create a variable reference and attach it to trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) * @hist_data: The trigger that will be referencing the variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) * @var_field: The VAR field to create a reference to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) * @system: The optional system string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) * @event_name: The optional event_name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) * Given a variable hist_field, create a VAR_REF hist_field that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) * represents a reference to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) * This function also adds the reference to the trigger that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) * now references the variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) * Return: The VAR_REF field if successful, NULL if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) static struct hist_field *create_var_ref(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) struct hist_field *var_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) char *system, char *event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) unsigned long flags = HIST_FIELD_FL_VAR_REF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) struct hist_field *ref_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /* Check if the variable already exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) for (i = 0; i < hist_data->n_var_refs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) ref_field = hist_data->var_refs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) if (ref_field->var.idx == var_field->var.idx &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) ref_field->var.hist_data == var_field->hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) get_hist_field(ref_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) return ref_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) if (ref_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if (init_var_ref(ref_field, var_field, system, event_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) destroy_hist_field(ref_field, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) hist_data->var_refs[hist_data->n_var_refs] = ref_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) ref_field->var_ref_idx = hist_data->n_var_refs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) return ref_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) static bool is_var_ref(char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (!var_name || strlen(var_name) < 2 || var_name[0] != '$')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) static char *field_name_from_var(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) char *name, *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) for (i = 0; i < hist_data->attrs->var_defs.n_vars; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) name = hist_data->attrs->var_defs.name[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (strcmp(var_name, name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) field = hist_data->attrs->var_defs.expr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (contains_operator(field) || is_var_ref(field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) return field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) static char *local_field_var_ref(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) char *system, char *event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) struct trace_event_call *call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (system && event_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) call = hist_data->event_file->event_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (strcmp(system, call->class->system) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) if (strcmp(event_name, trace_event_name(call)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) if (!!system != !!event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (!is_var_ref(var_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) var_name++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) return field_name_from_var(hist_data, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) static struct hist_field *parse_var_ref(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) char *system, char *event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) struct hist_field *var_field = NULL, *ref_field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (!is_var_ref(var_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) var_name++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) var_field = find_event_var(hist_data, system, event_name, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) if (var_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) ref_field = create_var_ref(hist_data, var_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) system, event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) if (!ref_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) hist_err(tr, HIST_ERR_VAR_NOT_FOUND, errpos(var_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) return ref_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) static struct ftrace_event_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) char *field_str, unsigned long *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) struct ftrace_event_field *field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) char *field_name, *modifier, *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) struct trace_array *tr = file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) modifier = str = kstrdup(field_str, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (!modifier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) field_name = strsep(&modifier, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) if (modifier) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) if (strcmp(modifier, "hex") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) *flags |= HIST_FIELD_FL_HEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) else if (strcmp(modifier, "sym") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) *flags |= HIST_FIELD_FL_SYM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) else if (strcmp(modifier, "sym-offset") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) *flags |= HIST_FIELD_FL_SYM_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) else if ((strcmp(modifier, "execname") == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) (strcmp(field_name, "common_pid") == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) *flags |= HIST_FIELD_FL_EXECNAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) else if (strcmp(modifier, "syscall") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) *flags |= HIST_FIELD_FL_SYSCALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) else if (strcmp(modifier, "log2") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) *flags |= HIST_FIELD_FL_LOG2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) else if (strcmp(modifier, "usecs") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) *flags |= HIST_FIELD_FL_TIMESTAMP_USECS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(modifier));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) field = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) if (strcmp(field_name, "common_timestamp") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) *flags |= HIST_FIELD_FL_TIMESTAMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) hist_data->enable_timestamps = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) hist_data->attrs->ts_in_usecs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) } else if (strcmp(field_name, "common_cpu") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) *flags |= HIST_FIELD_FL_CPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) field = trace_find_event_field(file->event_call, field_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) if (!field || !field->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) * For backward compatibility, if field_name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) * was "cpu", then we treat this the same as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) * common_cpu. This also works for "CPU".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) if (field && field->filter_type == FILTER_CPU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) *flags |= HIST_FIELD_FL_CPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) hist_err(tr, HIST_ERR_FIELD_NOT_FOUND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) field = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) kfree(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) return field;
^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 struct hist_field *create_alias(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) struct hist_field *var_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) struct hist_field *alias = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) unsigned long flags = HIST_FIELD_FL_ALIAS | HIST_FIELD_FL_VAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) alias = create_hist_field(hist_data, NULL, flags, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (!alias)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) alias->fn = var_ref->fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) alias->operands[0] = var_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) if (init_var_ref(alias, var_ref, var_ref->system, var_ref->event_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) destroy_hist_field(alias, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) return NULL;
^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) alias->var_ref_idx = var_ref->var_ref_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) return alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) static struct hist_field *parse_atom(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) struct trace_event_file *file, char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) unsigned long *flags, char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) char *s, *ref_system = NULL, *ref_event = NULL, *ref_var = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) struct ftrace_event_field *field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) struct hist_field *hist_field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) s = strchr(str, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if (s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) s = strchr(++s, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) if (s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) ref_system = strsep(&str, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) if (!str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) ref_event = strsep(&str, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) if (!str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) ref_var = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) }
^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) s = local_field_var_ref(hist_data, ref_system, ref_event, ref_var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) if (!s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) hist_field = parse_var_ref(hist_data, ref_system,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) ref_event, ref_var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (hist_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) if (var_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) hist_field = create_alias(hist_data, hist_field, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (!hist_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) str = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) field = parse_field(hist_data, file, str, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) if (IS_ERR(field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) ret = PTR_ERR(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) hist_field = create_hist_field(hist_data, field, *flags, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) if (!hist_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) char *str, unsigned long flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) char *var_name, unsigned int level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) static struct hist_field *parse_unary(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) char *str, unsigned long flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) char *var_name, unsigned int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) struct hist_field *operand1, *expr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) unsigned long operand_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) /* we support only -(xxx) i.e. explicit parens required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) if (level > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) str++; /* skip leading '-' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) s = strchr(str, '(');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) if (s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) s = strrchr(str, ')');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) *s = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) ret = -EINVAL; /* no closing ')' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) flags |= HIST_FIELD_FL_EXPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) expr = create_hist_field(hist_data, NULL, flags, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) if (!expr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) operand_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) operand1 = parse_expr(hist_data, file, str, operand_flags, NULL, ++level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) if (IS_ERR(operand1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) ret = PTR_ERR(operand1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) if (operand1->flags & HIST_FIELD_FL_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) /* String type can not be the operand of unary operator. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) destroy_hist_field(operand1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) expr->flags |= operand1->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) expr->fn = hist_field_unary_minus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) expr->operands[0] = operand1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) expr->size = operand1->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) expr->is_signed = operand1->is_signed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) expr->operator = FIELD_OP_UNARY_MINUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) expr->name = expr_str(expr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) expr->type = kstrdup(operand1->type, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) if (!expr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) return expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) destroy_hist_field(expr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) static int check_expr_operands(struct trace_array *tr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) struct hist_field *operand1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) struct hist_field *operand2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) unsigned long operand1_flags = operand1->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) unsigned long operand2_flags = operand2->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if ((operand1_flags & HIST_FIELD_FL_VAR_REF) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) (operand1_flags & HIST_FIELD_FL_ALIAS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) struct hist_field *var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) var = find_var_field(operand1->var.hist_data, operand1->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) if (!var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) operand1_flags = var->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) if ((operand2_flags & HIST_FIELD_FL_VAR_REF) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) (operand2_flags & HIST_FIELD_FL_ALIAS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) struct hist_field *var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) var = find_var_field(operand2->var.hist_data, operand2->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (!var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) operand2_flags = var->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) hist_err(tr, HIST_ERR_TIMESTAMP_MISMATCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) char *str, unsigned long flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) char *var_name, unsigned int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) struct hist_field *operand1 = NULL, *operand2 = NULL, *expr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) unsigned long operand_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) int field_op, ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) char *sep, *operand1_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) if (level > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) field_op = contains_operator(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) if (field_op == FIELD_OP_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) return parse_atom(hist_data, file, str, &flags, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) if (field_op == FIELD_OP_UNARY_MINUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) return parse_unary(hist_data, file, str, flags, var_name, ++level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) switch (field_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) case FIELD_OP_MINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) sep = "-";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) case FIELD_OP_PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) sep = "+";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) operand1_str = strsep(&str, sep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) if (!operand1_str || !str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) operand_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) operand1 = parse_atom(hist_data, file, operand1_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) &operand_flags, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (IS_ERR(operand1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) ret = PTR_ERR(operand1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) operand1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) if (operand1->flags & HIST_FIELD_FL_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(operand1_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) /* rest of string could be another expression e.g. b+c in a+b+c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) operand_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) operand2 = parse_expr(hist_data, file, str, operand_flags, NULL, ++level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) if (IS_ERR(operand2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) ret = PTR_ERR(operand2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) operand2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) if (operand2->flags & HIST_FIELD_FL_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) ret = check_expr_operands(file->tr, operand1, operand2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) flags |= HIST_FIELD_FL_EXPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) flags |= operand1->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) expr = create_hist_field(hist_data, NULL, flags, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) if (!expr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) operand1->read_once = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) operand2->read_once = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) expr->operands[0] = operand1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) expr->operands[1] = operand2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) /* The operand sizes should be the same, so just pick one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) expr->size = operand1->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) expr->is_signed = operand1->is_signed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) expr->operator = field_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) expr->name = expr_str(expr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) expr->type = kstrdup(operand1->type, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) if (!expr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) switch (field_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) case FIELD_OP_MINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) expr->fn = hist_field_minus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) case FIELD_OP_PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) expr->fn = hist_field_plus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) return expr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) destroy_hist_field(operand1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) destroy_hist_field(operand2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) destroy_hist_field(expr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) static char *find_trigger_filter(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) struct event_trigger_data *test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) list_for_each_entry(test, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) if (test->private_data == hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) return test->filter_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) static struct event_command trigger_hist_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) static int event_hist_trigger_func(struct event_command *cmd_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) char *glob, char *cmd, char *param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) static bool compatible_keys(struct hist_trigger_data *target_hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) unsigned int n_keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) struct hist_field *target_hist_field, *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) unsigned int n, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) if (hist_data->n_fields - hist_data->n_vals != n_keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) i = hist_data->n_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) j = target_hist_data->n_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) for (n = 0; n < n_keys; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) hist_field = hist_data->fields[i + n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) target_hist_field = target_hist_data->fields[j + n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) if (strcmp(hist_field->type, target_hist_field->type) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) if (hist_field->size != target_hist_field->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) if (hist_field->is_signed != target_hist_field->is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) static struct hist_trigger_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) find_compatible_hist(struct hist_trigger_data *target_hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) struct event_trigger_data *test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) unsigned int n_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) n_keys = target_hist_data->n_fields - target_hist_data->n_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) list_for_each_entry(test, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) hist_data = test->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) if (compatible_keys(target_hist_data, hist_data, n_keys))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) return hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) static struct trace_event_file *event_file(struct trace_array *tr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) char *system, char *event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) struct trace_event_file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) file = __find_event_file(tr, system, event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) return file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) static struct hist_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) find_synthetic_field_var(struct hist_trigger_data *target_hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) char *system, char *event_name, char *field_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) struct hist_field *event_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) char *synthetic_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) synthetic_name = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) if (!synthetic_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) strcpy(synthetic_name, "synthetic_");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) strcat(synthetic_name, field_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) event_var = find_event_var(target_hist_data, system, event_name, synthetic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) kfree(synthetic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) return event_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) * create_field_var_hist - Automatically create a histogram and var for a field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) * @target_hist_data: The target hist trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) * @subsys_name: Optional subsystem name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) * @event_name: Optional event name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) * @field_name: The name of the field (and the resulting variable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) * Hist trigger actions fetch data from variables, not directly from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) * events. However, for convenience, users are allowed to directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) * specify an event field in an action, which will be automatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) * converted into a variable on their behalf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) * If a user specifies a field on an event that isn't the event the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) * histogram currently being defined (the target event histogram), the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) * only way that can be accomplished is if a new hist trigger is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) * created and the field variable defined on that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) * This function creates a new histogram compatible with the target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) * event (meaning a histogram with the same key as the target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) * histogram), and creates a variable for the specified field, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) * with 'synthetic_' prepended to the variable name in order to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) * collision with normal field variables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) * Return: The variable created for the field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) static struct hist_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) create_field_var_hist(struct hist_trigger_data *target_hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) char *subsys_name, char *event_name, char *field_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) struct trace_array *tr = target_hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) struct hist_field *event_var = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) unsigned int i, n, first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) struct field_var_hist *var_hist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) struct trace_event_file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) struct hist_field *key_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) char *saved_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) char *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) if (target_hist_data->n_field_var_hists >= SYNTH_FIELDS_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) file = event_file(tr, subsys_name, event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) if (IS_ERR(file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) hist_err(tr, HIST_ERR_EVENT_FILE_NOT_FOUND, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) ret = PTR_ERR(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) * Look for a histogram compatible with target. We'll use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) * found histogram specification to create a new matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) * histogram with our variable on it. target_hist_data is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) * yet a registered histogram so we can't use that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) hist_data = find_compatible_hist(target_hist_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) if (!hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) hist_err(tr, HIST_ERR_HIST_NOT_FOUND, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) /* See if a synthetic field variable has already been created */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) event_var = find_synthetic_field_var(target_hist_data, subsys_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) event_name, field_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) if (!IS_ERR_OR_NULL(event_var))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) return event_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) var_hist = kzalloc(sizeof(*var_hist), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) if (!var_hist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) cmd = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if (!cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) kfree(var_hist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) /* Use the same keys as the compatible histogram */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) strcat(cmd, "keys=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) for_each_hist_key_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) key_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) if (!first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) strcat(cmd, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) strcat(cmd, key_field->field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) /* Create the synthetic field variable specification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) strcat(cmd, ":synthetic_");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) strcat(cmd, field_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) strcat(cmd, "=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) strcat(cmd, field_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) /* Use the same filter as the compatible histogram */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) saved_filter = find_trigger_filter(hist_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) if (saved_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) strcat(cmd, " if ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) strcat(cmd, saved_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) var_hist->cmd = kstrdup(cmd, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) if (!var_hist->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) kfree(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) kfree(var_hist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) /* Save the compatible histogram information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) var_hist->hist_data = hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) /* Create the new histogram with our variable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) ret = event_hist_trigger_func(&trigger_hist_cmd, file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) "", "hist", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) kfree(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) kfree(var_hist->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) kfree(var_hist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) hist_err(tr, HIST_ERR_HIST_CREATE_FAIL, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) kfree(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) /* If we can't find the variable, something went wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) event_var = find_synthetic_field_var(target_hist_data, subsys_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) event_name, field_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) if (IS_ERR_OR_NULL(event_var)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) kfree(var_hist->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) kfree(var_hist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) hist_err(tr, HIST_ERR_SYNTH_VAR_NOT_FOUND, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) n = target_hist_data->n_field_var_hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) target_hist_data->field_var_hists[n] = var_hist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) target_hist_data->n_field_var_hists++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) return event_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) static struct hist_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) find_target_event_var(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) char *subsys_name, char *event_name, char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) struct trace_event_file *file = hist_data->event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) struct hist_field *hist_field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) if (subsys_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) struct trace_event_call *call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) if (!event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) call = file->event_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) if (strcmp(subsys_name, call->class->system) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) if (strcmp(event_name, trace_event_name(call)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) hist_field = find_var_field(hist_data, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) static inline void __update_field_vars(struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) struct field_var **field_vars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) unsigned int n_field_vars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) unsigned int field_var_str_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) struct hist_elt_data *elt_data = elt->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) unsigned int i, j, var_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) u64 var_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) for (i = 0, j = field_var_str_start; i < n_field_vars; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) struct field_var *field_var = field_vars[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) struct hist_field *var = field_var->var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) struct hist_field *val = field_var->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) var_val = val->fn(val, elt, rbe, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) var_idx = var->var.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) if (val->flags & HIST_FIELD_FL_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) char *str = elt_data->field_var_str[j++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) char *val_str = (char *)(uintptr_t)var_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) size = min(val->size, STR_VAR_LEN_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) strscpy(str, val_str, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) var_val = (u64)(uintptr_t)str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) tracing_map_set_var(elt, var_idx, var_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) static void update_field_vars(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) void *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) __update_field_vars(elt, rbe, rec, hist_data->field_vars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) hist_data->n_field_vars, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) static void save_track_data_vars(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) struct tracing_map_elt *elt, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) struct ring_buffer_event *rbe, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) struct action_data *data, u64 *var_ref_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) __update_field_vars(elt, rbe, rec, hist_data->save_vars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) hist_data->n_save_vars, hist_data->n_field_var_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) static struct hist_field *create_var(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) char *name, int size, const char *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) struct hist_field *var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) if (find_var(hist_data, file, name) && !hist_data->remove) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) var = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) var = kzalloc(sizeof(struct hist_field), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) if (!var) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) var = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) idx = tracing_map_add_var(hist_data->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) if (idx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) kfree(var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) var = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) var->ref = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) var->flags = HIST_FIELD_FL_VAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) var->var.idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) var->var.hist_data = var->hist_data = hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) var->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) var->var.name = kstrdup(name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) var->type = kstrdup(type, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) if (!var->var.name || !var->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) kfree(var->var.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) kfree(var->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) kfree(var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) var = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) return var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) static struct field_var *create_field_var(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) char *field_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) struct hist_field *val = NULL, *var = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) unsigned long flags = HIST_FIELD_FL_VAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) struct trace_array *tr = file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) struct field_var *field_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) if (hist_data->n_field_vars >= SYNTH_FIELDS_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) val = parse_atom(hist_data, file, field_name, &flags, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) if (IS_ERR(val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) hist_err(tr, HIST_ERR_FIELD_VAR_PARSE_FAIL, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) ret = PTR_ERR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) var = create_var(hist_data, file, field_name, val->size, val->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) if (IS_ERR(var)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) hist_err(tr, HIST_ERR_VAR_CREATE_FIND_FAIL, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) kfree(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) ret = PTR_ERR(var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) field_var = kzalloc(sizeof(struct field_var), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) if (!field_var) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) kfree(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) kfree(var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) field_var->var = var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) field_var->val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) return field_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) field_var = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) * create_target_field_var - Automatically create a variable for a field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) * @target_hist_data: The target hist trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) * @subsys_name: Optional subsystem name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) * @event_name: Optional event name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) * @var_name: The name of the field (and the resulting variable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) * Hist trigger actions fetch data from variables, not directly from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) * events. However, for convenience, users are allowed to directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) * specify an event field in an action, which will be automatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) * converted into a variable on their behalf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) * This function creates a field variable with the name var_name on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) * the hist trigger currently being defined on the target event. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) * subsys_name and event_name are specified, this function simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) * verifies that they do in fact match the target event subsystem and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) * event name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) * Return: The variable created for the field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) static struct field_var *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) create_target_field_var(struct hist_trigger_data *target_hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) char *subsys_name, char *event_name, char *var_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) struct trace_event_file *file = target_hist_data->event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) if (subsys_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) struct trace_event_call *call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) if (!event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) call = file->event_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) if (strcmp(subsys_name, call->class->system) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) if (strcmp(event_name, trace_event_name(call)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) return create_field_var(target_hist_data, file, var_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) static bool check_track_val_max(u64 track_val, u64 var_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) if (var_val <= track_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) static bool check_track_val_changed(u64 track_val, u64 var_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) if (var_val == track_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) static u64 get_track_val(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) unsigned int track_var_idx = data->track_data.track_var->var.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) u64 track_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) track_val = tracing_map_read_var(elt, track_var_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) return track_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) static void save_track_val(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) struct action_data *data, u64 var_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) unsigned int track_var_idx = data->track_data.track_var->var.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) tracing_map_set_var(elt, track_var_idx, var_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) static void save_track_data(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) struct tracing_map_elt *elt, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) struct ring_buffer_event *rbe, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) struct action_data *data, u64 *var_ref_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) if (data->track_data.save_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) data->track_data.save_data(hist_data, elt, rec, rbe, key, data, var_ref_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) static bool check_track_val(struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) struct action_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) u64 var_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) u64 track_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) hist_data = data->track_data.track_var->hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) track_val = get_track_val(hist_data, elt, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) return data->track_data.check_val(track_val, var_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) #ifdef CONFIG_TRACER_SNAPSHOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) static bool cond_snapshot_update(struct trace_array *tr, void *cond_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) /* called with tr->max_lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) struct track_data *track_data = tr->cond_snapshot->cond_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) struct hist_elt_data *elt_data, *track_elt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) struct snapshot_context *context = cond_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) struct action_data *action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) u64 track_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) if (!track_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) action = track_data->action_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) track_val = get_track_val(track_data->hist_data, context->elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) track_data->action_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) if (!action->track_data.check_val(track_data->track_val, track_val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) track_data->track_val = track_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) memcpy(track_data->key, context->key, track_data->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) elt_data = context->elt->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) track_elt_data = track_data->elt.private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) if (elt_data->comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) strncpy(track_elt_data->comm, elt_data->comm, TASK_COMM_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) track_data->updated = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) static void save_track_data_snapshot(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) struct tracing_map_elt *elt, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) struct ring_buffer_event *rbe, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) struct action_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) u64 *var_ref_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) struct trace_event_file *file = hist_data->event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) struct snapshot_context context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) context.elt = elt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) context.key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) tracing_snapshot_cond(file->tr, &context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) static void hist_trigger_print_key(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) struct tracing_map_elt *elt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) static struct action_data *snapshot_action(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) if (!hist_data->n_actions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) for (i = 0; i < hist_data->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) struct action_data *data = hist_data->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) if (data->action == ACTION_SNAPSHOT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) static void track_data_snapshot_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) struct trace_event_file *file = hist_data->event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) struct track_data *track_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) struct action_data *action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) track_data = tracing_cond_snapshot_data(file->tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) if (!track_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) if (!track_data->updated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) action = snapshot_action(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) if (!action)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) seq_puts(m, "\nSnapshot taken (see tracing/snapshot). Details:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) seq_printf(m, "\ttriggering value { %s(%s) }: %10llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) action->handler == HANDLER_ONMAX ? "onmax" : "onchange",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) action->track_data.var_str, track_data->track_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) seq_puts(m, "\ttriggered by event with key: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) hist_trigger_print_key(m, hist_data, track_data->key, &track_data->elt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) static bool cond_snapshot_update(struct trace_array *tr, void *cond_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) static void save_track_data_snapshot(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) struct tracing_map_elt *elt, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) struct ring_buffer_event *rbe, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) struct action_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) u64 *var_ref_vals) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) static void track_data_snapshot_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) struct hist_trigger_data *hist_data) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) #endif /* CONFIG_TRACER_SNAPSHOT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) static void track_data_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) struct tracing_map_elt *elt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) u64 track_val = get_track_val(hist_data, elt, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) unsigned int i, save_var_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) if (data->handler == HANDLER_ONMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) seq_printf(m, "\n\tmax: %10llu", track_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) else if (data->handler == HANDLER_ONCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) seq_printf(m, "\n\tchanged: %10llu", track_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) if (data->action == ACTION_SNAPSHOT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) for (i = 0; i < hist_data->n_save_vars; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) struct hist_field *save_val = hist_data->save_vars[i]->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) struct hist_field *save_var = hist_data->save_vars[i]->var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) save_var_idx = save_var->var.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) val = tracing_map_read_var(elt, save_var_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) if (save_val->flags & HIST_FIELD_FL_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) seq_printf(m, " %s: %-32s", save_var->var.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) (char *)(uintptr_t)(val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) seq_printf(m, " %s: %10llu", save_var->var.name, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) static void ontrack_action(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) struct tracing_map_elt *elt, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) struct ring_buffer_event *rbe, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) struct action_data *data, u64 *var_ref_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) u64 var_val = var_ref_vals[data->track_data.var_ref->var_ref_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) if (check_track_val(elt, data, var_val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) save_track_val(hist_data, elt, data, var_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) save_track_data(hist_data, elt, rec, rbe, key, data, var_ref_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) static void action_data_destroy(struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) kfree(data->action_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) for (i = 0; i < data->n_params; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) kfree(data->params[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) if (data->synth_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) data->synth_event->ref--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) kfree(data->synth_event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) static void track_data_destroy(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) struct trace_event_file *file = hist_data->event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) destroy_hist_field(data->track_data.track_var, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) if (data->action == ACTION_SNAPSHOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) struct track_data *track_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) track_data = tracing_cond_snapshot_data(file->tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) if (track_data && track_data->hist_data == hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) tracing_snapshot_cond_disable(file->tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) track_data_free(track_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) kfree(data->track_data.var_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) action_data_destroy(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) static int action_create(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) struct action_data *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) static int track_data_create(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) struct hist_field *var_field, *ref_field, *track_var = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) struct trace_event_file *file = hist_data->event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) struct trace_array *tr = file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) char *track_data_var_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) track_data_var_str = data->track_data.var_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) if (track_data_var_str[0] != '$') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) hist_err(tr, HIST_ERR_ONX_NOT_VAR, errpos(track_data_var_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) track_data_var_str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) var_field = find_target_event_var(hist_data, NULL, NULL, track_data_var_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) if (!var_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) hist_err(tr, HIST_ERR_ONX_VAR_NOT_FOUND, errpos(track_data_var_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) ref_field = create_var_ref(hist_data, var_field, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) if (!ref_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) data->track_data.var_ref = ref_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) if (data->handler == HANDLER_ONMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) track_var = create_var(hist_data, file, "__max", sizeof(u64), "u64");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) if (IS_ERR(track_var)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) ret = PTR_ERR(track_var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) if (data->handler == HANDLER_ONCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) track_var = create_var(hist_data, file, "__change", sizeof(u64), "u64");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) if (IS_ERR(track_var)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) ret = PTR_ERR(track_var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) data->track_data.track_var = track_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) ret = action_create(hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) static int parse_action_params(struct trace_array *tr, char *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) char *param, *saved_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) bool first_param = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) while (params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) if (data->n_params >= SYNTH_FIELDS_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) param = strsep(¶ms, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) if (!param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) param = strstrip(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) if (strlen(param) < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) hist_err(tr, HIST_ERR_INVALID_PARAM, errpos(param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) saved_param = kstrdup(param, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) if (!saved_param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) if (first_param && data->use_trace_keyword) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) data->synth_event_name = saved_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) first_param = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) first_param = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) data->params[data->n_params++] = saved_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) static int action_parse(struct trace_array *tr, char *str, struct action_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) enum handler_id handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) char *action_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) strsep(&str, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) if (!str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) action_name = strsep(&str, "(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) if (!action_name || !str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) if (str_has_prefix(action_name, "save")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) char *params = strsep(&str, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) if (!params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) hist_err(tr, HIST_ERR_NO_SAVE_PARAMS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) ret = parse_action_params(tr, params, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) if (handler == HANDLER_ONMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) data->track_data.check_val = check_track_val_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) else if (handler == HANDLER_ONCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) data->track_data.check_val = check_track_val_changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) data->track_data.save_data = save_track_data_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) data->fn = ontrack_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) data->action = ACTION_SAVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) } else if (str_has_prefix(action_name, "snapshot")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) char *params = strsep(&str, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) if (!str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) if (handler == HANDLER_ONMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) data->track_data.check_val = check_track_val_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) else if (handler == HANDLER_ONCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) data->track_data.check_val = check_track_val_changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) data->track_data.save_data = save_track_data_snapshot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) data->fn = ontrack_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) data->action = ACTION_SNAPSHOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) char *params = strsep(&str, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) if (str_has_prefix(action_name, "trace"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) data->use_trace_keyword = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) if (params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) ret = parse_action_params(tr, params, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) if (handler == HANDLER_ONMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) data->track_data.check_val = check_track_val_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) else if (handler == HANDLER_ONCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) data->track_data.check_val = check_track_val_changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) if (handler != HANDLER_ONMATCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) data->track_data.save_data = action_trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) data->fn = ontrack_action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) data->fn = action_trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) data->action = ACTION_TRACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) data->action_name = kstrdup(action_name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) if (!data->action_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) data->handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) static struct action_data *track_data_parse(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) char *str, enum handler_id handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) struct action_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) char *var_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) var_str = strsep(&str, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) if (!var_str || !str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) data->track_data.var_str = kstrdup(var_str, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) if (!data->track_data.var_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) ret = action_parse(hist_data->event_file->tr, str, data, handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) track_data_destroy(hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) data = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) static void onmatch_destroy(struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) kfree(data->match_data.event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) kfree(data->match_data.event_system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) action_data_destroy(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) static void destroy_field_var(struct field_var *field_var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) if (!field_var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) destroy_hist_field(field_var->var, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) destroy_hist_field(field_var->val, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) kfree(field_var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) static void destroy_field_vars(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) for (i = 0; i < hist_data->n_field_vars; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) destroy_field_var(hist_data->field_vars[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) for (i = 0; i < hist_data->n_save_vars; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) destroy_field_var(hist_data->save_vars[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) static void save_field_var(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) struct field_var *field_var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) hist_data->field_vars[hist_data->n_field_vars++] = field_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) if (field_var->val->flags & HIST_FIELD_FL_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) hist_data->n_field_var_str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) static int check_synth_field(struct synth_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) struct hist_field *hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) unsigned int field_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) struct synth_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) if (field_pos >= event->n_fields)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) field = event->fields[field_pos];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) * A dynamic string synth field can accept static or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) * dynamic. A static string synth field can only accept a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) * same-sized static string, which is checked for later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) if (strstr(hist_field->type, "char[") && field->is_string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) && field->is_dynamic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) if (strcmp(field->type, hist_field->type) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) if (field->size != hist_field->size ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) (!field->is_string && field->is_signed != hist_field->is_signed))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) static struct hist_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) trace_action_find_var(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) struct action_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) char *system, char *event, char *var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) var++; /* skip '$' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) hist_field = find_target_event_var(hist_data, system, event, var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) if (!hist_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) if (!system && data->handler == HANDLER_ONMATCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) system = data->match_data.event_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) event = data->match_data.event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) hist_field = find_event_var(hist_data, system, event, var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) if (!hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, errpos(var));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) static struct hist_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) trace_action_create_field_var(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) struct action_data *data, char *system,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) char *event, char *var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) struct hist_field *hist_field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) struct field_var *field_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) * First try to create a field var on the target event (the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) * currently being defined). This will create a variable for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) * unqualified fields on the target event, or if qualified,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) * target fields that have qualified names matching the target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) field_var = create_target_field_var(hist_data, system, event, var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) if (field_var && !IS_ERR(field_var)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) save_field_var(hist_data, field_var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) hist_field = field_var->var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) field_var = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) * If no explicit system.event is specfied, default to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) * looking for fields on the onmatch(system.event.xxx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) * event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) if (!system && data->handler == HANDLER_ONMATCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) system = data->match_data.event_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) event = data->match_data.event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) * At this point, we're looking at a field on another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) * event. Because we can't modify a hist trigger on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) * another event to add a variable for a field, we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) * to create a new trigger on that event and create the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) * variable at the same time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) hist_field = create_field_var_hist(hist_data, system, event, var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) if (IS_ERR(hist_field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) return hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) destroy_field_var(field_var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) hist_field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) static int trace_action_create(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) char *event_name, *param, *system = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) struct hist_field *hist_field, *var_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) unsigned int field_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) struct synth_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) char *synth_event_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) int var_ref_idx, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) if (data->use_trace_keyword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) synth_event_name = data->synth_event_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) synth_event_name = data->action_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) event = find_synth_event(synth_event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) if (!event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) hist_err(tr, HIST_ERR_SYNTH_EVENT_NOT_FOUND, errpos(synth_event_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) event->ref++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) for (i = 0; i < data->n_params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) p = param = kstrdup(data->params[i], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) if (!param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) system = strsep(¶m, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) if (!param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) param = (char *)system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) system = event_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) event_name = strsep(¶m, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) if (!param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) if (param[0] == '$')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) hist_field = trace_action_find_var(hist_data, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) system, event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) hist_field = trace_action_create_field_var(hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) system,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) if (!hist_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) if (check_synth_field(event, hist_field, field_pos) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) var_ref = create_var_ref(hist_data, hist_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) system, event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) if (!var_ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) var_ref_idx = find_var_ref_idx(hist_data, var_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) if (WARN_ON(var_ref_idx < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) ret = var_ref_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) data->var_ref_idx[i] = var_ref_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) field_pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) hist_err(tr, HIST_ERR_SYNTH_TYPE_MISMATCH, errpos(param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) if (field_pos != event->n_fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) hist_err(tr, HIST_ERR_SYNTH_COUNT_MISMATCH, errpos(event->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) data->synth_event = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) event->ref--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) static int action_create(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) struct trace_event_file *file = hist_data->event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) struct trace_array *tr = file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) struct track_data *track_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) struct field_var *field_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) char *param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) if (data->action == ACTION_TRACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) return trace_action_create(hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) if (data->action == ACTION_SNAPSHOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) track_data = track_data_alloc(hist_data->key_size, data, hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) if (IS_ERR(track_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) ret = PTR_ERR(track_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) ret = tracing_snapshot_cond_enable(file->tr, track_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) cond_snapshot_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) track_data_free(track_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) if (data->action == ACTION_SAVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) if (hist_data->n_save_vars) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) hist_err(tr, HIST_ERR_TOO_MANY_SAVE_ACTIONS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) for (i = 0; i < data->n_params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) param = kstrdup(data->params[i], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) if (!param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) field_var = create_target_field_var(hist_data, NULL, NULL, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) if (IS_ERR(field_var)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) hist_err(tr, HIST_ERR_FIELD_VAR_CREATE_FAIL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) errpos(param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) ret = PTR_ERR(field_var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) kfree(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) hist_data->save_vars[hist_data->n_save_vars++] = field_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) if (field_var->val->flags & HIST_FIELD_FL_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) hist_data->n_save_var_str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) kfree(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) static int onmatch_create(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) return action_create(hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) static struct action_data *onmatch_parse(struct trace_array *tr, char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) char *match_event, *match_event_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) struct action_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) data = kzalloc(sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) match_event = strsep(&str, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) if (!match_event || !str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(match_event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) match_event_system = strsep(&match_event, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) if (!match_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) hist_err(tr, HIST_ERR_SUBSYS_NOT_FOUND, errpos(match_event_system));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) if (IS_ERR(event_file(tr, match_event_system, match_event))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) hist_err(tr, HIST_ERR_INVALID_SUBSYS_EVENT, errpos(match_event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) data->match_data.event = kstrdup(match_event, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) if (!data->match_data.event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) data->match_data.event_system = kstrdup(match_event_system, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) if (!data->match_data.event_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) ret = action_parse(tr, str, data, HANDLER_ONMATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) onmatch_destroy(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) data = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) static int create_hitcount_val(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) hist_data->fields[HITCOUNT_IDX] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) create_hist_field(hist_data, NULL, HIST_FIELD_FL_HITCOUNT, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) if (!hist_data->fields[HITCOUNT_IDX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) hist_data->n_vals++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) hist_data->n_fields++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) static int __create_val_field(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) unsigned int val_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) char *var_name, char *field_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) hist_field = parse_expr(hist_data, file, field_str, flags, var_name, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) if (IS_ERR(hist_field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) ret = PTR_ERR(hist_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) hist_data->fields[val_idx] = hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) ++hist_data->n_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) ++hist_data->n_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) static int create_val_field(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) unsigned int val_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) char *field_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) return __create_val_field(hist_data, val_idx, file, NULL, field_str, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) static int create_var_field(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) unsigned int val_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) char *var_name, char *expr_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) if (find_var(hist_data, file, var_name) && !hist_data->remove) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) hist_err(tr, HIST_ERR_DUPLICATE_VAR, errpos(var_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) flags |= HIST_FIELD_FL_VAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) hist_data->n_vars++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) if (WARN_ON(hist_data->n_vars > TRACING_MAP_VARS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) ret = __create_val_field(hist_data, val_idx, file, var_name, expr_str, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) if (!ret && hist_data->fields[val_idx]->flags & HIST_FIELD_FL_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) hist_data->fields[val_idx]->var_str_idx = hist_data->n_var_str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) static int create_val_fields(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) char *fields_str, *field_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) unsigned int i, j = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) ret = create_hitcount_val(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) fields_str = hist_data->attrs->vals_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) if (!fields_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) for (i = 0, j = 1; i < TRACING_MAP_VALS_MAX &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) j < TRACING_MAP_VALS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) field_str = strsep(&fields_str, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) if (!field_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) if (strcmp(field_str, "hitcount") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) ret = create_val_field(hist_data, j++, file, field_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) if (fields_str && (strcmp(fields_str, "hitcount") != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) static int create_key_field(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) unsigned int key_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) unsigned int key_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) char *field_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) struct hist_field *hist_field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) unsigned int key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) if (WARN_ON(key_idx >= HIST_FIELDS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) flags |= HIST_FIELD_FL_KEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) if (strcmp(field_str, "stacktrace") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) flags |= HIST_FIELD_FL_STACKTRACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) key_size = sizeof(unsigned long) * HIST_STACKTRACE_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) hist_field = create_hist_field(hist_data, NULL, flags, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) hist_field = parse_expr(hist_data, file, field_str, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) if (IS_ERR(hist_field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) ret = PTR_ERR(hist_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) if (field_has_hist_vars(hist_field, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) hist_err(tr, HIST_ERR_INVALID_REF_KEY, errpos(field_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) destroy_hist_field(hist_field, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) key_size = hist_field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) hist_data->fields[key_idx] = hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) key_size = ALIGN(key_size, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) hist_data->fields[key_idx]->size = key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) hist_data->fields[key_idx]->offset = key_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) hist_data->key_size += key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) if (hist_data->key_size > HIST_KEY_SIZE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) hist_data->n_keys++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) hist_data->n_fields++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) if (WARN_ON(hist_data->n_keys > TRACING_MAP_KEYS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) ret = key_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) static int create_key_fields(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) unsigned int i, key_offset = 0, n_vals = hist_data->n_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) char *fields_str, *field_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) fields_str = hist_data->attrs->keys_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) if (!fields_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) for (i = n_vals; i < n_vals + TRACING_MAP_KEYS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) field_str = strsep(&fields_str, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) if (!field_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) ret = create_key_field(hist_data, i, key_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) file, field_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) key_offset += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) if (fields_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) static int create_var_fields(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) unsigned int i, j = hist_data->n_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) unsigned int n_vars = hist_data->attrs->var_defs.n_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) for (i = 0; i < n_vars; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) char *var_name = hist_data->attrs->var_defs.name[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) char *expr = hist_data->attrs->var_defs.expr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) ret = create_var_field(hist_data, j++, file, var_name, expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) static void free_var_defs(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) for (i = 0; i < hist_data->attrs->var_defs.n_vars; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) kfree(hist_data->attrs->var_defs.name[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) kfree(hist_data->attrs->var_defs.expr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) hist_data->attrs->var_defs.n_vars = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) static int parse_var_defs(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) char *s, *str, *var_name, *field_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) unsigned int i, j, n_vars = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) for (i = 0; i < hist_data->attrs->n_assignments; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) str = hist_data->attrs->assignment_str[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) for (j = 0; j < TRACING_MAP_VARS_MAX; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) field_str = strsep(&str, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) if (!field_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) var_name = strsep(&field_str, "=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) if (!var_name || !field_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) hist_err(tr, HIST_ERR_MALFORMED_ASSIGNMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) errpos(var_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) if (n_vars == TRACING_MAP_VARS_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(var_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) s = kstrdup(var_name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) if (!s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) hist_data->attrs->var_defs.name[n_vars] = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) s = kstrdup(field_str, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) if (!s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) hist_data->attrs->var_defs.expr[n_vars++] = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) hist_data->attrs->var_defs.n_vars = n_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) free_var_defs(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) static int create_hist_fields(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) ret = parse_var_defs(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) ret = create_val_fields(hist_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) ret = create_var_fields(hist_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) ret = create_key_fields(hist_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) free_var_defs(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) static int is_descending(struct trace_array *tr, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) if (strcmp(str, "descending") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) if (strcmp(str, "ascending") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) hist_err(tr, HIST_ERR_INVALID_SORT_MODIFIER, errpos((char *)str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) static int create_sort_keys(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) char *fields_str = hist_data->attrs->sort_key_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) struct tracing_map_sort_key *sort_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) int descending, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) unsigned int i, j, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) hist_data->n_sort_keys = 1; /* we always have at least one, hitcount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) if (!fields_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) for (i = 0; i < TRACING_MAP_SORT_KEYS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) char *field_str, *field_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) const char *test_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) sort_key = &hist_data->sort_keys[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) field_str = strsep(&fields_str, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) if (!field_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) if (!*field_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) hist_err(tr, HIST_ERR_EMPTY_SORT_FIELD, errpos("sort="));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) if ((i == TRACING_MAP_SORT_KEYS_MAX - 1) && fields_str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) hist_err(tr, HIST_ERR_TOO_MANY_SORT_FIELDS, errpos("sort="));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) field_name = strsep(&field_str, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) if (!field_name || !*field_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) hist_err(tr, HIST_ERR_EMPTY_SORT_FIELD, errpos("sort="));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) if (strcmp(field_name, "hitcount") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) descending = is_descending(tr, field_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) if (descending < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) ret = descending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) sort_key->descending = descending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) for (j = 1, k = 1; j < hist_data->n_fields; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) hist_field = hist_data->fields[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) if (hist_field->flags & HIST_FIELD_FL_VAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) idx = k++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) test_name = hist_field_name(hist_field, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) if (strcmp(field_name, test_name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) sort_key->field_idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) descending = is_descending(tr, field_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) if (descending < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) ret = descending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) sort_key->descending = descending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) if (j == hist_data->n_fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) hist_err(tr, HIST_ERR_INVALID_SORT_FIELD, errpos(field_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) hist_data->n_sort_keys = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) static void destroy_actions(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) for (i = 0; i < hist_data->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) struct action_data *data = hist_data->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) if (data->handler == HANDLER_ONMATCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) onmatch_destroy(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) else if (data->handler == HANDLER_ONMAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) data->handler == HANDLER_ONCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) track_data_destroy(hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) static int parse_actions(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) struct trace_array *tr = hist_data->event_file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) struct action_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) for (i = 0; i < hist_data->attrs->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) str = hist_data->attrs->action_str[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) if ((len = str_has_prefix(str, "onmatch("))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) char *action_str = str + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) data = onmatch_parse(tr, action_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) if (IS_ERR(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) ret = PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) } else if ((len = str_has_prefix(str, "onmax("))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) char *action_str = str + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) data = track_data_parse(hist_data, action_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) HANDLER_ONMAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) if (IS_ERR(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) ret = PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) } else if ((len = str_has_prefix(str, "onchange("))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) char *action_str = str + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) data = track_data_parse(hist_data, action_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) HANDLER_ONCHANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) if (IS_ERR(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) ret = PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) hist_data->actions[hist_data->n_actions++] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) static int create_actions(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) struct action_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) for (i = 0; i < hist_data->attrs->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) data = hist_data->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) if (data->handler == HANDLER_ONMATCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) ret = onmatch_create(hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) } else if (data->handler == HANDLER_ONMAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) data->handler == HANDLER_ONCHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) ret = track_data_create(hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) static void print_actions(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) struct tracing_map_elt *elt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) for (i = 0; i < hist_data->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) struct action_data *data = hist_data->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) if (data->action == ACTION_SNAPSHOT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) if (data->handler == HANDLER_ONMAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) data->handler == HANDLER_ONCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) track_data_print(m, hist_data, elt, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) static void print_action_spec(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) if (data->action == ACTION_SAVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) for (i = 0; i < hist_data->n_save_vars; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) seq_printf(m, "%s", hist_data->save_vars[i]->var->var.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) if (i < hist_data->n_save_vars - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) seq_puts(m, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) } else if (data->action == ACTION_TRACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) if (data->use_trace_keyword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) seq_printf(m, "%s", data->synth_event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) for (i = 0; i < data->n_params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) if (i || data->use_trace_keyword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) seq_puts(m, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) seq_printf(m, "%s", data->params[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) static void print_track_data_spec(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) if (data->handler == HANDLER_ONMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) seq_puts(m, ":onmax(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) else if (data->handler == HANDLER_ONCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) seq_puts(m, ":onchange(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) seq_printf(m, "%s", data->track_data.var_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) seq_printf(m, ").%s(", data->action_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) print_action_spec(m, hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) seq_puts(m, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) static void print_onmatch_spec(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) struct action_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) seq_printf(m, ":onmatch(%s.%s).", data->match_data.event_system,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) data->match_data.event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) seq_printf(m, "%s(", data->action_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) print_action_spec(m, hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) seq_puts(m, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) static bool actions_match(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) struct hist_trigger_data *hist_data_test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) if (hist_data->n_actions != hist_data_test->n_actions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) for (i = 0; i < hist_data->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) struct action_data *data = hist_data->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) struct action_data *data_test = hist_data_test->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) char *action_name, *action_name_test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) if (data->handler != data_test->handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) if (data->action != data_test->action)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) if (data->n_params != data_test->n_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) for (j = 0; j < data->n_params; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) if (strcmp(data->params[j], data_test->params[j]) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) if (data->use_trace_keyword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) action_name = data->synth_event_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) action_name = data->action_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) if (data_test->use_trace_keyword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) action_name_test = data_test->synth_event_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) action_name_test = data_test->action_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) if (strcmp(action_name, action_name_test) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) if (data->handler == HANDLER_ONMATCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) if (strcmp(data->match_data.event_system,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) data_test->match_data.event_system) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) if (strcmp(data->match_data.event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) data_test->match_data.event) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) } else if (data->handler == HANDLER_ONMAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) data->handler == HANDLER_ONCHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) if (strcmp(data->track_data.var_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) data_test->track_data.var_str) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) static void print_actions_spec(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) for (i = 0; i < hist_data->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) struct action_data *data = hist_data->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) if (data->handler == HANDLER_ONMATCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) print_onmatch_spec(m, hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) else if (data->handler == HANDLER_ONMAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) data->handler == HANDLER_ONCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) print_track_data_spec(m, hist_data, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) static void destroy_field_var_hists(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) for (i = 0; i < hist_data->n_field_var_hists; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) kfree(hist_data->field_var_hists[i]->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) kfree(hist_data->field_var_hists[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) static void destroy_hist_data(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) if (!hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) destroy_hist_trigger_attrs(hist_data->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) destroy_hist_fields(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) tracing_map_destroy(hist_data->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) destroy_actions(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) destroy_field_vars(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) destroy_field_var_hists(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) kfree(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) static int create_tracing_map_fields(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) struct tracing_map *map = hist_data->map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) struct ftrace_event_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) int i, idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) for_each_hist_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) hist_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) if (hist_field->flags & HIST_FIELD_FL_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) tracing_map_cmp_fn_t cmp_fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) field = hist_field->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) cmp_fn = tracing_map_cmp_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) else if (!field || hist_field->flags & HIST_FIELD_FL_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) cmp_fn = tracing_map_cmp_num(hist_field->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) hist_field->is_signed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) else if (is_string_field(field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) cmp_fn = tracing_map_cmp_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) cmp_fn = tracing_map_cmp_num(field->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) field->is_signed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) idx = tracing_map_add_key_field(map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) hist_field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) cmp_fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) } else if (!(hist_field->flags & HIST_FIELD_FL_VAR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) idx = tracing_map_add_sum_field(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) if (hist_field->flags & HIST_FIELD_FL_VAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) idx = tracing_map_add_var(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) hist_field->var.idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) hist_field->var.hist_data = hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) static struct hist_trigger_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) create_hist_data(unsigned int map_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) struct hist_trigger_attrs *attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) bool remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) const struct tracing_map_ops *map_ops = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) hist_data = kzalloc(sizeof(*hist_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) if (!hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) hist_data->attrs = attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) hist_data->remove = remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) hist_data->event_file = file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) ret = parse_actions(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) ret = create_hist_fields(hist_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) ret = create_sort_keys(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) map_ops = &hist_trigger_elt_data_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) hist_data->map = tracing_map_create(map_bits, hist_data->key_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) map_ops, hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) if (IS_ERR(hist_data->map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) ret = PTR_ERR(hist_data->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) hist_data->map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) ret = create_tracing_map_fields(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) return hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) hist_data->attrs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) destroy_hist_data(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) hist_data = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) struct tracing_map_elt *elt, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) struct ring_buffer_event *rbe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) u64 *var_ref_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) struct hist_elt_data *elt_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) struct hist_field *hist_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) unsigned int i, var_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) u64 hist_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) elt_data = elt->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) elt_data->var_ref_vals = var_ref_vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) for_each_hist_val_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) hist_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) hist_val = hist_field->fn(hist_field, elt, rbe, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) if (hist_field->flags & HIST_FIELD_FL_VAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) var_idx = hist_field->var.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) if (hist_field->flags & HIST_FIELD_FL_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) unsigned int str_start, var_str_idx, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) char *str, *val_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) str_start = hist_data->n_field_var_str +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) hist_data->n_save_var_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) var_str_idx = hist_field->var_str_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) idx = str_start + var_str_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) str = elt_data->field_var_str[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) val_str = (char *)(uintptr_t)hist_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) size = min(hist_field->size, STR_VAR_LEN_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) strscpy(str, val_str, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) hist_val = (u64)(uintptr_t)str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) tracing_map_set_var(elt, var_idx, hist_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) tracing_map_update_sum(elt, i, hist_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) for_each_hist_key_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) hist_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) if (hist_field->flags & HIST_FIELD_FL_VAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) hist_val = hist_field->fn(hist_field, elt, rbe, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) var_idx = hist_field->var.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) tracing_map_set_var(elt, var_idx, hist_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) update_field_vars(hist_data, elt, rbe, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) static inline void add_to_key(char *compound_key, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) struct hist_field *key_field, void *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) size_t size = key_field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) if (key_field->flags & HIST_FIELD_FL_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) struct ftrace_event_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) field = key_field->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) if (field->filter_type == FILTER_DYN_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) size = *(u32 *)(rec + field->offset) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) else if (field->filter_type == FILTER_STATIC_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) size = field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) /* ensure NULL-termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) if (size > key_field->size - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) size = key_field->size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) strncpy(compound_key + key_field->offset, (char *)key, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) memcpy(compound_key + key_field->offset, key, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) hist_trigger_actions(struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) struct tracing_map_elt *elt, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) struct ring_buffer_event *rbe, void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) u64 *var_ref_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) struct action_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) for (i = 0; i < hist_data->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) data = hist_data->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) data->fn(hist_data, elt, rec, rbe, key, data, var_ref_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) static void event_hist_trigger(struct event_trigger_data *data, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) struct ring_buffer_event *rbe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) struct hist_trigger_data *hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) bool use_compound_key = (hist_data->n_keys > 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) unsigned long entries[HIST_STACKTRACE_DEPTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) u64 var_ref_vals[TRACING_MAP_VARS_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) char compound_key[HIST_KEY_SIZE_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) struct tracing_map_elt *elt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) struct hist_field *key_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) u64 field_contents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) void *key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) memset(compound_key, 0, hist_data->key_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) for_each_hist_key_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) key_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) memset(entries, 0, HIST_STACKTRACE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) stack_trace_save(entries, HIST_STACKTRACE_DEPTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) HIST_STACKTRACE_SKIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) key = entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) field_contents = key_field->fn(key_field, elt, rbe, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) if (key_field->flags & HIST_FIELD_FL_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) key = (void *)(unsigned long)field_contents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) use_compound_key = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) key = (void *)&field_contents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) if (use_compound_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) add_to_key(compound_key, key, key_field, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) if (use_compound_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) key = compound_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) if (hist_data->n_var_refs &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) !resolve_var_refs(hist_data, key, var_ref_vals, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) elt = tracing_map_insert(hist_data->map, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) if (!elt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) hist_trigger_elt_update(hist_data, elt, rec, rbe, var_ref_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) if (resolve_var_refs(hist_data, key, var_ref_vals, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) hist_trigger_actions(hist_data, elt, rec, rbe, key, var_ref_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) static void hist_trigger_stacktrace_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) unsigned long *stacktrace_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) unsigned int max_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) char str[KSYM_SYMBOL_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) unsigned int spaces = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) for (i = 0; i < max_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) if (!stacktrace_entries[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) seq_printf(m, "%*c", 1 + spaces, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) sprint_symbol(str, stacktrace_entries[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) seq_printf(m, "%s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) static void hist_trigger_print_key(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) struct tracing_map_elt *elt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) struct hist_field *key_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) char str[KSYM_SYMBOL_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) bool multiline = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) const char *field_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) u64 uval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) seq_puts(m, "{ ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) for_each_hist_key_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) key_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) if (i > hist_data->n_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) seq_puts(m, ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) field_name = hist_field_name(key_field, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) if (key_field->flags & HIST_FIELD_FL_HEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) uval = *(u64 *)(key + key_field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) seq_printf(m, "%s: %llx", field_name, uval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) } else if (key_field->flags & HIST_FIELD_FL_SYM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) uval = *(u64 *)(key + key_field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) sprint_symbol_no_offset(str, uval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) seq_printf(m, "%s: [%llx] %-45s", field_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) uval, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) } else if (key_field->flags & HIST_FIELD_FL_SYM_OFFSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) uval = *(u64 *)(key + key_field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) sprint_symbol(str, uval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) seq_printf(m, "%s: [%llx] %-55s", field_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) uval, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) } else if (key_field->flags & HIST_FIELD_FL_EXECNAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) struct hist_elt_data *elt_data = elt->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) char *comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) if (WARN_ON_ONCE(!elt_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) comm = elt_data->comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) uval = *(u64 *)(key + key_field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) seq_printf(m, "%s: %-16s[%10llu]", field_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) comm, uval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) } else if (key_field->flags & HIST_FIELD_FL_SYSCALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) const char *syscall_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) uval = *(u64 *)(key + key_field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) syscall_name = get_syscall_name(uval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) if (!syscall_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) syscall_name = "unknown_syscall";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) seq_printf(m, "%s: %-30s[%3llu]", field_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) syscall_name, uval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) } else if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) seq_puts(m, "stacktrace:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) hist_trigger_stacktrace_print(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) key + key_field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) HIST_STACKTRACE_DEPTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) multiline = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) } else if (key_field->flags & HIST_FIELD_FL_LOG2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) seq_printf(m, "%s: ~ 2^%-2llu", field_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) *(u64 *)(key + key_field->offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) } else if (key_field->flags & HIST_FIELD_FL_STRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) seq_printf(m, "%s: %-50s", field_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) (char *)(key + key_field->offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) uval = *(u64 *)(key + key_field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) seq_printf(m, "%s: %10llu", field_name, uval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) if (!multiline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) seq_puts(m, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) seq_puts(m, "}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) static void hist_trigger_entry_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) struct hist_trigger_data *hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) void *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) struct tracing_map_elt *elt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) const char *field_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) hist_trigger_print_key(m, hist_data, key, elt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) seq_printf(m, " hitcount: %10llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) tracing_map_read_sum(elt, HITCOUNT_IDX));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) for (i = 1; i < hist_data->n_vals; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) field_name = hist_field_name(hist_data->fields[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) if (hist_data->fields[i]->flags & HIST_FIELD_FL_VAR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) hist_data->fields[i]->flags & HIST_FIELD_FL_EXPR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) seq_printf(m, " %s: %10llx", field_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) tracing_map_read_sum(elt, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) seq_printf(m, " %s: %10llu", field_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) tracing_map_read_sum(elt, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) print_actions(m, hist_data, elt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) seq_puts(m, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) static int print_entries(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) struct tracing_map_sort_entry **sort_entries = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) struct tracing_map *map = hist_data->map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) int i, n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) n_entries = tracing_map_sort_entries(map, hist_data->sort_keys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) hist_data->n_sort_keys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) &sort_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) if (n_entries < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) return n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) for (i = 0; i < n_entries; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) hist_trigger_entry_print(m, hist_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) sort_entries[i]->key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) sort_entries[i]->elt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) tracing_map_destroy_sort_entries(sort_entries, n_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) return n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) static void hist_trigger_show(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) struct event_trigger_data *data, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) int n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) if (n > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) seq_puts(m, "\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) seq_puts(m, "# event histogram\n#\n# trigger info: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) data->ops->print(m, data->ops, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) seq_puts(m, "#\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) n_entries = print_entries(m, hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) if (n_entries < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) n_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) track_data_snapshot_print(m, hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) seq_printf(m, "\nTotals:\n Hits: %llu\n Entries: %u\n Dropped: %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) (u64)atomic64_read(&hist_data->map->hits),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) n_entries, (u64)atomic64_read(&hist_data->map->drops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) static int hist_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) struct event_trigger_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) struct trace_event_file *event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) int n = 0, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) mutex_lock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) event_file = event_file_data(m->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) if (unlikely(!event_file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) list_for_each_entry(data, &event_file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) if (data->cmd_ops->trigger_type == ETT_EVENT_HIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) hist_trigger_show(m, data, n++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) mutex_unlock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) static int event_hist_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) ret = security_locked_down(LOCKDOWN_TRACEFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) return single_open(file, hist_show, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) const struct file_operations event_hist_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) .open = event_hist_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) .release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) #ifdef CONFIG_HIST_TRIGGERS_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) static void hist_field_debug_show_flags(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) seq_puts(m, " flags:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) if (flags & HIST_FIELD_FL_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) seq_puts(m, " HIST_FIELD_FL_KEY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) else if (flags & HIST_FIELD_FL_HITCOUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) seq_puts(m, " VAL: HIST_FIELD_FL_HITCOUNT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) else if (flags & HIST_FIELD_FL_VAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) seq_puts(m, " HIST_FIELD_FL_VAR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) else if (flags & HIST_FIELD_FL_VAR_REF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) seq_puts(m, " HIST_FIELD_FL_VAR_REF\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) seq_puts(m, " VAL: normal u64 value\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) if (flags & HIST_FIELD_FL_ALIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) seq_puts(m, " HIST_FIELD_FL_ALIAS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) static int hist_field_debug_show(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) struct hist_field *field, unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) if ((field->flags & flags) != flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) seq_printf(m, "ERROR: bad flags - %lx\n", flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) hist_field_debug_show_flags(m, field->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) if (field->field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) seq_printf(m, " ftrace_event_field name: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) field->field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) if (field->flags & HIST_FIELD_FL_VAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) seq_printf(m, " var.name: %s\n", field->var.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) seq_printf(m, " var.idx (into tracing_map_elt.vars[]): %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) field->var.idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) if (field->flags & HIST_FIELD_FL_ALIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) seq_printf(m, " var_ref_idx (into hist_data->var_refs[]): %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) field->var_ref_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) if (field->flags & HIST_FIELD_FL_VAR_REF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) seq_printf(m, " name: %s\n", field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) seq_printf(m, " var.idx (into tracing_map_elt.vars[]): %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) field->var.idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) seq_printf(m, " var.hist_data: %p\n", field->var.hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) seq_printf(m, " var_ref_idx (into hist_data->var_refs[]): %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) field->var_ref_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) if (field->system)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) seq_printf(m, " system: %s\n", field->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) if (field->event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) seq_printf(m, " event_name: %s\n", field->event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) seq_printf(m, " type: %s\n", field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) seq_printf(m, " size: %u\n", field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) seq_printf(m, " is_signed: %u\n", field->is_signed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) static int field_var_debug_show(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) struct field_var *field_var, unsigned int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) bool save_vars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) const char *vars_name = save_vars ? "save_vars" : "field_vars";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) struct hist_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) seq_printf(m, "\n hist_data->%s[%d]:\n", vars_name, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) field = field_var->var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) seq_printf(m, "\n %s[%d].var:\n", vars_name, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) hist_field_debug_show_flags(m, field->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) seq_printf(m, " var.name: %s\n", field->var.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) seq_printf(m, " var.idx (into tracing_map_elt.vars[]): %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) field->var.idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) field = field_var->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) seq_printf(m, "\n %s[%d].val:\n", vars_name, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) if (field->field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) seq_printf(m, " ftrace_event_field name: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) field->field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) seq_printf(m, " type: %s\n", field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) seq_printf(m, " size: %u\n", field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) seq_printf(m, " is_signed: %u\n", field->is_signed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) static int hist_action_debug_show(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) struct action_data *data, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) if (data->handler == HANDLER_ONMAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) data->handler == HANDLER_ONCHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) seq_printf(m, "\n hist_data->actions[%d].track_data.var_ref:\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) ret = hist_field_debug_show(m, data->track_data.var_ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) HIST_FIELD_FL_VAR_REF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) seq_printf(m, "\n hist_data->actions[%d].track_data.track_var:\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) ret = hist_field_debug_show(m, data->track_data.track_var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) HIST_FIELD_FL_VAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) if (data->handler == HANDLER_ONMATCH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) seq_printf(m, "\n hist_data->actions[%d].match_data.event_system: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) i, data->match_data.event_system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) seq_printf(m, " hist_data->actions[%d].match_data.event: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) i, data->match_data.event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) static int hist_actions_debug_show(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) if (hist_data->n_actions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) seq_puts(m, "\n action tracking variables (for onmax()/onchange()/onmatch()):\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) for (i = 0; i < hist_data->n_actions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) struct action_data *action = hist_data->actions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) ret = hist_action_debug_show(m, action, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) if (hist_data->n_save_vars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) seq_puts(m, "\n save action variables (save() params):\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) for (i = 0; i < hist_data->n_save_vars; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) ret = field_var_debug_show(m, hist_data->save_vars[i], i, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) static void hist_trigger_debug_show(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) struct event_trigger_data *data, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) if (n > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) seq_puts(m, "\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) seq_puts(m, "# event histogram\n#\n# trigger info: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) data->ops->print(m, data->ops, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) seq_puts(m, "#\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) seq_printf(m, "hist_data: %p\n\n", hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) seq_printf(m, " n_vals: %u\n", hist_data->n_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) seq_printf(m, " n_keys: %u\n", hist_data->n_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) seq_printf(m, " n_fields: %u\n", hist_data->n_fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) seq_puts(m, "\n val fields:\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) seq_puts(m, " hist_data->fields[0]:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) ret = hist_field_debug_show(m, hist_data->fields[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) HIST_FIELD_FL_HITCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) for (i = 1; i < hist_data->n_vals; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) seq_printf(m, "\n hist_data->fields[%d]:\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) ret = hist_field_debug_show(m, hist_data->fields[i], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) seq_puts(m, "\n key fields:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) for (i = hist_data->n_vals; i < hist_data->n_fields; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) seq_printf(m, "\n hist_data->fields[%d]:\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) ret = hist_field_debug_show(m, hist_data->fields[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) HIST_FIELD_FL_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) if (hist_data->n_var_refs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) seq_puts(m, "\n variable reference fields:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) for (i = 0; i < hist_data->n_var_refs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) seq_printf(m, "\n hist_data->var_refs[%d]:\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) ret = hist_field_debug_show(m, hist_data->var_refs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) HIST_FIELD_FL_VAR_REF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) if (hist_data->n_field_vars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) seq_puts(m, "\n field variables:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) for (i = 0; i < hist_data->n_field_vars; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) ret = field_var_debug_show(m, hist_data->field_vars[i], i, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) ret = hist_actions_debug_show(m, hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) static int hist_debug_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) struct event_trigger_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) struct trace_event_file *event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) int n = 0, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) mutex_lock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) event_file = event_file_data(m->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) if (unlikely(!event_file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) list_for_each_entry(data, &event_file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) if (data->cmd_ops->trigger_type == ETT_EVENT_HIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) hist_trigger_debug_show(m, data, n++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) mutex_unlock(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) static int event_hist_debug_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) ret = security_locked_down(LOCKDOWN_TRACEFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) return single_open(file, hist_debug_show, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) const struct file_operations event_hist_debug_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) .open = event_hist_debug_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) .release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) const char *field_name = hist_field_name(hist_field, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) if (hist_field->var.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) seq_printf(m, "%s=", hist_field->var.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) if (hist_field->flags & HIST_FIELD_FL_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) seq_puts(m, "common_cpu");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) else if (field_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) if (hist_field->flags & HIST_FIELD_FL_VAR_REF ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) hist_field->flags & HIST_FIELD_FL_ALIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) seq_putc(m, '$');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) seq_printf(m, "%s", field_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) } else if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) seq_puts(m, "common_timestamp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) if (hist_field->flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) if (!(hist_field->flags & HIST_FIELD_FL_VAR_REF) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) !(hist_field->flags & HIST_FIELD_FL_EXPR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) const char *flags = get_hist_field_flags(hist_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) seq_printf(m, ".%s", flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) static int event_hist_trigger_print(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) struct event_trigger_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) struct event_trigger_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) struct hist_trigger_data *hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) struct hist_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) bool have_var = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) seq_puts(m, "hist:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) if (data->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) seq_printf(m, "%s:", data->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) seq_puts(m, "keys=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) for_each_hist_key_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) if (i > hist_data->n_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) seq_puts(m, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) if (field->flags & HIST_FIELD_FL_STACKTRACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) seq_puts(m, "stacktrace");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) hist_field_print(m, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) seq_puts(m, ":vals=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) for_each_hist_val_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) if (field->flags & HIST_FIELD_FL_VAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) have_var = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) if (i == HITCOUNT_IDX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) seq_puts(m, "hitcount");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) seq_puts(m, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) hist_field_print(m, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) if (have_var) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) unsigned int n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) seq_puts(m, ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) for_each_hist_val_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) if (field->flags & HIST_FIELD_FL_VAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) if (n++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) seq_puts(m, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) hist_field_print(m, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) seq_puts(m, ":sort=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) for (i = 0; i < hist_data->n_sort_keys; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) struct tracing_map_sort_key *sort_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) unsigned int idx, first_key_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) /* skip VAR vals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) first_key_idx = hist_data->n_vals - hist_data->n_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) sort_key = &hist_data->sort_keys[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) idx = sort_key->field_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) if (WARN_ON(idx >= HIST_FIELDS_MAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) if (i > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) seq_puts(m, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) if (idx == HITCOUNT_IDX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) seq_puts(m, "hitcount");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) if (idx >= first_key_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) idx += hist_data->n_vars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) hist_field_print(m, hist_data->fields[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) if (sort_key->descending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) seq_puts(m, ".descending");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) if (hist_data->enable_timestamps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) seq_printf(m, ":clock=%s", hist_data->attrs->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) print_actions_spec(m, hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) if (data->filter_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) seq_printf(m, " if %s", data->filter_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) if (data->paused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) seq_puts(m, " [paused]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) seq_puts(m, " [active]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) static int event_hist_trigger_init(struct event_trigger_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) struct event_trigger_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) struct hist_trigger_data *hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) if (!data->ref && hist_data->attrs->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) save_named_trigger(hist_data->attrs->name, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) data->ref++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) static void unregister_field_var_hists(struct hist_trigger_data *hist_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) struct trace_event_file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) char *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) for (i = 0; i < hist_data->n_field_var_hists; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) file = hist_data->field_var_hists[i]->hist_data->event_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) cmd = hist_data->field_var_hists[i]->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) ret = event_hist_trigger_func(&trigger_hist_cmd, file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) "!hist", "hist", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) static void event_hist_trigger_free(struct event_trigger_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) struct event_trigger_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) struct hist_trigger_data *hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) if (WARN_ON_ONCE(data->ref <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) data->ref--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) if (!data->ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) if (data->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) del_named_trigger(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) trigger_data_free(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) remove_hist_vars(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) unregister_field_var_hists(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) destroy_hist_data(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) static struct event_trigger_ops event_hist_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) .func = event_hist_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) .print = event_hist_trigger_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) .init = event_hist_trigger_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) .free = event_hist_trigger_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) static int event_hist_trigger_named_init(struct event_trigger_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) struct event_trigger_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) data->ref++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) save_named_trigger(data->named_data->name, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) event_hist_trigger_init(ops, data->named_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) static void event_hist_trigger_named_free(struct event_trigger_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) struct event_trigger_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) if (WARN_ON_ONCE(data->ref <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) event_hist_trigger_free(ops, data->named_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) data->ref--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) if (!data->ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) del_named_trigger(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) trigger_data_free(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) static struct event_trigger_ops event_hist_trigger_named_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) .func = event_hist_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) .print = event_hist_trigger_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) .init = event_hist_trigger_named_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) .free = event_hist_trigger_named_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) static struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) char *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) return &event_hist_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) static void hist_clear(struct event_trigger_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) struct hist_trigger_data *hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) if (data->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) pause_named_trigger(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) tracepoint_synchronize_unregister();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) tracing_map_clear(hist_data->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) if (data->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) unpause_named_trigger(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) static bool compatible_field(struct ftrace_event_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) struct ftrace_event_field *test_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) if (field == test_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) if (field == NULL || test_field == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) if (strcmp(field->name, test_field->name) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) if (strcmp(field->type, test_field->type) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) if (field->size != test_field->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) if (field->is_signed != test_field->is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) static bool hist_trigger_match(struct event_trigger_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) struct event_trigger_data *data_test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) struct event_trigger_data *named_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) bool ignore_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) struct tracing_map_sort_key *sort_key, *sort_key_test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) struct hist_trigger_data *hist_data, *hist_data_test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) struct hist_field *key_field, *key_field_test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) if (named_data && (named_data != data_test) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) (named_data != data_test->named_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) if (!named_data && is_named_trigger(data_test))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) hist_data_test = data_test->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) if (hist_data->n_vals != hist_data_test->n_vals ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) hist_data->n_fields != hist_data_test->n_fields ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) hist_data->n_sort_keys != hist_data_test->n_sort_keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) if (!ignore_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) if ((data->filter_str && !data_test->filter_str) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) (!data->filter_str && data_test->filter_str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) for_each_hist_field(i, hist_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) key_field = hist_data->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) key_field_test = hist_data_test->fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) if (key_field->flags != key_field_test->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) if (!compatible_field(key_field->field, key_field_test->field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) if (key_field->offset != key_field_test->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) if (key_field->size != key_field_test->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) if (key_field->is_signed != key_field_test->is_signed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) if (!!key_field->var.name != !!key_field_test->var.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) if (key_field->var.name &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) strcmp(key_field->var.name, key_field_test->var.name) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) for (i = 0; i < hist_data->n_sort_keys; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) sort_key = &hist_data->sort_keys[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) sort_key_test = &hist_data_test->sort_keys[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) if (sort_key->field_idx != sort_key_test->field_idx ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) sort_key->descending != sort_key_test->descending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) if (!ignore_filter && data->filter_str &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) (strcmp(data->filter_str, data_test->filter_str) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) if (!actions_match(hist_data, hist_data_test))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) struct event_trigger_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) struct hist_trigger_data *hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) struct event_trigger_data *test, *named_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) struct trace_array *tr = file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) if (hist_data->attrs->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) named_data = find_named_trigger(hist_data->attrs->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) if (named_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) if (!hist_trigger_match(data, named_data, named_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) hist_err(tr, HIST_ERR_NAMED_MISMATCH, errpos(hist_data->attrs->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) if (hist_data->attrs->name && !named_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) goto new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) list_for_each_entry(test, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) if (!hist_trigger_match(data, test, named_data, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) if (hist_data->attrs->pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) test->paused = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) else if (hist_data->attrs->cont)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) test->paused = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) else if (hist_data->attrs->clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) hist_clear(test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) hist_err(tr, HIST_ERR_TRIGGER_EEXIST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) new:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) if (hist_data->attrs->cont || hist_data->attrs->clear) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) hist_err(tr, HIST_ERR_TRIGGER_ENOENT_CLEAR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) if (hist_data->attrs->pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) data->paused = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) if (named_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) data->private_data = named_data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) set_named_trigger_data(data, named_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) data->ops = &event_hist_trigger_named_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) if (data->ops->init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) ret = data->ops->init(data->ops, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) if (hist_data->enable_timestamps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) char *clock = hist_data->attrs->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) ret = tracing_set_clock(file->tr, hist_data->attrs->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) tracing_set_time_stamp_abs(file->tr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) if (named_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) destroy_hist_data(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) static int hist_trigger_enable(struct event_trigger_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) list_add_tail_rcu(&data->list, &file->triggers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) update_cond_flag(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) if (trace_event_trigger_enable_disable(file, 1) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) list_del_rcu(&data->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) update_cond_flag(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) ret--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) static bool have_hist_trigger_match(struct event_trigger_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) struct hist_trigger_data *hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) struct event_trigger_data *test, *named_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) bool match = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) if (hist_data->attrs->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) named_data = find_named_trigger(hist_data->attrs->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) list_for_each_entry(test, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) if (hist_trigger_match(data, test, named_data, false)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) match = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) return match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) static bool hist_trigger_check_refs(struct event_trigger_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) struct hist_trigger_data *hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) struct event_trigger_data *test, *named_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) if (hist_data->attrs->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) named_data = find_named_trigger(hist_data->attrs->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) list_for_each_entry(test, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) if (!hist_trigger_match(data, test, named_data, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) hist_data = test->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) if (check_var_refs(hist_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) struct event_trigger_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) struct hist_trigger_data *hist_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) struct event_trigger_data *test, *named_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) bool unregistered = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) if (hist_data->attrs->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) named_data = find_named_trigger(hist_data->attrs->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) list_for_each_entry(test, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) if (!hist_trigger_match(data, test, named_data, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) unregistered = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) list_del_rcu(&test->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) trace_event_trigger_enable_disable(file, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) update_cond_flag(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) if (unregistered && test->ops->free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) test->ops->free(test->ops, test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) if (hist_data->enable_timestamps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) if (!hist_data->remove || unregistered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) tracing_set_time_stamp_abs(file->tr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) static bool hist_file_check_refs(struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) struct event_trigger_data *test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) list_for_each_entry(test, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) hist_data = test->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) if (check_var_refs(hist_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) static void hist_unreg_all(struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) struct event_trigger_data *test, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) struct synth_event *se;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) const char *se_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) if (hist_file_check_refs(file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) list_for_each_entry_safe(test, n, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) hist_data = test->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) list_del_rcu(&test->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) trace_event_trigger_enable_disable(file, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) se_name = trace_event_name(file->event_call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) se = find_synth_event(se_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) if (se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) se->ref--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) update_cond_flag(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) if (hist_data->enable_timestamps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) tracing_set_time_stamp_abs(file->tr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) if (test->ops->free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) test->ops->free(test->ops, test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) static int event_hist_trigger_func(struct event_command *cmd_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) char *glob, char *cmd, char *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) unsigned int hist_trigger_bits = TRACING_MAP_BITS_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) struct event_trigger_data *trigger_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) struct hist_trigger_attrs *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) struct event_trigger_ops *trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) struct hist_trigger_data *hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) struct synth_event *se;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) const char *se_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) bool remove = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) char *trigger, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) lockdep_assert_held(&event_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) if (glob && strlen(glob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) hist_err_clear();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) last_cmd_set(file, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) if (!param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) if (glob[0] == '!')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) remove = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) * separate the trigger from the filter (k:v [if filter])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) * allowing for whitespace in the trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) p = trigger = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) p = strstr(p, "if");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) if (p == param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) if (*(p - 1) != ' ' && *(p - 1) != '\t') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) if (p >= param + strlen(param) - (sizeof("if") - 1) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) if (*(p + sizeof("if") - 1) != ' ' && *(p + sizeof("if") - 1) != '\t') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) } while (p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) param = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) *(p - 1) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) param = strstrip(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) trigger = strstrip(trigger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) attrs = parse_hist_trigger_attrs(file->tr, trigger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) if (IS_ERR(attrs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) return PTR_ERR(attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) if (attrs->map_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) hist_trigger_bits = attrs->map_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) hist_data = create_hist_data(hist_trigger_bits, attrs, file, remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) if (IS_ERR(hist_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) destroy_hist_trigger_attrs(attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) return PTR_ERR(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745) trigger_ops = cmd_ops->get_trigger_ops(cmd, trigger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) if (!trigger_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) trigger_data->count = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) trigger_data->ops = trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) trigger_data->cmd_ops = cmd_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) INIT_LIST_HEAD(&trigger_data->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) RCU_INIT_POINTER(trigger_data->filter, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) trigger_data->private_data = hist_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) /* if param is non-empty, it's supposed to be a filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) if (param && cmd_ops->set_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) ret = cmd_ops->set_filter(param, trigger_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) if (remove) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) if (!have_hist_trigger_match(trigger_data, file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) if (hist_trigger_check_refs(trigger_data, file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) se_name = trace_event_name(file->event_call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) se = find_synth_event(se_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) if (se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) se->ref--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) * The above returns on success the # of triggers registered,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) * but if it didn't register any it returns zero. Consider no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) * triggers registered a failure too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) if (!(attrs->pause || attrs->cont || attrs->clear))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) } else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) if (get_named_trigger_data(trigger_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) goto enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) if (has_hist_vars(hist_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) save_hist_vars(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) ret = create_actions(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) goto out_unreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) ret = tracing_map_init(hist_data->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) goto out_unreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) ret = hist_trigger_enable(trigger_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) goto out_unreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) se_name = trace_event_name(file->event_call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) se = find_synth_event(se_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) if (se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) se->ref++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) /* Just return zero, not the number of registered triggers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) hist_err_clear();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) out_unreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) if (cmd_ops->set_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) cmd_ops->set_filter(NULL, trigger_data, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) remove_hist_vars(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) kfree(trigger_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) destroy_hist_data(hist_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) static struct event_command trigger_hist_cmd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) .name = "hist",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) .trigger_type = ETT_EVENT_HIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) .flags = EVENT_CMD_FL_NEEDS_REC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) .func = event_hist_trigger_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) .reg = hist_register_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) .unreg = hist_unregister_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) .unreg_all = hist_unreg_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) .get_trigger_ops = event_hist_get_trigger_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) .set_filter = set_trigger_filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) __init int register_trigger_hist_cmd(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) ret = register_event_command(&trigger_hist_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) WARN_ON(ret < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) hist_enable_trigger(struct event_trigger_data *data, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) struct ring_buffer_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) struct enable_trigger_data *enable_data = data->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870) struct event_trigger_data *test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) list_for_each_entry_rcu(test, &enable_data->file->triggers, list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) lockdep_is_held(&event_mutex)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) if (enable_data->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) test->paused = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) test->paused = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) hist_enable_count_trigger(struct event_trigger_data *data, void *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) struct ring_buffer_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) if (!data->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) if (data->count != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) (data->count)--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) hist_enable_trigger(data, rec, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) static struct event_trigger_ops hist_enable_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) .func = hist_enable_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) .print = event_enable_trigger_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) .init = event_trigger_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) .free = event_enable_trigger_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) static struct event_trigger_ops hist_enable_count_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) .func = hist_enable_count_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) .print = event_enable_trigger_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) .init = event_trigger_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) .free = event_enable_trigger_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) static struct event_trigger_ops hist_disable_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) .func = hist_enable_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) .print = event_enable_trigger_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) .init = event_trigger_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) .free = event_enable_trigger_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917) static struct event_trigger_ops hist_disable_count_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) .func = hist_enable_count_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) .print = event_enable_trigger_print,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920) .init = event_trigger_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) .free = event_enable_trigger_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) static struct event_trigger_ops *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) hist_enable_get_trigger_ops(char *cmd, char *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) struct event_trigger_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) bool enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) enable = (strcmp(cmd, ENABLE_HIST_STR) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) ops = param ? &hist_enable_count_trigger_ops :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) &hist_enable_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) ops = param ? &hist_disable_count_trigger_ops :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) &hist_disable_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) return ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) static void hist_enable_unreg_all(struct trace_event_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) struct event_trigger_data *test, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) list_for_each_entry_safe(test, n, &file->triggers, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) if (test->cmd_ops->trigger_type == ETT_HIST_ENABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) list_del_rcu(&test->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) update_cond_flag(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) trace_event_trigger_enable_disable(file, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951) if (test->ops->free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) test->ops->free(test->ops, test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) static struct event_command trigger_hist_enable_cmd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) .name = ENABLE_HIST_STR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) .trigger_type = ETT_HIST_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) .func = event_enable_trigger_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) .reg = event_enable_register_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) .unreg = event_enable_unregister_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) .unreg_all = hist_enable_unreg_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) .get_trigger_ops = hist_enable_get_trigger_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) .set_filter = set_trigger_filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) static struct event_command trigger_hist_disable_cmd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) .name = DISABLE_HIST_STR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) .trigger_type = ETT_HIST_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) .func = event_enable_trigger_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) .reg = event_enable_register_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) .unreg = event_enable_unregister_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) .unreg_all = hist_enable_unreg_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) .get_trigger_ops = hist_enable_get_trigger_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) .set_filter = set_trigger_filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) static __init void unregister_trigger_hist_enable_disable_cmds(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) unregister_event_command(&trigger_hist_enable_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) unregister_event_command(&trigger_hist_disable_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) __init int register_trigger_hist_enable_disable_cmds(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) ret = register_event_command(&trigger_hist_enable_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) if (WARN_ON(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) ret = register_event_command(&trigger_hist_disable_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) if (WARN_ON(ret < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) unregister_trigger_hist_enable_disable_cmds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) }