2 * trace_events_hist - trace event hist triggers
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * Copyright (C) 2015 Tom Zanussi <tom.zanussi@linux.intel.com>
17 #include <linux/module.h>
18 #include <linux/kallsyms.h>
19 #include <linux/mutex.h>
20 #include <linux/slab.h>
21 #include <linux/stacktrace.h>
23 #include "tracing_map.h"
28 typedef u64 (*hist_field_fn_t) (struct hist_field *field, void *event);
31 struct ftrace_event_field *field;
38 static u64 hist_field_counter(struct hist_field *field, void *event)
43 static u64 hist_field_string(struct hist_field *hist_field, void *event)
45 char *addr = (char *)(event + hist_field->field->offset);
47 return (u64)(unsigned long)addr;
50 #define DEFINE_HIST_FIELD_FN(type) \
51 static u64 hist_field_##type(struct hist_field *hist_field, void *event)\
53 type *addr = (type *)(event + hist_field->field->offset); \
58 DEFINE_HIST_FIELD_FN(s64);
59 DEFINE_HIST_FIELD_FN(u64);
60 DEFINE_HIST_FIELD_FN(s32);
61 DEFINE_HIST_FIELD_FN(u32);
62 DEFINE_HIST_FIELD_FN(s16);
63 DEFINE_HIST_FIELD_FN(u16);
64 DEFINE_HIST_FIELD_FN(s8);
65 DEFINE_HIST_FIELD_FN(u8);
67 #define for_each_hist_field(i, hist_data) \
68 for ((i) = 0; (i) < (hist_data)->n_fields; (i)++)
70 #define for_each_hist_val_field(i, hist_data) \
71 for ((i) = 0; (i) < (hist_data)->n_vals; (i)++)
73 #define for_each_hist_key_field(i, hist_data) \
74 for ((i) = (hist_data)->n_vals; (i) < (hist_data)->n_fields; (i)++)
76 #define HITCOUNT_IDX 0
77 #define HIST_KEY_SIZE_MAX (MAX_FILTER_STR_VAL + sizeof(u64))
79 enum hist_field_flags {
80 HIST_FIELD_FL_HITCOUNT = 1,
81 HIST_FIELD_FL_KEY = 2,
82 HIST_FIELD_FL_STRING = 4,
83 HIST_FIELD_FL_HEX = 8,
84 HIST_FIELD_FL_SYM = 16,
85 HIST_FIELD_FL_SYM_OFFSET = 32,
86 HIST_FIELD_FL_EXECNAME = 64,
89 struct hist_trigger_attrs {
96 unsigned int map_bits;
99 struct hist_trigger_data {
100 struct hist_field *fields[TRACING_MAP_FIELDS_MAX];
103 unsigned int n_fields;
104 unsigned int key_size;
105 struct tracing_map_sort_key sort_keys[TRACING_MAP_SORT_KEYS_MAX];
106 unsigned int n_sort_keys;
107 struct trace_event_file *event_file;
108 struct hist_trigger_attrs *attrs;
109 struct tracing_map *map;
112 static hist_field_fn_t select_value_fn(int field_size, int field_is_signed)
114 hist_field_fn_t fn = NULL;
116 switch (field_size) {
146 static int parse_map_size(char *str)
148 unsigned long size, map_bits;
157 ret = kstrtoul(str, 0, &size);
161 map_bits = ilog2(roundup_pow_of_two(size));
162 if (map_bits < TRACING_MAP_BITS_MIN ||
163 map_bits > TRACING_MAP_BITS_MAX)
171 static void destroy_hist_trigger_attrs(struct hist_trigger_attrs *attrs)
176 kfree(attrs->sort_key_str);
177 kfree(attrs->keys_str);
178 kfree(attrs->vals_str);
182 static struct hist_trigger_attrs *parse_hist_trigger_attrs(char *trigger_str)
184 struct hist_trigger_attrs *attrs;
187 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
189 return ERR_PTR(-ENOMEM);
191 while (trigger_str) {
192 char *str = strsep(&trigger_str, ":");
194 if ((strncmp(str, "key=", strlen("key=")) == 0) ||
195 (strncmp(str, "keys=", strlen("keys=")) == 0))
196 attrs->keys_str = kstrdup(str, GFP_KERNEL);
197 else if ((strncmp(str, "val=", strlen("val=")) == 0) ||
198 (strncmp(str, "vals=", strlen("vals=")) == 0) ||
199 (strncmp(str, "values=", strlen("values=")) == 0))
200 attrs->vals_str = kstrdup(str, GFP_KERNEL);
201 else if (strncmp(str, "sort=", strlen("sort=")) == 0)
202 attrs->sort_key_str = kstrdup(str, GFP_KERNEL);
203 else if (strcmp(str, "pause") == 0)
205 else if ((strcmp(str, "cont") == 0) ||
206 (strcmp(str, "continue") == 0))
208 else if (strcmp(str, "clear") == 0)
210 else if (strncmp(str, "size=", strlen("size=")) == 0) {
211 int map_bits = parse_map_size(str);
217 attrs->map_bits = map_bits;
224 if (!attrs->keys_str) {
231 destroy_hist_trigger_attrs(attrs);
236 static inline void save_comm(char *comm, struct task_struct *task)
239 strcpy(comm, "<idle>");
243 if (WARN_ON_ONCE(task->pid < 0)) {
244 strcpy(comm, "<XXX>");
248 memcpy(comm, task->comm, TASK_COMM_LEN);
251 static void hist_trigger_elt_comm_free(struct tracing_map_elt *elt)
253 kfree((char *)elt->private_data);
256 static int hist_trigger_elt_comm_alloc(struct tracing_map_elt *elt)
258 struct hist_trigger_data *hist_data = elt->map->private_data;
259 struct hist_field *key_field;
262 for_each_hist_key_field(i, hist_data) {
263 key_field = hist_data->fields[i];
265 if (key_field->flags & HIST_FIELD_FL_EXECNAME) {
266 unsigned int size = TASK_COMM_LEN + 1;
268 elt->private_data = kzalloc(size, GFP_KERNEL);
269 if (!elt->private_data)
278 static void hist_trigger_elt_comm_copy(struct tracing_map_elt *to,
279 struct tracing_map_elt *from)
281 char *comm_from = from->private_data;
282 char *comm_to = to->private_data;
285 memcpy(comm_to, comm_from, TASK_COMM_LEN + 1);
288 static void hist_trigger_elt_comm_init(struct tracing_map_elt *elt)
290 char *comm = elt->private_data;
293 save_comm(comm, current);
296 static const struct tracing_map_ops hist_trigger_elt_comm_ops = {
297 .elt_alloc = hist_trigger_elt_comm_alloc,
298 .elt_copy = hist_trigger_elt_comm_copy,
299 .elt_free = hist_trigger_elt_comm_free,
300 .elt_init = hist_trigger_elt_comm_init,
303 static void destroy_hist_field(struct hist_field *hist_field)
308 static struct hist_field *create_hist_field(struct ftrace_event_field *field,
311 struct hist_field *hist_field;
313 if (field && is_function_field(field))
316 hist_field = kzalloc(sizeof(struct hist_field), GFP_KERNEL);
320 if (flags & HIST_FIELD_FL_HITCOUNT) {
321 hist_field->fn = hist_field_counter;
325 if (is_string_field(field)) {
326 flags |= HIST_FIELD_FL_STRING;
327 hist_field->fn = hist_field_string;
329 hist_field->fn = select_value_fn(field->size,
331 if (!hist_field->fn) {
332 destroy_hist_field(hist_field);
337 hist_field->field = field;
338 hist_field->flags = flags;
343 static void destroy_hist_fields(struct hist_trigger_data *hist_data)
347 for (i = 0; i < TRACING_MAP_FIELDS_MAX; i++) {
348 if (hist_data->fields[i]) {
349 destroy_hist_field(hist_data->fields[i]);
350 hist_data->fields[i] = NULL;
355 static int create_hitcount_val(struct hist_trigger_data *hist_data)
357 hist_data->fields[HITCOUNT_IDX] =
358 create_hist_field(NULL, HIST_FIELD_FL_HITCOUNT);
359 if (!hist_data->fields[HITCOUNT_IDX])
364 if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX))
370 static int create_val_field(struct hist_trigger_data *hist_data,
371 unsigned int val_idx,
372 struct trace_event_file *file,
375 struct ftrace_event_field *field = NULL;
376 unsigned long flags = 0;
380 if (WARN_ON(val_idx >= TRACING_MAP_VALS_MAX))
383 field_name = strsep(&field_str, ".");
385 if (strcmp(field_str, "hex") == 0)
386 flags |= HIST_FIELD_FL_HEX;
393 field = trace_find_event_field(file->event_call, field_name);
399 hist_data->fields[val_idx] = create_hist_field(field, flags);
400 if (!hist_data->fields[val_idx]) {
407 if (WARN_ON(hist_data->n_vals > TRACING_MAP_VALS_MAX))
413 static int create_val_fields(struct hist_trigger_data *hist_data,
414 struct trace_event_file *file)
416 char *fields_str, *field_str;
420 ret = create_hitcount_val(hist_data);
424 fields_str = hist_data->attrs->vals_str;
428 strsep(&fields_str, "=");
432 for (i = 0, j = 1; i < TRACING_MAP_VALS_MAX &&
433 j < TRACING_MAP_VALS_MAX; i++) {
434 field_str = strsep(&fields_str, ",");
437 if (strcmp(field_str, "hitcount") == 0)
439 ret = create_val_field(hist_data, j++, file, field_str);
443 if (fields_str && (strcmp(fields_str, "hitcount") != 0))
449 static int create_key_field(struct hist_trigger_data *hist_data,
450 unsigned int key_idx,
451 unsigned int key_offset,
452 struct trace_event_file *file,
455 struct ftrace_event_field *field = NULL;
456 unsigned long flags = 0;
457 unsigned int key_size;
461 if (WARN_ON(key_idx >= TRACING_MAP_FIELDS_MAX))
464 flags |= HIST_FIELD_FL_KEY;
466 field_name = strsep(&field_str, ".");
468 if (strcmp(field_str, "hex") == 0)
469 flags |= HIST_FIELD_FL_HEX;
470 else if (strcmp(field_str, "sym") == 0)
471 flags |= HIST_FIELD_FL_SYM;
472 else if (strcmp(field_str, "sym-offset") == 0)
473 flags |= HIST_FIELD_FL_SYM_OFFSET;
474 else if ((strcmp(field_str, "execname") == 0) &&
475 (strcmp(field_name, "common_pid") == 0))
476 flags |= HIST_FIELD_FL_EXECNAME;
483 field = trace_find_event_field(file->event_call, field_name);
489 key_size = field->size;
491 hist_data->fields[key_idx] = create_hist_field(field, flags);
492 if (!hist_data->fields[key_idx]) {
497 key_size = ALIGN(key_size, sizeof(u64));
498 hist_data->fields[key_idx]->size = key_size;
499 hist_data->fields[key_idx]->offset = key_offset;
500 hist_data->key_size += key_size;
501 if (hist_data->key_size > HIST_KEY_SIZE_MAX) {
508 if (WARN_ON(hist_data->n_keys > TRACING_MAP_KEYS_MAX))
516 static int create_key_fields(struct hist_trigger_data *hist_data,
517 struct trace_event_file *file)
519 unsigned int i, key_offset = 0, n_vals = hist_data->n_vals;
520 char *fields_str, *field_str;
523 fields_str = hist_data->attrs->keys_str;
527 strsep(&fields_str, "=");
531 for (i = n_vals; i < n_vals + TRACING_MAP_KEYS_MAX; i++) {
532 field_str = strsep(&fields_str, ",");
535 ret = create_key_field(hist_data, i, key_offset,
550 static int create_hist_fields(struct hist_trigger_data *hist_data,
551 struct trace_event_file *file)
555 ret = create_val_fields(hist_data, file);
559 ret = create_key_fields(hist_data, file);
563 hist_data->n_fields = hist_data->n_vals + hist_data->n_keys;
568 static int is_descending(const char *str)
573 if (strcmp(str, "descending") == 0)
576 if (strcmp(str, "ascending") == 0)
582 static int create_sort_keys(struct hist_trigger_data *hist_data)
584 char *fields_str = hist_data->attrs->sort_key_str;
585 struct ftrace_event_field *field = NULL;
586 struct tracing_map_sort_key *sort_key;
587 int descending, ret = 0;
590 hist_data->n_sort_keys = 1; /* we always have at least one, hitcount */
595 strsep(&fields_str, "=");
601 for (i = 0; i < TRACING_MAP_SORT_KEYS_MAX; i++) {
602 char *field_str, *field_name;
604 sort_key = &hist_data->sort_keys[i];
606 field_str = strsep(&fields_str, ",");
613 if ((i == TRACING_MAP_SORT_KEYS_MAX - 1) && fields_str) {
618 field_name = strsep(&field_str, ".");
624 if (strcmp(field_name, "hitcount") == 0) {
625 descending = is_descending(field_str);
626 if (descending < 0) {
630 sort_key->descending = descending;
634 for (j = 1; j < hist_data->n_fields; j++) {
635 field = hist_data->fields[j]->field;
636 if (field && (strcmp(field_name, field->name) == 0)) {
637 sort_key->field_idx = j;
638 descending = is_descending(field_str);
639 if (descending < 0) {
643 sort_key->descending = descending;
647 if (j == hist_data->n_fields) {
652 hist_data->n_sort_keys = i;
657 static void destroy_hist_data(struct hist_trigger_data *hist_data)
659 destroy_hist_trigger_attrs(hist_data->attrs);
660 destroy_hist_fields(hist_data);
661 tracing_map_destroy(hist_data->map);
665 static int create_tracing_map_fields(struct hist_trigger_data *hist_data)
667 struct tracing_map *map = hist_data->map;
668 struct ftrace_event_field *field;
669 struct hist_field *hist_field;
672 for_each_hist_field(i, hist_data) {
673 hist_field = hist_data->fields[i];
674 if (hist_field->flags & HIST_FIELD_FL_KEY) {
675 tracing_map_cmp_fn_t cmp_fn;
677 field = hist_field->field;
679 if (is_string_field(field))
680 cmp_fn = tracing_map_cmp_string;
682 cmp_fn = tracing_map_cmp_num(field->size,
684 idx = tracing_map_add_key_field(map,
689 idx = tracing_map_add_sum_field(map);
698 static bool need_tracing_map_ops(struct hist_trigger_data *hist_data)
700 struct hist_field *key_field;
703 for_each_hist_key_field(i, hist_data) {
704 key_field = hist_data->fields[i];
706 if (key_field->flags & HIST_FIELD_FL_EXECNAME)
713 static struct hist_trigger_data *
714 create_hist_data(unsigned int map_bits,
715 struct hist_trigger_attrs *attrs,
716 struct trace_event_file *file)
718 const struct tracing_map_ops *map_ops = NULL;
719 struct hist_trigger_data *hist_data;
722 hist_data = kzalloc(sizeof(*hist_data), GFP_KERNEL);
724 return ERR_PTR(-ENOMEM);
726 hist_data->attrs = attrs;
728 ret = create_hist_fields(hist_data, file);
732 ret = create_sort_keys(hist_data);
736 if (need_tracing_map_ops(hist_data))
737 map_ops = &hist_trigger_elt_comm_ops;
739 hist_data->map = tracing_map_create(map_bits, hist_data->key_size,
741 if (IS_ERR(hist_data->map)) {
742 ret = PTR_ERR(hist_data->map);
743 hist_data->map = NULL;
747 ret = create_tracing_map_fields(hist_data);
751 ret = tracing_map_init(hist_data->map);
755 hist_data->event_file = file;
759 hist_data->attrs = NULL;
761 destroy_hist_data(hist_data);
763 hist_data = ERR_PTR(ret);
768 static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
769 struct tracing_map_elt *elt,
772 struct hist_field *hist_field;
776 for_each_hist_val_field(i, hist_data) {
777 hist_field = hist_data->fields[i];
778 hist_val = hist_field->fn(hist_field, rec);
779 tracing_map_update_sum(elt, i, hist_val);
783 static void event_hist_trigger(struct event_trigger_data *data, void *rec)
785 struct hist_trigger_data *hist_data = data->private_data;
786 char compound_key[HIST_KEY_SIZE_MAX];
787 struct hist_field *key_field;
788 struct tracing_map_elt *elt;
793 if (hist_data->n_keys > 1)
794 memset(compound_key, 0, hist_data->key_size);
796 for_each_hist_key_field(i, hist_data) {
797 key_field = hist_data->fields[i];
799 field_contents = key_field->fn(key_field, rec);
800 if (key_field->flags & HIST_FIELD_FL_STRING)
801 key = (void *)(unsigned long)field_contents;
803 key = (void *)&field_contents;
805 if (hist_data->n_keys > 1) {
806 memcpy(compound_key + key_field->offset, key,
811 if (hist_data->n_keys > 1)
814 elt = tracing_map_insert(hist_data->map, key);
816 hist_trigger_elt_update(hist_data, elt, rec);
820 hist_trigger_entry_print(struct seq_file *m,
821 struct hist_trigger_data *hist_data, void *key,
822 struct tracing_map_elt *elt)
824 struct hist_field *key_field;
825 char str[KSYM_SYMBOL_LEN];
831 for_each_hist_key_field(i, hist_data) {
832 key_field = hist_data->fields[i];
834 if (i > hist_data->n_vals)
837 if (key_field->flags & HIST_FIELD_FL_HEX) {
838 uval = *(u64 *)(key + key_field->offset);
839 seq_printf(m, "%s: %llx",
840 key_field->field->name, uval);
841 } else if (key_field->flags & HIST_FIELD_FL_SYM) {
842 uval = *(u64 *)(key + key_field->offset);
843 sprint_symbol_no_offset(str, uval);
844 seq_printf(m, "%s: [%llx] %-45s",
845 key_field->field->name, uval, str);
846 } else if (key_field->flags & HIST_FIELD_FL_SYM_OFFSET) {
847 uval = *(u64 *)(key + key_field->offset);
848 sprint_symbol(str, uval);
849 seq_printf(m, "%s: [%llx] %-55s",
850 key_field->field->name, uval, str);
851 } else if (key_field->flags & HIST_FIELD_FL_EXECNAME) {
852 char *comm = elt->private_data;
854 uval = *(u64 *)(key + key_field->offset);
855 seq_printf(m, "%s: %-16s[%10llu]",
856 key_field->field->name, comm, uval);
857 } else if (key_field->flags & HIST_FIELD_FL_STRING) {
858 seq_printf(m, "%s: %-50s", key_field->field->name,
859 (char *)(key + key_field->offset));
861 uval = *(u64 *)(key + key_field->offset);
862 seq_printf(m, "%s: %10llu", key_field->field->name,
869 seq_printf(m, " hitcount: %10llu",
870 tracing_map_read_sum(elt, HITCOUNT_IDX));
872 for (i = 1; i < hist_data->n_vals; i++) {
873 if (hist_data->fields[i]->flags & HIST_FIELD_FL_HEX) {
874 seq_printf(m, " %s: %10llx",
875 hist_data->fields[i]->field->name,
876 tracing_map_read_sum(elt, i));
878 seq_printf(m, " %s: %10llu",
879 hist_data->fields[i]->field->name,
880 tracing_map_read_sum(elt, i));
887 static int print_entries(struct seq_file *m,
888 struct hist_trigger_data *hist_data)
890 struct tracing_map_sort_entry **sort_entries = NULL;
891 struct tracing_map *map = hist_data->map;
892 unsigned int i, n_entries;
894 n_entries = tracing_map_sort_entries(map, hist_data->sort_keys,
895 hist_data->n_sort_keys,
900 for (i = 0; i < n_entries; i++)
901 hist_trigger_entry_print(m, hist_data,
902 sort_entries[i]->key,
903 sort_entries[i]->elt);
905 tracing_map_destroy_sort_entries(sort_entries, n_entries);
910 static int hist_show(struct seq_file *m, void *v)
912 struct event_trigger_data *test, *data = NULL;
913 struct trace_event_file *event_file;
914 struct hist_trigger_data *hist_data;
915 int n_entries, ret = 0;
917 mutex_lock(&event_mutex);
919 event_file = event_file_data(m->private);
920 if (unlikely(!event_file)) {
925 list_for_each_entry_rcu(test, &event_file->triggers, list) {
926 if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
934 seq_puts(m, "# event histogram\n#\n# trigger info: ");
935 data->ops->print(m, data->ops, data);
938 hist_data = data->private_data;
939 n_entries = print_entries(m, hist_data);
945 seq_printf(m, "\nTotals:\n Hits: %llu\n Entries: %u\n Dropped: %llu\n",
946 (u64)atomic64_read(&hist_data->map->hits),
947 n_entries, (u64)atomic64_read(&hist_data->map->drops));
949 mutex_unlock(&event_mutex);
954 static int event_hist_open(struct inode *inode, struct file *file)
956 return single_open(file, hist_show, file);
959 const struct file_operations event_hist_fops = {
960 .open = event_hist_open,
963 .release = single_release,
966 static const char *get_hist_field_flags(struct hist_field *hist_field)
968 const char *flags_str = NULL;
970 if (hist_field->flags & HIST_FIELD_FL_HEX)
972 else if (hist_field->flags & HIST_FIELD_FL_SYM)
974 else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET)
975 flags_str = "sym-offset";
976 else if (hist_field->flags & HIST_FIELD_FL_EXECNAME)
977 flags_str = "execname";
982 static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
984 seq_printf(m, "%s", hist_field->field->name);
985 if (hist_field->flags) {
986 const char *flags_str = get_hist_field_flags(hist_field);
989 seq_printf(m, ".%s", flags_str);
993 static int event_hist_trigger_print(struct seq_file *m,
994 struct event_trigger_ops *ops,
995 struct event_trigger_data *data)
997 struct hist_trigger_data *hist_data = data->private_data;
998 struct hist_field *key_field;
1001 seq_puts(m, "hist:keys=");
1003 for_each_hist_key_field(i, hist_data) {
1004 key_field = hist_data->fields[i];
1006 if (i > hist_data->n_vals)
1009 hist_field_print(m, key_field);
1012 seq_puts(m, ":vals=");
1014 for_each_hist_val_field(i, hist_data) {
1015 if (i == HITCOUNT_IDX)
1016 seq_puts(m, "hitcount");
1019 hist_field_print(m, hist_data->fields[i]);
1023 seq_puts(m, ":sort=");
1025 for (i = 0; i < hist_data->n_sort_keys; i++) {
1026 struct tracing_map_sort_key *sort_key;
1028 sort_key = &hist_data->sort_keys[i];
1033 if (sort_key->field_idx == HITCOUNT_IDX)
1034 seq_puts(m, "hitcount");
1036 unsigned int idx = sort_key->field_idx;
1038 if (WARN_ON(idx >= TRACING_MAP_FIELDS_MAX))
1041 hist_field_print(m, hist_data->fields[idx]);
1044 if (sort_key->descending)
1045 seq_puts(m, ".descending");
1048 seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits));
1050 if (data->filter_str)
1051 seq_printf(m, " if %s", data->filter_str);
1054 seq_puts(m, " [paused]");
1056 seq_puts(m, " [active]");
1063 static void event_hist_trigger_free(struct event_trigger_ops *ops,
1064 struct event_trigger_data *data)
1066 struct hist_trigger_data *hist_data = data->private_data;
1068 if (WARN_ON_ONCE(data->ref <= 0))
1073 trigger_data_free(data);
1074 destroy_hist_data(hist_data);
1078 static struct event_trigger_ops event_hist_trigger_ops = {
1079 .func = event_hist_trigger,
1080 .print = event_hist_trigger_print,
1081 .init = event_trigger_init,
1082 .free = event_hist_trigger_free,
1085 static struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
1088 return &event_hist_trigger_ops;
1091 static void hist_clear(struct event_trigger_data *data)
1093 struct hist_trigger_data *hist_data = data->private_data;
1096 paused = data->paused;
1097 data->paused = true;
1099 synchronize_sched();
1101 tracing_map_clear(hist_data->map);
1103 data->paused = paused;
1106 static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,
1107 struct event_trigger_data *data,
1108 struct trace_event_file *file)
1110 struct hist_trigger_data *hist_data = data->private_data;
1111 struct event_trigger_data *test;
1114 list_for_each_entry_rcu(test, &file->triggers, list) {
1115 if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
1116 if (hist_data->attrs->pause)
1117 test->paused = true;
1118 else if (hist_data->attrs->cont)
1119 test->paused = false;
1120 else if (hist_data->attrs->clear)
1128 if (hist_data->attrs->cont || hist_data->attrs->clear) {
1133 if (hist_data->attrs->pause)
1134 data->paused = true;
1136 if (data->ops->init) {
1137 ret = data->ops->init(data->ops, data);
1142 list_add_rcu(&data->list, &file->triggers);
1145 update_cond_flag(file);
1146 if (trace_event_trigger_enable_disable(file, 1) < 0) {
1147 list_del_rcu(&data->list);
1148 update_cond_flag(file);
1155 static int event_hist_trigger_func(struct event_command *cmd_ops,
1156 struct trace_event_file *file,
1157 char *glob, char *cmd, char *param)
1159 unsigned int hist_trigger_bits = TRACING_MAP_BITS_DEFAULT;
1160 struct event_trigger_data *trigger_data;
1161 struct hist_trigger_attrs *attrs;
1162 struct event_trigger_ops *trigger_ops;
1163 struct hist_trigger_data *hist_data;
1170 /* separate the trigger from the filter (k:v [if filter]) */
1171 trigger = strsep(¶m, " \t");
1175 attrs = parse_hist_trigger_attrs(trigger);
1177 return PTR_ERR(attrs);
1179 if (attrs->map_bits)
1180 hist_trigger_bits = attrs->map_bits;
1182 hist_data = create_hist_data(hist_trigger_bits, attrs, file);
1183 if (IS_ERR(hist_data)) {
1184 destroy_hist_trigger_attrs(attrs);
1185 return PTR_ERR(hist_data);
1188 trigger_ops = cmd_ops->get_trigger_ops(cmd, trigger);
1191 trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL);
1195 trigger_data->count = -1;
1196 trigger_data->ops = trigger_ops;
1197 trigger_data->cmd_ops = cmd_ops;
1199 INIT_LIST_HEAD(&trigger_data->list);
1200 RCU_INIT_POINTER(trigger_data->filter, NULL);
1202 trigger_data->private_data = hist_data;
1204 if (glob[0] == '!') {
1205 cmd_ops->unreg(glob+1, trigger_ops, trigger_data, file);
1210 if (!param) /* if param is non-empty, it's supposed to be a filter */
1213 if (!cmd_ops->set_filter)
1216 ret = cmd_ops->set_filter(param, trigger_data, file);
1220 ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file);
1222 * The above returns on success the # of triggers registered,
1223 * but if it didn't register any it returns zero. Consider no
1224 * triggers registered a failure too.
1227 if (!(attrs->pause || attrs->cont || attrs->clear))
1232 /* Just return zero, not the number of registered triggers */
1237 if (cmd_ops->set_filter)
1238 cmd_ops->set_filter(NULL, trigger_data, NULL);
1240 kfree(trigger_data);
1242 destroy_hist_data(hist_data);
1246 static struct event_command trigger_hist_cmd = {
1248 .trigger_type = ETT_EVENT_HIST,
1249 .flags = EVENT_CMD_FL_NEEDS_REC,
1250 .func = event_hist_trigger_func,
1251 .reg = hist_register_trigger,
1252 .unreg = unregister_trigger,
1253 .get_trigger_ops = event_hist_get_trigger_ops,
1254 .set_filter = set_trigger_filter,
1257 __init int register_trigger_hist_cmd(void)
1261 ret = register_event_command(&trigger_hist_cmd);