hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/kernel/trace/trace_events_hist.c
....@@ -7,19 +7,76 @@
77
88 #include <linux/module.h>
99 #include <linux/kallsyms.h>
10
+#include <linux/security.h>
1011 #include <linux/mutex.h>
1112 #include <linux/slab.h>
1213 #include <linux/stacktrace.h>
1314 #include <linux/rculist.h>
1415 #include <linux/tracefs.h>
1516
17
+/* for gfp flag names */
18
+#include <linux/trace_events.h>
19
+#include <trace/events/mmflags.h>
20
+
1621 #include "tracing_map.h"
17
-#include "trace.h"
22
+#include "trace_synth.h"
1823
19
-#define SYNTH_SYSTEM "synthetic"
20
-#define SYNTH_FIELDS_MAX 16
24
+#define ERRORS \
25
+ C(NONE, "No error"), \
26
+ C(DUPLICATE_VAR, "Variable already defined"), \
27
+ C(VAR_NOT_UNIQUE, "Variable name not unique, need to use fully qualified name (subsys.event.var) for variable"), \
28
+ C(TOO_MANY_VARS, "Too many variables defined"), \
29
+ C(MALFORMED_ASSIGNMENT, "Malformed assignment"), \
30
+ C(NAMED_MISMATCH, "Named hist trigger doesn't match existing named trigger (includes variables)"), \
31
+ C(TRIGGER_EEXIST, "Hist trigger already exists"), \
32
+ C(TRIGGER_ENOENT_CLEAR, "Can't clear or continue a nonexistent hist trigger"), \
33
+ C(SET_CLOCK_FAIL, "Couldn't set trace_clock"), \
34
+ C(BAD_FIELD_MODIFIER, "Invalid field modifier"), \
35
+ C(TOO_MANY_SUBEXPR, "Too many subexpressions (3 max)"), \
36
+ C(TIMESTAMP_MISMATCH, "Timestamp units in expression don't match"), \
37
+ C(TOO_MANY_FIELD_VARS, "Too many field variables defined"), \
38
+ C(EVENT_FILE_NOT_FOUND, "Event file not found"), \
39
+ C(HIST_NOT_FOUND, "Matching event histogram not found"), \
40
+ C(HIST_CREATE_FAIL, "Couldn't create histogram for field"), \
41
+ C(SYNTH_VAR_NOT_FOUND, "Couldn't find synthetic variable"), \
42
+ C(SYNTH_EVENT_NOT_FOUND,"Couldn't find synthetic event"), \
43
+ C(SYNTH_TYPE_MISMATCH, "Param type doesn't match synthetic event field type"), \
44
+ C(SYNTH_COUNT_MISMATCH, "Param count doesn't match synthetic event field count"), \
45
+ C(FIELD_VAR_PARSE_FAIL, "Couldn't parse field variable"), \
46
+ C(VAR_CREATE_FIND_FAIL, "Couldn't create or find variable"), \
47
+ C(ONX_NOT_VAR, "For onmax(x) or onchange(x), x must be a variable"), \
48
+ C(ONX_VAR_NOT_FOUND, "Couldn't find onmax or onchange variable"), \
49
+ C(ONX_VAR_CREATE_FAIL, "Couldn't create onmax or onchange variable"), \
50
+ C(FIELD_VAR_CREATE_FAIL,"Couldn't create field variable"), \
51
+ C(TOO_MANY_PARAMS, "Too many action params"), \
52
+ C(PARAM_NOT_FOUND, "Couldn't find param"), \
53
+ C(INVALID_PARAM, "Invalid action param"), \
54
+ C(ACTION_NOT_FOUND, "No action found"), \
55
+ C(NO_SAVE_PARAMS, "No params found for save()"), \
56
+ C(TOO_MANY_SAVE_ACTIONS,"Can't have more than one save() action per hist"), \
57
+ C(ACTION_MISMATCH, "Handler doesn't support action"), \
58
+ C(NO_CLOSING_PAREN, "No closing paren found"), \
59
+ C(SUBSYS_NOT_FOUND, "Missing subsystem"), \
60
+ C(INVALID_SUBSYS_EVENT, "Invalid subsystem or event name"), \
61
+ C(INVALID_REF_KEY, "Using variable references in keys not supported"), \
62
+ C(VAR_NOT_FOUND, "Couldn't find variable"), \
63
+ C(FIELD_NOT_FOUND, "Couldn't find field"), \
64
+ C(EMPTY_ASSIGNMENT, "Empty assignment"), \
65
+ C(INVALID_SORT_MODIFIER,"Invalid sort modifier"), \
66
+ C(EMPTY_SORT_FIELD, "Empty sort field"), \
67
+ C(TOO_MANY_SORT_FIELDS, "Too many sort fields (Max = 2)"), \
68
+ C(INVALID_SORT_FIELD, "Sort field must be a key or a val"), \
69
+ C(INVALID_STR_OPERAND, "String type can not be an operand in expression"),
2170
22
-#define STR_VAR_LEN_MAX 32 /* must be multiple of sizeof(u64) */
71
+#undef C
72
+#define C(a, b) HIST_ERR_##a
73
+
74
+enum { ERRORS };
75
+
76
+#undef C
77
+#define C(a, b) b
78
+
79
+static const char *err_text[] = { ERRORS };
2380
2481 struct hist_field;
2582
....@@ -39,6 +96,16 @@
3996 FIELD_OP_UNARY_MINUS,
4097 };
4198
99
+/*
100
+ * A hist_var (histogram variable) contains variable information for
101
+ * hist_fields having the HIST_FIELD_FL_VAR or HIST_FIELD_FL_VAR_REF
102
+ * flag set. A hist_var has a variable name e.g. ts0, and is
103
+ * associated with a given histogram trigger, as specified by
104
+ * hist_data. The hist_var idx is the unique index assigned to the
105
+ * variable by the hist trigger's tracing_map. The idx is what is
106
+ * used to set a variable's value and, by a variable reference, to
107
+ * retrieve it.
108
+ */
42109 struct hist_var {
43110 char *name;
44111 struct hist_trigger_data *hist_data;
....@@ -56,14 +123,33 @@
56123 const char *type;
57124 struct hist_field *operands[HIST_FIELD_OPERANDS_MAX];
58125 struct hist_trigger_data *hist_data;
126
+
127
+ /*
128
+ * Variable fields contain variable-specific info in var.
129
+ */
59130 struct hist_var var;
60131 enum field_op_id operator;
61132 char *system;
62133 char *event_name;
134
+
135
+ /*
136
+ * The name field is used for EXPR and VAR_REF fields. VAR
137
+ * fields contain the variable name in var.name.
138
+ */
63139 char *name;
64
- unsigned int var_idx;
140
+
141
+ /*
142
+ * When a histogram trigger is hit, if it has any references
143
+ * to variables, the values of those variables are collected
144
+ * into a var_ref_vals array by resolve_var_refs(). The
145
+ * current value of each variable is read from the tracing_map
146
+ * using the hist field's hist_var.idx and entered into the
147
+ * var_ref_idx entry i.e. var_ref_vals[var_ref_idx].
148
+ */
65149 unsigned int var_ref_idx;
66150 bool read_once;
151
+
152
+ unsigned int var_str_idx;
67153 };
68154
69155 static u64 hist_field_none(struct hist_field *field,
....@@ -266,6 +352,7 @@
266352 unsigned int n_keys;
267353 unsigned int n_fields;
268354 unsigned int n_vars;
355
+ unsigned int n_var_str;
269356 unsigned int key_size;
270357 struct tracing_map_sort_key sort_keys[TRACING_MAP_SORT_KEYS_MAX];
271358 unsigned int n_sort_keys;
....@@ -280,592 +367,225 @@
280367 struct action_data *actions[HIST_ACTIONS_MAX];
281368 unsigned int n_actions;
282369
283
- struct hist_field *synth_var_refs[SYNTH_FIELDS_MAX];
284
- unsigned int n_synth_var_refs;
285370 struct field_var *field_vars[SYNTH_FIELDS_MAX];
286371 unsigned int n_field_vars;
287372 unsigned int n_field_var_str;
288373 struct field_var_hist *field_var_hists[SYNTH_FIELDS_MAX];
289374 unsigned int n_field_var_hists;
290375
291
- struct field_var *max_vars[SYNTH_FIELDS_MAX];
292
- unsigned int n_max_vars;
293
- unsigned int n_max_var_str;
294
-};
295
-
296
-struct synth_field {
297
- char *type;
298
- char *name;
299
- size_t size;
300
- bool is_signed;
301
- bool is_string;
302
-};
303
-
304
-struct synth_event {
305
- struct list_head list;
306
- int ref;
307
- char *name;
308
- struct synth_field **fields;
309
- unsigned int n_fields;
310
- unsigned int n_u64;
311
- struct trace_event_class class;
312
- struct trace_event_call call;
313
- struct tracepoint *tp;
376
+ struct field_var *save_vars[SYNTH_FIELDS_MAX];
377
+ unsigned int n_save_vars;
378
+ unsigned int n_save_var_str;
314379 };
315380
316381 struct action_data;
317382
318383 typedef void (*action_fn_t) (struct hist_trigger_data *hist_data,
319384 struct tracing_map_elt *elt, void *rec,
320
- struct ring_buffer_event *rbe,
385
+ struct ring_buffer_event *rbe, void *key,
321386 struct action_data *data, u64 *var_ref_vals);
322387
388
+typedef bool (*check_track_val_fn_t) (u64 track_val, u64 var_val);
389
+
390
+enum handler_id {
391
+ HANDLER_ONMATCH = 1,
392
+ HANDLER_ONMAX,
393
+ HANDLER_ONCHANGE,
394
+};
395
+
396
+enum action_id {
397
+ ACTION_SAVE = 1,
398
+ ACTION_TRACE,
399
+ ACTION_SNAPSHOT,
400
+};
401
+
323402 struct action_data {
403
+ enum handler_id handler;
404
+ enum action_id action;
405
+ char *action_name;
324406 action_fn_t fn;
407
+
325408 unsigned int n_params;
326409 char *params[SYNTH_FIELDS_MAX];
327410
411
+ /*
412
+ * When a histogram trigger is hit, the values of any
413
+ * references to variables, including variables being passed
414
+ * as parameters to synthetic events, are collected into a
415
+ * var_ref_vals array. This var_ref_idx array is an array of
416
+ * indices into the var_ref_vals array, one for each synthetic
417
+ * event param, and is passed to the synthetic event
418
+ * invocation.
419
+ */
420
+ unsigned int var_ref_idx[SYNTH_FIELDS_MAX];
421
+ struct synth_event *synth_event;
422
+ bool use_trace_keyword;
423
+ char *synth_event_name;
424
+
328425 union {
329426 struct {
330
- unsigned int var_ref_idx;
331
- char *match_event;
332
- char *match_event_system;
333
- char *synth_event_name;
334
- struct synth_event *synth_event;
335
- } onmatch;
427
+ char *event;
428
+ char *event_system;
429
+ } match_data;
336430
337431 struct {
432
+ /*
433
+ * var_str contains the $-unstripped variable
434
+ * name referenced by var_ref, and used when
435
+ * printing the action. Because var_ref
436
+ * creation is deferred to create_actions(),
437
+ * we need a per-action way to save it until
438
+ * then, thus var_str.
439
+ */
338440 char *var_str;
339
- char *fn_name;
340
- unsigned int max_var_ref_idx;
341
- struct hist_field *max_var;
342
- struct hist_field *var;
343
- } onmax;
441
+
442
+ /*
443
+ * var_ref refers to the variable being
444
+ * tracked e.g onmax($var).
445
+ */
446
+ struct hist_field *var_ref;
447
+
448
+ /*
449
+ * track_var contains the 'invisible' tracking
450
+ * variable created to keep the current
451
+ * e.g. max value.
452
+ */
453
+ struct hist_field *track_var;
454
+
455
+ check_track_val_fn_t check_val;
456
+ action_fn_t save_data;
457
+ } track_data;
344458 };
345459 };
346460
461
+struct track_data {
462
+ u64 track_val;
463
+ bool updated;
347464
348
-static char last_hist_cmd[MAX_FILTER_STR_VAL];
349
-static char hist_err_str[MAX_FILTER_STR_VAL];
465
+ unsigned int key_len;
466
+ void *key;
467
+ struct tracing_map_elt elt;
350468
351
-static void last_cmd_set(char *str)
469
+ struct action_data *action_data;
470
+ struct hist_trigger_data *hist_data;
471
+};
472
+
473
+struct hist_elt_data {
474
+ char *comm;
475
+ u64 *var_ref_vals;
476
+ char *field_var_str[SYNTH_FIELDS_MAX];
477
+};
478
+
479
+struct snapshot_context {
480
+ struct tracing_map_elt *elt;
481
+ void *key;
482
+};
483
+
484
+static void track_data_free(struct track_data *track_data)
352485 {
353
- if (!str)
486
+ struct hist_elt_data *elt_data;
487
+
488
+ if (!track_data)
354489 return;
355490
356
- strncpy(last_hist_cmd, str, MAX_FILTER_STR_VAL - 1);
491
+ kfree(track_data->key);
492
+
493
+ elt_data = track_data->elt.private_data;
494
+ if (elt_data) {
495
+ kfree(elt_data->comm);
496
+ kfree(elt_data);
497
+ }
498
+
499
+ kfree(track_data);
357500 }
358501
359
-static void hist_err(char *str, char *var)
502
+static struct track_data *track_data_alloc(unsigned int key_len,
503
+ struct action_data *action_data,
504
+ struct hist_trigger_data *hist_data)
360505 {
361
- int maxlen = MAX_FILTER_STR_VAL - 1;
506
+ struct track_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
507
+ struct hist_elt_data *elt_data;
508
+
509
+ if (!data)
510
+ return ERR_PTR(-ENOMEM);
511
+
512
+ data->key = kzalloc(key_len, GFP_KERNEL);
513
+ if (!data->key) {
514
+ track_data_free(data);
515
+ return ERR_PTR(-ENOMEM);
516
+ }
517
+
518
+ data->key_len = key_len;
519
+ data->action_data = action_data;
520
+ data->hist_data = hist_data;
521
+
522
+ elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL);
523
+ if (!elt_data) {
524
+ track_data_free(data);
525
+ return ERR_PTR(-ENOMEM);
526
+ }
527
+
528
+ data->elt.private_data = elt_data;
529
+
530
+ elt_data->comm = kzalloc(TASK_COMM_LEN, GFP_KERNEL);
531
+ if (!elt_data->comm) {
532
+ track_data_free(data);
533
+ return ERR_PTR(-ENOMEM);
534
+ }
535
+
536
+ return data;
537
+}
538
+
539
+static char last_cmd[MAX_FILTER_STR_VAL];
540
+static char last_cmd_loc[MAX_FILTER_STR_VAL];
541
+
542
+static int errpos(char *str)
543
+{
544
+ return err_pos(last_cmd, str);
545
+}
546
+
547
+static void last_cmd_set(struct trace_event_file *file, char *str)
548
+{
549
+ const char *system = NULL, *name = NULL;
550
+ struct trace_event_call *call;
362551
363552 if (!str)
364553 return;
365554
366
- if (strlen(hist_err_str))
367
- return;
555
+ strcpy(last_cmd, "hist:");
556
+ strncat(last_cmd, str, MAX_FILTER_STR_VAL - 1 - sizeof("hist:"));
368557
369
- if (!var)
370
- var = "";
558
+ if (file) {
559
+ call = file->event_call;
560
+ system = call->class->system;
561
+ if (system) {
562
+ name = trace_event_name(call);
563
+ if (!name)
564
+ system = NULL;
565
+ }
566
+ }
371567
372
- if (strlen(hist_err_str) + strlen(str) + strlen(var) > maxlen)
373
- return;
374
-
375
- strcat(hist_err_str, str);
376
- strcat(hist_err_str, var);
568
+ if (system)
569
+ snprintf(last_cmd_loc, MAX_FILTER_STR_VAL, "hist:%s:%s", system, name);
377570 }
378571
379
-static void hist_err_event(char *str, char *system, char *event, char *var)
572
+static void hist_err(struct trace_array *tr, u8 err_type, u8 err_pos)
380573 {
381
- char err[MAX_FILTER_STR_VAL];
382
-
383
- if (system && var)
384
- snprintf(err, MAX_FILTER_STR_VAL, "%s.%s.%s", system, event, var);
385
- else if (system)
386
- snprintf(err, MAX_FILTER_STR_VAL, "%s.%s", system, event);
387
- else
388
- strscpy(err, var, MAX_FILTER_STR_VAL);
389
-
390
- hist_err(str, err);
574
+ tracing_log_err(tr, last_cmd_loc, last_cmd, err_text,
575
+ err_type, err_pos);
391576 }
392577
393578 static void hist_err_clear(void)
394579 {
395
- hist_err_str[0] = '\0';
396
-}
397
-
398
-static bool have_hist_err(void)
399
-{
400
- if (strlen(hist_err_str))
401
- return true;
402
-
403
- return false;
404
-}
405
-
406
-static LIST_HEAD(synth_event_list);
407
-static DEFINE_MUTEX(synth_event_mutex);
408
-
409
-struct synth_trace_event {
410
- struct trace_entry ent;
411
- u64 fields[];
412
-};
413
-
414
-static int synth_event_define_fields(struct trace_event_call *call)
415
-{
416
- struct synth_trace_event trace;
417
- int offset = offsetof(typeof(trace), fields);
418
- struct synth_event *event = call->data;
419
- unsigned int i, size, n_u64;
420
- char *name, *type;
421
- bool is_signed;
422
- int ret = 0;
423
-
424
- for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
425
- size = event->fields[i]->size;
426
- is_signed = event->fields[i]->is_signed;
427
- type = event->fields[i]->type;
428
- name = event->fields[i]->name;
429
- ret = trace_define_field(call, type, name, offset, size,
430
- is_signed, FILTER_OTHER);
431
- if (ret)
432
- break;
433
-
434
- if (event->fields[i]->is_string) {
435
- offset += STR_VAR_LEN_MAX;
436
- n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
437
- } else {
438
- offset += sizeof(u64);
439
- n_u64++;
440
- }
441
- }
442
-
443
- event->n_u64 = n_u64;
444
-
445
- return ret;
446
-}
447
-
448
-static bool synth_field_signed(char *type)
449
-{
450
- if (strncmp(type, "u", 1) == 0)
451
- return false;
452
- if (strcmp(type, "gfp_t") == 0)
453
- return false;
454
-
455
- return true;
456
-}
457
-
458
-static int synth_field_is_string(char *type)
459
-{
460
- if (strstr(type, "char[") != NULL)
461
- return true;
462
-
463
- return false;
464
-}
465
-
466
-static int synth_field_string_size(char *type)
467
-{
468
- char buf[4], *end, *start;
469
- unsigned int len;
470
- int size, err;
471
-
472
- start = strstr(type, "char[");
473
- if (start == NULL)
474
- return -EINVAL;
475
- start += strlen("char[");
476
-
477
- end = strchr(type, ']');
478
- if (!end || end < start)
479
- return -EINVAL;
480
-
481
- len = end - start;
482
- if (len > 3)
483
- return -EINVAL;
484
-
485
- strncpy(buf, start, len);
486
- buf[len] = '\0';
487
-
488
- err = kstrtouint(buf, 0, &size);
489
- if (err)
490
- return err;
491
-
492
- if (size > STR_VAR_LEN_MAX)
493
- return -EINVAL;
494
-
495
- return size;
496
-}
497
-
498
-static int synth_field_size(char *type)
499
-{
500
- int size = 0;
501
-
502
- if (strcmp(type, "s64") == 0)
503
- size = sizeof(s64);
504
- else if (strcmp(type, "u64") == 0)
505
- size = sizeof(u64);
506
- else if (strcmp(type, "s32") == 0)
507
- size = sizeof(s32);
508
- else if (strcmp(type, "u32") == 0)
509
- size = sizeof(u32);
510
- else if (strcmp(type, "s16") == 0)
511
- size = sizeof(s16);
512
- else if (strcmp(type, "u16") == 0)
513
- size = sizeof(u16);
514
- else if (strcmp(type, "s8") == 0)
515
- size = sizeof(s8);
516
- else if (strcmp(type, "u8") == 0)
517
- size = sizeof(u8);
518
- else if (strcmp(type, "char") == 0)
519
- size = sizeof(char);
520
- else if (strcmp(type, "unsigned char") == 0)
521
- size = sizeof(unsigned char);
522
- else if (strcmp(type, "int") == 0)
523
- size = sizeof(int);
524
- else if (strcmp(type, "unsigned int") == 0)
525
- size = sizeof(unsigned int);
526
- else if (strcmp(type, "long") == 0)
527
- size = sizeof(long);
528
- else if (strcmp(type, "unsigned long") == 0)
529
- size = sizeof(unsigned long);
530
- else if (strcmp(type, "pid_t") == 0)
531
- size = sizeof(pid_t);
532
- else if (synth_field_is_string(type))
533
- size = synth_field_string_size(type);
534
-
535
- return size;
536
-}
537
-
538
-static const char *synth_field_fmt(char *type)
539
-{
540
- const char *fmt = "%llu";
541
-
542
- if (strcmp(type, "s64") == 0)
543
- fmt = "%lld";
544
- else if (strcmp(type, "u64") == 0)
545
- fmt = "%llu";
546
- else if (strcmp(type, "s32") == 0)
547
- fmt = "%d";
548
- else if (strcmp(type, "u32") == 0)
549
- fmt = "%u";
550
- else if (strcmp(type, "s16") == 0)
551
- fmt = "%d";
552
- else if (strcmp(type, "u16") == 0)
553
- fmt = "%u";
554
- else if (strcmp(type, "s8") == 0)
555
- fmt = "%d";
556
- else if (strcmp(type, "u8") == 0)
557
- fmt = "%u";
558
- else if (strcmp(type, "char") == 0)
559
- fmt = "%d";
560
- else if (strcmp(type, "unsigned char") == 0)
561
- fmt = "%u";
562
- else if (strcmp(type, "int") == 0)
563
- fmt = "%d";
564
- else if (strcmp(type, "unsigned int") == 0)
565
- fmt = "%u";
566
- else if (strcmp(type, "long") == 0)
567
- fmt = "%ld";
568
- else if (strcmp(type, "unsigned long") == 0)
569
- fmt = "%lu";
570
- else if (strcmp(type, "pid_t") == 0)
571
- fmt = "%d";
572
- else if (synth_field_is_string(type))
573
- fmt = "%s";
574
-
575
- return fmt;
576
-}
577
-
578
-static enum print_line_t print_synth_event(struct trace_iterator *iter,
579
- int flags,
580
- struct trace_event *event)
581
-{
582
- struct trace_array *tr = iter->tr;
583
- struct trace_seq *s = &iter->seq;
584
- struct synth_trace_event *entry;
585
- struct synth_event *se;
586
- unsigned int i, n_u64;
587
- char print_fmt[32];
588
- const char *fmt;
589
-
590
- entry = (struct synth_trace_event *)iter->ent;
591
- se = container_of(event, struct synth_event, call.event);
592
-
593
- trace_seq_printf(s, "%s: ", se->name);
594
-
595
- for (i = 0, n_u64 = 0; i < se->n_fields; i++) {
596
- if (trace_seq_has_overflowed(s))
597
- goto end;
598
-
599
- fmt = synth_field_fmt(se->fields[i]->type);
600
-
601
- /* parameter types */
602
- if (tr->trace_flags & TRACE_ITER_VERBOSE)
603
- trace_seq_printf(s, "%s ", fmt);
604
-
605
- snprintf(print_fmt, sizeof(print_fmt), "%%s=%s%%s", fmt);
606
-
607
- /* parameter values */
608
- if (se->fields[i]->is_string) {
609
- trace_seq_printf(s, print_fmt, se->fields[i]->name,
610
- (char *)&entry->fields[n_u64],
611
- i == se->n_fields - 1 ? "" : " ");
612
- n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
613
- } else {
614
- trace_seq_printf(s, print_fmt, se->fields[i]->name,
615
- entry->fields[n_u64],
616
- i == se->n_fields - 1 ? "" : " ");
617
- n_u64++;
618
- }
619
- }
620
-end:
621
- trace_seq_putc(s, '\n');
622
-
623
- return trace_handle_return(s);
624
-}
625
-
626
-static struct trace_event_functions synth_event_funcs = {
627
- .trace = print_synth_event
628
-};
629
-
630
-static notrace void trace_event_raw_event_synth(void *__data,
631
- u64 *var_ref_vals,
632
- unsigned int var_ref_idx)
633
-{
634
- struct trace_event_file *trace_file = __data;
635
- struct synth_trace_event *entry;
636
- struct trace_event_buffer fbuffer;
637
- struct ring_buffer *buffer;
638
- struct synth_event *event;
639
- unsigned int i, n_u64;
640
- int fields_size = 0;
641
-
642
- event = trace_file->event_call->data;
643
-
644
- if (trace_trigger_soft_disabled(trace_file))
645
- return;
646
-
647
- fields_size = event->n_u64 * sizeof(u64);
648
-
649
- /*
650
- * Avoid ring buffer recursion detection, as this event
651
- * is being performed within another event.
652
- */
653
- buffer = trace_file->tr->trace_buffer.buffer;
654
- ring_buffer_nest_start(buffer);
655
-
656
- entry = trace_event_buffer_reserve(&fbuffer, trace_file,
657
- sizeof(*entry) + fields_size);
658
- if (!entry)
659
- goto out;
660
-
661
- for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
662
- if (event->fields[i]->is_string) {
663
- char *str_val = (char *)(long)var_ref_vals[var_ref_idx + i];
664
- char *str_field = (char *)&entry->fields[n_u64];
665
-
666
- strscpy(str_field, str_val, STR_VAR_LEN_MAX);
667
- n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
668
- } else {
669
- struct synth_field *field = event->fields[i];
670
- u64 val = var_ref_vals[var_ref_idx + i];
671
-
672
- switch (field->size) {
673
- case 1:
674
- *(u8 *)&entry->fields[n_u64] = (u8)val;
675
- break;
676
-
677
- case 2:
678
- *(u16 *)&entry->fields[n_u64] = (u16)val;
679
- break;
680
-
681
- case 4:
682
- *(u32 *)&entry->fields[n_u64] = (u32)val;
683
- break;
684
-
685
- default:
686
- entry->fields[n_u64] = val;
687
- break;
688
- }
689
- n_u64++;
690
- }
691
- }
692
-
693
- trace_event_buffer_commit(&fbuffer);
694
-out:
695
- ring_buffer_nest_end(buffer);
696
-}
697
-
698
-static void free_synth_event_print_fmt(struct trace_event_call *call)
699
-{
700
- if (call) {
701
- kfree(call->print_fmt);
702
- call->print_fmt = NULL;
703
- }
704
-}
705
-
706
-static int __set_synth_event_print_fmt(struct synth_event *event,
707
- char *buf, int len)
708
-{
709
- const char *fmt;
710
- int pos = 0;
711
- int i;
712
-
713
- /* When len=0, we just calculate the needed length */
714
-#define LEN_OR_ZERO (len ? len - pos : 0)
715
-
716
- pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
717
- for (i = 0; i < event->n_fields; i++) {
718
- fmt = synth_field_fmt(event->fields[i]->type);
719
- pos += snprintf(buf + pos, LEN_OR_ZERO, "%s=%s%s",
720
- event->fields[i]->name, fmt,
721
- i == event->n_fields - 1 ? "" : ", ");
722
- }
723
- pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
724
-
725
- for (i = 0; i < event->n_fields; i++) {
726
- pos += snprintf(buf + pos, LEN_OR_ZERO,
727
- ", REC->%s", event->fields[i]->name);
728
- }
729
-
730
-#undef LEN_OR_ZERO
731
-
732
- /* return the length of print_fmt */
733
- return pos;
734
-}
735
-
736
-static int set_synth_event_print_fmt(struct trace_event_call *call)
737
-{
738
- struct synth_event *event = call->data;
739
- char *print_fmt;
740
- int len;
741
-
742
- /* First: called with 0 length to calculate the needed length */
743
- len = __set_synth_event_print_fmt(event, NULL, 0);
744
-
745
- print_fmt = kmalloc(len + 1, GFP_KERNEL);
746
- if (!print_fmt)
747
- return -ENOMEM;
748
-
749
- /* Second: actually write the @print_fmt */
750
- __set_synth_event_print_fmt(event, print_fmt, len + 1);
751
- call->print_fmt = print_fmt;
752
-
753
- return 0;
754
-}
755
-
756
-static void free_synth_field(struct synth_field *field)
757
-{
758
- kfree(field->type);
759
- kfree(field->name);
760
- kfree(field);
761
-}
762
-
763
-static struct synth_field *parse_synth_field(int argc, char **argv,
764
- int *consumed)
765
-{
766
- struct synth_field *field;
767
- const char *prefix = NULL;
768
- char *field_type = argv[0], *field_name;
769
- int len, ret = 0;
770
- char *array;
771
-
772
- if (field_type[0] == ';')
773
- field_type++;
774
-
775
- if (!strcmp(field_type, "unsigned")) {
776
- if (argc < 3)
777
- return ERR_PTR(-EINVAL);
778
- prefix = "unsigned ";
779
- field_type = argv[1];
780
- field_name = argv[2];
781
- *consumed = 3;
782
- } else {
783
- field_name = argv[1];
784
- *consumed = 2;
785
- }
786
-
787
- len = strlen(field_name);
788
- if (field_name[len - 1] == ';')
789
- field_name[len - 1] = '\0';
790
-
791
- field = kzalloc(sizeof(*field), GFP_KERNEL);
792
- if (!field)
793
- return ERR_PTR(-ENOMEM);
794
-
795
- len = strlen(field_type) + 1;
796
- array = strchr(field_name, '[');
797
- if (array)
798
- len += strlen(array);
799
- if (prefix)
800
- len += strlen(prefix);
801
- field->type = kzalloc(len, GFP_KERNEL);
802
- if (!field->type) {
803
- ret = -ENOMEM;
804
- goto free;
805
- }
806
- if (prefix)
807
- strcat(field->type, prefix);
808
- strcat(field->type, field_type);
809
- if (array) {
810
- strcat(field->type, array);
811
- *array = '\0';
812
- }
813
-
814
- field->size = synth_field_size(field->type);
815
- if (!field->size) {
816
- ret = -EINVAL;
817
- goto free;
818
- }
819
-
820
- if (synth_field_is_string(field->type))
821
- field->is_string = true;
822
-
823
- field->is_signed = synth_field_signed(field->type);
824
-
825
- field->name = kstrdup(field_name, GFP_KERNEL);
826
- if (!field->name) {
827
- ret = -ENOMEM;
828
- goto free;
829
- }
830
- out:
831
- return field;
832
- free:
833
- free_synth_field(field);
834
- field = ERR_PTR(ret);
835
- goto out;
836
-}
837
-
838
-static void free_synth_tracepoint(struct tracepoint *tp)
839
-{
840
- if (!tp)
841
- return;
842
-
843
- kfree(tp->name);
844
- kfree(tp);
845
-}
846
-
847
-static struct tracepoint *alloc_synth_tracepoint(char *name)
848
-{
849
- struct tracepoint *tp;
850
-
851
- tp = kzalloc(sizeof(*tp), GFP_KERNEL);
852
- if (!tp)
853
- return ERR_PTR(-ENOMEM);
854
-
855
- tp->name = kstrdup(name, GFP_KERNEL);
856
- if (!tp->name) {
857
- kfree(tp);
858
- return ERR_PTR(-ENOMEM);
859
- }
860
-
861
- return tp;
580
+ last_cmd[0] = '\0';
581
+ last_cmd_loc[0] = '\0';
862582 }
863583
864584 typedef void (*synth_probe_func_t) (void *__data, u64 *var_ref_vals,
865
- unsigned int var_ref_idx);
585
+ unsigned int *var_ref_idx);
866586
867587 static inline void trace_synth(struct synth_event *event, u64 *var_ref_vals,
868
- unsigned int var_ref_idx)
588
+ unsigned int *var_ref_idx)
869589 {
870590 struct tracepoint *tp = event->tp;
871591
....@@ -888,365 +608,19 @@
888608 }
889609 }
890610
891
-static struct synth_event *find_synth_event(const char *name)
892
-{
893
- struct synth_event *event;
894
-
895
- list_for_each_entry(event, &synth_event_list, list) {
896
- if (strcmp(event->name, name) == 0)
897
- return event;
898
- }
899
-
900
- return NULL;
901
-}
902
-
903
-static int register_synth_event(struct synth_event *event)
904
-{
905
- struct trace_event_call *call = &event->call;
906
- int ret = 0;
907
-
908
- event->call.class = &event->class;
909
- event->class.system = kstrdup(SYNTH_SYSTEM, GFP_KERNEL);
910
- if (!event->class.system) {
911
- ret = -ENOMEM;
912
- goto out;
913
- }
914
-
915
- event->tp = alloc_synth_tracepoint(event->name);
916
- if (IS_ERR(event->tp)) {
917
- ret = PTR_ERR(event->tp);
918
- event->tp = NULL;
919
- goto out;
920
- }
921
-
922
- INIT_LIST_HEAD(&call->class->fields);
923
- call->event.funcs = &synth_event_funcs;
924
- call->class->define_fields = synth_event_define_fields;
925
-
926
- ret = register_trace_event(&call->event);
927
- if (!ret) {
928
- ret = -ENODEV;
929
- goto out;
930
- }
931
- call->flags = TRACE_EVENT_FL_TRACEPOINT;
932
- call->class->reg = trace_event_reg;
933
- call->class->probe = trace_event_raw_event_synth;
934
- call->data = event;
935
- call->tp = event->tp;
936
-
937
- ret = trace_add_event_call_nolock(call);
938
- if (ret) {
939
- pr_warn("Failed to register synthetic event: %s\n",
940
- trace_event_name(call));
941
- goto err;
942
- }
943
-
944
- ret = set_synth_event_print_fmt(call);
945
- if (ret < 0) {
946
- trace_remove_event_call(call);
947
- goto err;
948
- }
949
- out:
950
- return ret;
951
- err:
952
- unregister_trace_event(&call->event);
953
- goto out;
954
-}
955
-
956
-static int unregister_synth_event(struct synth_event *event)
957
-{
958
- struct trace_event_call *call = &event->call;
959
- int ret;
960
-
961
- ret = trace_remove_event_call_nolock(call);
962
-
963
- return ret;
964
-}
965
-
966
-static void free_synth_event(struct synth_event *event)
967
-{
968
- unsigned int i;
969
-
970
- if (!event)
971
- return;
972
-
973
- for (i = 0; i < event->n_fields; i++)
974
- free_synth_field(event->fields[i]);
975
-
976
- kfree(event->fields);
977
- kfree(event->name);
978
- kfree(event->class.system);
979
- free_synth_tracepoint(event->tp);
980
- free_synth_event_print_fmt(&event->call);
981
- kfree(event);
982
-}
983
-
984
-static struct synth_event *alloc_synth_event(char *event_name, int n_fields,
985
- struct synth_field **fields)
986
-{
987
- struct synth_event *event;
988
- unsigned int i;
989
-
990
- event = kzalloc(sizeof(*event), GFP_KERNEL);
991
- if (!event) {
992
- event = ERR_PTR(-ENOMEM);
993
- goto out;
994
- }
995
-
996
- event->name = kstrdup(event_name, GFP_KERNEL);
997
- if (!event->name) {
998
- kfree(event);
999
- event = ERR_PTR(-ENOMEM);
1000
- goto out;
1001
- }
1002
-
1003
- event->fields = kcalloc(n_fields, sizeof(*event->fields), GFP_KERNEL);
1004
- if (!event->fields) {
1005
- free_synth_event(event);
1006
- event = ERR_PTR(-ENOMEM);
1007
- goto out;
1008
- }
1009
-
1010
- for (i = 0; i < n_fields; i++)
1011
- event->fields[i] = fields[i];
1012
-
1013
- event->n_fields = n_fields;
1014
- out:
1015
- return event;
1016
-}
1017
-
1018611 static void action_trace(struct hist_trigger_data *hist_data,
1019612 struct tracing_map_elt *elt, void *rec,
1020
- struct ring_buffer_event *rbe,
613
+ struct ring_buffer_event *rbe, void *key,
1021614 struct action_data *data, u64 *var_ref_vals)
1022615 {
1023
- struct synth_event *event = data->onmatch.synth_event;
616
+ struct synth_event *event = data->synth_event;
1024617
1025
- trace_synth(event, var_ref_vals, data->onmatch.var_ref_idx);
618
+ trace_synth(event, var_ref_vals, data->var_ref_idx);
1026619 }
1027620
1028621 struct hist_var_data {
1029622 struct list_head list;
1030623 struct hist_trigger_data *hist_data;
1031
-};
1032
-
1033
-static void add_or_delete_synth_event(struct synth_event *event, int delete)
1034
-{
1035
- if (delete)
1036
- free_synth_event(event);
1037
- else {
1038
- if (!find_synth_event(event->name))
1039
- list_add(&event->list, &synth_event_list);
1040
- else
1041
- free_synth_event(event);
1042
- }
1043
-}
1044
-
1045
-static int create_synth_event(int argc, char **argv)
1046
-{
1047
- struct synth_field *field, *fields[SYNTH_FIELDS_MAX];
1048
- struct synth_event *event = NULL;
1049
- bool delete_event = false;
1050
- int i, consumed = 0, n_fields = 0, ret = 0;
1051
- char *name;
1052
-
1053
- mutex_lock(&event_mutex);
1054
- mutex_lock(&synth_event_mutex);
1055
-
1056
- /*
1057
- * Argument syntax:
1058
- * - Add synthetic event: <event_name> field[;field] ...
1059
- * - Remove synthetic event: !<event_name> field[;field] ...
1060
- * where 'field' = type field_name
1061
- */
1062
- if (argc < 1) {
1063
- ret = -EINVAL;
1064
- goto out;
1065
- }
1066
-
1067
- name = argv[0];
1068
- if (name[0] == '!') {
1069
- delete_event = true;
1070
- name++;
1071
- }
1072
-
1073
- event = find_synth_event(name);
1074
- if (event) {
1075
- if (delete_event) {
1076
- if (event->ref) {
1077
- event = NULL;
1078
- ret = -EBUSY;
1079
- goto out;
1080
- }
1081
- list_del(&event->list);
1082
- goto out;
1083
- }
1084
- event = NULL;
1085
- ret = -EEXIST;
1086
- goto out;
1087
- } else if (delete_event) {
1088
- ret = -ENOENT;
1089
- goto out;
1090
- }
1091
-
1092
- if (argc < 2) {
1093
- ret = -EINVAL;
1094
- goto out;
1095
- }
1096
-
1097
- for (i = 1; i < argc - 1; i++) {
1098
- if (strcmp(argv[i], ";") == 0)
1099
- continue;
1100
- if (n_fields == SYNTH_FIELDS_MAX) {
1101
- ret = -EINVAL;
1102
- goto err;
1103
- }
1104
-
1105
- field = parse_synth_field(argc - i, &argv[i], &consumed);
1106
- if (IS_ERR(field)) {
1107
- ret = PTR_ERR(field);
1108
- goto err;
1109
- }
1110
- fields[n_fields++] = field;
1111
- i += consumed - 1;
1112
- }
1113
-
1114
- if (i < argc && strcmp(argv[i], ";") != 0) {
1115
- ret = -EINVAL;
1116
- goto err;
1117
- }
1118
-
1119
- event = alloc_synth_event(name, n_fields, fields);
1120
- if (IS_ERR(event)) {
1121
- ret = PTR_ERR(event);
1122
- event = NULL;
1123
- goto err;
1124
- }
1125
- out:
1126
- if (event) {
1127
- if (delete_event) {
1128
- ret = unregister_synth_event(event);
1129
- add_or_delete_synth_event(event, !ret);
1130
- } else {
1131
- ret = register_synth_event(event);
1132
- add_or_delete_synth_event(event, ret);
1133
- }
1134
- }
1135
- mutex_unlock(&synth_event_mutex);
1136
- mutex_unlock(&event_mutex);
1137
-
1138
- return ret;
1139
- err:
1140
- mutex_unlock(&synth_event_mutex);
1141
- mutex_unlock(&event_mutex);
1142
-
1143
- for (i = 0; i < n_fields; i++)
1144
- free_synth_field(fields[i]);
1145
- free_synth_event(event);
1146
-
1147
- return ret;
1148
-}
1149
-
1150
-static int release_all_synth_events(void)
1151
-{
1152
- struct synth_event *event, *e;
1153
- int ret = 0;
1154
-
1155
- mutex_lock(&event_mutex);
1156
- mutex_lock(&synth_event_mutex);
1157
-
1158
- list_for_each_entry(event, &synth_event_list, list) {
1159
- if (event->ref) {
1160
- mutex_unlock(&synth_event_mutex);
1161
- return -EBUSY;
1162
- }
1163
- }
1164
-
1165
- list_for_each_entry_safe(event, e, &synth_event_list, list) {
1166
- list_del(&event->list);
1167
-
1168
- ret = unregister_synth_event(event);
1169
- add_or_delete_synth_event(event, !ret);
1170
- }
1171
- mutex_unlock(&synth_event_mutex);
1172
- mutex_unlock(&event_mutex);
1173
-
1174
- return ret;
1175
-}
1176
-
1177
-
1178
-static void *synth_events_seq_start(struct seq_file *m, loff_t *pos)
1179
-{
1180
- mutex_lock(&synth_event_mutex);
1181
-
1182
- return seq_list_start(&synth_event_list, *pos);
1183
-}
1184
-
1185
-static void *synth_events_seq_next(struct seq_file *m, void *v, loff_t *pos)
1186
-{
1187
- return seq_list_next(v, &synth_event_list, pos);
1188
-}
1189
-
1190
-static void synth_events_seq_stop(struct seq_file *m, void *v)
1191
-{
1192
- mutex_unlock(&synth_event_mutex);
1193
-}
1194
-
1195
-static int synth_events_seq_show(struct seq_file *m, void *v)
1196
-{
1197
- struct synth_field *field;
1198
- struct synth_event *event = v;
1199
- unsigned int i;
1200
-
1201
- seq_printf(m, "%s\t", event->name);
1202
-
1203
- for (i = 0; i < event->n_fields; i++) {
1204
- field = event->fields[i];
1205
-
1206
- /* parameter values */
1207
- seq_printf(m, "%s %s%s", field->type, field->name,
1208
- i == event->n_fields - 1 ? "" : "; ");
1209
- }
1210
-
1211
- seq_putc(m, '\n');
1212
-
1213
- return 0;
1214
-}
1215
-
1216
-static const struct seq_operations synth_events_seq_op = {
1217
- .start = synth_events_seq_start,
1218
- .next = synth_events_seq_next,
1219
- .stop = synth_events_seq_stop,
1220
- .show = synth_events_seq_show
1221
-};
1222
-
1223
-static int synth_events_open(struct inode *inode, struct file *file)
1224
-{
1225
- int ret;
1226
-
1227
- if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
1228
- ret = release_all_synth_events();
1229
- if (ret < 0)
1230
- return ret;
1231
- }
1232
-
1233
- return seq_open(file, &synth_events_seq_op);
1234
-}
1235
-
1236
-static ssize_t synth_events_write(struct file *file,
1237
- const char __user *buffer,
1238
- size_t count, loff_t *ppos)
1239
-{
1240
- return trace_parse_run_command(file, buffer, count, ppos,
1241
- create_synth_event);
1242
-}
1243
-
1244
-static const struct file_operations synth_events_fops = {
1245
- .open = synth_events_open,
1246
- .write = synth_events_write,
1247
- .read = seq_read,
1248
- .llseek = seq_lseek,
1249
- .release = seq_release,
1250624 };
1251625
1252626 static u64 hist_field_timestamp(struct hist_field *hist_field,
....@@ -1291,49 +665,13 @@
1291665 struct hist_trigger_data *var_data,
1292666 unsigned int var_idx)
1293667 {
1294
- struct hist_field *found = NULL;
668
+ WARN_ON(!(hist_field && hist_field->flags & HIST_FIELD_FL_VAR_REF));
1295669
1296
- if (hist_field && hist_field->flags & HIST_FIELD_FL_VAR_REF) {
1297
- if (hist_field->var.idx == var_idx &&
1298
- hist_field->var.hist_data == var_data) {
1299
- found = hist_field;
1300
- }
1301
- }
670
+ if (hist_field && hist_field->var.idx == var_idx &&
671
+ hist_field->var.hist_data == var_data)
672
+ return hist_field;
1302673
1303
- return found;
1304
-}
1305
-
1306
-static struct hist_field *
1307
-check_field_for_var_refs(struct hist_trigger_data *hist_data,
1308
- struct hist_field *hist_field,
1309
- struct hist_trigger_data *var_data,
1310
- unsigned int var_idx,
1311
- unsigned int level)
1312
-{
1313
- struct hist_field *found = NULL;
1314
- unsigned int i;
1315
-
1316
- if (level > 3)
1317
- return found;
1318
-
1319
- if (!hist_field)
1320
- return found;
1321
-
1322
- found = check_field_for_var_ref(hist_field, var_data, var_idx);
1323
- if (found)
1324
- return found;
1325
-
1326
- for (i = 0; i < HIST_FIELD_OPERANDS_MAX; i++) {
1327
- struct hist_field *operand;
1328
-
1329
- operand = hist_field->operands[i];
1330
- found = check_field_for_var_refs(hist_data, operand, var_data,
1331
- var_idx, level + 1);
1332
- if (found)
1333
- return found;
1334
- }
1335
-
1336
- return found;
674
+ return NULL;
1337675 }
1338676
1339677 /**
....@@ -1352,26 +690,16 @@
1352690 struct hist_trigger_data *var_data,
1353691 unsigned int var_idx)
1354692 {
1355
- struct hist_field *hist_field, *found = NULL;
693
+ struct hist_field *hist_field;
1356694 unsigned int i;
1357695
1358
- for_each_hist_field(i, hist_data) {
1359
- hist_field = hist_data->fields[i];
1360
- found = check_field_for_var_refs(hist_data, hist_field,
1361
- var_data, var_idx, 0);
1362
- if (found)
1363
- return found;
696
+ for (i = 0; i < hist_data->n_var_refs; i++) {
697
+ hist_field = hist_data->var_refs[i];
698
+ if (check_field_for_var_ref(hist_field, var_data, var_idx))
699
+ return hist_field;
1364700 }
1365701
1366
- for (i = 0; i < hist_data->n_synth_var_refs; i++) {
1367
- hist_field = hist_data->synth_var_refs[i];
1368
- found = check_field_for_var_refs(hist_data, hist_field,
1369
- var_data, var_idx, 0);
1370
- if (found)
1371
- return found;
1372
- }
1373
-
1374
- return found;
702
+ return NULL;
1375703 }
1376704
1377705 /**
....@@ -1502,7 +830,7 @@
1502830 if (var_data)
1503831 return 0;
1504832
1505
- if (trace_array_get(tr) < 0)
833
+ if (tracing_check_open_get_tr(tr))
1506834 return -ENODEV;
1507835
1508836 var_data = kzalloc(sizeof(*var_data), GFP_KERNEL);
....@@ -1600,7 +928,7 @@
1600928
1601929 if (find_var_field(var_hist_data, var_name)) {
1602930 if (found) {
1603
- hist_err_event("Variable name not unique, need to use fully qualified name (subsys.event.var) for variable: ", system, event_name, var_name);
931
+ hist_err(tr, HIST_ERR_VAR_NOT_UNIQUE, errpos(var_name));
1604932 return NULL;
1605933 }
1606934
....@@ -1643,9 +971,9 @@
1643971 for (i = 0; i < hist_data->n_actions; i++) {
1644972 struct action_data *data = hist_data->actions[i];
1645973
1646
- if (data->fn == action_trace) {
1647
- char *system = data->onmatch.match_event_system;
1648
- char *event_name = data->onmatch.match_event;
974
+ if (data->handler == HANDLER_ONMATCH) {
975
+ char *system = data->match_data.event_system;
976
+ char *event_name = data->match_data.event;
1649977
1650978 file = find_var_file(tr, system, event_name, var_name);
1651979 if (!file)
....@@ -1653,7 +981,8 @@
1653981 hist_field = find_file_var(file, var_name);
1654982 if (hist_field) {
1655983 if (found) {
1656
- hist_err_event("Variable name not unique, need to use fully qualified name (subsys.event.var) for variable: ", system, event_name, var_name);
984
+ hist_err(tr, HIST_ERR_VAR_NOT_UNIQUE,
985
+ errpos(var_name));
1657986 return ERR_PTR(-EINVAL);
1658987 }
1659988
....@@ -1689,12 +1018,6 @@
16891018
16901019 return hist_field;
16911020 }
1692
-
1693
-struct hist_elt_data {
1694
- char *comm;
1695
- u64 *var_ref_vals;
1696
- char *field_var_str[SYNTH_FIELDS_MAX];
1697
-};
16981021
16991022 static u64 hist_field_var_ref(struct hist_field *hist_field,
17001023 struct tracing_map_elt *elt,
....@@ -1763,6 +1086,9 @@
17631086 unsigned int level)
17641087 {
17651088 const char *field_name = "";
1089
+
1090
+ if (WARN_ON_ONCE(!field))
1091
+ return field_name;
17661092
17671093 if (level > 1)
17681094 return field_name;
....@@ -1835,12 +1161,6 @@
18351161 unsigned long size, map_bits;
18361162 int ret;
18371163
1838
- strsep(&str, "=");
1839
- if (!str) {
1840
- ret = -EINVAL;
1841
- goto out;
1842
- }
1843
-
18441164 ret = kstrtoul(str, 0, &size);
18451165 if (ret)
18461166 goto out;
....@@ -1883,8 +1203,9 @@
18831203 if (attrs->n_actions >= HIST_ACTIONS_MAX)
18841204 return ret;
18851205
1886
- if ((strncmp(str, "onmatch(", strlen("onmatch(")) == 0) ||
1887
- (strncmp(str, "onmax(", strlen("onmax(")) == 0)) {
1206
+ if ((str_has_prefix(str, "onmatch(")) ||
1207
+ (str_has_prefix(str, "onmax(")) ||
1208
+ (str_has_prefix(str, "onchange("))) {
18881209 attrs->action_str[attrs->n_actions] = kstrdup(str, GFP_KERNEL);
18891210 if (!attrs->action_str[attrs->n_actions]) {
18901211 ret = -ENOMEM;
....@@ -1893,47 +1214,43 @@
18931214 attrs->n_actions++;
18941215 ret = 0;
18951216 }
1896
-
18971217 return ret;
18981218 }
18991219
1900
-static int parse_assignment(char *str, struct hist_trigger_attrs *attrs)
1220
+static int parse_assignment(struct trace_array *tr,
1221
+ char *str, struct hist_trigger_attrs *attrs)
19011222 {
1902
- int ret = 0;
1223
+ int len, ret = 0;
19031224
1904
- if ((strncmp(str, "key=", strlen("key=")) == 0) ||
1905
- (strncmp(str, "keys=", strlen("keys=")) == 0)) {
1906
- attrs->keys_str = kstrdup(str, GFP_KERNEL);
1225
+ if ((len = str_has_prefix(str, "key=")) ||
1226
+ (len = str_has_prefix(str, "keys="))) {
1227
+ attrs->keys_str = kstrdup(str + len, GFP_KERNEL);
19071228 if (!attrs->keys_str) {
19081229 ret = -ENOMEM;
19091230 goto out;
19101231 }
1911
- } else if ((strncmp(str, "val=", strlen("val=")) == 0) ||
1912
- (strncmp(str, "vals=", strlen("vals=")) == 0) ||
1913
- (strncmp(str, "values=", strlen("values=")) == 0)) {
1914
- attrs->vals_str = kstrdup(str, GFP_KERNEL);
1232
+ } else if ((len = str_has_prefix(str, "val=")) ||
1233
+ (len = str_has_prefix(str, "vals=")) ||
1234
+ (len = str_has_prefix(str, "values="))) {
1235
+ attrs->vals_str = kstrdup(str + len, GFP_KERNEL);
19151236 if (!attrs->vals_str) {
19161237 ret = -ENOMEM;
19171238 goto out;
19181239 }
1919
- } else if (strncmp(str, "sort=", strlen("sort=")) == 0) {
1920
- attrs->sort_key_str = kstrdup(str, GFP_KERNEL);
1240
+ } else if ((len = str_has_prefix(str, "sort="))) {
1241
+ attrs->sort_key_str = kstrdup(str + len, GFP_KERNEL);
19211242 if (!attrs->sort_key_str) {
19221243 ret = -ENOMEM;
19231244 goto out;
19241245 }
1925
- } else if (strncmp(str, "name=", strlen("name=")) == 0) {
1246
+ } else if (str_has_prefix(str, "name=")) {
19261247 attrs->name = kstrdup(str, GFP_KERNEL);
19271248 if (!attrs->name) {
19281249 ret = -ENOMEM;
19291250 goto out;
19301251 }
1931
- } else if (strncmp(str, "clock=", strlen("clock=")) == 0) {
1932
- strsep(&str, "=");
1933
- if (!str) {
1934
- ret = -EINVAL;
1935
- goto out;
1936
- }
1252
+ } else if ((len = str_has_prefix(str, "clock="))) {
1253
+ str += len;
19371254
19381255 str = strstrip(str);
19391256 attrs->clock = kstrdup(str, GFP_KERNEL);
....@@ -1941,8 +1258,8 @@
19411258 ret = -ENOMEM;
19421259 goto out;
19431260 }
1944
- } else if (strncmp(str, "size=", strlen("size=")) == 0) {
1945
- int map_bits = parse_map_size(str);
1261
+ } else if ((len = str_has_prefix(str, "size="))) {
1262
+ int map_bits = parse_map_size(str + len);
19461263
19471264 if (map_bits < 0) {
19481265 ret = map_bits;
....@@ -1953,7 +1270,7 @@
19531270 char *assignment;
19541271
19551272 if (attrs->n_assignments == TRACING_MAP_VARS_MAX) {
1956
- hist_err("Too many variables defined: ", str);
1273
+ hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(str));
19571274 ret = -EINVAL;
19581275 goto out;
19591276 }
....@@ -1970,7 +1287,8 @@
19701287 return ret;
19711288 }
19721289
1973
-static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str)
1290
+static struct hist_trigger_attrs *
1291
+parse_hist_trigger_attrs(struct trace_array *tr, char *trigger_str)
19741292 {
19751293 struct hist_trigger_attrs *attrs;
19761294 int ret = 0;
....@@ -1981,9 +1299,16 @@
19811299
19821300 while (trigger_str) {
19831301 char *str = strsep(&trigger_str, ":");
1302
+ char *rhs;
19841303
1985
- if (strchr(str, '=')) {
1986
- ret = parse_assignment(str, attrs);
1304
+ rhs = strchr(str, '=');
1305
+ if (rhs) {
1306
+ if (!strlen(++rhs)) {
1307
+ ret = -EINVAL;
1308
+ hist_err(tr, HIST_ERR_EMPTY_ASSIGNMENT, errpos(str));
1309
+ goto free;
1310
+ }
1311
+ ret = parse_assignment(tr, str, attrs);
19871312 if (ret)
19881313 goto free;
19891314 } else if (strcmp(str, "pause") == 0)
....@@ -2032,7 +1357,7 @@
20321357 return;
20331358 }
20341359
2035
- memcpy(comm, task->comm, TASK_COMM_LEN);
1360
+ strncpy(comm, task->comm, TASK_COMM_LEN);
20361361 }
20371362
20381363 static void hist_elt_data_free(struct hist_elt_data *elt_data)
....@@ -2078,7 +1403,14 @@
20781403 }
20791404 }
20801405
2081
- n_str = hist_data->n_field_var_str + hist_data->n_max_var_str;
1406
+ n_str = hist_data->n_field_var_str + hist_data->n_save_var_str +
1407
+ hist_data->n_var_str;
1408
+ if (n_str > SYNTH_FIELDS_MAX) {
1409
+ hist_elt_data_free(elt_data);
1410
+ return -EINVAL;
1411
+ }
1412
+
1413
+ BUILD_BUG_ON(STR_VAR_LEN_MAX & (sizeof(u64) - 1));
20821414
20831415 size = STR_VAR_LEN_MAX;
20841416
....@@ -2247,6 +1579,9 @@
22471579 kfree(hist_field->name);
22481580 kfree(hist_field->type);
22491581
1582
+ kfree(hist_field->system);
1583
+ kfree(hist_field->event_name);
1584
+
22501585 kfree(hist_field);
22511586 }
22521587
....@@ -2314,6 +1649,8 @@
23141649 unsigned long fl = flags & ~HIST_FIELD_FL_LOG2;
23151650 hist_field->fn = hist_field_log2;
23161651 hist_field->operands[0] = create_hist_field(hist_data, field, fl, NULL);
1652
+ if (!hist_field->operands[0])
1653
+ goto free;
23171654 hist_field->size = hist_field->operands[0]->size;
23181655 hist_field->type = kstrdup(hist_field->operands[0]->type, GFP_KERNEL);
23191656 if (!hist_field->type)
....@@ -2352,9 +1689,10 @@
23521689 if (!hist_field->type)
23531690 goto free;
23541691
2355
- if (field->filter_type == FILTER_STATIC_STRING)
1692
+ if (field->filter_type == FILTER_STATIC_STRING) {
23561693 hist_field->fn = hist_field_string;
2357
- else if (field->filter_type == FILTER_DYN_STRING)
1694
+ hist_field->size = field->size;
1695
+ } else if (field->filter_type == FILTER_DYN_STRING)
23581696 hist_field->fn = hist_field_dynstring;
23591697 else
23601698 hist_field->fn = hist_field_pstring;
....@@ -2456,10 +1794,29 @@
24561794 return err;
24571795 free:
24581796 kfree(ref_field->system);
1797
+ ref_field->system = NULL;
24591798 kfree(ref_field->event_name);
1799
+ ref_field->event_name = NULL;
24601800 kfree(ref_field->name);
1801
+ ref_field->name = NULL;
24611802
24621803 goto out;
1804
+}
1805
+
1806
+static int find_var_ref_idx(struct hist_trigger_data *hist_data,
1807
+ struct hist_field *var_field)
1808
+{
1809
+ struct hist_field *ref_field;
1810
+ int i;
1811
+
1812
+ for (i = 0; i < hist_data->n_var_refs; i++) {
1813
+ ref_field = hist_data->var_refs[i];
1814
+ if (ref_field->var.idx == var_field->var.idx &&
1815
+ ref_field->var.hist_data == var_field->hist_data)
1816
+ return i;
1817
+ }
1818
+
1819
+ return -ENOENT;
24631820 }
24641821
24651822 /**
....@@ -2494,7 +1851,9 @@
24941851 return ref_field;
24951852 }
24961853 }
2497
-
1854
+ /* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */
1855
+ if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX)
1856
+ return NULL;
24981857 ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
24991858 if (ref_field) {
25001859 if (init_var_ref(ref_field, var_field, system, event_name)) {
....@@ -2569,6 +1928,7 @@
25691928 char *var_name)
25701929 {
25711930 struct hist_field *var_field = NULL, *ref_field = NULL;
1931
+ struct trace_array *tr = hist_data->event_file->tr;
25721932
25731933 if (!is_var_ref(var_name))
25741934 return NULL;
....@@ -2581,8 +1941,7 @@
25811941 system, event_name);
25821942
25831943 if (!ref_field)
2584
- hist_err_event("Couldn't find variable: $",
2585
- system, event_name, var_name);
1944
+ hist_err(tr, HIST_ERR_VAR_NOT_FOUND, errpos(var_name));
25861945
25871946 return ref_field;
25881947 }
....@@ -2593,6 +1952,7 @@
25931952 {
25941953 struct ftrace_event_field *field = NULL;
25951954 char *field_name, *modifier, *str;
1955
+ struct trace_array *tr = file->tr;
25961956
25971957 modifier = str = kstrdup(field_str, GFP_KERNEL);
25981958 if (!modifier)
....@@ -2616,7 +1976,7 @@
26161976 else if (strcmp(modifier, "usecs") == 0)
26171977 *flags |= HIST_FIELD_FL_TIMESTAMP_USECS;
26181978 else {
2619
- hist_err("Invalid field modifier: ", modifier);
1979
+ hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(modifier));
26201980 field = ERR_PTR(-EINVAL);
26211981 goto out;
26221982 }
....@@ -2635,12 +1995,13 @@
26351995 /*
26361996 * For backward compatibility, if field_name
26371997 * was "cpu", then we treat this the same as
2638
- * common_cpu.
1998
+ * common_cpu. This also works for "CPU".
26391999 */
2640
- if (strcmp(field_name, "cpu") == 0) {
2000
+ if (field && field->filter_type == FILTER_CPU) {
26412001 *flags |= HIST_FIELD_FL_CPU;
26422002 } else {
2643
- hist_err("Couldn't find field: ", field_name);
2003
+ hist_err(tr, HIST_ERR_FIELD_NOT_FOUND,
2004
+ errpos(field_name));
26442005 field = ERR_PTR(-EINVAL);
26452006 goto out;
26462007 }
....@@ -2705,7 +2066,8 @@
27052066
27062067 s = local_field_var_ref(hist_data, ref_system, ref_event, ref_var);
27072068 if (!s) {
2708
- hist_field = parse_var_ref(hist_data, ref_system, ref_event, ref_var);
2069
+ hist_field = parse_var_ref(hist_data, ref_system,
2070
+ ref_event, ref_var);
27092071 if (hist_field) {
27102072 if (var_name) {
27112073 hist_field = create_alias(hist_data, hist_field, var_name);
....@@ -2754,7 +2116,7 @@
27542116 /* we support only -(xxx) i.e. explicit parens required */
27552117
27562118 if (level > 3) {
2757
- hist_err("Too many subexpressions (3 max): ", str);
2119
+ hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str));
27582120 ret = -EINVAL;
27592121 goto free;
27602122 }
....@@ -2792,6 +2154,7 @@
27922154 }
27932155 if (operand1->flags & HIST_FIELD_FL_STRING) {
27942156 /* String type can not be the operand of unary operator. */
2157
+ hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
27952158 destroy_hist_field(operand1, 0);
27962159 ret = -EINVAL;
27972160 goto free;
....@@ -2801,6 +2164,8 @@
28012164 (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
28022165 expr->fn = hist_field_unary_minus;
28032166 expr->operands[0] = operand1;
2167
+ expr->size = operand1->size;
2168
+ expr->is_signed = operand1->is_signed;
28042169 expr->operator = FIELD_OP_UNARY_MINUS;
28052170 expr->name = expr_str(expr, 0);
28062171 expr->type = kstrdup(operand1->type, GFP_KERNEL);
....@@ -2815,7 +2180,8 @@
28152180 return ERR_PTR(ret);
28162181 }
28172182
2818
-static int check_expr_operands(struct hist_field *operand1,
2183
+static int check_expr_operands(struct trace_array *tr,
2184
+ struct hist_field *operand1,
28192185 struct hist_field *operand2)
28202186 {
28212187 unsigned long operand1_flags = operand1->flags;
....@@ -2843,7 +2209,7 @@
28432209
28442210 if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) !=
28452211 (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) {
2846
- hist_err("Timestamp units in expression don't match", NULL);
2212
+ hist_err(tr, HIST_ERR_TIMESTAMP_MISMATCH, 0);
28472213 return -EINVAL;
28482214 }
28492215
....@@ -2861,7 +2227,7 @@
28612227 char *sep, *operand1_str;
28622228
28632229 if (level > 3) {
2864
- hist_err("Too many subexpressions (3 max): ", str);
2230
+ hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str));
28652231 return ERR_PTR(-EINVAL);
28662232 }
28672233
....@@ -2897,6 +2263,7 @@
28972263 goto free;
28982264 }
28992265 if (operand1->flags & HIST_FIELD_FL_STRING) {
2266
+ hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(operand1_str));
29002267 ret = -EINVAL;
29012268 goto free;
29022269 }
....@@ -2910,11 +2277,12 @@
29102277 goto free;
29112278 }
29122279 if (operand2->flags & HIST_FIELD_FL_STRING) {
2280
+ hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
29132281 ret = -EINVAL;
29142282 goto free;
29152283 }
29162284
2917
- ret = check_expr_operands(operand1, operand2);
2285
+ ret = check_expr_operands(file->tr, operand1, operand2);
29182286 if (ret)
29192287 goto free;
29202288
....@@ -2937,6 +2305,7 @@
29372305
29382306 /* The operand sizes should be the same, so just pick one */
29392307 expr->size = operand1->size;
2308
+ expr->is_signed = operand1->is_signed;
29402309
29412310 expr->operator = field_op;
29422311 expr->name = expr_str(expr, 0);
....@@ -3115,16 +2484,14 @@
31152484 int ret;
31162485
31172486 if (target_hist_data->n_field_var_hists >= SYNTH_FIELDS_MAX) {
3118
- hist_err_event("onmatch: Too many field variables defined: ",
3119
- subsys_name, event_name, field_name);
2487
+ hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name));
31202488 return ERR_PTR(-EINVAL);
31212489 }
31222490
31232491 file = event_file(tr, subsys_name, event_name);
31242492
31252493 if (IS_ERR(file)) {
3126
- hist_err_event("onmatch: Event file not found: ",
3127
- subsys_name, event_name, field_name);
2494
+ hist_err(tr, HIST_ERR_EVENT_FILE_NOT_FOUND, errpos(field_name));
31282495 ret = PTR_ERR(file);
31292496 return ERR_PTR(ret);
31302497 }
....@@ -3137,8 +2504,7 @@
31372504 */
31382505 hist_data = find_compatible_hist(target_hist_data, file);
31392506 if (!hist_data) {
3140
- hist_err_event("onmatch: Matching event histogram not found: ",
3141
- subsys_name, event_name, field_name);
2507
+ hist_err(tr, HIST_ERR_HIST_NOT_FOUND, errpos(field_name));
31422508 return ERR_PTR(-EINVAL);
31432509 }
31442510
....@@ -3199,8 +2565,7 @@
31992565 kfree(cmd);
32002566 kfree(var_hist->cmd);
32012567 kfree(var_hist);
3202
- hist_err_event("onmatch: Couldn't create histogram for field: ",
3203
- subsys_name, event_name, field_name);
2568
+ hist_err(tr, HIST_ERR_HIST_CREATE_FAIL, errpos(field_name));
32042569 return ERR_PTR(ret);
32052570 }
32062571
....@@ -3212,8 +2577,7 @@
32122577 if (IS_ERR_OR_NULL(event_var)) {
32132578 kfree(var_hist->cmd);
32142579 kfree(var_hist);
3215
- hist_err_event("onmatch: Couldn't find synthetic variable: ",
3216
- subsys_name, event_name, field_name);
2580
+ hist_err(tr, HIST_ERR_SYNTH_VAR_NOT_FOUND, errpos(field_name));
32172581 return ERR_PTR(-EINVAL);
32182582 }
32192583
....@@ -3273,8 +2637,10 @@
32732637 if (val->flags & HIST_FIELD_FL_STRING) {
32742638 char *str = elt_data->field_var_str[j++];
32752639 char *val_str = (char *)(uintptr_t)var_val;
2640
+ unsigned int size;
32762641
3277
- strscpy(str, val_str, STR_VAR_LEN_MAX);
2642
+ size = min(val->size, STR_VAR_LEN_MAX);
2643
+ strscpy(str, val_str, size);
32782644 var_val = (u64)(uintptr_t)str;
32792645 }
32802646 tracing_map_set_var(elt, var_idx, var_val);
....@@ -3290,13 +2656,13 @@
32902656 hist_data->n_field_vars, 0);
32912657 }
32922658
3293
-static void update_max_vars(struct hist_trigger_data *hist_data,
3294
- struct tracing_map_elt *elt,
3295
- struct ring_buffer_event *rbe,
3296
- void *rec)
2659
+static void save_track_data_vars(struct hist_trigger_data *hist_data,
2660
+ struct tracing_map_elt *elt, void *rec,
2661
+ struct ring_buffer_event *rbe, void *key,
2662
+ struct action_data *data, u64 *var_ref_vals)
32972663 {
3298
- __update_field_vars(elt, rbe, rec, hist_data->max_vars,
3299
- hist_data->n_max_vars, hist_data->n_field_var_str);
2664
+ __update_field_vars(elt, rbe, rec, hist_data->save_vars,
2665
+ hist_data->n_save_vars, hist_data->n_field_var_str);
33002666 }
33012667
33022668 static struct hist_field *create_var(struct hist_trigger_data *hist_data,
....@@ -3324,6 +2690,7 @@
33242690 goto out;
33252691 }
33262692
2693
+ var->ref = 1;
33272694 var->flags = HIST_FIELD_FL_VAR;
33282695 var->var.idx = idx;
33292696 var->var.hist_data = var->hist_data = hist_data;
....@@ -3346,25 +2713,26 @@
33462713 {
33472714 struct hist_field *val = NULL, *var = NULL;
33482715 unsigned long flags = HIST_FIELD_FL_VAR;
2716
+ struct trace_array *tr = file->tr;
33492717 struct field_var *field_var;
33502718 int ret = 0;
33512719
33522720 if (hist_data->n_field_vars >= SYNTH_FIELDS_MAX) {
3353
- hist_err("Too many field variables defined: ", field_name);
2721
+ hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name));
33542722 ret = -EINVAL;
33552723 goto err;
33562724 }
33572725
33582726 val = parse_atom(hist_data, file, field_name, &flags, NULL);
33592727 if (IS_ERR(val)) {
3360
- hist_err("Couldn't parse field variable: ", field_name);
2728
+ hist_err(tr, HIST_ERR_FIELD_VAR_PARSE_FAIL, errpos(field_name));
33612729 ret = PTR_ERR(val);
33622730 goto err;
33632731 }
33642732
33652733 var = create_var(hist_data, file, field_name, val->size, val->type);
33662734 if (IS_ERR(var)) {
3367
- hist_err("Couldn't create or find variable: ", field_name);
2735
+ hist_err(tr, HIST_ERR_VAR_CREATE_FIND_FAIL, errpos(field_name));
33682736 kfree(val);
33692737 ret = PTR_ERR(var);
33702738 goto err;
....@@ -3431,18 +2799,196 @@
34312799 return create_field_var(target_hist_data, file, var_name);
34322800 }
34332801
3434
-static void onmax_print(struct seq_file *m,
3435
- struct hist_trigger_data *hist_data,
3436
- struct tracing_map_elt *elt,
3437
- struct action_data *data)
2802
+static bool check_track_val_max(u64 track_val, u64 var_val)
34382803 {
3439
- unsigned int i, save_var_idx, max_idx = data->onmax.max_var->var.idx;
2804
+ if (var_val <= track_val)
2805
+ return false;
34402806
3441
- seq_printf(m, "\n\tmax: %10llu", tracing_map_read_var(elt, max_idx));
2807
+ return true;
2808
+}
34422809
3443
- for (i = 0; i < hist_data->n_max_vars; i++) {
3444
- struct hist_field *save_val = hist_data->max_vars[i]->val;
3445
- struct hist_field *save_var = hist_data->max_vars[i]->var;
2810
+static bool check_track_val_changed(u64 track_val, u64 var_val)
2811
+{
2812
+ if (var_val == track_val)
2813
+ return false;
2814
+
2815
+ return true;
2816
+}
2817
+
2818
+static u64 get_track_val(struct hist_trigger_data *hist_data,
2819
+ struct tracing_map_elt *elt,
2820
+ struct action_data *data)
2821
+{
2822
+ unsigned int track_var_idx = data->track_data.track_var->var.idx;
2823
+ u64 track_val;
2824
+
2825
+ track_val = tracing_map_read_var(elt, track_var_idx);
2826
+
2827
+ return track_val;
2828
+}
2829
+
2830
+static void save_track_val(struct hist_trigger_data *hist_data,
2831
+ struct tracing_map_elt *elt,
2832
+ struct action_data *data, u64 var_val)
2833
+{
2834
+ unsigned int track_var_idx = data->track_data.track_var->var.idx;
2835
+
2836
+ tracing_map_set_var(elt, track_var_idx, var_val);
2837
+}
2838
+
2839
+static void save_track_data(struct hist_trigger_data *hist_data,
2840
+ struct tracing_map_elt *elt, void *rec,
2841
+ struct ring_buffer_event *rbe, void *key,
2842
+ struct action_data *data, u64 *var_ref_vals)
2843
+{
2844
+ if (data->track_data.save_data)
2845
+ data->track_data.save_data(hist_data, elt, rec, rbe, key, data, var_ref_vals);
2846
+}
2847
+
2848
+static bool check_track_val(struct tracing_map_elt *elt,
2849
+ struct action_data *data,
2850
+ u64 var_val)
2851
+{
2852
+ struct hist_trigger_data *hist_data;
2853
+ u64 track_val;
2854
+
2855
+ hist_data = data->track_data.track_var->hist_data;
2856
+ track_val = get_track_val(hist_data, elt, data);
2857
+
2858
+ return data->track_data.check_val(track_val, var_val);
2859
+}
2860
+
2861
+#ifdef CONFIG_TRACER_SNAPSHOT
2862
+static bool cond_snapshot_update(struct trace_array *tr, void *cond_data)
2863
+{
2864
+ /* called with tr->max_lock held */
2865
+ struct track_data *track_data = tr->cond_snapshot->cond_data;
2866
+ struct hist_elt_data *elt_data, *track_elt_data;
2867
+ struct snapshot_context *context = cond_data;
2868
+ struct action_data *action;
2869
+ u64 track_val;
2870
+
2871
+ if (!track_data)
2872
+ return false;
2873
+
2874
+ action = track_data->action_data;
2875
+
2876
+ track_val = get_track_val(track_data->hist_data, context->elt,
2877
+ track_data->action_data);
2878
+
2879
+ if (!action->track_data.check_val(track_data->track_val, track_val))
2880
+ return false;
2881
+
2882
+ track_data->track_val = track_val;
2883
+ memcpy(track_data->key, context->key, track_data->key_len);
2884
+
2885
+ elt_data = context->elt->private_data;
2886
+ track_elt_data = track_data->elt.private_data;
2887
+ if (elt_data->comm)
2888
+ strncpy(track_elt_data->comm, elt_data->comm, TASK_COMM_LEN);
2889
+
2890
+ track_data->updated = true;
2891
+
2892
+ return true;
2893
+}
2894
+
2895
+static void save_track_data_snapshot(struct hist_trigger_data *hist_data,
2896
+ struct tracing_map_elt *elt, void *rec,
2897
+ struct ring_buffer_event *rbe, void *key,
2898
+ struct action_data *data,
2899
+ u64 *var_ref_vals)
2900
+{
2901
+ struct trace_event_file *file = hist_data->event_file;
2902
+ struct snapshot_context context;
2903
+
2904
+ context.elt = elt;
2905
+ context.key = key;
2906
+
2907
+ tracing_snapshot_cond(file->tr, &context);
2908
+}
2909
+
2910
+static void hist_trigger_print_key(struct seq_file *m,
2911
+ struct hist_trigger_data *hist_data,
2912
+ void *key,
2913
+ struct tracing_map_elt *elt);
2914
+
2915
+static struct action_data *snapshot_action(struct hist_trigger_data *hist_data)
2916
+{
2917
+ unsigned int i;
2918
+
2919
+ if (!hist_data->n_actions)
2920
+ return NULL;
2921
+
2922
+ for (i = 0; i < hist_data->n_actions; i++) {
2923
+ struct action_data *data = hist_data->actions[i];
2924
+
2925
+ if (data->action == ACTION_SNAPSHOT)
2926
+ return data;
2927
+ }
2928
+
2929
+ return NULL;
2930
+}
2931
+
2932
+static void track_data_snapshot_print(struct seq_file *m,
2933
+ struct hist_trigger_data *hist_data)
2934
+{
2935
+ struct trace_event_file *file = hist_data->event_file;
2936
+ struct track_data *track_data;
2937
+ struct action_data *action;
2938
+
2939
+ track_data = tracing_cond_snapshot_data(file->tr);
2940
+ if (!track_data)
2941
+ return;
2942
+
2943
+ if (!track_data->updated)
2944
+ return;
2945
+
2946
+ action = snapshot_action(hist_data);
2947
+ if (!action)
2948
+ return;
2949
+
2950
+ seq_puts(m, "\nSnapshot taken (see tracing/snapshot). Details:\n");
2951
+ seq_printf(m, "\ttriggering value { %s(%s) }: %10llu",
2952
+ action->handler == HANDLER_ONMAX ? "onmax" : "onchange",
2953
+ action->track_data.var_str, track_data->track_val);
2954
+
2955
+ seq_puts(m, "\ttriggered by event with key: ");
2956
+ hist_trigger_print_key(m, hist_data, track_data->key, &track_data->elt);
2957
+ seq_putc(m, '\n');
2958
+}
2959
+#else
2960
+static bool cond_snapshot_update(struct trace_array *tr, void *cond_data)
2961
+{
2962
+ return false;
2963
+}
2964
+static void save_track_data_snapshot(struct hist_trigger_data *hist_data,
2965
+ struct tracing_map_elt *elt, void *rec,
2966
+ struct ring_buffer_event *rbe, void *key,
2967
+ struct action_data *data,
2968
+ u64 *var_ref_vals) {}
2969
+static void track_data_snapshot_print(struct seq_file *m,
2970
+ struct hist_trigger_data *hist_data) {}
2971
+#endif /* CONFIG_TRACER_SNAPSHOT */
2972
+
2973
+static void track_data_print(struct seq_file *m,
2974
+ struct hist_trigger_data *hist_data,
2975
+ struct tracing_map_elt *elt,
2976
+ struct action_data *data)
2977
+{
2978
+ u64 track_val = get_track_val(hist_data, elt, data);
2979
+ unsigned int i, save_var_idx;
2980
+
2981
+ if (data->handler == HANDLER_ONMAX)
2982
+ seq_printf(m, "\n\tmax: %10llu", track_val);
2983
+ else if (data->handler == HANDLER_ONCHANGE)
2984
+ seq_printf(m, "\n\tchanged: %10llu", track_val);
2985
+
2986
+ if (data->action == ACTION_SNAPSHOT)
2987
+ return;
2988
+
2989
+ for (i = 0; i < hist_data->n_save_vars; i++) {
2990
+ struct hist_field *save_val = hist_data->save_vars[i]->val;
2991
+ struct hist_field *save_var = hist_data->save_vars[i]->var;
34462992 u64 val;
34472993
34482994 save_var_idx = save_var->var.idx;
....@@ -3457,64 +3003,82 @@
34573003 }
34583004 }
34593005
3460
-static void onmax_save(struct hist_trigger_data *hist_data,
3461
- struct tracing_map_elt *elt, void *rec,
3462
- struct ring_buffer_event *rbe,
3463
- struct action_data *data, u64 *var_ref_vals)
3006
+static void ontrack_action(struct hist_trigger_data *hist_data,
3007
+ struct tracing_map_elt *elt, void *rec,
3008
+ struct ring_buffer_event *rbe, void *key,
3009
+ struct action_data *data, u64 *var_ref_vals)
34643010 {
3465
- unsigned int max_idx = data->onmax.max_var->var.idx;
3466
- unsigned int max_var_ref_idx = data->onmax.max_var_ref_idx;
3011
+ u64 var_val = var_ref_vals[data->track_data.var_ref->var_ref_idx];
34673012
3468
- u64 var_val, max_val;
3469
-
3470
- var_val = var_ref_vals[max_var_ref_idx];
3471
- max_val = tracing_map_read_var(elt, max_idx);
3472
-
3473
- if (var_val <= max_val)
3474
- return;
3475
-
3476
- tracing_map_set_var(elt, max_idx, var_val);
3477
-
3478
- update_max_vars(hist_data, elt, rbe, rec);
3013
+ if (check_track_val(elt, data, var_val)) {
3014
+ save_track_val(hist_data, elt, data, var_val);
3015
+ save_track_data(hist_data, elt, rec, rbe, key, data, var_ref_vals);
3016
+ }
34793017 }
34803018
3481
-static void onmax_destroy(struct action_data *data)
3019
+static void action_data_destroy(struct action_data *data)
34823020 {
34833021 unsigned int i;
34843022
3485
- destroy_hist_field(data->onmax.max_var, 0);
3486
- destroy_hist_field(data->onmax.var, 0);
3023
+ lockdep_assert_held(&event_mutex);
34873024
3488
- kfree(data->onmax.var_str);
3489
- kfree(data->onmax.fn_name);
3025
+ kfree(data->action_name);
34903026
34913027 for (i = 0; i < data->n_params; i++)
34923028 kfree(data->params[i]);
34933029
3030
+ if (data->synth_event)
3031
+ data->synth_event->ref--;
3032
+
3033
+ kfree(data->synth_event_name);
3034
+
34943035 kfree(data);
34953036 }
34963037
3497
-static int onmax_create(struct hist_trigger_data *hist_data,
3498
- struct action_data *data)
3038
+static void track_data_destroy(struct hist_trigger_data *hist_data,
3039
+ struct action_data *data)
34993040 {
35003041 struct trace_event_file *file = hist_data->event_file;
3501
- struct hist_field *var_field, *ref_field, *max_var;
3502
- unsigned int var_ref_idx = hist_data->n_var_refs;
3503
- struct field_var *field_var;
3504
- char *onmax_var_str, *param;
3505
- unsigned int i;
3042
+
3043
+ destroy_hist_field(data->track_data.track_var, 0);
3044
+
3045
+ if (data->action == ACTION_SNAPSHOT) {
3046
+ struct track_data *track_data;
3047
+
3048
+ track_data = tracing_cond_snapshot_data(file->tr);
3049
+ if (track_data && track_data->hist_data == hist_data) {
3050
+ tracing_snapshot_cond_disable(file->tr);
3051
+ track_data_free(track_data);
3052
+ }
3053
+ }
3054
+
3055
+ kfree(data->track_data.var_str);
3056
+
3057
+ action_data_destroy(data);
3058
+}
3059
+
3060
+static int action_create(struct hist_trigger_data *hist_data,
3061
+ struct action_data *data);
3062
+
3063
+static int track_data_create(struct hist_trigger_data *hist_data,
3064
+ struct action_data *data)
3065
+{
3066
+ struct hist_field *var_field, *ref_field, *track_var = NULL;
3067
+ struct trace_event_file *file = hist_data->event_file;
3068
+ struct trace_array *tr = file->tr;
3069
+ char *track_data_var_str;
35063070 int ret = 0;
35073071
3508
- onmax_var_str = data->onmax.var_str;
3509
- if (onmax_var_str[0] != '$') {
3510
- hist_err("onmax: For onmax(x), x must be a variable: ", onmax_var_str);
3072
+ track_data_var_str = data->track_data.var_str;
3073
+ if (track_data_var_str[0] != '$') {
3074
+ hist_err(tr, HIST_ERR_ONX_NOT_VAR, errpos(track_data_var_str));
35113075 return -EINVAL;
35123076 }
3513
- onmax_var_str++;
3077
+ track_data_var_str++;
35143078
3515
- var_field = find_target_event_var(hist_data, NULL, NULL, onmax_var_str);
3079
+ var_field = find_target_event_var(hist_data, NULL, NULL, track_data_var_str);
35163080 if (!var_field) {
3517
- hist_err("onmax: Couldn't find onmax variable: ", onmax_var_str);
3081
+ hist_err(tr, HIST_ERR_ONX_VAR_NOT_FOUND, errpos(track_data_var_str));
35183082 return -EINVAL;
35193083 }
35203084
....@@ -3522,61 +3086,54 @@
35223086 if (!ref_field)
35233087 return -ENOMEM;
35243088
3525
- data->onmax.var = ref_field;
3089
+ data->track_data.var_ref = ref_field;
35263090
3527
- data->fn = onmax_save;
3528
- data->onmax.max_var_ref_idx = var_ref_idx;
3529
- max_var = create_var(hist_data, file, "max", sizeof(u64), "u64");
3530
- if (IS_ERR(max_var)) {
3531
- hist_err("onmax: Couldn't create onmax variable: ", "max");
3532
- ret = PTR_ERR(max_var);
3091
+ if (data->handler == HANDLER_ONMAX)
3092
+ track_var = create_var(hist_data, file, "__max", sizeof(u64), "u64");
3093
+ if (IS_ERR(track_var)) {
3094
+ hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0);
3095
+ ret = PTR_ERR(track_var);
35333096 goto out;
35343097 }
3535
- data->onmax.max_var = max_var;
35363098
3537
- for (i = 0; i < data->n_params; i++) {
3538
- param = kstrdup(data->params[i], GFP_KERNEL);
3539
- if (!param) {
3540
- ret = -ENOMEM;
3541
- goto out;
3542
- }
3543
-
3544
- field_var = create_target_field_var(hist_data, NULL, NULL, param);
3545
- if (IS_ERR(field_var)) {
3546
- hist_err("onmax: Couldn't create field variable: ", param);
3547
- ret = PTR_ERR(field_var);
3548
- kfree(param);
3549
- goto out;
3550
- }
3551
-
3552
- hist_data->max_vars[hist_data->n_max_vars++] = field_var;
3553
- if (field_var->val->flags & HIST_FIELD_FL_STRING)
3554
- hist_data->n_max_var_str++;
3555
-
3556
- kfree(param);
3099
+ if (data->handler == HANDLER_ONCHANGE)
3100
+ track_var = create_var(hist_data, file, "__change", sizeof(u64), "u64");
3101
+ if (IS_ERR(track_var)) {
3102
+ hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0);
3103
+ ret = PTR_ERR(track_var);
3104
+ goto out;
35573105 }
3106
+ data->track_data.track_var = track_var;
3107
+
3108
+ ret = action_create(hist_data, data);
35583109 out:
35593110 return ret;
35603111 }
35613112
3562
-static int parse_action_params(char *params, struct action_data *data)
3113
+static int parse_action_params(struct trace_array *tr, char *params,
3114
+ struct action_data *data)
35633115 {
35643116 char *param, *saved_param;
3117
+ bool first_param = true;
35653118 int ret = 0;
35663119
35673120 while (params) {
3568
- if (data->n_params >= SYNTH_FIELDS_MAX)
3121
+ if (data->n_params >= SYNTH_FIELDS_MAX) {
3122
+ hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);
3123
+ ret = -EINVAL;
35693124 goto out;
3125
+ }
35703126
35713127 param = strsep(&params, ",");
35723128 if (!param) {
3129
+ hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, 0);
35733130 ret = -EINVAL;
35743131 goto out;
35753132 }
35763133
35773134 param = strstrip(param);
35783135 if (strlen(param) < 2) {
3579
- hist_err("Invalid action param: ", param);
3136
+ hist_err(tr, HIST_ERR_INVALID_PARAM, errpos(param));
35803137 ret = -EINVAL;
35813138 goto out;
35823139 }
....@@ -3587,88 +3144,164 @@
35873144 goto out;
35883145 }
35893146
3147
+ if (first_param && data->use_trace_keyword) {
3148
+ data->synth_event_name = saved_param;
3149
+ first_param = false;
3150
+ continue;
3151
+ }
3152
+ first_param = false;
3153
+
35903154 data->params[data->n_params++] = saved_param;
35913155 }
35923156 out:
35933157 return ret;
35943158 }
35953159
3596
-static struct action_data *onmax_parse(char *str)
3160
+static int action_parse(struct trace_array *tr, char *str, struct action_data *data,
3161
+ enum handler_id handler)
35973162 {
3598
- char *onmax_fn_name, *onmax_var_str;
3163
+ char *action_name;
3164
+ int ret = 0;
3165
+
3166
+ strsep(&str, ".");
3167
+ if (!str) {
3168
+ hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0);
3169
+ ret = -EINVAL;
3170
+ goto out;
3171
+ }
3172
+
3173
+ action_name = strsep(&str, "(");
3174
+ if (!action_name || !str) {
3175
+ hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0);
3176
+ ret = -EINVAL;
3177
+ goto out;
3178
+ }
3179
+
3180
+ if (str_has_prefix(action_name, "save")) {
3181
+ char *params = strsep(&str, ")");
3182
+
3183
+ if (!params) {
3184
+ hist_err(tr, HIST_ERR_NO_SAVE_PARAMS, 0);
3185
+ ret = -EINVAL;
3186
+ goto out;
3187
+ }
3188
+
3189
+ ret = parse_action_params(tr, params, data);
3190
+ if (ret)
3191
+ goto out;
3192
+
3193
+ if (handler == HANDLER_ONMAX)
3194
+ data->track_data.check_val = check_track_val_max;
3195
+ else if (handler == HANDLER_ONCHANGE)
3196
+ data->track_data.check_val = check_track_val_changed;
3197
+ else {
3198
+ hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name));
3199
+ ret = -EINVAL;
3200
+ goto out;
3201
+ }
3202
+
3203
+ data->track_data.save_data = save_track_data_vars;
3204
+ data->fn = ontrack_action;
3205
+ data->action = ACTION_SAVE;
3206
+ } else if (str_has_prefix(action_name, "snapshot")) {
3207
+ char *params = strsep(&str, ")");
3208
+
3209
+ if (!str) {
3210
+ hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(params));
3211
+ ret = -EINVAL;
3212
+ goto out;
3213
+ }
3214
+
3215
+ if (handler == HANDLER_ONMAX)
3216
+ data->track_data.check_val = check_track_val_max;
3217
+ else if (handler == HANDLER_ONCHANGE)
3218
+ data->track_data.check_val = check_track_val_changed;
3219
+ else {
3220
+ hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name));
3221
+ ret = -EINVAL;
3222
+ goto out;
3223
+ }
3224
+
3225
+ data->track_data.save_data = save_track_data_snapshot;
3226
+ data->fn = ontrack_action;
3227
+ data->action = ACTION_SNAPSHOT;
3228
+ } else {
3229
+ char *params = strsep(&str, ")");
3230
+
3231
+ if (str_has_prefix(action_name, "trace"))
3232
+ data->use_trace_keyword = true;
3233
+
3234
+ if (params) {
3235
+ ret = parse_action_params(tr, params, data);
3236
+ if (ret)
3237
+ goto out;
3238
+ }
3239
+
3240
+ if (handler == HANDLER_ONMAX)
3241
+ data->track_data.check_val = check_track_val_max;
3242
+ else if (handler == HANDLER_ONCHANGE)
3243
+ data->track_data.check_val = check_track_val_changed;
3244
+
3245
+ if (handler != HANDLER_ONMATCH) {
3246
+ data->track_data.save_data = action_trace;
3247
+ data->fn = ontrack_action;
3248
+ } else
3249
+ data->fn = action_trace;
3250
+
3251
+ data->action = ACTION_TRACE;
3252
+ }
3253
+
3254
+ data->action_name = kstrdup(action_name, GFP_KERNEL);
3255
+ if (!data->action_name) {
3256
+ ret = -ENOMEM;
3257
+ goto out;
3258
+ }
3259
+
3260
+ data->handler = handler;
3261
+ out:
3262
+ return ret;
3263
+}
3264
+
3265
+static struct action_data *track_data_parse(struct hist_trigger_data *hist_data,
3266
+ char *str, enum handler_id handler)
3267
+{
35993268 struct action_data *data;
36003269 int ret = -EINVAL;
3270
+ char *var_str;
36013271
36023272 data = kzalloc(sizeof(*data), GFP_KERNEL);
36033273 if (!data)
36043274 return ERR_PTR(-ENOMEM);
36053275
3606
- onmax_var_str = strsep(&str, ")");
3607
- if (!onmax_var_str || !str) {
3276
+ var_str = strsep(&str, ")");
3277
+ if (!var_str || !str) {
36083278 ret = -EINVAL;
36093279 goto free;
36103280 }
36113281
3612
- data->onmax.var_str = kstrdup(onmax_var_str, GFP_KERNEL);
3613
- if (!data->onmax.var_str) {
3282
+ data->track_data.var_str = kstrdup(var_str, GFP_KERNEL);
3283
+ if (!data->track_data.var_str) {
36143284 ret = -ENOMEM;
36153285 goto free;
36163286 }
36173287
3618
- strsep(&str, ".");
3619
- if (!str)
3288
+ ret = action_parse(hist_data->event_file->tr, str, data, handler);
3289
+ if (ret)
36203290 goto free;
3621
-
3622
- onmax_fn_name = strsep(&str, "(");
3623
- if (!onmax_fn_name || !str)
3624
- goto free;
3625
-
3626
- if (strncmp(onmax_fn_name, "save", strlen("save")) == 0) {
3627
- char *params = strsep(&str, ")");
3628
-
3629
- if (!params) {
3630
- ret = -EINVAL;
3631
- goto free;
3632
- }
3633
-
3634
- ret = parse_action_params(params, data);
3635
- if (ret)
3636
- goto free;
3637
- } else
3638
- goto free;
3639
-
3640
- data->onmax.fn_name = kstrdup(onmax_fn_name, GFP_KERNEL);
3641
- if (!data->onmax.fn_name) {
3642
- ret = -ENOMEM;
3643
- goto free;
3644
- }
36453291 out:
36463292 return data;
36473293 free:
3648
- onmax_destroy(data);
3294
+ track_data_destroy(hist_data, data);
36493295 data = ERR_PTR(ret);
36503296 goto out;
36513297 }
36523298
36533299 static void onmatch_destroy(struct action_data *data)
36543300 {
3655
- unsigned int i;
3301
+ kfree(data->match_data.event);
3302
+ kfree(data->match_data.event_system);
36563303
3657
- mutex_lock(&synth_event_mutex);
3658
-
3659
- kfree(data->onmatch.match_event);
3660
- kfree(data->onmatch.match_event_system);
3661
- kfree(data->onmatch.synth_event_name);
3662
-
3663
- for (i = 0; i < data->n_params; i++)
3664
- kfree(data->params[i]);
3665
-
3666
- if (data->onmatch.synth_event)
3667
- data->onmatch.synth_event->ref--;
3668
-
3669
- kfree(data);
3670
-
3671
- mutex_unlock(&synth_event_mutex);
3304
+ action_data_destroy(data);
36723305 }
36733306
36743307 static void destroy_field_var(struct field_var *field_var)
....@@ -3688,6 +3321,9 @@
36883321
36893322 for (i = 0; i < hist_data->n_field_vars; i++)
36903323 destroy_field_var(hist_data->field_vars[i]);
3324
+
3325
+ for (i = 0; i < hist_data->n_save_vars; i++)
3326
+ destroy_field_var(hist_data->save_vars[i]);
36913327 }
36923328
36933329 static void save_field_var(struct hist_trigger_data *hist_data,
....@@ -3700,20 +3336,6 @@
37003336 }
37013337
37023338
3703
-static void destroy_synth_var_refs(struct hist_trigger_data *hist_data)
3704
-{
3705
- unsigned int i;
3706
-
3707
- for (i = 0; i < hist_data->n_synth_var_refs; i++)
3708
- destroy_hist_field(hist_data->synth_var_refs[i], 0);
3709
-}
3710
-
3711
-static void save_synth_var_ref(struct hist_trigger_data *hist_data,
3712
- struct hist_field *var_ref)
3713
-{
3714
- hist_data->synth_var_refs[hist_data->n_synth_var_refs++] = var_ref;
3715
-}
3716
-
37173339 static int check_synth_field(struct synth_event *event,
37183340 struct hist_field *hist_field,
37193341 unsigned int field_pos)
....@@ -3725,40 +3347,54 @@
37253347
37263348 field = event->fields[field_pos];
37273349
3728
- if (strcmp(field->type, hist_field->type) != 0)
3729
- return -EINVAL;
3350
+ /*
3351
+ * A dynamic string synth field can accept static or
3352
+ * dynamic. A static string synth field can only accept a
3353
+ * same-sized static string, which is checked for later.
3354
+ */
3355
+ if (strstr(hist_field->type, "char[") && field->is_string
3356
+ && field->is_dynamic)
3357
+ return 0;
3358
+
3359
+ if (strcmp(field->type, hist_field->type) != 0) {
3360
+ if (field->size != hist_field->size ||
3361
+ (!field->is_string && field->is_signed != hist_field->is_signed))
3362
+ return -EINVAL;
3363
+ }
37303364
37313365 return 0;
37323366 }
37333367
37343368 static struct hist_field *
3735
-onmatch_find_var(struct hist_trigger_data *hist_data, struct action_data *data,
3736
- char *system, char *event, char *var)
3369
+trace_action_find_var(struct hist_trigger_data *hist_data,
3370
+ struct action_data *data,
3371
+ char *system, char *event, char *var)
37373372 {
3373
+ struct trace_array *tr = hist_data->event_file->tr;
37383374 struct hist_field *hist_field;
37393375
37403376 var++; /* skip '$' */
37413377
37423378 hist_field = find_target_event_var(hist_data, system, event, var);
37433379 if (!hist_field) {
3744
- if (!system) {
3745
- system = data->onmatch.match_event_system;
3746
- event = data->onmatch.match_event;
3380
+ if (!system && data->handler == HANDLER_ONMATCH) {
3381
+ system = data->match_data.event_system;
3382
+ event = data->match_data.event;
37473383 }
37483384
37493385 hist_field = find_event_var(hist_data, system, event, var);
37503386 }
37513387
37523388 if (!hist_field)
3753
- hist_err_event("onmatch: Couldn't find onmatch param: $", system, event, var);
3389
+ hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, errpos(var));
37543390
37553391 return hist_field;
37563392 }
37573393
37583394 static struct hist_field *
3759
-onmatch_create_field_var(struct hist_trigger_data *hist_data,
3760
- struct action_data *data, char *system,
3761
- char *event, char *var)
3395
+trace_action_create_field_var(struct hist_trigger_data *hist_data,
3396
+ struct action_data *data, char *system,
3397
+ char *event, char *var)
37623398 {
37633399 struct hist_field *hist_field = NULL;
37643400 struct field_var *field_var;
....@@ -3781,9 +3417,9 @@
37813417 * looking for fields on the onmatch(system.event.xxx)
37823418 * event.
37833419 */
3784
- if (!system) {
3785
- system = data->onmatch.match_event_system;
3786
- event = data->onmatch.match_event;
3420
+ if (!system && data->handler == HANDLER_ONMATCH) {
3421
+ system = data->match_data.event_system;
3422
+ event = data->match_data.event;
37873423 }
37883424
37893425 if (!event)
....@@ -3807,28 +3443,36 @@
38073443 goto out;
38083444 }
38093445
3810
-static int onmatch_create(struct hist_trigger_data *hist_data,
3811
- struct trace_event_file *file,
3812
- struct action_data *data)
3446
+static int trace_action_create(struct hist_trigger_data *hist_data,
3447
+ struct action_data *data)
38133448 {
3449
+ struct trace_array *tr = hist_data->event_file->tr;
38143450 char *event_name, *param, *system = NULL;
38153451 struct hist_field *hist_field, *var_ref;
3816
- unsigned int i, var_ref_idx;
3452
+ unsigned int i;
38173453 unsigned int field_pos = 0;
38183454 struct synth_event *event;
3819
- int ret = 0;
3455
+ char *synth_event_name;
3456
+ int var_ref_idx, ret = 0;
38203457
3821
- mutex_lock(&synth_event_mutex);
3822
- event = find_synth_event(data->onmatch.synth_event_name);
3458
+ lockdep_assert_held(&event_mutex);
3459
+
3460
+ /* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */
3461
+ if (data->n_params > SYNTH_FIELDS_MAX)
3462
+ return -EINVAL;
3463
+
3464
+ if (data->use_trace_keyword)
3465
+ synth_event_name = data->synth_event_name;
3466
+ else
3467
+ synth_event_name = data->action_name;
3468
+
3469
+ event = find_synth_event(synth_event_name);
38233470 if (!event) {
3824
- hist_err("onmatch: Couldn't find synthetic event: ", data->onmatch.synth_event_name);
3825
- mutex_unlock(&synth_event_mutex);
3471
+ hist_err(tr, HIST_ERR_SYNTH_EVENT_NOT_FOUND, errpos(synth_event_name));
38263472 return -EINVAL;
38273473 }
3828
- event->ref++;
3829
- mutex_unlock(&synth_event_mutex);
38303474
3831
- var_ref_idx = hist_data->n_var_refs;
3475
+ event->ref++;
38323476
38333477 for (i = 0; i < data->n_params; i++) {
38343478 char *p;
....@@ -3853,13 +3497,15 @@
38533497 }
38543498
38553499 if (param[0] == '$')
3856
- hist_field = onmatch_find_var(hist_data, data, system,
3857
- event_name, param);
3500
+ hist_field = trace_action_find_var(hist_data, data,
3501
+ system, event_name,
3502
+ param);
38583503 else
3859
- hist_field = onmatch_create_field_var(hist_data, data,
3860
- system,
3861
- event_name,
3862
- param);
3504
+ hist_field = trace_action_create_field_var(hist_data,
3505
+ data,
3506
+ system,
3507
+ event_name,
3508
+ param);
38633509
38643510 if (!hist_field) {
38653511 kfree(p);
....@@ -3876,42 +3522,112 @@
38763522 goto err;
38773523 }
38783524
3879
- save_synth_var_ref(hist_data, var_ref);
3525
+ var_ref_idx = find_var_ref_idx(hist_data, var_ref);
3526
+ if (WARN_ON(var_ref_idx < 0)) {
3527
+ kfree(p);
3528
+ ret = var_ref_idx;
3529
+ goto err;
3530
+ }
3531
+
3532
+ data->var_ref_idx[i] = var_ref_idx;
3533
+
38803534 field_pos++;
38813535 kfree(p);
38823536 continue;
38833537 }
38843538
3885
- hist_err_event("onmatch: Param type doesn't match synthetic event field type: ",
3886
- system, event_name, param);
3539
+ hist_err(tr, HIST_ERR_SYNTH_TYPE_MISMATCH, errpos(param));
38873540 kfree(p);
38883541 ret = -EINVAL;
38893542 goto err;
38903543 }
38913544
38923545 if (field_pos != event->n_fields) {
3893
- hist_err("onmatch: Param count doesn't match synthetic event field count: ", event->name);
3546
+ hist_err(tr, HIST_ERR_SYNTH_COUNT_MISMATCH, errpos(event->name));
38943547 ret = -EINVAL;
38953548 goto err;
38963549 }
38973550
3898
- data->fn = action_trace;
3899
- data->onmatch.synth_event = event;
3900
- data->onmatch.var_ref_idx = var_ref_idx;
3551
+ data->synth_event = event;
39013552 out:
39023553 return ret;
39033554 err:
3904
- mutex_lock(&synth_event_mutex);
39053555 event->ref--;
3906
- mutex_unlock(&synth_event_mutex);
39073556
39083557 goto out;
3558
+}
3559
+
3560
+static int action_create(struct hist_trigger_data *hist_data,
3561
+ struct action_data *data)
3562
+{
3563
+ struct trace_event_file *file = hist_data->event_file;
3564
+ struct trace_array *tr = file->tr;
3565
+ struct track_data *track_data;
3566
+ struct field_var *field_var;
3567
+ unsigned int i;
3568
+ char *param;
3569
+ int ret = 0;
3570
+
3571
+ if (data->action == ACTION_TRACE)
3572
+ return trace_action_create(hist_data, data);
3573
+
3574
+ if (data->action == ACTION_SNAPSHOT) {
3575
+ track_data = track_data_alloc(hist_data->key_size, data, hist_data);
3576
+ if (IS_ERR(track_data)) {
3577
+ ret = PTR_ERR(track_data);
3578
+ goto out;
3579
+ }
3580
+
3581
+ ret = tracing_snapshot_cond_enable(file->tr, track_data,
3582
+ cond_snapshot_update);
3583
+ if (ret)
3584
+ track_data_free(track_data);
3585
+
3586
+ goto out;
3587
+ }
3588
+
3589
+ if (data->action == ACTION_SAVE) {
3590
+ if (hist_data->n_save_vars) {
3591
+ ret = -EEXIST;
3592
+ hist_err(tr, HIST_ERR_TOO_MANY_SAVE_ACTIONS, 0);
3593
+ goto out;
3594
+ }
3595
+
3596
+ for (i = 0; i < data->n_params; i++) {
3597
+ param = kstrdup(data->params[i], GFP_KERNEL);
3598
+ if (!param) {
3599
+ ret = -ENOMEM;
3600
+ goto out;
3601
+ }
3602
+
3603
+ field_var = create_target_field_var(hist_data, NULL, NULL, param);
3604
+ if (IS_ERR(field_var)) {
3605
+ hist_err(tr, HIST_ERR_FIELD_VAR_CREATE_FAIL,
3606
+ errpos(param));
3607
+ ret = PTR_ERR(field_var);
3608
+ kfree(param);
3609
+ goto out;
3610
+ }
3611
+
3612
+ hist_data->save_vars[hist_data->n_save_vars++] = field_var;
3613
+ if (field_var->val->flags & HIST_FIELD_FL_STRING)
3614
+ hist_data->n_save_var_str++;
3615
+ kfree(param);
3616
+ }
3617
+ }
3618
+ out:
3619
+ return ret;
3620
+}
3621
+
3622
+static int onmatch_create(struct hist_trigger_data *hist_data,
3623
+ struct action_data *data)
3624
+{
3625
+ return action_create(hist_data, data);
39093626 }
39103627
39113628 static struct action_data *onmatch_parse(struct trace_array *tr, char *str)
39123629 {
39133630 char *match_event, *match_event_system;
3914
- char *synth_event_name, *params;
39153631 struct action_data *data;
39163632 int ret = -EINVAL;
39173633
....@@ -3921,59 +3637,34 @@
39213637
39223638 match_event = strsep(&str, ")");
39233639 if (!match_event || !str) {
3924
- hist_err("onmatch: Missing closing paren: ", match_event);
3640
+ hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(match_event));
39253641 goto free;
39263642 }
39273643
39283644 match_event_system = strsep(&match_event, ".");
39293645 if (!match_event) {
3930
- hist_err("onmatch: Missing subsystem for match event: ", match_event_system);
3646
+ hist_err(tr, HIST_ERR_SUBSYS_NOT_FOUND, errpos(match_event_system));
39313647 goto free;
39323648 }
39333649
39343650 if (IS_ERR(event_file(tr, match_event_system, match_event))) {
3935
- hist_err_event("onmatch: Invalid subsystem or event name: ",
3936
- match_event_system, match_event, NULL);
3651
+ hist_err(tr, HIST_ERR_INVALID_SUBSYS_EVENT, errpos(match_event));
39373652 goto free;
39383653 }
39393654
3940
- data->onmatch.match_event = kstrdup(match_event, GFP_KERNEL);
3941
- if (!data->onmatch.match_event) {
3655
+ data->match_data.event = kstrdup(match_event, GFP_KERNEL);
3656
+ if (!data->match_data.event) {
39423657 ret = -ENOMEM;
39433658 goto free;
39443659 }
39453660
3946
- data->onmatch.match_event_system = kstrdup(match_event_system, GFP_KERNEL);
3947
- if (!data->onmatch.match_event_system) {
3661
+ data->match_data.event_system = kstrdup(match_event_system, GFP_KERNEL);
3662
+ if (!data->match_data.event_system) {
39483663 ret = -ENOMEM;
39493664 goto free;
39503665 }
39513666
3952
- strsep(&str, ".");
3953
- if (!str) {
3954
- hist_err("onmatch: Missing . after onmatch(): ", str);
3955
- goto free;
3956
- }
3957
-
3958
- synth_event_name = strsep(&str, "(");
3959
- if (!synth_event_name || !str) {
3960
- hist_err("onmatch: Missing opening paramlist paren: ", synth_event_name);
3961
- goto free;
3962
- }
3963
-
3964
- data->onmatch.synth_event_name = kstrdup(synth_event_name, GFP_KERNEL);
3965
- if (!data->onmatch.synth_event_name) {
3966
- ret = -ENOMEM;
3967
- goto free;
3968
- }
3969
-
3970
- params = strsep(&str, ")");
3971
- if (!params || !str || (str && strlen(str))) {
3972
- hist_err("onmatch: Missing closing paramlist paren: ", params);
3973
- goto free;
3974
- }
3975
-
3976
- ret = parse_action_params(params, data);
3667
+ ret = action_parse(tr, str, data, HANDLER_ONMATCH);
39773668 if (ret)
39783669 goto free;
39793670 out:
....@@ -4042,13 +3733,15 @@
40423733 struct trace_event_file *file,
40433734 char *var_name, char *expr_str)
40443735 {
3736
+ struct trace_array *tr = hist_data->event_file->tr;
40453737 unsigned long flags = 0;
3738
+ int ret;
40463739
40473740 if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX))
40483741 return -EINVAL;
40493742
40503743 if (find_var(hist_data, file, var_name) && !hist_data->remove) {
4051
- hist_err("Variable already defined: ", var_name);
3744
+ hist_err(tr, HIST_ERR_DUPLICATE_VAR, errpos(var_name));
40523745 return -EINVAL;
40533746 }
40543747
....@@ -4057,7 +3750,12 @@
40573750 if (WARN_ON(hist_data->n_vars > TRACING_MAP_VARS_MAX))
40583751 return -EINVAL;
40593752
4060
- return __create_val_field(hist_data, val_idx, file, var_name, expr_str, flags);
3753
+ ret = __create_val_field(hist_data, val_idx, file, var_name, expr_str, flags);
3754
+
3755
+ if (!ret && hist_data->fields[val_idx]->flags & HIST_FIELD_FL_STRING)
3756
+ hist_data->fields[val_idx]->var_str_idx = hist_data->n_var_str++;
3757
+
3758
+ return ret;
40613759 }
40623760
40633761 static int create_val_fields(struct hist_trigger_data *hist_data,
....@@ -4072,10 +3770,6 @@
40723770 goto out;
40733771
40743772 fields_str = hist_data->attrs->vals_str;
4075
- if (!fields_str)
4076
- goto out;
4077
-
4078
- strsep(&fields_str, "=");
40793773 if (!fields_str)
40803774 goto out;
40813775
....@@ -4105,8 +3799,8 @@
41053799 struct trace_event_file *file,
41063800 char *field_str)
41073801 {
3802
+ struct trace_array *tr = hist_data->event_file->tr;
41083803 struct hist_field *hist_field = NULL;
4109
-
41103804 unsigned long flags = 0;
41113805 unsigned int key_size;
41123806 int ret = 0;
....@@ -4128,8 +3822,8 @@
41283822 goto out;
41293823 }
41303824
4131
- if (hist_field->flags & HIST_FIELD_FL_VAR_REF) {
4132
- hist_err("Using variable references as keys not supported: ", field_str);
3825
+ if (field_has_hist_vars(hist_field, 0)) {
3826
+ hist_err(tr, HIST_ERR_INVALID_REF_KEY, errpos(field_str));
41333827 destroy_hist_field(hist_field, 0);
41343828 ret = -EINVAL;
41353829 goto out;
....@@ -4170,10 +3864,6 @@
41703864 int ret = -EINVAL;
41713865
41723866 fields_str = hist_data->attrs->keys_str;
4173
- if (!fields_str)
4174
- goto out;
4175
-
4176
- strsep(&fields_str, "=");
41773867 if (!fields_str)
41783868 goto out;
41793869
....@@ -4230,6 +3920,7 @@
42303920
42313921 static int parse_var_defs(struct hist_trigger_data *hist_data)
42323922 {
3923
+ struct trace_array *tr = hist_data->event_file->tr;
42333924 char *s, *str, *var_name, *field_str;
42343925 unsigned int i, j, n_vars = 0;
42353926 int ret = 0;
....@@ -4243,13 +3934,14 @@
42433934
42443935 var_name = strsep(&field_str, "=");
42453936 if (!var_name || !field_str) {
4246
- hist_err("Malformed assignment: ", var_name);
3937
+ hist_err(tr, HIST_ERR_MALFORMED_ASSIGNMENT,
3938
+ errpos(var_name));
42473939 ret = -EINVAL;
42483940 goto free;
42493941 }
42503942
42513943 if (n_vars == TRACING_MAP_VARS_MAX) {
4252
- hist_err("Too many variables defined: ", var_name);
3944
+ hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(var_name));
42533945 ret = -EINVAL;
42543946 goto free;
42553947 }
....@@ -4263,6 +3955,8 @@
42633955
42643956 s = kstrdup(field_str, GFP_KERNEL);
42653957 if (!s) {
3958
+ kfree(hist_data->attrs->var_defs.name[n_vars]);
3959
+ hist_data->attrs->var_defs.name[n_vars] = NULL;
42663960 ret = -ENOMEM;
42673961 goto free;
42683962 }
....@@ -4305,7 +3999,7 @@
43053999 return ret;
43064000 }
43074001
4308
-static int is_descending(const char *str)
4002
+static int is_descending(struct trace_array *tr, const char *str)
43094003 {
43104004 if (!str)
43114005 return 0;
....@@ -4316,11 +4010,14 @@
43164010 if (strcmp(str, "ascending") == 0)
43174011 return 0;
43184012
4013
+ hist_err(tr, HIST_ERR_INVALID_SORT_MODIFIER, errpos((char *)str));
4014
+
43194015 return -EINVAL;
43204016 }
43214017
43224018 static int create_sort_keys(struct hist_trigger_data *hist_data)
43234019 {
4020
+ struct trace_array *tr = hist_data->event_file->tr;
43244021 char *fields_str = hist_data->attrs->sort_key_str;
43254022 struct tracing_map_sort_key *sort_key;
43264023 int descending, ret = 0;
....@@ -4331,12 +4028,6 @@
43314028 if (!fields_str)
43324029 goto out;
43334030
4334
- strsep(&fields_str, "=");
4335
- if (!fields_str) {
4336
- ret = -EINVAL;
4337
- goto out;
4338
- }
4339
-
43404031 for (i = 0; i < TRACING_MAP_SORT_KEYS_MAX; i++) {
43414032 struct hist_field *hist_field;
43424033 char *field_str, *field_name;
....@@ -4345,25 +4036,30 @@
43454036 sort_key = &hist_data->sort_keys[i];
43464037
43474038 field_str = strsep(&fields_str, ",");
4348
- if (!field_str) {
4349
- if (i == 0)
4350
- ret = -EINVAL;
4039
+ if (!field_str)
4040
+ break;
4041
+
4042
+ if (!*field_str) {
4043
+ ret = -EINVAL;
4044
+ hist_err(tr, HIST_ERR_EMPTY_SORT_FIELD, errpos("sort="));
43514045 break;
43524046 }
43534047
43544048 if ((i == TRACING_MAP_SORT_KEYS_MAX - 1) && fields_str) {
4049
+ hist_err(tr, HIST_ERR_TOO_MANY_SORT_FIELDS, errpos("sort="));
43554050 ret = -EINVAL;
43564051 break;
43574052 }
43584053
43594054 field_name = strsep(&field_str, ".");
4360
- if (!field_name) {
4055
+ if (!field_name || !*field_name) {
43614056 ret = -EINVAL;
4057
+ hist_err(tr, HIST_ERR_EMPTY_SORT_FIELD, errpos("sort="));
43624058 break;
43634059 }
43644060
43654061 if (strcmp(field_name, "hitcount") == 0) {
4366
- descending = is_descending(field_str);
4062
+ descending = is_descending(tr, field_str);
43674063 if (descending < 0) {
43684064 ret = descending;
43694065 break;
....@@ -4385,7 +4081,7 @@
43854081
43864082 if (strcmp(field_name, test_name) == 0) {
43874083 sort_key->field_idx = idx;
4388
- descending = is_descending(field_str);
4084
+ descending = is_descending(tr, field_str);
43894085 if (descending < 0) {
43904086 ret = descending;
43914087 goto out;
....@@ -4396,6 +4092,7 @@
43964092 }
43974093 if (j == hist_data->n_fields) {
43984094 ret = -EINVAL;
4095
+ hist_err(tr, HIST_ERR_INVALID_SORT_FIELD, errpos(field_name));
43994096 break;
44004097 }
44014098 }
....@@ -4412,10 +4109,11 @@
44124109 for (i = 0; i < hist_data->n_actions; i++) {
44134110 struct action_data *data = hist_data->actions[i];
44144111
4415
- if (data->fn == action_trace)
4112
+ if (data->handler == HANDLER_ONMATCH)
44164113 onmatch_destroy(data);
4417
- else if (data->fn == onmax_save)
4418
- onmax_destroy(data);
4114
+ else if (data->handler == HANDLER_ONMAX ||
4115
+ data->handler == HANDLER_ONCHANGE)
4116
+ track_data_destroy(hist_data, data);
44194117 else
44204118 kfree(data);
44214119 }
....@@ -4428,28 +4126,37 @@
44284126 unsigned int i;
44294127 int ret = 0;
44304128 char *str;
4129
+ int len;
44314130
44324131 for (i = 0; i < hist_data->attrs->n_actions; i++) {
44334132 str = hist_data->attrs->action_str[i];
44344133
4435
- if (strncmp(str, "onmatch(", strlen("onmatch(")) == 0) {
4436
- char *action_str = str + strlen("onmatch(");
4134
+ if ((len = str_has_prefix(str, "onmatch("))) {
4135
+ char *action_str = str + len;
44374136
44384137 data = onmatch_parse(tr, action_str);
44394138 if (IS_ERR(data)) {
44404139 ret = PTR_ERR(data);
44414140 break;
44424141 }
4443
- data->fn = action_trace;
4444
- } else if (strncmp(str, "onmax(", strlen("onmax(")) == 0) {
4445
- char *action_str = str + strlen("onmax(");
4142
+ } else if ((len = str_has_prefix(str, "onmax("))) {
4143
+ char *action_str = str + len;
44464144
4447
- data = onmax_parse(action_str);
4145
+ data = track_data_parse(hist_data, action_str,
4146
+ HANDLER_ONMAX);
44484147 if (IS_ERR(data)) {
44494148 ret = PTR_ERR(data);
44504149 break;
44514150 }
4452
- data->fn = onmax_save;
4151
+ } else if ((len = str_has_prefix(str, "onchange("))) {
4152
+ char *action_str = str + len;
4153
+
4154
+ data = track_data_parse(hist_data, action_str,
4155
+ HANDLER_ONCHANGE);
4156
+ if (IS_ERR(data)) {
4157
+ ret = PTR_ERR(data);
4158
+ break;
4159
+ }
44534160 } else {
44544161 ret = -EINVAL;
44554162 break;
....@@ -4461,8 +4168,7 @@
44614168 return ret;
44624169 }
44634170
4464
-static int create_actions(struct hist_trigger_data *hist_data,
4465
- struct trace_event_file *file)
4171
+static int create_actions(struct hist_trigger_data *hist_data)
44664172 {
44674173 struct action_data *data;
44684174 unsigned int i;
....@@ -4471,14 +4177,18 @@
44714177 for (i = 0; i < hist_data->attrs->n_actions; i++) {
44724178 data = hist_data->actions[i];
44734179
4474
- if (data->fn == action_trace) {
4475
- ret = onmatch_create(hist_data, file, data);
4180
+ if (data->handler == HANDLER_ONMATCH) {
4181
+ ret = onmatch_create(hist_data, data);
44764182 if (ret)
4477
- return ret;
4478
- } else if (data->fn == onmax_save) {
4479
- ret = onmax_create(hist_data, data);
4183
+ break;
4184
+ } else if (data->handler == HANDLER_ONMAX ||
4185
+ data->handler == HANDLER_ONCHANGE) {
4186
+ ret = track_data_create(hist_data, data);
44804187 if (ret)
4481
- return ret;
4188
+ break;
4189
+ } else {
4190
+ ret = -EINVAL;
4191
+ break;
44824192 }
44834193 }
44844194
....@@ -4494,26 +4204,51 @@
44944204 for (i = 0; i < hist_data->n_actions; i++) {
44954205 struct action_data *data = hist_data->actions[i];
44964206
4497
- if (data->fn == onmax_save)
4498
- onmax_print(m, hist_data, elt, data);
4207
+ if (data->action == ACTION_SNAPSHOT)
4208
+ continue;
4209
+
4210
+ if (data->handler == HANDLER_ONMAX ||
4211
+ data->handler == HANDLER_ONCHANGE)
4212
+ track_data_print(m, hist_data, elt, data);
44994213 }
45004214 }
45014215
4502
-static void print_onmax_spec(struct seq_file *m,
4503
- struct hist_trigger_data *hist_data,
4504
- struct action_data *data)
4216
+static void print_action_spec(struct seq_file *m,
4217
+ struct hist_trigger_data *hist_data,
4218
+ struct action_data *data)
45054219 {
45064220 unsigned int i;
45074221
4508
- seq_puts(m, ":onmax(");
4509
- seq_printf(m, "%s", data->onmax.var_str);
4510
- seq_printf(m, ").%s(", data->onmax.fn_name);
4511
-
4512
- for (i = 0; i < hist_data->n_max_vars; i++) {
4513
- seq_printf(m, "%s", hist_data->max_vars[i]->var->var.name);
4514
- if (i < hist_data->n_max_vars - 1)
4515
- seq_puts(m, ",");
4222
+ if (data->action == ACTION_SAVE) {
4223
+ for (i = 0; i < hist_data->n_save_vars; i++) {
4224
+ seq_printf(m, "%s", hist_data->save_vars[i]->var->var.name);
4225
+ if (i < hist_data->n_save_vars - 1)
4226
+ seq_puts(m, ",");
4227
+ }
4228
+ } else if (data->action == ACTION_TRACE) {
4229
+ if (data->use_trace_keyword)
4230
+ seq_printf(m, "%s", data->synth_event_name);
4231
+ for (i = 0; i < data->n_params; i++) {
4232
+ if (i || data->use_trace_keyword)
4233
+ seq_puts(m, ",");
4234
+ seq_printf(m, "%s", data->params[i]);
4235
+ }
45164236 }
4237
+}
4238
+
4239
+static void print_track_data_spec(struct seq_file *m,
4240
+ struct hist_trigger_data *hist_data,
4241
+ struct action_data *data)
4242
+{
4243
+ if (data->handler == HANDLER_ONMAX)
4244
+ seq_puts(m, ":onmax(");
4245
+ else if (data->handler == HANDLER_ONCHANGE)
4246
+ seq_puts(m, ":onchange(");
4247
+ seq_printf(m, "%s", data->track_data.var_str);
4248
+ seq_printf(m, ").%s(", data->action_name);
4249
+
4250
+ print_action_spec(m, hist_data, data);
4251
+
45174252 seq_puts(m, ")");
45184253 }
45194254
....@@ -4521,18 +4256,12 @@
45214256 struct hist_trigger_data *hist_data,
45224257 struct action_data *data)
45234258 {
4524
- unsigned int i;
4259
+ seq_printf(m, ":onmatch(%s.%s).", data->match_data.event_system,
4260
+ data->match_data.event);
45254261
4526
- seq_printf(m, ":onmatch(%s.%s).", data->onmatch.match_event_system,
4527
- data->onmatch.match_event);
4262
+ seq_printf(m, "%s(", data->action_name);
45284263
4529
- seq_printf(m, "%s(", data->onmatch.synth_event->name);
4530
-
4531
- for (i = 0; i < data->n_params; i++) {
4532
- if (i)
4533
- seq_puts(m, ",");
4534
- seq_printf(m, "%s", data->params[i]);
4535
- }
4264
+ print_action_spec(m, hist_data, data);
45364265
45374266 seq_puts(m, ")");
45384267 }
....@@ -4548,8 +4277,11 @@
45484277 for (i = 0; i < hist_data->n_actions; i++) {
45494278 struct action_data *data = hist_data->actions[i];
45504279 struct action_data *data_test = hist_data_test->actions[i];
4280
+ char *action_name, *action_name_test;
45514281
4552
- if (data->fn != data_test->fn)
4282
+ if (data->handler != data_test->handler)
4283
+ return false;
4284
+ if (data->action != data_test->action)
45534285 return false;
45544286
45554287 if (data->n_params != data_test->n_params)
....@@ -4560,22 +4292,30 @@
45604292 return false;
45614293 }
45624294
4563
- if (data->fn == action_trace) {
4564
- if (strcmp(data->onmatch.synth_event_name,
4565
- data_test->onmatch.synth_event_name) != 0)
4295
+ if (data->use_trace_keyword)
4296
+ action_name = data->synth_event_name;
4297
+ else
4298
+ action_name = data->action_name;
4299
+
4300
+ if (data_test->use_trace_keyword)
4301
+ action_name_test = data_test->synth_event_name;
4302
+ else
4303
+ action_name_test = data_test->action_name;
4304
+
4305
+ if (strcmp(action_name, action_name_test) != 0)
4306
+ return false;
4307
+
4308
+ if (data->handler == HANDLER_ONMATCH) {
4309
+ if (strcmp(data->match_data.event_system,
4310
+ data_test->match_data.event_system) != 0)
45664311 return false;
4567
- if (strcmp(data->onmatch.match_event_system,
4568
- data_test->onmatch.match_event_system) != 0)
4312
+ if (strcmp(data->match_data.event,
4313
+ data_test->match_data.event) != 0)
45694314 return false;
4570
- if (strcmp(data->onmatch.match_event,
4571
- data_test->onmatch.match_event) != 0)
4572
- return false;
4573
- } else if (data->fn == onmax_save) {
4574
- if (strcmp(data->onmax.var_str,
4575
- data_test->onmax.var_str) != 0)
4576
- return false;
4577
- if (strcmp(data->onmax.fn_name,
4578
- data_test->onmax.fn_name) != 0)
4315
+ } else if (data->handler == HANDLER_ONMAX ||
4316
+ data->handler == HANDLER_ONCHANGE) {
4317
+ if (strcmp(data->track_data.var_str,
4318
+ data_test->track_data.var_str) != 0)
45794319 return false;
45804320 }
45814321 }
....@@ -4592,10 +4332,11 @@
45924332 for (i = 0; i < hist_data->n_actions; i++) {
45934333 struct action_data *data = hist_data->actions[i];
45944334
4595
- if (data->fn == action_trace)
4335
+ if (data->handler == HANDLER_ONMATCH)
45964336 print_onmatch_spec(m, hist_data, data);
4597
- else if (data->fn == onmax_save)
4598
- print_onmax_spec(m, hist_data, data);
4337
+ else if (data->handler == HANDLER_ONMAX ||
4338
+ data->handler == HANDLER_ONCHANGE)
4339
+ print_track_data_spec(m, hist_data, data);
45994340 }
46004341 }
46014342
....@@ -4621,7 +4362,6 @@
46214362 destroy_actions(hist_data);
46224363 destroy_field_vars(hist_data);
46234364 destroy_field_var_hists(hist_data);
4624
- destroy_synth_var_refs(hist_data);
46254365
46264366 kfree(hist_data);
46274367 }
....@@ -4642,7 +4382,7 @@
46424382
46434383 if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
46444384 cmp_fn = tracing_map_cmp_none;
4645
- else if (!field)
4385
+ else if (!field || hist_field->flags & HIST_FIELD_FL_CPU)
46464386 cmp_fn = tracing_map_cmp_num(hist_field->size,
46474387 hist_field->is_signed);
46484388 else if (is_string_field(field))
....@@ -4744,6 +4484,25 @@
47444484 hist_val = hist_field->fn(hist_field, elt, rbe, rec);
47454485 if (hist_field->flags & HIST_FIELD_FL_VAR) {
47464486 var_idx = hist_field->var.idx;
4487
+
4488
+ if (hist_field->flags & HIST_FIELD_FL_STRING) {
4489
+ unsigned int str_start, var_str_idx, idx;
4490
+ char *str, *val_str;
4491
+ unsigned int size;
4492
+
4493
+ str_start = hist_data->n_field_var_str +
4494
+ hist_data->n_save_var_str;
4495
+ var_str_idx = hist_field->var_str_idx;
4496
+ idx = str_start + var_str_idx;
4497
+
4498
+ str = elt_data->field_var_str[idx];
4499
+ val_str = (char *)(uintptr_t)hist_val;
4500
+
4501
+ size = min(hist_field->size, STR_VAR_LEN_MAX);
4502
+ strscpy(str, val_str, size);
4503
+
4504
+ hist_val = (u64)(uintptr_t)str;
4505
+ }
47474506 tracing_map_set_var(elt, var_idx, hist_val);
47484507 continue;
47494508 }
....@@ -4788,14 +4547,15 @@
47884547 static void
47894548 hist_trigger_actions(struct hist_trigger_data *hist_data,
47904549 struct tracing_map_elt *elt, void *rec,
4791
- struct ring_buffer_event *rbe, u64 *var_ref_vals)
4550
+ struct ring_buffer_event *rbe, void *key,
4551
+ u64 *var_ref_vals)
47924552 {
47934553 struct action_data *data;
47944554 unsigned int i;
47954555
47964556 for (i = 0; i < hist_data->n_actions; i++) {
47974557 data = hist_data->actions[i];
4798
- data->fn(hist_data, elt, rec, rbe, data, var_ref_vals);
4558
+ data->fn(hist_data, elt, rec, rbe, key, data, var_ref_vals);
47994559 }
48004560 }
48014561
....@@ -4808,7 +4568,6 @@
48084568 u64 var_ref_vals[TRACING_MAP_VARS_MAX];
48094569 char compound_key[HIST_KEY_SIZE_MAX];
48104570 struct tracing_map_elt *elt = NULL;
4811
- struct stack_trace stacktrace;
48124571 struct hist_field *key_field;
48134572 u64 field_contents;
48144573 void *key = NULL;
....@@ -4820,14 +4579,9 @@
48204579 key_field = hist_data->fields[i];
48214580
48224581 if (key_field->flags & HIST_FIELD_FL_STACKTRACE) {
4823
- stacktrace.max_entries = HIST_STACKTRACE_DEPTH;
4824
- stacktrace.entries = entries;
4825
- stacktrace.nr_entries = 0;
4826
- stacktrace.skip = HIST_STACKTRACE_SKIP;
4827
-
4828
- memset(stacktrace.entries, 0, HIST_STACKTRACE_SIZE);
4829
- save_stack_trace(&stacktrace);
4830
-
4582
+ memset(entries, 0, HIST_STACKTRACE_SIZE);
4583
+ stack_trace_save(entries, HIST_STACKTRACE_DEPTH,
4584
+ HIST_STACKTRACE_SKIP);
48314585 key = entries;
48324586 } else {
48334587 field_contents = key_field->fn(key_field, elt, rbe, rec);
....@@ -4856,7 +4610,7 @@
48564610 hist_trigger_elt_update(hist_data, elt, rec, rbe, var_ref_vals);
48574611
48584612 if (resolve_var_refs(hist_data, key, var_ref_vals, true))
4859
- hist_trigger_actions(hist_data, elt, rec, rbe, var_ref_vals);
4613
+ hist_trigger_actions(hist_data, elt, rec, rbe, key, var_ref_vals);
48604614 }
48614615
48624616 static void hist_trigger_stacktrace_print(struct seq_file *m,
....@@ -4868,7 +4622,7 @@
48684622 unsigned int i;
48694623
48704624 for (i = 0; i < max_entries; i++) {
4871
- if (stacktrace_entries[i] == ULONG_MAX)
4625
+ if (!stacktrace_entries[i])
48724626 return;
48734627
48744628 seq_printf(m, "%*c", 1 + spaces, ' ');
....@@ -4877,10 +4631,10 @@
48774631 }
48784632 }
48794633
4880
-static void
4881
-hist_trigger_entry_print(struct seq_file *m,
4882
- struct hist_trigger_data *hist_data, void *key,
4883
- struct tracing_map_elt *elt)
4634
+static void hist_trigger_print_key(struct seq_file *m,
4635
+ struct hist_trigger_data *hist_data,
4636
+ void *key,
4637
+ struct tracing_map_elt *elt)
48844638 {
48854639 struct hist_field *key_field;
48864640 char str[KSYM_SYMBOL_LEN];
....@@ -4956,6 +4710,17 @@
49564710 seq_puts(m, " ");
49574711
49584712 seq_puts(m, "}");
4713
+}
4714
+
4715
+static void hist_trigger_entry_print(struct seq_file *m,
4716
+ struct hist_trigger_data *hist_data,
4717
+ void *key,
4718
+ struct tracing_map_elt *elt)
4719
+{
4720
+ const char *field_name;
4721
+ unsigned int i;
4722
+
4723
+ hist_trigger_print_key(m, hist_data, key, elt);
49594724
49604725 seq_printf(m, " hitcount: %10llu",
49614726 tracing_map_read_sum(elt, HITCOUNT_IDX));
....@@ -5022,6 +4787,8 @@
50224787 if (n_entries < 0)
50234788 n_entries = 0;
50244789
4790
+ track_data_snapshot_print(m, hist_data);
4791
+
50254792 seq_printf(m, "\nTotals:\n Hits: %llu\n Entries: %u\n Dropped: %llu\n",
50264793 (u64)atomic64_read(&hist_data->map->hits),
50274794 n_entries, (u64)atomic64_read(&hist_data->map->drops));
....@@ -5046,11 +4813,6 @@
50464813 hist_trigger_show(m, data, n++);
50474814 }
50484815
5049
- if (have_hist_err()) {
5050
- seq_printf(m, "\nERROR: %s\n", hist_err_str);
5051
- seq_printf(m, " Last command: %s\n", last_hist_cmd);
5052
- }
5053
-
50544816 out_unlock:
50554817 mutex_unlock(&event_mutex);
50564818
....@@ -5059,6 +4821,12 @@
50594821
50604822 static int event_hist_open(struct inode *inode, struct file *file)
50614823 {
4824
+ int ret;
4825
+
4826
+ ret = security_locked_down(LOCKDOWN_TRACEFS);
4827
+ if (ret)
4828
+ return ret;
4829
+
50624830 return single_open(file, hist_show, file);
50634831 }
50644832
....@@ -5068,6 +4836,279 @@
50684836 .llseek = seq_lseek,
50694837 .release = single_release,
50704838 };
4839
+
4840
+#ifdef CONFIG_HIST_TRIGGERS_DEBUG
4841
+static void hist_field_debug_show_flags(struct seq_file *m,
4842
+ unsigned long flags)
4843
+{
4844
+ seq_puts(m, " flags:\n");
4845
+
4846
+ if (flags & HIST_FIELD_FL_KEY)
4847
+ seq_puts(m, " HIST_FIELD_FL_KEY\n");
4848
+ else if (flags & HIST_FIELD_FL_HITCOUNT)
4849
+ seq_puts(m, " VAL: HIST_FIELD_FL_HITCOUNT\n");
4850
+ else if (flags & HIST_FIELD_FL_VAR)
4851
+ seq_puts(m, " HIST_FIELD_FL_VAR\n");
4852
+ else if (flags & HIST_FIELD_FL_VAR_REF)
4853
+ seq_puts(m, " HIST_FIELD_FL_VAR_REF\n");
4854
+ else
4855
+ seq_puts(m, " VAL: normal u64 value\n");
4856
+
4857
+ if (flags & HIST_FIELD_FL_ALIAS)
4858
+ seq_puts(m, " HIST_FIELD_FL_ALIAS\n");
4859
+}
4860
+
4861
+static int hist_field_debug_show(struct seq_file *m,
4862
+ struct hist_field *field, unsigned long flags)
4863
+{
4864
+ if ((field->flags & flags) != flags) {
4865
+ seq_printf(m, "ERROR: bad flags - %lx\n", flags);
4866
+ return -EINVAL;
4867
+ }
4868
+
4869
+ hist_field_debug_show_flags(m, field->flags);
4870
+ if (field->field)
4871
+ seq_printf(m, " ftrace_event_field name: %s\n",
4872
+ field->field->name);
4873
+
4874
+ if (field->flags & HIST_FIELD_FL_VAR) {
4875
+ seq_printf(m, " var.name: %s\n", field->var.name);
4876
+ seq_printf(m, " var.idx (into tracing_map_elt.vars[]): %u\n",
4877
+ field->var.idx);
4878
+ }
4879
+
4880
+ if (field->flags & HIST_FIELD_FL_ALIAS)
4881
+ seq_printf(m, " var_ref_idx (into hist_data->var_refs[]): %u\n",
4882
+ field->var_ref_idx);
4883
+
4884
+ if (field->flags & HIST_FIELD_FL_VAR_REF) {
4885
+ seq_printf(m, " name: %s\n", field->name);
4886
+ seq_printf(m, " var.idx (into tracing_map_elt.vars[]): %u\n",
4887
+ field->var.idx);
4888
+ seq_printf(m, " var.hist_data: %p\n", field->var.hist_data);
4889
+ seq_printf(m, " var_ref_idx (into hist_data->var_refs[]): %u\n",
4890
+ field->var_ref_idx);
4891
+ if (field->system)
4892
+ seq_printf(m, " system: %s\n", field->system);
4893
+ if (field->event_name)
4894
+ seq_printf(m, " event_name: %s\n", field->event_name);
4895
+ }
4896
+
4897
+ seq_printf(m, " type: %s\n", field->type);
4898
+ seq_printf(m, " size: %u\n", field->size);
4899
+ seq_printf(m, " is_signed: %u\n", field->is_signed);
4900
+
4901
+ return 0;
4902
+}
4903
+
4904
+static int field_var_debug_show(struct seq_file *m,
4905
+ struct field_var *field_var, unsigned int i,
4906
+ bool save_vars)
4907
+{
4908
+ const char *vars_name = save_vars ? "save_vars" : "field_vars";
4909
+ struct hist_field *field;
4910
+ int ret = 0;
4911
+
4912
+ seq_printf(m, "\n hist_data->%s[%d]:\n", vars_name, i);
4913
+
4914
+ field = field_var->var;
4915
+
4916
+ seq_printf(m, "\n %s[%d].var:\n", vars_name, i);
4917
+
4918
+ hist_field_debug_show_flags(m, field->flags);
4919
+ seq_printf(m, " var.name: %s\n", field->var.name);
4920
+ seq_printf(m, " var.idx (into tracing_map_elt.vars[]): %u\n",
4921
+ field->var.idx);
4922
+
4923
+ field = field_var->val;
4924
+
4925
+ seq_printf(m, "\n %s[%d].val:\n", vars_name, i);
4926
+ if (field->field)
4927
+ seq_printf(m, " ftrace_event_field name: %s\n",
4928
+ field->field->name);
4929
+ else {
4930
+ ret = -EINVAL;
4931
+ goto out;
4932
+ }
4933
+
4934
+ seq_printf(m, " type: %s\n", field->type);
4935
+ seq_printf(m, " size: %u\n", field->size);
4936
+ seq_printf(m, " is_signed: %u\n", field->is_signed);
4937
+out:
4938
+ return ret;
4939
+}
4940
+
4941
+static int hist_action_debug_show(struct seq_file *m,
4942
+ struct action_data *data, int i)
4943
+{
4944
+ int ret = 0;
4945
+
4946
+ if (data->handler == HANDLER_ONMAX ||
4947
+ data->handler == HANDLER_ONCHANGE) {
4948
+ seq_printf(m, "\n hist_data->actions[%d].track_data.var_ref:\n", i);
4949
+ ret = hist_field_debug_show(m, data->track_data.var_ref,
4950
+ HIST_FIELD_FL_VAR_REF);
4951
+ if (ret)
4952
+ goto out;
4953
+
4954
+ seq_printf(m, "\n hist_data->actions[%d].track_data.track_var:\n", i);
4955
+ ret = hist_field_debug_show(m, data->track_data.track_var,
4956
+ HIST_FIELD_FL_VAR);
4957
+ if (ret)
4958
+ goto out;
4959
+ }
4960
+
4961
+ if (data->handler == HANDLER_ONMATCH) {
4962
+ seq_printf(m, "\n hist_data->actions[%d].match_data.event_system: %s\n",
4963
+ i, data->match_data.event_system);
4964
+ seq_printf(m, " hist_data->actions[%d].match_data.event: %s\n",
4965
+ i, data->match_data.event);
4966
+ }
4967
+out:
4968
+ return ret;
4969
+}
4970
+
4971
+static int hist_actions_debug_show(struct seq_file *m,
4972
+ struct hist_trigger_data *hist_data)
4973
+{
4974
+ int i, ret = 0;
4975
+
4976
+ if (hist_data->n_actions)
4977
+ seq_puts(m, "\n action tracking variables (for onmax()/onchange()/onmatch()):\n");
4978
+
4979
+ for (i = 0; i < hist_data->n_actions; i++) {
4980
+ struct action_data *action = hist_data->actions[i];
4981
+
4982
+ ret = hist_action_debug_show(m, action, i);
4983
+ if (ret)
4984
+ goto out;
4985
+ }
4986
+
4987
+ if (hist_data->n_save_vars)
4988
+ seq_puts(m, "\n save action variables (save() params):\n");
4989
+
4990
+ for (i = 0; i < hist_data->n_save_vars; i++) {
4991
+ ret = field_var_debug_show(m, hist_data->save_vars[i], i, true);
4992
+ if (ret)
4993
+ goto out;
4994
+ }
4995
+out:
4996
+ return ret;
4997
+}
4998
+
4999
+static void hist_trigger_debug_show(struct seq_file *m,
5000
+ struct event_trigger_data *data, int n)
5001
+{
5002
+ struct hist_trigger_data *hist_data;
5003
+ int i, ret;
5004
+
5005
+ if (n > 0)
5006
+ seq_puts(m, "\n\n");
5007
+
5008
+ seq_puts(m, "# event histogram\n#\n# trigger info: ");
5009
+ data->ops->print(m, data->ops, data);
5010
+ seq_puts(m, "#\n\n");
5011
+
5012
+ hist_data = data->private_data;
5013
+
5014
+ seq_printf(m, "hist_data: %p\n\n", hist_data);
5015
+ seq_printf(m, " n_vals: %u\n", hist_data->n_vals);
5016
+ seq_printf(m, " n_keys: %u\n", hist_data->n_keys);
5017
+ seq_printf(m, " n_fields: %u\n", hist_data->n_fields);
5018
+
5019
+ seq_puts(m, "\n val fields:\n\n");
5020
+
5021
+ seq_puts(m, " hist_data->fields[0]:\n");
5022
+ ret = hist_field_debug_show(m, hist_data->fields[0],
5023
+ HIST_FIELD_FL_HITCOUNT);
5024
+ if (ret)
5025
+ return;
5026
+
5027
+ for (i = 1; i < hist_data->n_vals; i++) {
5028
+ seq_printf(m, "\n hist_data->fields[%d]:\n", i);
5029
+ ret = hist_field_debug_show(m, hist_data->fields[i], 0);
5030
+ if (ret)
5031
+ return;
5032
+ }
5033
+
5034
+ seq_puts(m, "\n key fields:\n");
5035
+
5036
+ for (i = hist_data->n_vals; i < hist_data->n_fields; i++) {
5037
+ seq_printf(m, "\n hist_data->fields[%d]:\n", i);
5038
+ ret = hist_field_debug_show(m, hist_data->fields[i],
5039
+ HIST_FIELD_FL_KEY);
5040
+ if (ret)
5041
+ return;
5042
+ }
5043
+
5044
+ if (hist_data->n_var_refs)
5045
+ seq_puts(m, "\n variable reference fields:\n");
5046
+
5047
+ for (i = 0; i < hist_data->n_var_refs; i++) {
5048
+ seq_printf(m, "\n hist_data->var_refs[%d]:\n", i);
5049
+ ret = hist_field_debug_show(m, hist_data->var_refs[i],
5050
+ HIST_FIELD_FL_VAR_REF);
5051
+ if (ret)
5052
+ return;
5053
+ }
5054
+
5055
+ if (hist_data->n_field_vars)
5056
+ seq_puts(m, "\n field variables:\n");
5057
+
5058
+ for (i = 0; i < hist_data->n_field_vars; i++) {
5059
+ ret = field_var_debug_show(m, hist_data->field_vars[i], i, false);
5060
+ if (ret)
5061
+ return;
5062
+ }
5063
+
5064
+ ret = hist_actions_debug_show(m, hist_data);
5065
+ if (ret)
5066
+ return;
5067
+}
5068
+
5069
+static int hist_debug_show(struct seq_file *m, void *v)
5070
+{
5071
+ struct event_trigger_data *data;
5072
+ struct trace_event_file *event_file;
5073
+ int n = 0, ret = 0;
5074
+
5075
+ mutex_lock(&event_mutex);
5076
+
5077
+ event_file = event_file_data(m->private);
5078
+ if (unlikely(!event_file)) {
5079
+ ret = -ENODEV;
5080
+ goto out_unlock;
5081
+ }
5082
+
5083
+ list_for_each_entry(data, &event_file->triggers, list) {
5084
+ if (data->cmd_ops->trigger_type == ETT_EVENT_HIST)
5085
+ hist_trigger_debug_show(m, data, n++);
5086
+ }
5087
+
5088
+ out_unlock:
5089
+ mutex_unlock(&event_mutex);
5090
+
5091
+ return ret;
5092
+}
5093
+
5094
+static int event_hist_debug_open(struct inode *inode, struct file *file)
5095
+{
5096
+ int ret;
5097
+
5098
+ ret = security_locked_down(LOCKDOWN_TRACEFS);
5099
+ if (ret)
5100
+ return ret;
5101
+
5102
+ return single_open(file, hist_debug_show, file);
5103
+}
5104
+
5105
+const struct file_operations event_hist_debug_fops = {
5106
+ .open = event_hist_debug_open,
5107
+ .read = seq_read,
5108
+ .llseek = seq_lseek,
5109
+ .release = single_release,
5110
+};
5111
+#endif
50715112
50725113 static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
50735114 {
....@@ -5415,6 +5456,7 @@
54155456 {
54165457 struct hist_trigger_data *hist_data = data->private_data;
54175458 struct event_trigger_data *test, *named_data = NULL;
5459
+ struct trace_array *tr = file->tr;
54185460 int ret = 0;
54195461
54205462 if (hist_data->attrs->name) {
....@@ -5422,7 +5464,7 @@
54225464 if (named_data) {
54235465 if (!hist_trigger_match(data, named_data, named_data,
54245466 true)) {
5425
- hist_err("Named hist trigger doesn't match existing named trigger (includes variables): ", hist_data->attrs->name);
5467
+ hist_err(tr, HIST_ERR_NAMED_MISMATCH, errpos(hist_data->attrs->name));
54265468 ret = -EINVAL;
54275469 goto out;
54285470 }
....@@ -5445,7 +5487,7 @@
54455487 else if (hist_data->attrs->clear)
54465488 hist_clear(test);
54475489 else {
5448
- hist_err("Hist trigger already exists", NULL);
5490
+ hist_err(tr, HIST_ERR_TRIGGER_EEXIST, 0);
54495491 ret = -EEXIST;
54505492 }
54515493 goto out;
....@@ -5453,7 +5495,7 @@
54535495 }
54545496 new:
54555497 if (hist_data->attrs->cont || hist_data->attrs->clear) {
5456
- hist_err("Can't clear or continue a nonexistent hist trigger", NULL);
5498
+ hist_err(tr, HIST_ERR_TRIGGER_ENOENT_CLEAR, 0);
54575499 ret = -ENOENT;
54585500 goto out;
54595501 }
....@@ -5478,7 +5520,7 @@
54785520
54795521 ret = tracing_set_clock(file->tr, hist_data->attrs->clock);
54805522 if (ret) {
5481
- hist_err("Couldn't set trace_clock: ", clock);
5523
+ hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock));
54825524 goto out;
54835525 }
54845526
....@@ -5619,6 +5661,8 @@
56195661 struct synth_event *se;
56205662 const char *se_name;
56215663
5664
+ lockdep_assert_held(&event_mutex);
5665
+
56225666 if (hist_file_check_refs(file))
56235667 return;
56245668
....@@ -5628,12 +5672,10 @@
56285672 list_del_rcu(&test->list);
56295673 trace_event_trigger_enable_disable(file, 0);
56305674
5631
- mutex_lock(&synth_event_mutex);
56325675 se_name = trace_event_name(file->event_call);
56335676 se = find_synth_event(se_name);
56345677 if (se)
56355678 se->ref--;
5636
- mutex_unlock(&synth_event_mutex);
56375679
56385680 update_cond_flag(file);
56395681 if (hist_data->enable_timestamps)
....@@ -5659,9 +5701,11 @@
56595701 char *trigger, *p;
56605702 int ret = 0;
56615703
5704
+ lockdep_assert_held(&event_mutex);
5705
+
56625706 if (glob && strlen(glob)) {
5663
- last_cmd_set(param);
56645707 hist_err_clear();
5708
+ last_cmd_set(file, param);
56655709 }
56665710
56675711 if (!param)
....@@ -5685,9 +5729,9 @@
56855729 p++;
56865730 continue;
56875731 }
5688
- if (p >= param + strlen(param) - strlen("if") - 1)
5732
+ if (p >= param + strlen(param) - (sizeof("if") - 1) - 1)
56895733 return -EINVAL;
5690
- if (*(p + strlen("if")) != ' ' && *(p + strlen("if")) != '\t') {
5734
+ if (*(p + sizeof("if") - 1) != ' ' && *(p + sizeof("if") - 1) != '\t') {
56915735 p++;
56925736 continue;
56935737 }
....@@ -5702,7 +5746,7 @@
57025746 trigger = strstrip(trigger);
57035747 }
57045748
5705
- attrs = parse_hist_trigger_attrs(trigger);
5749
+ attrs = parse_hist_trigger_attrs(file->tr, trigger);
57065750 if (IS_ERR(attrs))
57075751 return PTR_ERR(attrs);
57085752
....@@ -5749,14 +5793,10 @@
57495793 }
57505794
57515795 cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
5752
-
5753
- mutex_lock(&synth_event_mutex);
57545796 se_name = trace_event_name(file->event_call);
57555797 se = find_synth_event(se_name);
57565798 if (se)
57575799 se->ref--;
5758
- mutex_unlock(&synth_event_mutex);
5759
-
57605800 ret = 0;
57615801 goto out_free;
57625802 }
....@@ -5777,12 +5817,15 @@
57775817 if (get_named_trigger_data(trigger_data))
57785818 goto enable;
57795819
5780
- if (has_hist_vars(hist_data))
5781
- save_hist_vars(hist_data);
5782
-
5783
- ret = create_actions(hist_data, file);
5820
+ ret = create_actions(hist_data);
57845821 if (ret)
57855822 goto out_unreg;
5823
+
5824
+ if (has_hist_vars(hist_data) || hist_data->n_var_refs) {
5825
+ ret = save_hist_vars(hist_data);
5826
+ if (ret)
5827
+ goto out_unreg;
5828
+ }
57865829
57875830 ret = tracing_map_init(hist_data->map);
57885831 if (ret)
....@@ -5792,17 +5835,14 @@
57925835 if (ret)
57935836 goto out_unreg;
57945837
5795
- mutex_lock(&synth_event_mutex);
57965838 se_name = trace_event_name(file->event_call);
57975839 se = find_synth_event(se_name);
57985840 if (se)
57995841 se->ref++;
5800
- mutex_unlock(&synth_event_mutex);
5801
-
58025842 /* Just return zero, not the number of registered triggers */
58035843 ret = 0;
58045844 out:
5805
- if (ret == 0)
5845
+ if (ret == 0 && glob[0])
58065846 hist_err_clear();
58075847
58085848 return ret;
....@@ -5849,7 +5889,8 @@
58495889 struct enable_trigger_data *enable_data = data->private_data;
58505890 struct event_trigger_data *test;
58515891
5852
- list_for_each_entry_rcu(test, &enable_data->file->triggers, list) {
5892
+ list_for_each_entry_rcu(test, &enable_data->file->triggers, list,
5893
+ lockdep_is_held(&event_mutex)) {
58535894 if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
58545895 if (enable_data->enable)
58555896 test->paused = false;
....@@ -5974,31 +6015,3 @@
59746015
59756016 return ret;
59766017 }
5977
-
5978
-static __init int trace_events_hist_init(void)
5979
-{
5980
- struct dentry *entry = NULL;
5981
- struct dentry *d_tracer;
5982
- int err = 0;
5983
-
5984
- d_tracer = tracing_init_dentry();
5985
- if (IS_ERR(d_tracer)) {
5986
- err = PTR_ERR(d_tracer);
5987
- goto err;
5988
- }
5989
-
5990
- entry = tracefs_create_file("synthetic_events", 0644, d_tracer,
5991
- NULL, &synth_events_fops);
5992
- if (!entry) {
5993
- err = -ENODEV;
5994
- goto err;
5995
- }
5996
-
5997
- return err;
5998
- err:
5999
- pr_warn("Could not create tracefs 'synthetic_events' entry\n");
6000
-
6001
- return err;
6002
-}
6003
-
6004
-fs_initcall(trace_events_hist_init);