forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
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[TRACING_MAP_VARS_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,
....@@ -1835,12 +1158,6 @@
18351158 unsigned long size, map_bits;
18361159 int ret;
18371160
1838
- strsep(&str, "=");
1839
- if (!str) {
1840
- ret = -EINVAL;
1841
- goto out;
1842
- }
1843
-
18441161 ret = kstrtoul(str, 0, &size);
18451162 if (ret)
18461163 goto out;
....@@ -1883,8 +1200,9 @@
18831200 if (attrs->n_actions >= HIST_ACTIONS_MAX)
18841201 return ret;
18851202
1886
- if ((strncmp(str, "onmatch(", strlen("onmatch(")) == 0) ||
1887
- (strncmp(str, "onmax(", strlen("onmax(")) == 0)) {
1203
+ if ((str_has_prefix(str, "onmatch(")) ||
1204
+ (str_has_prefix(str, "onmax(")) ||
1205
+ (str_has_prefix(str, "onchange("))) {
18881206 attrs->action_str[attrs->n_actions] = kstrdup(str, GFP_KERNEL);
18891207 if (!attrs->action_str[attrs->n_actions]) {
18901208 ret = -ENOMEM;
....@@ -1893,47 +1211,43 @@
18931211 attrs->n_actions++;
18941212 ret = 0;
18951213 }
1896
-
18971214 return ret;
18981215 }
18991216
1900
-static int parse_assignment(char *str, struct hist_trigger_attrs *attrs)
1217
+static int parse_assignment(struct trace_array *tr,
1218
+ char *str, struct hist_trigger_attrs *attrs)
19011219 {
1902
- int ret = 0;
1220
+ int len, ret = 0;
19031221
1904
- if ((strncmp(str, "key=", strlen("key=")) == 0) ||
1905
- (strncmp(str, "keys=", strlen("keys=")) == 0)) {
1906
- attrs->keys_str = kstrdup(str, GFP_KERNEL);
1222
+ if ((len = str_has_prefix(str, "key=")) ||
1223
+ (len = str_has_prefix(str, "keys="))) {
1224
+ attrs->keys_str = kstrdup(str + len, GFP_KERNEL);
19071225 if (!attrs->keys_str) {
19081226 ret = -ENOMEM;
19091227 goto out;
19101228 }
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);
1229
+ } else if ((len = str_has_prefix(str, "val=")) ||
1230
+ (len = str_has_prefix(str, "vals=")) ||
1231
+ (len = str_has_prefix(str, "values="))) {
1232
+ attrs->vals_str = kstrdup(str + len, GFP_KERNEL);
19151233 if (!attrs->vals_str) {
19161234 ret = -ENOMEM;
19171235 goto out;
19181236 }
1919
- } else if (strncmp(str, "sort=", strlen("sort=")) == 0) {
1920
- attrs->sort_key_str = kstrdup(str, GFP_KERNEL);
1237
+ } else if ((len = str_has_prefix(str, "sort="))) {
1238
+ attrs->sort_key_str = kstrdup(str + len, GFP_KERNEL);
19211239 if (!attrs->sort_key_str) {
19221240 ret = -ENOMEM;
19231241 goto out;
19241242 }
1925
- } else if (strncmp(str, "name=", strlen("name=")) == 0) {
1243
+ } else if (str_has_prefix(str, "name=")) {
19261244 attrs->name = kstrdup(str, GFP_KERNEL);
19271245 if (!attrs->name) {
19281246 ret = -ENOMEM;
19291247 goto out;
19301248 }
1931
- } else if (strncmp(str, "clock=", strlen("clock=")) == 0) {
1932
- strsep(&str, "=");
1933
- if (!str) {
1934
- ret = -EINVAL;
1935
- goto out;
1936
- }
1249
+ } else if ((len = str_has_prefix(str, "clock="))) {
1250
+ str += len;
19371251
19381252 str = strstrip(str);
19391253 attrs->clock = kstrdup(str, GFP_KERNEL);
....@@ -1941,8 +1255,8 @@
19411255 ret = -ENOMEM;
19421256 goto out;
19431257 }
1944
- } else if (strncmp(str, "size=", strlen("size=")) == 0) {
1945
- int map_bits = parse_map_size(str);
1258
+ } else if ((len = str_has_prefix(str, "size="))) {
1259
+ int map_bits = parse_map_size(str + len);
19461260
19471261 if (map_bits < 0) {
19481262 ret = map_bits;
....@@ -1953,7 +1267,7 @@
19531267 char *assignment;
19541268
19551269 if (attrs->n_assignments == TRACING_MAP_VARS_MAX) {
1956
- hist_err("Too many variables defined: ", str);
1270
+ hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(str));
19571271 ret = -EINVAL;
19581272 goto out;
19591273 }
....@@ -1970,7 +1284,8 @@
19701284 return ret;
19711285 }
19721286
1973
-static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str)
1287
+static struct hist_trigger_attrs *
1288
+parse_hist_trigger_attrs(struct trace_array *tr, char *trigger_str)
19741289 {
19751290 struct hist_trigger_attrs *attrs;
19761291 int ret = 0;
....@@ -1981,9 +1296,16 @@
19811296
19821297 while (trigger_str) {
19831298 char *str = strsep(&trigger_str, ":");
1299
+ char *rhs;
19841300
1985
- if (strchr(str, '=')) {
1986
- ret = parse_assignment(str, attrs);
1301
+ rhs = strchr(str, '=');
1302
+ if (rhs) {
1303
+ if (!strlen(++rhs)) {
1304
+ ret = -EINVAL;
1305
+ hist_err(tr, HIST_ERR_EMPTY_ASSIGNMENT, errpos(str));
1306
+ goto free;
1307
+ }
1308
+ ret = parse_assignment(tr, str, attrs);
19871309 if (ret)
19881310 goto free;
19891311 } else if (strcmp(str, "pause") == 0)
....@@ -2032,7 +1354,7 @@
20321354 return;
20331355 }
20341356
2035
- memcpy(comm, task->comm, TASK_COMM_LEN);
1357
+ strncpy(comm, task->comm, TASK_COMM_LEN);
20361358 }
20371359
20381360 static void hist_elt_data_free(struct hist_elt_data *elt_data)
....@@ -2078,7 +1400,14 @@
20781400 }
20791401 }
20801402
2081
- n_str = hist_data->n_field_var_str + hist_data->n_max_var_str;
1403
+ n_str = hist_data->n_field_var_str + hist_data->n_save_var_str +
1404
+ hist_data->n_var_str;
1405
+ if (n_str > SYNTH_FIELDS_MAX) {
1406
+ hist_elt_data_free(elt_data);
1407
+ return -EINVAL;
1408
+ }
1409
+
1410
+ BUILD_BUG_ON(STR_VAR_LEN_MAX & (sizeof(u64) - 1));
20821411
20831412 size = STR_VAR_LEN_MAX;
20841413
....@@ -2247,6 +1576,9 @@
22471576 kfree(hist_field->name);
22481577 kfree(hist_field->type);
22491578
1579
+ kfree(hist_field->system);
1580
+ kfree(hist_field->event_name);
1581
+
22501582 kfree(hist_field);
22511583 }
22521584
....@@ -2352,9 +1684,10 @@
23521684 if (!hist_field->type)
23531685 goto free;
23541686
2355
- if (field->filter_type == FILTER_STATIC_STRING)
1687
+ if (field->filter_type == FILTER_STATIC_STRING) {
23561688 hist_field->fn = hist_field_string;
2357
- else if (field->filter_type == FILTER_DYN_STRING)
1689
+ hist_field->size = field->size;
1690
+ } else if (field->filter_type == FILTER_DYN_STRING)
23581691 hist_field->fn = hist_field_dynstring;
23591692 else
23601693 hist_field->fn = hist_field_pstring;
....@@ -2456,10 +1789,29 @@
24561789 return err;
24571790 free:
24581791 kfree(ref_field->system);
1792
+ ref_field->system = NULL;
24591793 kfree(ref_field->event_name);
1794
+ ref_field->event_name = NULL;
24601795 kfree(ref_field->name);
1796
+ ref_field->name = NULL;
24611797
24621798 goto out;
1799
+}
1800
+
1801
+static int find_var_ref_idx(struct hist_trigger_data *hist_data,
1802
+ struct hist_field *var_field)
1803
+{
1804
+ struct hist_field *ref_field;
1805
+ int i;
1806
+
1807
+ for (i = 0; i < hist_data->n_var_refs; i++) {
1808
+ ref_field = hist_data->var_refs[i];
1809
+ if (ref_field->var.idx == var_field->var.idx &&
1810
+ ref_field->var.hist_data == var_field->hist_data)
1811
+ return i;
1812
+ }
1813
+
1814
+ return -ENOENT;
24631815 }
24641816
24651817 /**
....@@ -2569,6 +1921,7 @@
25691921 char *var_name)
25701922 {
25711923 struct hist_field *var_field = NULL, *ref_field = NULL;
1924
+ struct trace_array *tr = hist_data->event_file->tr;
25721925
25731926 if (!is_var_ref(var_name))
25741927 return NULL;
....@@ -2581,8 +1934,7 @@
25811934 system, event_name);
25821935
25831936 if (!ref_field)
2584
- hist_err_event("Couldn't find variable: $",
2585
- system, event_name, var_name);
1937
+ hist_err(tr, HIST_ERR_VAR_NOT_FOUND, errpos(var_name));
25861938
25871939 return ref_field;
25881940 }
....@@ -2593,6 +1945,7 @@
25931945 {
25941946 struct ftrace_event_field *field = NULL;
25951947 char *field_name, *modifier, *str;
1948
+ struct trace_array *tr = file->tr;
25961949
25971950 modifier = str = kstrdup(field_str, GFP_KERNEL);
25981951 if (!modifier)
....@@ -2616,7 +1969,7 @@
26161969 else if (strcmp(modifier, "usecs") == 0)
26171970 *flags |= HIST_FIELD_FL_TIMESTAMP_USECS;
26181971 else {
2619
- hist_err("Invalid field modifier: ", modifier);
1972
+ hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(modifier));
26201973 field = ERR_PTR(-EINVAL);
26211974 goto out;
26221975 }
....@@ -2635,12 +1988,13 @@
26351988 /*
26361989 * For backward compatibility, if field_name
26371990 * was "cpu", then we treat this the same as
2638
- * common_cpu.
1991
+ * common_cpu. This also works for "CPU".
26391992 */
2640
- if (strcmp(field_name, "cpu") == 0) {
1993
+ if (field && field->filter_type == FILTER_CPU) {
26411994 *flags |= HIST_FIELD_FL_CPU;
26421995 } else {
2643
- hist_err("Couldn't find field: ", field_name);
1996
+ hist_err(tr, HIST_ERR_FIELD_NOT_FOUND,
1997
+ errpos(field_name));
26441998 field = ERR_PTR(-EINVAL);
26451999 goto out;
26462000 }
....@@ -2705,7 +2059,8 @@
27052059
27062060 s = local_field_var_ref(hist_data, ref_system, ref_event, ref_var);
27072061 if (!s) {
2708
- hist_field = parse_var_ref(hist_data, ref_system, ref_event, ref_var);
2062
+ hist_field = parse_var_ref(hist_data, ref_system,
2063
+ ref_event, ref_var);
27092064 if (hist_field) {
27102065 if (var_name) {
27112066 hist_field = create_alias(hist_data, hist_field, var_name);
....@@ -2754,7 +2109,7 @@
27542109 /* we support only -(xxx) i.e. explicit parens required */
27552110
27562111 if (level > 3) {
2757
- hist_err("Too many subexpressions (3 max): ", str);
2112
+ hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str));
27582113 ret = -EINVAL;
27592114 goto free;
27602115 }
....@@ -2792,6 +2147,7 @@
27922147 }
27932148 if (operand1->flags & HIST_FIELD_FL_STRING) {
27942149 /* String type can not be the operand of unary operator. */
2150
+ hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
27952151 destroy_hist_field(operand1, 0);
27962152 ret = -EINVAL;
27972153 goto free;
....@@ -2801,6 +2157,8 @@
28012157 (HIST_FIELD_FL_TIMESTAMP | HIST_FIELD_FL_TIMESTAMP_USECS);
28022158 expr->fn = hist_field_unary_minus;
28032159 expr->operands[0] = operand1;
2160
+ expr->size = operand1->size;
2161
+ expr->is_signed = operand1->is_signed;
28042162 expr->operator = FIELD_OP_UNARY_MINUS;
28052163 expr->name = expr_str(expr, 0);
28062164 expr->type = kstrdup(operand1->type, GFP_KERNEL);
....@@ -2815,7 +2173,8 @@
28152173 return ERR_PTR(ret);
28162174 }
28172175
2818
-static int check_expr_operands(struct hist_field *operand1,
2176
+static int check_expr_operands(struct trace_array *tr,
2177
+ struct hist_field *operand1,
28192178 struct hist_field *operand2)
28202179 {
28212180 unsigned long operand1_flags = operand1->flags;
....@@ -2843,7 +2202,7 @@
28432202
28442203 if ((operand1_flags & HIST_FIELD_FL_TIMESTAMP_USECS) !=
28452204 (operand2_flags & HIST_FIELD_FL_TIMESTAMP_USECS)) {
2846
- hist_err("Timestamp units in expression don't match", NULL);
2205
+ hist_err(tr, HIST_ERR_TIMESTAMP_MISMATCH, 0);
28472206 return -EINVAL;
28482207 }
28492208
....@@ -2861,7 +2220,7 @@
28612220 char *sep, *operand1_str;
28622221
28632222 if (level > 3) {
2864
- hist_err("Too many subexpressions (3 max): ", str);
2223
+ hist_err(file->tr, HIST_ERR_TOO_MANY_SUBEXPR, errpos(str));
28652224 return ERR_PTR(-EINVAL);
28662225 }
28672226
....@@ -2897,6 +2256,7 @@
28972256 goto free;
28982257 }
28992258 if (operand1->flags & HIST_FIELD_FL_STRING) {
2259
+ hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(operand1_str));
29002260 ret = -EINVAL;
29012261 goto free;
29022262 }
....@@ -2910,11 +2270,12 @@
29102270 goto free;
29112271 }
29122272 if (operand2->flags & HIST_FIELD_FL_STRING) {
2273
+ hist_err(file->tr, HIST_ERR_INVALID_STR_OPERAND, errpos(str));
29132274 ret = -EINVAL;
29142275 goto free;
29152276 }
29162277
2917
- ret = check_expr_operands(operand1, operand2);
2278
+ ret = check_expr_operands(file->tr, operand1, operand2);
29182279 if (ret)
29192280 goto free;
29202281
....@@ -2937,6 +2298,7 @@
29372298
29382299 /* The operand sizes should be the same, so just pick one */
29392300 expr->size = operand1->size;
2301
+ expr->is_signed = operand1->is_signed;
29402302
29412303 expr->operator = field_op;
29422304 expr->name = expr_str(expr, 0);
....@@ -3115,16 +2477,14 @@
31152477 int ret;
31162478
31172479 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);
2480
+ hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name));
31202481 return ERR_PTR(-EINVAL);
31212482 }
31222483
31232484 file = event_file(tr, subsys_name, event_name);
31242485
31252486 if (IS_ERR(file)) {
3126
- hist_err_event("onmatch: Event file not found: ",
3127
- subsys_name, event_name, field_name);
2487
+ hist_err(tr, HIST_ERR_EVENT_FILE_NOT_FOUND, errpos(field_name));
31282488 ret = PTR_ERR(file);
31292489 return ERR_PTR(ret);
31302490 }
....@@ -3137,8 +2497,7 @@
31372497 */
31382498 hist_data = find_compatible_hist(target_hist_data, file);
31392499 if (!hist_data) {
3140
- hist_err_event("onmatch: Matching event histogram not found: ",
3141
- subsys_name, event_name, field_name);
2500
+ hist_err(tr, HIST_ERR_HIST_NOT_FOUND, errpos(field_name));
31422501 return ERR_PTR(-EINVAL);
31432502 }
31442503
....@@ -3199,8 +2558,7 @@
31992558 kfree(cmd);
32002559 kfree(var_hist->cmd);
32012560 kfree(var_hist);
3202
- hist_err_event("onmatch: Couldn't create histogram for field: ",
3203
- subsys_name, event_name, field_name);
2561
+ hist_err(tr, HIST_ERR_HIST_CREATE_FAIL, errpos(field_name));
32042562 return ERR_PTR(ret);
32052563 }
32062564
....@@ -3212,8 +2570,7 @@
32122570 if (IS_ERR_OR_NULL(event_var)) {
32132571 kfree(var_hist->cmd);
32142572 kfree(var_hist);
3215
- hist_err_event("onmatch: Couldn't find synthetic variable: ",
3216
- subsys_name, event_name, field_name);
2573
+ hist_err(tr, HIST_ERR_SYNTH_VAR_NOT_FOUND, errpos(field_name));
32172574 return ERR_PTR(-EINVAL);
32182575 }
32192576
....@@ -3273,8 +2630,10 @@
32732630 if (val->flags & HIST_FIELD_FL_STRING) {
32742631 char *str = elt_data->field_var_str[j++];
32752632 char *val_str = (char *)(uintptr_t)var_val;
2633
+ unsigned int size;
32762634
3277
- strscpy(str, val_str, STR_VAR_LEN_MAX);
2635
+ size = min(val->size, STR_VAR_LEN_MAX);
2636
+ strscpy(str, val_str, size);
32782637 var_val = (u64)(uintptr_t)str;
32792638 }
32802639 tracing_map_set_var(elt, var_idx, var_val);
....@@ -3290,13 +2649,13 @@
32902649 hist_data->n_field_vars, 0);
32912650 }
32922651
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)
2652
+static void save_track_data_vars(struct hist_trigger_data *hist_data,
2653
+ struct tracing_map_elt *elt, void *rec,
2654
+ struct ring_buffer_event *rbe, void *key,
2655
+ struct action_data *data, u64 *var_ref_vals)
32972656 {
3298
- __update_field_vars(elt, rbe, rec, hist_data->max_vars,
3299
- hist_data->n_max_vars, hist_data->n_field_var_str);
2657
+ __update_field_vars(elt, rbe, rec, hist_data->save_vars,
2658
+ hist_data->n_save_vars, hist_data->n_field_var_str);
33002659 }
33012660
33022661 static struct hist_field *create_var(struct hist_trigger_data *hist_data,
....@@ -3324,6 +2683,7 @@
33242683 goto out;
33252684 }
33262685
2686
+ var->ref = 1;
33272687 var->flags = HIST_FIELD_FL_VAR;
33282688 var->var.idx = idx;
33292689 var->var.hist_data = var->hist_data = hist_data;
....@@ -3346,25 +2706,26 @@
33462706 {
33472707 struct hist_field *val = NULL, *var = NULL;
33482708 unsigned long flags = HIST_FIELD_FL_VAR;
2709
+ struct trace_array *tr = file->tr;
33492710 struct field_var *field_var;
33502711 int ret = 0;
33512712
33522713 if (hist_data->n_field_vars >= SYNTH_FIELDS_MAX) {
3353
- hist_err("Too many field variables defined: ", field_name);
2714
+ hist_err(tr, HIST_ERR_TOO_MANY_FIELD_VARS, errpos(field_name));
33542715 ret = -EINVAL;
33552716 goto err;
33562717 }
33572718
33582719 val = parse_atom(hist_data, file, field_name, &flags, NULL);
33592720 if (IS_ERR(val)) {
3360
- hist_err("Couldn't parse field variable: ", field_name);
2721
+ hist_err(tr, HIST_ERR_FIELD_VAR_PARSE_FAIL, errpos(field_name));
33612722 ret = PTR_ERR(val);
33622723 goto err;
33632724 }
33642725
33652726 var = create_var(hist_data, file, field_name, val->size, val->type);
33662727 if (IS_ERR(var)) {
3367
- hist_err("Couldn't create or find variable: ", field_name);
2728
+ hist_err(tr, HIST_ERR_VAR_CREATE_FIND_FAIL, errpos(field_name));
33682729 kfree(val);
33692730 ret = PTR_ERR(var);
33702731 goto err;
....@@ -3431,18 +2792,196 @@
34312792 return create_field_var(target_hist_data, file, var_name);
34322793 }
34332794
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)
2795
+static bool check_track_val_max(u64 track_val, u64 var_val)
34382796 {
3439
- unsigned int i, save_var_idx, max_idx = data->onmax.max_var->var.idx;
2797
+ if (var_val <= track_val)
2798
+ return false;
34402799
3441
- seq_printf(m, "\n\tmax: %10llu", tracing_map_read_var(elt, max_idx));
2800
+ return true;
2801
+}
34422802
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;
2803
+static bool check_track_val_changed(u64 track_val, u64 var_val)
2804
+{
2805
+ if (var_val == track_val)
2806
+ return false;
2807
+
2808
+ return true;
2809
+}
2810
+
2811
+static u64 get_track_val(struct hist_trigger_data *hist_data,
2812
+ struct tracing_map_elt *elt,
2813
+ struct action_data *data)
2814
+{
2815
+ unsigned int track_var_idx = data->track_data.track_var->var.idx;
2816
+ u64 track_val;
2817
+
2818
+ track_val = tracing_map_read_var(elt, track_var_idx);
2819
+
2820
+ return track_val;
2821
+}
2822
+
2823
+static void save_track_val(struct hist_trigger_data *hist_data,
2824
+ struct tracing_map_elt *elt,
2825
+ struct action_data *data, u64 var_val)
2826
+{
2827
+ unsigned int track_var_idx = data->track_data.track_var->var.idx;
2828
+
2829
+ tracing_map_set_var(elt, track_var_idx, var_val);
2830
+}
2831
+
2832
+static void save_track_data(struct hist_trigger_data *hist_data,
2833
+ struct tracing_map_elt *elt, void *rec,
2834
+ struct ring_buffer_event *rbe, void *key,
2835
+ struct action_data *data, u64 *var_ref_vals)
2836
+{
2837
+ if (data->track_data.save_data)
2838
+ data->track_data.save_data(hist_data, elt, rec, rbe, key, data, var_ref_vals);
2839
+}
2840
+
2841
+static bool check_track_val(struct tracing_map_elt *elt,
2842
+ struct action_data *data,
2843
+ u64 var_val)
2844
+{
2845
+ struct hist_trigger_data *hist_data;
2846
+ u64 track_val;
2847
+
2848
+ hist_data = data->track_data.track_var->hist_data;
2849
+ track_val = get_track_val(hist_data, elt, data);
2850
+
2851
+ return data->track_data.check_val(track_val, var_val);
2852
+}
2853
+
2854
+#ifdef CONFIG_TRACER_SNAPSHOT
2855
+static bool cond_snapshot_update(struct trace_array *tr, void *cond_data)
2856
+{
2857
+ /* called with tr->max_lock held */
2858
+ struct track_data *track_data = tr->cond_snapshot->cond_data;
2859
+ struct hist_elt_data *elt_data, *track_elt_data;
2860
+ struct snapshot_context *context = cond_data;
2861
+ struct action_data *action;
2862
+ u64 track_val;
2863
+
2864
+ if (!track_data)
2865
+ return false;
2866
+
2867
+ action = track_data->action_data;
2868
+
2869
+ track_val = get_track_val(track_data->hist_data, context->elt,
2870
+ track_data->action_data);
2871
+
2872
+ if (!action->track_data.check_val(track_data->track_val, track_val))
2873
+ return false;
2874
+
2875
+ track_data->track_val = track_val;
2876
+ memcpy(track_data->key, context->key, track_data->key_len);
2877
+
2878
+ elt_data = context->elt->private_data;
2879
+ track_elt_data = track_data->elt.private_data;
2880
+ if (elt_data->comm)
2881
+ strncpy(track_elt_data->comm, elt_data->comm, TASK_COMM_LEN);
2882
+
2883
+ track_data->updated = true;
2884
+
2885
+ return true;
2886
+}
2887
+
2888
+static void save_track_data_snapshot(struct hist_trigger_data *hist_data,
2889
+ struct tracing_map_elt *elt, void *rec,
2890
+ struct ring_buffer_event *rbe, void *key,
2891
+ struct action_data *data,
2892
+ u64 *var_ref_vals)
2893
+{
2894
+ struct trace_event_file *file = hist_data->event_file;
2895
+ struct snapshot_context context;
2896
+
2897
+ context.elt = elt;
2898
+ context.key = key;
2899
+
2900
+ tracing_snapshot_cond(file->tr, &context);
2901
+}
2902
+
2903
+static void hist_trigger_print_key(struct seq_file *m,
2904
+ struct hist_trigger_data *hist_data,
2905
+ void *key,
2906
+ struct tracing_map_elt *elt);
2907
+
2908
+static struct action_data *snapshot_action(struct hist_trigger_data *hist_data)
2909
+{
2910
+ unsigned int i;
2911
+
2912
+ if (!hist_data->n_actions)
2913
+ return NULL;
2914
+
2915
+ for (i = 0; i < hist_data->n_actions; i++) {
2916
+ struct action_data *data = hist_data->actions[i];
2917
+
2918
+ if (data->action == ACTION_SNAPSHOT)
2919
+ return data;
2920
+ }
2921
+
2922
+ return NULL;
2923
+}
2924
+
2925
+static void track_data_snapshot_print(struct seq_file *m,
2926
+ struct hist_trigger_data *hist_data)
2927
+{
2928
+ struct trace_event_file *file = hist_data->event_file;
2929
+ struct track_data *track_data;
2930
+ struct action_data *action;
2931
+
2932
+ track_data = tracing_cond_snapshot_data(file->tr);
2933
+ if (!track_data)
2934
+ return;
2935
+
2936
+ if (!track_data->updated)
2937
+ return;
2938
+
2939
+ action = snapshot_action(hist_data);
2940
+ if (!action)
2941
+ return;
2942
+
2943
+ seq_puts(m, "\nSnapshot taken (see tracing/snapshot). Details:\n");
2944
+ seq_printf(m, "\ttriggering value { %s(%s) }: %10llu",
2945
+ action->handler == HANDLER_ONMAX ? "onmax" : "onchange",
2946
+ action->track_data.var_str, track_data->track_val);
2947
+
2948
+ seq_puts(m, "\ttriggered by event with key: ");
2949
+ hist_trigger_print_key(m, hist_data, track_data->key, &track_data->elt);
2950
+ seq_putc(m, '\n');
2951
+}
2952
+#else
2953
+static bool cond_snapshot_update(struct trace_array *tr, void *cond_data)
2954
+{
2955
+ return false;
2956
+}
2957
+static void save_track_data_snapshot(struct hist_trigger_data *hist_data,
2958
+ struct tracing_map_elt *elt, void *rec,
2959
+ struct ring_buffer_event *rbe, void *key,
2960
+ struct action_data *data,
2961
+ u64 *var_ref_vals) {}
2962
+static void track_data_snapshot_print(struct seq_file *m,
2963
+ struct hist_trigger_data *hist_data) {}
2964
+#endif /* CONFIG_TRACER_SNAPSHOT */
2965
+
2966
+static void track_data_print(struct seq_file *m,
2967
+ struct hist_trigger_data *hist_data,
2968
+ struct tracing_map_elt *elt,
2969
+ struct action_data *data)
2970
+{
2971
+ u64 track_val = get_track_val(hist_data, elt, data);
2972
+ unsigned int i, save_var_idx;
2973
+
2974
+ if (data->handler == HANDLER_ONMAX)
2975
+ seq_printf(m, "\n\tmax: %10llu", track_val);
2976
+ else if (data->handler == HANDLER_ONCHANGE)
2977
+ seq_printf(m, "\n\tchanged: %10llu", track_val);
2978
+
2979
+ if (data->action == ACTION_SNAPSHOT)
2980
+ return;
2981
+
2982
+ for (i = 0; i < hist_data->n_save_vars; i++) {
2983
+ struct hist_field *save_val = hist_data->save_vars[i]->val;
2984
+ struct hist_field *save_var = hist_data->save_vars[i]->var;
34462985 u64 val;
34472986
34482987 save_var_idx = save_var->var.idx;
....@@ -3457,64 +2996,82 @@
34572996 }
34582997 }
34592998
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)
2999
+static void ontrack_action(struct hist_trigger_data *hist_data,
3000
+ struct tracing_map_elt *elt, void *rec,
3001
+ struct ring_buffer_event *rbe, void *key,
3002
+ struct action_data *data, u64 *var_ref_vals)
34643003 {
3465
- unsigned int max_idx = data->onmax.max_var->var.idx;
3466
- unsigned int max_var_ref_idx = data->onmax.max_var_ref_idx;
3004
+ u64 var_val = var_ref_vals[data->track_data.var_ref->var_ref_idx];
34673005
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);
3006
+ if (check_track_val(elt, data, var_val)) {
3007
+ save_track_val(hist_data, elt, data, var_val);
3008
+ save_track_data(hist_data, elt, rec, rbe, key, data, var_ref_vals);
3009
+ }
34793010 }
34803011
3481
-static void onmax_destroy(struct action_data *data)
3012
+static void action_data_destroy(struct action_data *data)
34823013 {
34833014 unsigned int i;
34843015
3485
- destroy_hist_field(data->onmax.max_var, 0);
3486
- destroy_hist_field(data->onmax.var, 0);
3016
+ lockdep_assert_held(&event_mutex);
34873017
3488
- kfree(data->onmax.var_str);
3489
- kfree(data->onmax.fn_name);
3018
+ kfree(data->action_name);
34903019
34913020 for (i = 0; i < data->n_params; i++)
34923021 kfree(data->params[i]);
34933022
3023
+ if (data->synth_event)
3024
+ data->synth_event->ref--;
3025
+
3026
+ kfree(data->synth_event_name);
3027
+
34943028 kfree(data);
34953029 }
34963030
3497
-static int onmax_create(struct hist_trigger_data *hist_data,
3498
- struct action_data *data)
3031
+static void track_data_destroy(struct hist_trigger_data *hist_data,
3032
+ struct action_data *data)
34993033 {
35003034 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;
3035
+
3036
+ destroy_hist_field(data->track_data.track_var, 0);
3037
+
3038
+ if (data->action == ACTION_SNAPSHOT) {
3039
+ struct track_data *track_data;
3040
+
3041
+ track_data = tracing_cond_snapshot_data(file->tr);
3042
+ if (track_data && track_data->hist_data == hist_data) {
3043
+ tracing_snapshot_cond_disable(file->tr);
3044
+ track_data_free(track_data);
3045
+ }
3046
+ }
3047
+
3048
+ kfree(data->track_data.var_str);
3049
+
3050
+ action_data_destroy(data);
3051
+}
3052
+
3053
+static int action_create(struct hist_trigger_data *hist_data,
3054
+ struct action_data *data);
3055
+
3056
+static int track_data_create(struct hist_trigger_data *hist_data,
3057
+ struct action_data *data)
3058
+{
3059
+ struct hist_field *var_field, *ref_field, *track_var = NULL;
3060
+ struct trace_event_file *file = hist_data->event_file;
3061
+ struct trace_array *tr = file->tr;
3062
+ char *track_data_var_str;
35063063 int ret = 0;
35073064
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);
3065
+ track_data_var_str = data->track_data.var_str;
3066
+ if (track_data_var_str[0] != '$') {
3067
+ hist_err(tr, HIST_ERR_ONX_NOT_VAR, errpos(track_data_var_str));
35113068 return -EINVAL;
35123069 }
3513
- onmax_var_str++;
3070
+ track_data_var_str++;
35143071
3515
- var_field = find_target_event_var(hist_data, NULL, NULL, onmax_var_str);
3072
+ var_field = find_target_event_var(hist_data, NULL, NULL, track_data_var_str);
35163073 if (!var_field) {
3517
- hist_err("onmax: Couldn't find onmax variable: ", onmax_var_str);
3074
+ hist_err(tr, HIST_ERR_ONX_VAR_NOT_FOUND, errpos(track_data_var_str));
35183075 return -EINVAL;
35193076 }
35203077
....@@ -3522,61 +3079,53 @@
35223079 if (!ref_field)
35233080 return -ENOMEM;
35243081
3525
- data->onmax.var = ref_field;
3082
+ data->track_data.var_ref = ref_field;
35263083
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);
3084
+ if (data->handler == HANDLER_ONMAX)
3085
+ track_var = create_var(hist_data, file, "__max", sizeof(u64), "u64");
3086
+ if (IS_ERR(track_var)) {
3087
+ hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0);
3088
+ ret = PTR_ERR(track_var);
35333089 goto out;
35343090 }
3535
- data->onmax.max_var = max_var;
35363091
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);
3092
+ if (data->handler == HANDLER_ONCHANGE)
3093
+ track_var = create_var(hist_data, file, "__change", sizeof(u64), "u64");
3094
+ if (IS_ERR(track_var)) {
3095
+ hist_err(tr, HIST_ERR_ONX_VAR_CREATE_FAIL, 0);
3096
+ ret = PTR_ERR(track_var);
3097
+ goto out;
35573098 }
3099
+ data->track_data.track_var = track_var;
3100
+
3101
+ ret = action_create(hist_data, data);
35583102 out:
35593103 return ret;
35603104 }
35613105
3562
-static int parse_action_params(char *params, struct action_data *data)
3106
+static int parse_action_params(struct trace_array *tr, char *params,
3107
+ struct action_data *data)
35633108 {
35643109 char *param, *saved_param;
3110
+ bool first_param = true;
35653111 int ret = 0;
35663112
35673113 while (params) {
3568
- if (data->n_params >= SYNTH_FIELDS_MAX)
3114
+ if (data->n_params >= SYNTH_FIELDS_MAX) {
3115
+ hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);
35693116 goto out;
3117
+ }
35703118
35713119 param = strsep(&params, ",");
35723120 if (!param) {
3121
+ hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, 0);
35733122 ret = -EINVAL;
35743123 goto out;
35753124 }
35763125
35773126 param = strstrip(param);
35783127 if (strlen(param) < 2) {
3579
- hist_err("Invalid action param: ", param);
3128
+ hist_err(tr, HIST_ERR_INVALID_PARAM, errpos(param));
35803129 ret = -EINVAL;
35813130 goto out;
35823131 }
....@@ -3587,88 +3136,164 @@
35873136 goto out;
35883137 }
35893138
3139
+ if (first_param && data->use_trace_keyword) {
3140
+ data->synth_event_name = saved_param;
3141
+ first_param = false;
3142
+ continue;
3143
+ }
3144
+ first_param = false;
3145
+
35903146 data->params[data->n_params++] = saved_param;
35913147 }
35923148 out:
35933149 return ret;
35943150 }
35953151
3596
-static struct action_data *onmax_parse(char *str)
3152
+static int action_parse(struct trace_array *tr, char *str, struct action_data *data,
3153
+ enum handler_id handler)
35973154 {
3598
- char *onmax_fn_name, *onmax_var_str;
3155
+ char *action_name;
3156
+ int ret = 0;
3157
+
3158
+ strsep(&str, ".");
3159
+ if (!str) {
3160
+ hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0);
3161
+ ret = -EINVAL;
3162
+ goto out;
3163
+ }
3164
+
3165
+ action_name = strsep(&str, "(");
3166
+ if (!action_name || !str) {
3167
+ hist_err(tr, HIST_ERR_ACTION_NOT_FOUND, 0);
3168
+ ret = -EINVAL;
3169
+ goto out;
3170
+ }
3171
+
3172
+ if (str_has_prefix(action_name, "save")) {
3173
+ char *params = strsep(&str, ")");
3174
+
3175
+ if (!params) {
3176
+ hist_err(tr, HIST_ERR_NO_SAVE_PARAMS, 0);
3177
+ ret = -EINVAL;
3178
+ goto out;
3179
+ }
3180
+
3181
+ ret = parse_action_params(tr, params, data);
3182
+ if (ret)
3183
+ goto out;
3184
+
3185
+ if (handler == HANDLER_ONMAX)
3186
+ data->track_data.check_val = check_track_val_max;
3187
+ else if (handler == HANDLER_ONCHANGE)
3188
+ data->track_data.check_val = check_track_val_changed;
3189
+ else {
3190
+ hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name));
3191
+ ret = -EINVAL;
3192
+ goto out;
3193
+ }
3194
+
3195
+ data->track_data.save_data = save_track_data_vars;
3196
+ data->fn = ontrack_action;
3197
+ data->action = ACTION_SAVE;
3198
+ } else if (str_has_prefix(action_name, "snapshot")) {
3199
+ char *params = strsep(&str, ")");
3200
+
3201
+ if (!str) {
3202
+ hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(params));
3203
+ ret = -EINVAL;
3204
+ goto out;
3205
+ }
3206
+
3207
+ if (handler == HANDLER_ONMAX)
3208
+ data->track_data.check_val = check_track_val_max;
3209
+ else if (handler == HANDLER_ONCHANGE)
3210
+ data->track_data.check_val = check_track_val_changed;
3211
+ else {
3212
+ hist_err(tr, HIST_ERR_ACTION_MISMATCH, errpos(action_name));
3213
+ ret = -EINVAL;
3214
+ goto out;
3215
+ }
3216
+
3217
+ data->track_data.save_data = save_track_data_snapshot;
3218
+ data->fn = ontrack_action;
3219
+ data->action = ACTION_SNAPSHOT;
3220
+ } else {
3221
+ char *params = strsep(&str, ")");
3222
+
3223
+ if (str_has_prefix(action_name, "trace"))
3224
+ data->use_trace_keyword = true;
3225
+
3226
+ if (params) {
3227
+ ret = parse_action_params(tr, params, data);
3228
+ if (ret)
3229
+ goto out;
3230
+ }
3231
+
3232
+ if (handler == HANDLER_ONMAX)
3233
+ data->track_data.check_val = check_track_val_max;
3234
+ else if (handler == HANDLER_ONCHANGE)
3235
+ data->track_data.check_val = check_track_val_changed;
3236
+
3237
+ if (handler != HANDLER_ONMATCH) {
3238
+ data->track_data.save_data = action_trace;
3239
+ data->fn = ontrack_action;
3240
+ } else
3241
+ data->fn = action_trace;
3242
+
3243
+ data->action = ACTION_TRACE;
3244
+ }
3245
+
3246
+ data->action_name = kstrdup(action_name, GFP_KERNEL);
3247
+ if (!data->action_name) {
3248
+ ret = -ENOMEM;
3249
+ goto out;
3250
+ }
3251
+
3252
+ data->handler = handler;
3253
+ out:
3254
+ return ret;
3255
+}
3256
+
3257
+static struct action_data *track_data_parse(struct hist_trigger_data *hist_data,
3258
+ char *str, enum handler_id handler)
3259
+{
35993260 struct action_data *data;
36003261 int ret = -EINVAL;
3262
+ char *var_str;
36013263
36023264 data = kzalloc(sizeof(*data), GFP_KERNEL);
36033265 if (!data)
36043266 return ERR_PTR(-ENOMEM);
36053267
3606
- onmax_var_str = strsep(&str, ")");
3607
- if (!onmax_var_str || !str) {
3268
+ var_str = strsep(&str, ")");
3269
+ if (!var_str || !str) {
36083270 ret = -EINVAL;
36093271 goto free;
36103272 }
36113273
3612
- data->onmax.var_str = kstrdup(onmax_var_str, GFP_KERNEL);
3613
- if (!data->onmax.var_str) {
3274
+ data->track_data.var_str = kstrdup(var_str, GFP_KERNEL);
3275
+ if (!data->track_data.var_str) {
36143276 ret = -ENOMEM;
36153277 goto free;
36163278 }
36173279
3618
- strsep(&str, ".");
3619
- if (!str)
3280
+ ret = action_parse(hist_data->event_file->tr, str, data, handler);
3281
+ if (ret)
36203282 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
- }
36453283 out:
36463284 return data;
36473285 free:
3648
- onmax_destroy(data);
3286
+ track_data_destroy(hist_data, data);
36493287 data = ERR_PTR(ret);
36503288 goto out;
36513289 }
36523290
36533291 static void onmatch_destroy(struct action_data *data)
36543292 {
3655
- unsigned int i;
3293
+ kfree(data->match_data.event);
3294
+ kfree(data->match_data.event_system);
36563295
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);
3296
+ action_data_destroy(data);
36723297 }
36733298
36743299 static void destroy_field_var(struct field_var *field_var)
....@@ -3688,6 +3313,9 @@
36883313
36893314 for (i = 0; i < hist_data->n_field_vars; i++)
36903315 destroy_field_var(hist_data->field_vars[i]);
3316
+
3317
+ for (i = 0; i < hist_data->n_save_vars; i++)
3318
+ destroy_field_var(hist_data->save_vars[i]);
36913319 }
36923320
36933321 static void save_field_var(struct hist_trigger_data *hist_data,
....@@ -3700,20 +3328,6 @@
37003328 }
37013329
37023330
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
-
37173331 static int check_synth_field(struct synth_event *event,
37183332 struct hist_field *hist_field,
37193333 unsigned int field_pos)
....@@ -3725,40 +3339,54 @@
37253339
37263340 field = event->fields[field_pos];
37273341
3728
- if (strcmp(field->type, hist_field->type) != 0)
3729
- return -EINVAL;
3342
+ /*
3343
+ * A dynamic string synth field can accept static or
3344
+ * dynamic. A static string synth field can only accept a
3345
+ * same-sized static string, which is checked for later.
3346
+ */
3347
+ if (strstr(hist_field->type, "char[") && field->is_string
3348
+ && field->is_dynamic)
3349
+ return 0;
3350
+
3351
+ if (strcmp(field->type, hist_field->type) != 0) {
3352
+ if (field->size != hist_field->size ||
3353
+ (!field->is_string && field->is_signed != hist_field->is_signed))
3354
+ return -EINVAL;
3355
+ }
37303356
37313357 return 0;
37323358 }
37333359
37343360 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)
3361
+trace_action_find_var(struct hist_trigger_data *hist_data,
3362
+ struct action_data *data,
3363
+ char *system, char *event, char *var)
37373364 {
3365
+ struct trace_array *tr = hist_data->event_file->tr;
37383366 struct hist_field *hist_field;
37393367
37403368 var++; /* skip '$' */
37413369
37423370 hist_field = find_target_event_var(hist_data, system, event, var);
37433371 if (!hist_field) {
3744
- if (!system) {
3745
- system = data->onmatch.match_event_system;
3746
- event = data->onmatch.match_event;
3372
+ if (!system && data->handler == HANDLER_ONMATCH) {
3373
+ system = data->match_data.event_system;
3374
+ event = data->match_data.event;
37473375 }
37483376
37493377 hist_field = find_event_var(hist_data, system, event, var);
37503378 }
37513379
37523380 if (!hist_field)
3753
- hist_err_event("onmatch: Couldn't find onmatch param: $", system, event, var);
3381
+ hist_err(tr, HIST_ERR_PARAM_NOT_FOUND, errpos(var));
37543382
37553383 return hist_field;
37563384 }
37573385
37583386 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)
3387
+trace_action_create_field_var(struct hist_trigger_data *hist_data,
3388
+ struct action_data *data, char *system,
3389
+ char *event, char *var)
37623390 {
37633391 struct hist_field *hist_field = NULL;
37643392 struct field_var *field_var;
....@@ -3781,9 +3409,9 @@
37813409 * looking for fields on the onmatch(system.event.xxx)
37823410 * event.
37833411 */
3784
- if (!system) {
3785
- system = data->onmatch.match_event_system;
3786
- event = data->onmatch.match_event;
3412
+ if (!system && data->handler == HANDLER_ONMATCH) {
3413
+ system = data->match_data.event_system;
3414
+ event = data->match_data.event;
37873415 }
37883416
37893417 if (!event)
....@@ -3807,28 +3435,32 @@
38073435 goto out;
38083436 }
38093437
3810
-static int onmatch_create(struct hist_trigger_data *hist_data,
3811
- struct trace_event_file *file,
3812
- struct action_data *data)
3438
+static int trace_action_create(struct hist_trigger_data *hist_data,
3439
+ struct action_data *data)
38133440 {
3441
+ struct trace_array *tr = hist_data->event_file->tr;
38143442 char *event_name, *param, *system = NULL;
38153443 struct hist_field *hist_field, *var_ref;
3816
- unsigned int i, var_ref_idx;
3444
+ unsigned int i;
38173445 unsigned int field_pos = 0;
38183446 struct synth_event *event;
3819
- int ret = 0;
3447
+ char *synth_event_name;
3448
+ int var_ref_idx, ret = 0;
38203449
3821
- mutex_lock(&synth_event_mutex);
3822
- event = find_synth_event(data->onmatch.synth_event_name);
3450
+ lockdep_assert_held(&event_mutex);
3451
+
3452
+ if (data->use_trace_keyword)
3453
+ synth_event_name = data->synth_event_name;
3454
+ else
3455
+ synth_event_name = data->action_name;
3456
+
3457
+ event = find_synth_event(synth_event_name);
38233458 if (!event) {
3824
- hist_err("onmatch: Couldn't find synthetic event: ", data->onmatch.synth_event_name);
3825
- mutex_unlock(&synth_event_mutex);
3459
+ hist_err(tr, HIST_ERR_SYNTH_EVENT_NOT_FOUND, errpos(synth_event_name));
38263460 return -EINVAL;
38273461 }
3828
- event->ref++;
3829
- mutex_unlock(&synth_event_mutex);
38303462
3831
- var_ref_idx = hist_data->n_var_refs;
3463
+ event->ref++;
38323464
38333465 for (i = 0; i < data->n_params; i++) {
38343466 char *p;
....@@ -3853,13 +3485,15 @@
38533485 }
38543486
38553487 if (param[0] == '$')
3856
- hist_field = onmatch_find_var(hist_data, data, system,
3857
- event_name, param);
3488
+ hist_field = trace_action_find_var(hist_data, data,
3489
+ system, event_name,
3490
+ param);
38583491 else
3859
- hist_field = onmatch_create_field_var(hist_data, data,
3860
- system,
3861
- event_name,
3862
- param);
3492
+ hist_field = trace_action_create_field_var(hist_data,
3493
+ data,
3494
+ system,
3495
+ event_name,
3496
+ param);
38633497
38643498 if (!hist_field) {
38653499 kfree(p);
....@@ -3876,42 +3510,112 @@
38763510 goto err;
38773511 }
38783512
3879
- save_synth_var_ref(hist_data, var_ref);
3513
+ var_ref_idx = find_var_ref_idx(hist_data, var_ref);
3514
+ if (WARN_ON(var_ref_idx < 0)) {
3515
+ kfree(p);
3516
+ ret = var_ref_idx;
3517
+ goto err;
3518
+ }
3519
+
3520
+ data->var_ref_idx[i] = var_ref_idx;
3521
+
38803522 field_pos++;
38813523 kfree(p);
38823524 continue;
38833525 }
38843526
3885
- hist_err_event("onmatch: Param type doesn't match synthetic event field type: ",
3886
- system, event_name, param);
3527
+ hist_err(tr, HIST_ERR_SYNTH_TYPE_MISMATCH, errpos(param));
38873528 kfree(p);
38883529 ret = -EINVAL;
38893530 goto err;
38903531 }
38913532
38923533 if (field_pos != event->n_fields) {
3893
- hist_err("onmatch: Param count doesn't match synthetic event field count: ", event->name);
3534
+ hist_err(tr, HIST_ERR_SYNTH_COUNT_MISMATCH, errpos(event->name));
38943535 ret = -EINVAL;
38953536 goto err;
38963537 }
38973538
3898
- data->fn = action_trace;
3899
- data->onmatch.synth_event = event;
3900
- data->onmatch.var_ref_idx = var_ref_idx;
3539
+ data->synth_event = event;
39013540 out:
39023541 return ret;
39033542 err:
3904
- mutex_lock(&synth_event_mutex);
39053543 event->ref--;
3906
- mutex_unlock(&synth_event_mutex);
39073544
39083545 goto out;
3546
+}
3547
+
3548
+static int action_create(struct hist_trigger_data *hist_data,
3549
+ struct action_data *data)
3550
+{
3551
+ struct trace_event_file *file = hist_data->event_file;
3552
+ struct trace_array *tr = file->tr;
3553
+ struct track_data *track_data;
3554
+ struct field_var *field_var;
3555
+ unsigned int i;
3556
+ char *param;
3557
+ int ret = 0;
3558
+
3559
+ if (data->action == ACTION_TRACE)
3560
+ return trace_action_create(hist_data, data);
3561
+
3562
+ if (data->action == ACTION_SNAPSHOT) {
3563
+ track_data = track_data_alloc(hist_data->key_size, data, hist_data);
3564
+ if (IS_ERR(track_data)) {
3565
+ ret = PTR_ERR(track_data);
3566
+ goto out;
3567
+ }
3568
+
3569
+ ret = tracing_snapshot_cond_enable(file->tr, track_data,
3570
+ cond_snapshot_update);
3571
+ if (ret)
3572
+ track_data_free(track_data);
3573
+
3574
+ goto out;
3575
+ }
3576
+
3577
+ if (data->action == ACTION_SAVE) {
3578
+ if (hist_data->n_save_vars) {
3579
+ ret = -EEXIST;
3580
+ hist_err(tr, HIST_ERR_TOO_MANY_SAVE_ACTIONS, 0);
3581
+ goto out;
3582
+ }
3583
+
3584
+ for (i = 0; i < data->n_params; i++) {
3585
+ param = kstrdup(data->params[i], GFP_KERNEL);
3586
+ if (!param) {
3587
+ ret = -ENOMEM;
3588
+ goto out;
3589
+ }
3590
+
3591
+ field_var = create_target_field_var(hist_data, NULL, NULL, param);
3592
+ if (IS_ERR(field_var)) {
3593
+ hist_err(tr, HIST_ERR_FIELD_VAR_CREATE_FAIL,
3594
+ errpos(param));
3595
+ ret = PTR_ERR(field_var);
3596
+ kfree(param);
3597
+ goto out;
3598
+ }
3599
+
3600
+ hist_data->save_vars[hist_data->n_save_vars++] = field_var;
3601
+ if (field_var->val->flags & HIST_FIELD_FL_STRING)
3602
+ hist_data->n_save_var_str++;
3603
+ kfree(param);
3604
+ }
3605
+ }
3606
+ out:
3607
+ return ret;
3608
+}
3609
+
3610
+static int onmatch_create(struct hist_trigger_data *hist_data,
3611
+ struct action_data *data)
3612
+{
3613
+ return action_create(hist_data, data);
39093614 }
39103615
39113616 static struct action_data *onmatch_parse(struct trace_array *tr, char *str)
39123617 {
39133618 char *match_event, *match_event_system;
3914
- char *synth_event_name, *params;
39153619 struct action_data *data;
39163620 int ret = -EINVAL;
39173621
....@@ -3921,59 +3625,34 @@
39213625
39223626 match_event = strsep(&str, ")");
39233627 if (!match_event || !str) {
3924
- hist_err("onmatch: Missing closing paren: ", match_event);
3628
+ hist_err(tr, HIST_ERR_NO_CLOSING_PAREN, errpos(match_event));
39253629 goto free;
39263630 }
39273631
39283632 match_event_system = strsep(&match_event, ".");
39293633 if (!match_event) {
3930
- hist_err("onmatch: Missing subsystem for match event: ", match_event_system);
3634
+ hist_err(tr, HIST_ERR_SUBSYS_NOT_FOUND, errpos(match_event_system));
39313635 goto free;
39323636 }
39333637
39343638 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);
3639
+ hist_err(tr, HIST_ERR_INVALID_SUBSYS_EVENT, errpos(match_event));
39373640 goto free;
39383641 }
39393642
3940
- data->onmatch.match_event = kstrdup(match_event, GFP_KERNEL);
3941
- if (!data->onmatch.match_event) {
3643
+ data->match_data.event = kstrdup(match_event, GFP_KERNEL);
3644
+ if (!data->match_data.event) {
39423645 ret = -ENOMEM;
39433646 goto free;
39443647 }
39453648
3946
- data->onmatch.match_event_system = kstrdup(match_event_system, GFP_KERNEL);
3947
- if (!data->onmatch.match_event_system) {
3649
+ data->match_data.event_system = kstrdup(match_event_system, GFP_KERNEL);
3650
+ if (!data->match_data.event_system) {
39483651 ret = -ENOMEM;
39493652 goto free;
39503653 }
39513654
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);
3655
+ ret = action_parse(tr, str, data, HANDLER_ONMATCH);
39773656 if (ret)
39783657 goto free;
39793658 out:
....@@ -4042,13 +3721,15 @@
40423721 struct trace_event_file *file,
40433722 char *var_name, char *expr_str)
40443723 {
3724
+ struct trace_array *tr = hist_data->event_file->tr;
40453725 unsigned long flags = 0;
3726
+ int ret;
40463727
40473728 if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX + TRACING_MAP_VARS_MAX))
40483729 return -EINVAL;
40493730
40503731 if (find_var(hist_data, file, var_name) && !hist_data->remove) {
4051
- hist_err("Variable already defined: ", var_name);
3732
+ hist_err(tr, HIST_ERR_DUPLICATE_VAR, errpos(var_name));
40523733 return -EINVAL;
40533734 }
40543735
....@@ -4057,7 +3738,12 @@
40573738 if (WARN_ON(hist_data->n_vars > TRACING_MAP_VARS_MAX))
40583739 return -EINVAL;
40593740
4060
- return __create_val_field(hist_data, val_idx, file, var_name, expr_str, flags);
3741
+ ret = __create_val_field(hist_data, val_idx, file, var_name, expr_str, flags);
3742
+
3743
+ if (!ret && hist_data->fields[val_idx]->flags & HIST_FIELD_FL_STRING)
3744
+ hist_data->fields[val_idx]->var_str_idx = hist_data->n_var_str++;
3745
+
3746
+ return ret;
40613747 }
40623748
40633749 static int create_val_fields(struct hist_trigger_data *hist_data,
....@@ -4072,10 +3758,6 @@
40723758 goto out;
40733759
40743760 fields_str = hist_data->attrs->vals_str;
4075
- if (!fields_str)
4076
- goto out;
4077
-
4078
- strsep(&fields_str, "=");
40793761 if (!fields_str)
40803762 goto out;
40813763
....@@ -4105,8 +3787,8 @@
41053787 struct trace_event_file *file,
41063788 char *field_str)
41073789 {
3790
+ struct trace_array *tr = hist_data->event_file->tr;
41083791 struct hist_field *hist_field = NULL;
4109
-
41103792 unsigned long flags = 0;
41113793 unsigned int key_size;
41123794 int ret = 0;
....@@ -4128,8 +3810,8 @@
41283810 goto out;
41293811 }
41303812
4131
- if (hist_field->flags & HIST_FIELD_FL_VAR_REF) {
4132
- hist_err("Using variable references as keys not supported: ", field_str);
3813
+ if (field_has_hist_vars(hist_field, 0)) {
3814
+ hist_err(tr, HIST_ERR_INVALID_REF_KEY, errpos(field_str));
41333815 destroy_hist_field(hist_field, 0);
41343816 ret = -EINVAL;
41353817 goto out;
....@@ -4170,10 +3852,6 @@
41703852 int ret = -EINVAL;
41713853
41723854 fields_str = hist_data->attrs->keys_str;
4173
- if (!fields_str)
4174
- goto out;
4175
-
4176
- strsep(&fields_str, "=");
41773855 if (!fields_str)
41783856 goto out;
41793857
....@@ -4230,6 +3908,7 @@
42303908
42313909 static int parse_var_defs(struct hist_trigger_data *hist_data)
42323910 {
3911
+ struct trace_array *tr = hist_data->event_file->tr;
42333912 char *s, *str, *var_name, *field_str;
42343913 unsigned int i, j, n_vars = 0;
42353914 int ret = 0;
....@@ -4243,13 +3922,14 @@
42433922
42443923 var_name = strsep(&field_str, "=");
42453924 if (!var_name || !field_str) {
4246
- hist_err("Malformed assignment: ", var_name);
3925
+ hist_err(tr, HIST_ERR_MALFORMED_ASSIGNMENT,
3926
+ errpos(var_name));
42473927 ret = -EINVAL;
42483928 goto free;
42493929 }
42503930
42513931 if (n_vars == TRACING_MAP_VARS_MAX) {
4252
- hist_err("Too many variables defined: ", var_name);
3932
+ hist_err(tr, HIST_ERR_TOO_MANY_VARS, errpos(var_name));
42533933 ret = -EINVAL;
42543934 goto free;
42553935 }
....@@ -4263,6 +3943,8 @@
42633943
42643944 s = kstrdup(field_str, GFP_KERNEL);
42653945 if (!s) {
3946
+ kfree(hist_data->attrs->var_defs.name[n_vars]);
3947
+ hist_data->attrs->var_defs.name[n_vars] = NULL;
42663948 ret = -ENOMEM;
42673949 goto free;
42683950 }
....@@ -4305,7 +3987,7 @@
43053987 return ret;
43063988 }
43073989
4308
-static int is_descending(const char *str)
3990
+static int is_descending(struct trace_array *tr, const char *str)
43093991 {
43103992 if (!str)
43113993 return 0;
....@@ -4316,11 +3998,14 @@
43163998 if (strcmp(str, "ascending") == 0)
43173999 return 0;
43184000
4001
+ hist_err(tr, HIST_ERR_INVALID_SORT_MODIFIER, errpos((char *)str));
4002
+
43194003 return -EINVAL;
43204004 }
43214005
43224006 static int create_sort_keys(struct hist_trigger_data *hist_data)
43234007 {
4008
+ struct trace_array *tr = hist_data->event_file->tr;
43244009 char *fields_str = hist_data->attrs->sort_key_str;
43254010 struct tracing_map_sort_key *sort_key;
43264011 int descending, ret = 0;
....@@ -4331,12 +4016,6 @@
43314016 if (!fields_str)
43324017 goto out;
43334018
4334
- strsep(&fields_str, "=");
4335
- if (!fields_str) {
4336
- ret = -EINVAL;
4337
- goto out;
4338
- }
4339
-
43404019 for (i = 0; i < TRACING_MAP_SORT_KEYS_MAX; i++) {
43414020 struct hist_field *hist_field;
43424021 char *field_str, *field_name;
....@@ -4345,25 +4024,30 @@
43454024 sort_key = &hist_data->sort_keys[i];
43464025
43474026 field_str = strsep(&fields_str, ",");
4348
- if (!field_str) {
4349
- if (i == 0)
4350
- ret = -EINVAL;
4027
+ if (!field_str)
4028
+ break;
4029
+
4030
+ if (!*field_str) {
4031
+ ret = -EINVAL;
4032
+ hist_err(tr, HIST_ERR_EMPTY_SORT_FIELD, errpos("sort="));
43514033 break;
43524034 }
43534035
43544036 if ((i == TRACING_MAP_SORT_KEYS_MAX - 1) && fields_str) {
4037
+ hist_err(tr, HIST_ERR_TOO_MANY_SORT_FIELDS, errpos("sort="));
43554038 ret = -EINVAL;
43564039 break;
43574040 }
43584041
43594042 field_name = strsep(&field_str, ".");
4360
- if (!field_name) {
4043
+ if (!field_name || !*field_name) {
43614044 ret = -EINVAL;
4045
+ hist_err(tr, HIST_ERR_EMPTY_SORT_FIELD, errpos("sort="));
43624046 break;
43634047 }
43644048
43654049 if (strcmp(field_name, "hitcount") == 0) {
4366
- descending = is_descending(field_str);
4050
+ descending = is_descending(tr, field_str);
43674051 if (descending < 0) {
43684052 ret = descending;
43694053 break;
....@@ -4385,7 +4069,7 @@
43854069
43864070 if (strcmp(field_name, test_name) == 0) {
43874071 sort_key->field_idx = idx;
4388
- descending = is_descending(field_str);
4072
+ descending = is_descending(tr, field_str);
43894073 if (descending < 0) {
43904074 ret = descending;
43914075 goto out;
....@@ -4396,6 +4080,7 @@
43964080 }
43974081 if (j == hist_data->n_fields) {
43984082 ret = -EINVAL;
4083
+ hist_err(tr, HIST_ERR_INVALID_SORT_FIELD, errpos(field_name));
43994084 break;
44004085 }
44014086 }
....@@ -4412,10 +4097,11 @@
44124097 for (i = 0; i < hist_data->n_actions; i++) {
44134098 struct action_data *data = hist_data->actions[i];
44144099
4415
- if (data->fn == action_trace)
4100
+ if (data->handler == HANDLER_ONMATCH)
44164101 onmatch_destroy(data);
4417
- else if (data->fn == onmax_save)
4418
- onmax_destroy(data);
4102
+ else if (data->handler == HANDLER_ONMAX ||
4103
+ data->handler == HANDLER_ONCHANGE)
4104
+ track_data_destroy(hist_data, data);
44194105 else
44204106 kfree(data);
44214107 }
....@@ -4428,28 +4114,37 @@
44284114 unsigned int i;
44294115 int ret = 0;
44304116 char *str;
4117
+ int len;
44314118
44324119 for (i = 0; i < hist_data->attrs->n_actions; i++) {
44334120 str = hist_data->attrs->action_str[i];
44344121
4435
- if (strncmp(str, "onmatch(", strlen("onmatch(")) == 0) {
4436
- char *action_str = str + strlen("onmatch(");
4122
+ if ((len = str_has_prefix(str, "onmatch("))) {
4123
+ char *action_str = str + len;
44374124
44384125 data = onmatch_parse(tr, action_str);
44394126 if (IS_ERR(data)) {
44404127 ret = PTR_ERR(data);
44414128 break;
44424129 }
4443
- data->fn = action_trace;
4444
- } else if (strncmp(str, "onmax(", strlen("onmax(")) == 0) {
4445
- char *action_str = str + strlen("onmax(");
4130
+ } else if ((len = str_has_prefix(str, "onmax("))) {
4131
+ char *action_str = str + len;
44464132
4447
- data = onmax_parse(action_str);
4133
+ data = track_data_parse(hist_data, action_str,
4134
+ HANDLER_ONMAX);
44484135 if (IS_ERR(data)) {
44494136 ret = PTR_ERR(data);
44504137 break;
44514138 }
4452
- data->fn = onmax_save;
4139
+ } else if ((len = str_has_prefix(str, "onchange("))) {
4140
+ char *action_str = str + len;
4141
+
4142
+ data = track_data_parse(hist_data, action_str,
4143
+ HANDLER_ONCHANGE);
4144
+ if (IS_ERR(data)) {
4145
+ ret = PTR_ERR(data);
4146
+ break;
4147
+ }
44534148 } else {
44544149 ret = -EINVAL;
44554150 break;
....@@ -4461,8 +4156,7 @@
44614156 return ret;
44624157 }
44634158
4464
-static int create_actions(struct hist_trigger_data *hist_data,
4465
- struct trace_event_file *file)
4159
+static int create_actions(struct hist_trigger_data *hist_data)
44664160 {
44674161 struct action_data *data;
44684162 unsigned int i;
....@@ -4471,14 +4165,18 @@
44714165 for (i = 0; i < hist_data->attrs->n_actions; i++) {
44724166 data = hist_data->actions[i];
44734167
4474
- if (data->fn == action_trace) {
4475
- ret = onmatch_create(hist_data, file, data);
4168
+ if (data->handler == HANDLER_ONMATCH) {
4169
+ ret = onmatch_create(hist_data, data);
44764170 if (ret)
4477
- return ret;
4478
- } else if (data->fn == onmax_save) {
4479
- ret = onmax_create(hist_data, data);
4171
+ break;
4172
+ } else if (data->handler == HANDLER_ONMAX ||
4173
+ data->handler == HANDLER_ONCHANGE) {
4174
+ ret = track_data_create(hist_data, data);
44804175 if (ret)
4481
- return ret;
4176
+ break;
4177
+ } else {
4178
+ ret = -EINVAL;
4179
+ break;
44824180 }
44834181 }
44844182
....@@ -4494,26 +4192,51 @@
44944192 for (i = 0; i < hist_data->n_actions; i++) {
44954193 struct action_data *data = hist_data->actions[i];
44964194
4497
- if (data->fn == onmax_save)
4498
- onmax_print(m, hist_data, elt, data);
4195
+ if (data->action == ACTION_SNAPSHOT)
4196
+ continue;
4197
+
4198
+ if (data->handler == HANDLER_ONMAX ||
4199
+ data->handler == HANDLER_ONCHANGE)
4200
+ track_data_print(m, hist_data, elt, data);
44994201 }
45004202 }
45014203
4502
-static void print_onmax_spec(struct seq_file *m,
4503
- struct hist_trigger_data *hist_data,
4504
- struct action_data *data)
4204
+static void print_action_spec(struct seq_file *m,
4205
+ struct hist_trigger_data *hist_data,
4206
+ struct action_data *data)
45054207 {
45064208 unsigned int i;
45074209
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, ",");
4210
+ if (data->action == ACTION_SAVE) {
4211
+ for (i = 0; i < hist_data->n_save_vars; i++) {
4212
+ seq_printf(m, "%s", hist_data->save_vars[i]->var->var.name);
4213
+ if (i < hist_data->n_save_vars - 1)
4214
+ seq_puts(m, ",");
4215
+ }
4216
+ } else if (data->action == ACTION_TRACE) {
4217
+ if (data->use_trace_keyword)
4218
+ seq_printf(m, "%s", data->synth_event_name);
4219
+ for (i = 0; i < data->n_params; i++) {
4220
+ if (i || data->use_trace_keyword)
4221
+ seq_puts(m, ",");
4222
+ seq_printf(m, "%s", data->params[i]);
4223
+ }
45164224 }
4225
+}
4226
+
4227
+static void print_track_data_spec(struct seq_file *m,
4228
+ struct hist_trigger_data *hist_data,
4229
+ struct action_data *data)
4230
+{
4231
+ if (data->handler == HANDLER_ONMAX)
4232
+ seq_puts(m, ":onmax(");
4233
+ else if (data->handler == HANDLER_ONCHANGE)
4234
+ seq_puts(m, ":onchange(");
4235
+ seq_printf(m, "%s", data->track_data.var_str);
4236
+ seq_printf(m, ").%s(", data->action_name);
4237
+
4238
+ print_action_spec(m, hist_data, data);
4239
+
45174240 seq_puts(m, ")");
45184241 }
45194242
....@@ -4521,18 +4244,12 @@
45214244 struct hist_trigger_data *hist_data,
45224245 struct action_data *data)
45234246 {
4524
- unsigned int i;
4247
+ seq_printf(m, ":onmatch(%s.%s).", data->match_data.event_system,
4248
+ data->match_data.event);
45254249
4526
- seq_printf(m, ":onmatch(%s.%s).", data->onmatch.match_event_system,
4527
- data->onmatch.match_event);
4250
+ seq_printf(m, "%s(", data->action_name);
45284251
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
- }
4252
+ print_action_spec(m, hist_data, data);
45364253
45374254 seq_puts(m, ")");
45384255 }
....@@ -4548,8 +4265,11 @@
45484265 for (i = 0; i < hist_data->n_actions; i++) {
45494266 struct action_data *data = hist_data->actions[i];
45504267 struct action_data *data_test = hist_data_test->actions[i];
4268
+ char *action_name, *action_name_test;
45514269
4552
- if (data->fn != data_test->fn)
4270
+ if (data->handler != data_test->handler)
4271
+ return false;
4272
+ if (data->action != data_test->action)
45534273 return false;
45544274
45554275 if (data->n_params != data_test->n_params)
....@@ -4560,22 +4280,30 @@
45604280 return false;
45614281 }
45624282
4563
- if (data->fn == action_trace) {
4564
- if (strcmp(data->onmatch.synth_event_name,
4565
- data_test->onmatch.synth_event_name) != 0)
4283
+ if (data->use_trace_keyword)
4284
+ action_name = data->synth_event_name;
4285
+ else
4286
+ action_name = data->action_name;
4287
+
4288
+ if (data_test->use_trace_keyword)
4289
+ action_name_test = data_test->synth_event_name;
4290
+ else
4291
+ action_name_test = data_test->action_name;
4292
+
4293
+ if (strcmp(action_name, action_name_test) != 0)
4294
+ return false;
4295
+
4296
+ if (data->handler == HANDLER_ONMATCH) {
4297
+ if (strcmp(data->match_data.event_system,
4298
+ data_test->match_data.event_system) != 0)
45664299 return false;
4567
- if (strcmp(data->onmatch.match_event_system,
4568
- data_test->onmatch.match_event_system) != 0)
4300
+ if (strcmp(data->match_data.event,
4301
+ data_test->match_data.event) != 0)
45694302 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)
4303
+ } else if (data->handler == HANDLER_ONMAX ||
4304
+ data->handler == HANDLER_ONCHANGE) {
4305
+ if (strcmp(data->track_data.var_str,
4306
+ data_test->track_data.var_str) != 0)
45794307 return false;
45804308 }
45814309 }
....@@ -4592,10 +4320,11 @@
45924320 for (i = 0; i < hist_data->n_actions; i++) {
45934321 struct action_data *data = hist_data->actions[i];
45944322
4595
- if (data->fn == action_trace)
4323
+ if (data->handler == HANDLER_ONMATCH)
45964324 print_onmatch_spec(m, hist_data, data);
4597
- else if (data->fn == onmax_save)
4598
- print_onmax_spec(m, hist_data, data);
4325
+ else if (data->handler == HANDLER_ONMAX ||
4326
+ data->handler == HANDLER_ONCHANGE)
4327
+ print_track_data_spec(m, hist_data, data);
45994328 }
46004329 }
46014330
....@@ -4621,7 +4350,6 @@
46214350 destroy_actions(hist_data);
46224351 destroy_field_vars(hist_data);
46234352 destroy_field_var_hists(hist_data);
4624
- destroy_synth_var_refs(hist_data);
46254353
46264354 kfree(hist_data);
46274355 }
....@@ -4642,7 +4370,7 @@
46424370
46434371 if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
46444372 cmp_fn = tracing_map_cmp_none;
4645
- else if (!field)
4373
+ else if (!field || hist_field->flags & HIST_FIELD_FL_CPU)
46464374 cmp_fn = tracing_map_cmp_num(hist_field->size,
46474375 hist_field->is_signed);
46484376 else if (is_string_field(field))
....@@ -4744,6 +4472,25 @@
47444472 hist_val = hist_field->fn(hist_field, elt, rbe, rec);
47454473 if (hist_field->flags & HIST_FIELD_FL_VAR) {
47464474 var_idx = hist_field->var.idx;
4475
+
4476
+ if (hist_field->flags & HIST_FIELD_FL_STRING) {
4477
+ unsigned int str_start, var_str_idx, idx;
4478
+ char *str, *val_str;
4479
+ unsigned int size;
4480
+
4481
+ str_start = hist_data->n_field_var_str +
4482
+ hist_data->n_save_var_str;
4483
+ var_str_idx = hist_field->var_str_idx;
4484
+ idx = str_start + var_str_idx;
4485
+
4486
+ str = elt_data->field_var_str[idx];
4487
+ val_str = (char *)(uintptr_t)hist_val;
4488
+
4489
+ size = min(hist_field->size, STR_VAR_LEN_MAX);
4490
+ strscpy(str, val_str, size);
4491
+
4492
+ hist_val = (u64)(uintptr_t)str;
4493
+ }
47474494 tracing_map_set_var(elt, var_idx, hist_val);
47484495 continue;
47494496 }
....@@ -4788,14 +4535,15 @@
47884535 static void
47894536 hist_trigger_actions(struct hist_trigger_data *hist_data,
47904537 struct tracing_map_elt *elt, void *rec,
4791
- struct ring_buffer_event *rbe, u64 *var_ref_vals)
4538
+ struct ring_buffer_event *rbe, void *key,
4539
+ u64 *var_ref_vals)
47924540 {
47934541 struct action_data *data;
47944542 unsigned int i;
47954543
47964544 for (i = 0; i < hist_data->n_actions; i++) {
47974545 data = hist_data->actions[i];
4798
- data->fn(hist_data, elt, rec, rbe, data, var_ref_vals);
4546
+ data->fn(hist_data, elt, rec, rbe, key, data, var_ref_vals);
47994547 }
48004548 }
48014549
....@@ -4808,7 +4556,6 @@
48084556 u64 var_ref_vals[TRACING_MAP_VARS_MAX];
48094557 char compound_key[HIST_KEY_SIZE_MAX];
48104558 struct tracing_map_elt *elt = NULL;
4811
- struct stack_trace stacktrace;
48124559 struct hist_field *key_field;
48134560 u64 field_contents;
48144561 void *key = NULL;
....@@ -4820,14 +4567,9 @@
48204567 key_field = hist_data->fields[i];
48214568
48224569 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
-
4570
+ memset(entries, 0, HIST_STACKTRACE_SIZE);
4571
+ stack_trace_save(entries, HIST_STACKTRACE_DEPTH,
4572
+ HIST_STACKTRACE_SKIP);
48314573 key = entries;
48324574 } else {
48334575 field_contents = key_field->fn(key_field, elt, rbe, rec);
....@@ -4856,7 +4598,7 @@
48564598 hist_trigger_elt_update(hist_data, elt, rec, rbe, var_ref_vals);
48574599
48584600 if (resolve_var_refs(hist_data, key, var_ref_vals, true))
4859
- hist_trigger_actions(hist_data, elt, rec, rbe, var_ref_vals);
4601
+ hist_trigger_actions(hist_data, elt, rec, rbe, key, var_ref_vals);
48604602 }
48614603
48624604 static void hist_trigger_stacktrace_print(struct seq_file *m,
....@@ -4868,7 +4610,7 @@
48684610 unsigned int i;
48694611
48704612 for (i = 0; i < max_entries; i++) {
4871
- if (stacktrace_entries[i] == ULONG_MAX)
4613
+ if (!stacktrace_entries[i])
48724614 return;
48734615
48744616 seq_printf(m, "%*c", 1 + spaces, ' ');
....@@ -4877,10 +4619,10 @@
48774619 }
48784620 }
48794621
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)
4622
+static void hist_trigger_print_key(struct seq_file *m,
4623
+ struct hist_trigger_data *hist_data,
4624
+ void *key,
4625
+ struct tracing_map_elt *elt)
48844626 {
48854627 struct hist_field *key_field;
48864628 char str[KSYM_SYMBOL_LEN];
....@@ -4956,6 +4698,17 @@
49564698 seq_puts(m, " ");
49574699
49584700 seq_puts(m, "}");
4701
+}
4702
+
4703
+static void hist_trigger_entry_print(struct seq_file *m,
4704
+ struct hist_trigger_data *hist_data,
4705
+ void *key,
4706
+ struct tracing_map_elt *elt)
4707
+{
4708
+ const char *field_name;
4709
+ unsigned int i;
4710
+
4711
+ hist_trigger_print_key(m, hist_data, key, elt);
49594712
49604713 seq_printf(m, " hitcount: %10llu",
49614714 tracing_map_read_sum(elt, HITCOUNT_IDX));
....@@ -5022,6 +4775,8 @@
50224775 if (n_entries < 0)
50234776 n_entries = 0;
50244777
4778
+ track_data_snapshot_print(m, hist_data);
4779
+
50254780 seq_printf(m, "\nTotals:\n Hits: %llu\n Entries: %u\n Dropped: %llu\n",
50264781 (u64)atomic64_read(&hist_data->map->hits),
50274782 n_entries, (u64)atomic64_read(&hist_data->map->drops));
....@@ -5046,11 +4801,6 @@
50464801 hist_trigger_show(m, data, n++);
50474802 }
50484803
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
-
50544804 out_unlock:
50554805 mutex_unlock(&event_mutex);
50564806
....@@ -5059,6 +4809,12 @@
50594809
50604810 static int event_hist_open(struct inode *inode, struct file *file)
50614811 {
4812
+ int ret;
4813
+
4814
+ ret = security_locked_down(LOCKDOWN_TRACEFS);
4815
+ if (ret)
4816
+ return ret;
4817
+
50624818 return single_open(file, hist_show, file);
50634819 }
50644820
....@@ -5068,6 +4824,279 @@
50684824 .llseek = seq_lseek,
50694825 .release = single_release,
50704826 };
4827
+
4828
+#ifdef CONFIG_HIST_TRIGGERS_DEBUG
4829
+static void hist_field_debug_show_flags(struct seq_file *m,
4830
+ unsigned long flags)
4831
+{
4832
+ seq_puts(m, " flags:\n");
4833
+
4834
+ if (flags & HIST_FIELD_FL_KEY)
4835
+ seq_puts(m, " HIST_FIELD_FL_KEY\n");
4836
+ else if (flags & HIST_FIELD_FL_HITCOUNT)
4837
+ seq_puts(m, " VAL: HIST_FIELD_FL_HITCOUNT\n");
4838
+ else if (flags & HIST_FIELD_FL_VAR)
4839
+ seq_puts(m, " HIST_FIELD_FL_VAR\n");
4840
+ else if (flags & HIST_FIELD_FL_VAR_REF)
4841
+ seq_puts(m, " HIST_FIELD_FL_VAR_REF\n");
4842
+ else
4843
+ seq_puts(m, " VAL: normal u64 value\n");
4844
+
4845
+ if (flags & HIST_FIELD_FL_ALIAS)
4846
+ seq_puts(m, " HIST_FIELD_FL_ALIAS\n");
4847
+}
4848
+
4849
+static int hist_field_debug_show(struct seq_file *m,
4850
+ struct hist_field *field, unsigned long flags)
4851
+{
4852
+ if ((field->flags & flags) != flags) {
4853
+ seq_printf(m, "ERROR: bad flags - %lx\n", flags);
4854
+ return -EINVAL;
4855
+ }
4856
+
4857
+ hist_field_debug_show_flags(m, field->flags);
4858
+ if (field->field)
4859
+ seq_printf(m, " ftrace_event_field name: %s\n",
4860
+ field->field->name);
4861
+
4862
+ if (field->flags & HIST_FIELD_FL_VAR) {
4863
+ seq_printf(m, " var.name: %s\n", field->var.name);
4864
+ seq_printf(m, " var.idx (into tracing_map_elt.vars[]): %u\n",
4865
+ field->var.idx);
4866
+ }
4867
+
4868
+ if (field->flags & HIST_FIELD_FL_ALIAS)
4869
+ seq_printf(m, " var_ref_idx (into hist_data->var_refs[]): %u\n",
4870
+ field->var_ref_idx);
4871
+
4872
+ if (field->flags & HIST_FIELD_FL_VAR_REF) {
4873
+ seq_printf(m, " name: %s\n", field->name);
4874
+ seq_printf(m, " var.idx (into tracing_map_elt.vars[]): %u\n",
4875
+ field->var.idx);
4876
+ seq_printf(m, " var.hist_data: %p\n", field->var.hist_data);
4877
+ seq_printf(m, " var_ref_idx (into hist_data->var_refs[]): %u\n",
4878
+ field->var_ref_idx);
4879
+ if (field->system)
4880
+ seq_printf(m, " system: %s\n", field->system);
4881
+ if (field->event_name)
4882
+ seq_printf(m, " event_name: %s\n", field->event_name);
4883
+ }
4884
+
4885
+ seq_printf(m, " type: %s\n", field->type);
4886
+ seq_printf(m, " size: %u\n", field->size);
4887
+ seq_printf(m, " is_signed: %u\n", field->is_signed);
4888
+
4889
+ return 0;
4890
+}
4891
+
4892
+static int field_var_debug_show(struct seq_file *m,
4893
+ struct field_var *field_var, unsigned int i,
4894
+ bool save_vars)
4895
+{
4896
+ const char *vars_name = save_vars ? "save_vars" : "field_vars";
4897
+ struct hist_field *field;
4898
+ int ret = 0;
4899
+
4900
+ seq_printf(m, "\n hist_data->%s[%d]:\n", vars_name, i);
4901
+
4902
+ field = field_var->var;
4903
+
4904
+ seq_printf(m, "\n %s[%d].var:\n", vars_name, i);
4905
+
4906
+ hist_field_debug_show_flags(m, field->flags);
4907
+ seq_printf(m, " var.name: %s\n", field->var.name);
4908
+ seq_printf(m, " var.idx (into tracing_map_elt.vars[]): %u\n",
4909
+ field->var.idx);
4910
+
4911
+ field = field_var->val;
4912
+
4913
+ seq_printf(m, "\n %s[%d].val:\n", vars_name, i);
4914
+ if (field->field)
4915
+ seq_printf(m, " ftrace_event_field name: %s\n",
4916
+ field->field->name);
4917
+ else {
4918
+ ret = -EINVAL;
4919
+ goto out;
4920
+ }
4921
+
4922
+ seq_printf(m, " type: %s\n", field->type);
4923
+ seq_printf(m, " size: %u\n", field->size);
4924
+ seq_printf(m, " is_signed: %u\n", field->is_signed);
4925
+out:
4926
+ return ret;
4927
+}
4928
+
4929
+static int hist_action_debug_show(struct seq_file *m,
4930
+ struct action_data *data, int i)
4931
+{
4932
+ int ret = 0;
4933
+
4934
+ if (data->handler == HANDLER_ONMAX ||
4935
+ data->handler == HANDLER_ONCHANGE) {
4936
+ seq_printf(m, "\n hist_data->actions[%d].track_data.var_ref:\n", i);
4937
+ ret = hist_field_debug_show(m, data->track_data.var_ref,
4938
+ HIST_FIELD_FL_VAR_REF);
4939
+ if (ret)
4940
+ goto out;
4941
+
4942
+ seq_printf(m, "\n hist_data->actions[%d].track_data.track_var:\n", i);
4943
+ ret = hist_field_debug_show(m, data->track_data.track_var,
4944
+ HIST_FIELD_FL_VAR);
4945
+ if (ret)
4946
+ goto out;
4947
+ }
4948
+
4949
+ if (data->handler == HANDLER_ONMATCH) {
4950
+ seq_printf(m, "\n hist_data->actions[%d].match_data.event_system: %s\n",
4951
+ i, data->match_data.event_system);
4952
+ seq_printf(m, " hist_data->actions[%d].match_data.event: %s\n",
4953
+ i, data->match_data.event);
4954
+ }
4955
+out:
4956
+ return ret;
4957
+}
4958
+
4959
+static int hist_actions_debug_show(struct seq_file *m,
4960
+ struct hist_trigger_data *hist_data)
4961
+{
4962
+ int i, ret = 0;
4963
+
4964
+ if (hist_data->n_actions)
4965
+ seq_puts(m, "\n action tracking variables (for onmax()/onchange()/onmatch()):\n");
4966
+
4967
+ for (i = 0; i < hist_data->n_actions; i++) {
4968
+ struct action_data *action = hist_data->actions[i];
4969
+
4970
+ ret = hist_action_debug_show(m, action, i);
4971
+ if (ret)
4972
+ goto out;
4973
+ }
4974
+
4975
+ if (hist_data->n_save_vars)
4976
+ seq_puts(m, "\n save action variables (save() params):\n");
4977
+
4978
+ for (i = 0; i < hist_data->n_save_vars; i++) {
4979
+ ret = field_var_debug_show(m, hist_data->save_vars[i], i, true);
4980
+ if (ret)
4981
+ goto out;
4982
+ }
4983
+out:
4984
+ return ret;
4985
+}
4986
+
4987
+static void hist_trigger_debug_show(struct seq_file *m,
4988
+ struct event_trigger_data *data, int n)
4989
+{
4990
+ struct hist_trigger_data *hist_data;
4991
+ int i, ret;
4992
+
4993
+ if (n > 0)
4994
+ seq_puts(m, "\n\n");
4995
+
4996
+ seq_puts(m, "# event histogram\n#\n# trigger info: ");
4997
+ data->ops->print(m, data->ops, data);
4998
+ seq_puts(m, "#\n\n");
4999
+
5000
+ hist_data = data->private_data;
5001
+
5002
+ seq_printf(m, "hist_data: %p\n\n", hist_data);
5003
+ seq_printf(m, " n_vals: %u\n", hist_data->n_vals);
5004
+ seq_printf(m, " n_keys: %u\n", hist_data->n_keys);
5005
+ seq_printf(m, " n_fields: %u\n", hist_data->n_fields);
5006
+
5007
+ seq_puts(m, "\n val fields:\n\n");
5008
+
5009
+ seq_puts(m, " hist_data->fields[0]:\n");
5010
+ ret = hist_field_debug_show(m, hist_data->fields[0],
5011
+ HIST_FIELD_FL_HITCOUNT);
5012
+ if (ret)
5013
+ return;
5014
+
5015
+ for (i = 1; i < hist_data->n_vals; i++) {
5016
+ seq_printf(m, "\n hist_data->fields[%d]:\n", i);
5017
+ ret = hist_field_debug_show(m, hist_data->fields[i], 0);
5018
+ if (ret)
5019
+ return;
5020
+ }
5021
+
5022
+ seq_puts(m, "\n key fields:\n");
5023
+
5024
+ for (i = hist_data->n_vals; i < hist_data->n_fields; i++) {
5025
+ seq_printf(m, "\n hist_data->fields[%d]:\n", i);
5026
+ ret = hist_field_debug_show(m, hist_data->fields[i],
5027
+ HIST_FIELD_FL_KEY);
5028
+ if (ret)
5029
+ return;
5030
+ }
5031
+
5032
+ if (hist_data->n_var_refs)
5033
+ seq_puts(m, "\n variable reference fields:\n");
5034
+
5035
+ for (i = 0; i < hist_data->n_var_refs; i++) {
5036
+ seq_printf(m, "\n hist_data->var_refs[%d]:\n", i);
5037
+ ret = hist_field_debug_show(m, hist_data->var_refs[i],
5038
+ HIST_FIELD_FL_VAR_REF);
5039
+ if (ret)
5040
+ return;
5041
+ }
5042
+
5043
+ if (hist_data->n_field_vars)
5044
+ seq_puts(m, "\n field variables:\n");
5045
+
5046
+ for (i = 0; i < hist_data->n_field_vars; i++) {
5047
+ ret = field_var_debug_show(m, hist_data->field_vars[i], i, false);
5048
+ if (ret)
5049
+ return;
5050
+ }
5051
+
5052
+ ret = hist_actions_debug_show(m, hist_data);
5053
+ if (ret)
5054
+ return;
5055
+}
5056
+
5057
+static int hist_debug_show(struct seq_file *m, void *v)
5058
+{
5059
+ struct event_trigger_data *data;
5060
+ struct trace_event_file *event_file;
5061
+ int n = 0, ret = 0;
5062
+
5063
+ mutex_lock(&event_mutex);
5064
+
5065
+ event_file = event_file_data(m->private);
5066
+ if (unlikely(!event_file)) {
5067
+ ret = -ENODEV;
5068
+ goto out_unlock;
5069
+ }
5070
+
5071
+ list_for_each_entry(data, &event_file->triggers, list) {
5072
+ if (data->cmd_ops->trigger_type == ETT_EVENT_HIST)
5073
+ hist_trigger_debug_show(m, data, n++);
5074
+ }
5075
+
5076
+ out_unlock:
5077
+ mutex_unlock(&event_mutex);
5078
+
5079
+ return ret;
5080
+}
5081
+
5082
+static int event_hist_debug_open(struct inode *inode, struct file *file)
5083
+{
5084
+ int ret;
5085
+
5086
+ ret = security_locked_down(LOCKDOWN_TRACEFS);
5087
+ if (ret)
5088
+ return ret;
5089
+
5090
+ return single_open(file, hist_debug_show, file);
5091
+}
5092
+
5093
+const struct file_operations event_hist_debug_fops = {
5094
+ .open = event_hist_debug_open,
5095
+ .read = seq_read,
5096
+ .llseek = seq_lseek,
5097
+ .release = single_release,
5098
+};
5099
+#endif
50715100
50725101 static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
50735102 {
....@@ -5415,6 +5444,7 @@
54155444 {
54165445 struct hist_trigger_data *hist_data = data->private_data;
54175446 struct event_trigger_data *test, *named_data = NULL;
5447
+ struct trace_array *tr = file->tr;
54185448 int ret = 0;
54195449
54205450 if (hist_data->attrs->name) {
....@@ -5422,7 +5452,7 @@
54225452 if (named_data) {
54235453 if (!hist_trigger_match(data, named_data, named_data,
54245454 true)) {
5425
- hist_err("Named hist trigger doesn't match existing named trigger (includes variables): ", hist_data->attrs->name);
5455
+ hist_err(tr, HIST_ERR_NAMED_MISMATCH, errpos(hist_data->attrs->name));
54265456 ret = -EINVAL;
54275457 goto out;
54285458 }
....@@ -5445,7 +5475,7 @@
54455475 else if (hist_data->attrs->clear)
54465476 hist_clear(test);
54475477 else {
5448
- hist_err("Hist trigger already exists", NULL);
5478
+ hist_err(tr, HIST_ERR_TRIGGER_EEXIST, 0);
54495479 ret = -EEXIST;
54505480 }
54515481 goto out;
....@@ -5453,7 +5483,7 @@
54535483 }
54545484 new:
54555485 if (hist_data->attrs->cont || hist_data->attrs->clear) {
5456
- hist_err("Can't clear or continue a nonexistent hist trigger", NULL);
5486
+ hist_err(tr, HIST_ERR_TRIGGER_ENOENT_CLEAR, 0);
54575487 ret = -ENOENT;
54585488 goto out;
54595489 }
....@@ -5478,7 +5508,7 @@
54785508
54795509 ret = tracing_set_clock(file->tr, hist_data->attrs->clock);
54805510 if (ret) {
5481
- hist_err("Couldn't set trace_clock: ", clock);
5511
+ hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock));
54825512 goto out;
54835513 }
54845514
....@@ -5619,6 +5649,8 @@
56195649 struct synth_event *se;
56205650 const char *se_name;
56215651
5652
+ lockdep_assert_held(&event_mutex);
5653
+
56225654 if (hist_file_check_refs(file))
56235655 return;
56245656
....@@ -5628,12 +5660,10 @@
56285660 list_del_rcu(&test->list);
56295661 trace_event_trigger_enable_disable(file, 0);
56305662
5631
- mutex_lock(&synth_event_mutex);
56325663 se_name = trace_event_name(file->event_call);
56335664 se = find_synth_event(se_name);
56345665 if (se)
56355666 se->ref--;
5636
- mutex_unlock(&synth_event_mutex);
56375667
56385668 update_cond_flag(file);
56395669 if (hist_data->enable_timestamps)
....@@ -5659,9 +5689,11 @@
56595689 char *trigger, *p;
56605690 int ret = 0;
56615691
5692
+ lockdep_assert_held(&event_mutex);
5693
+
56625694 if (glob && strlen(glob)) {
5663
- last_cmd_set(param);
56645695 hist_err_clear();
5696
+ last_cmd_set(file, param);
56655697 }
56665698
56675699 if (!param)
....@@ -5685,9 +5717,9 @@
56855717 p++;
56865718 continue;
56875719 }
5688
- if (p >= param + strlen(param) - strlen("if") - 1)
5720
+ if (p >= param + strlen(param) - (sizeof("if") - 1) - 1)
56895721 return -EINVAL;
5690
- if (*(p + strlen("if")) != ' ' && *(p + strlen("if")) != '\t') {
5722
+ if (*(p + sizeof("if") - 1) != ' ' && *(p + sizeof("if") - 1) != '\t') {
56915723 p++;
56925724 continue;
56935725 }
....@@ -5702,7 +5734,7 @@
57025734 trigger = strstrip(trigger);
57035735 }
57045736
5705
- attrs = parse_hist_trigger_attrs(trigger);
5737
+ attrs = parse_hist_trigger_attrs(file->tr, trigger);
57065738 if (IS_ERR(attrs))
57075739 return PTR_ERR(attrs);
57085740
....@@ -5749,14 +5781,10 @@
57495781 }
57505782
57515783 cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
5752
-
5753
- mutex_lock(&synth_event_mutex);
57545784 se_name = trace_event_name(file->event_call);
57555785 se = find_synth_event(se_name);
57565786 if (se)
57575787 se->ref--;
5758
- mutex_unlock(&synth_event_mutex);
5759
-
57605788 ret = 0;
57615789 goto out_free;
57625790 }
....@@ -5780,7 +5808,7 @@
57805808 if (has_hist_vars(hist_data))
57815809 save_hist_vars(hist_data);
57825810
5783
- ret = create_actions(hist_data, file);
5811
+ ret = create_actions(hist_data);
57845812 if (ret)
57855813 goto out_unreg;
57865814
....@@ -5792,13 +5820,10 @@
57925820 if (ret)
57935821 goto out_unreg;
57945822
5795
- mutex_lock(&synth_event_mutex);
57965823 se_name = trace_event_name(file->event_call);
57975824 se = find_synth_event(se_name);
57985825 if (se)
57995826 se->ref++;
5800
- mutex_unlock(&synth_event_mutex);
5801
-
58025827 /* Just return zero, not the number of registered triggers */
58035828 ret = 0;
58045829 out:
....@@ -5849,7 +5874,8 @@
58495874 struct enable_trigger_data *enable_data = data->private_data;
58505875 struct event_trigger_data *test;
58515876
5852
- list_for_each_entry_rcu(test, &enable_data->file->triggers, list) {
5877
+ list_for_each_entry_rcu(test, &enable_data->file->triggers, list,
5878
+ lockdep_is_held(&event_mutex)) {
58535879 if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
58545880 if (enable_data->enable)
58555881 test->paused = false;
....@@ -5974,31 +6000,3 @@
59746000
59756001 return ret;
59766002 }
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);