summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorVedang Patel <vedang.patel@intel.com>2018-01-15 21:51:38 -0500
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2018-03-10 16:05:49 -0500
commitc193707dde77ace92a649cd59a17e105e2fbeaef (patch)
tree4469f19c58457806bb5a1ea7ed3508e140b19cea /kernel
parentcbf4100efb8f279b6f35917b748b2239019c7a96 (diff)
tracing: Remove code which merges duplicates
We now have the logic to detect and remove duplicates in the tracing_map hash table. The code which merges duplicates in the histogram is redundant now. So, modify this code just to detect duplicates. The duplication detection code is still kept to ensure that any rare race condition which might cause duplicates does not go unnoticed. Link: http://lkml.kernel.org/r/55215cf59e2674391bdaf772fdafc4c393352b03.1516069914.git.tom.zanussi@linux.intel.com Signed-off-by: Vedang Patel <vedang.patel@intel.com> Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace_events_hist.c11
-rw-r--r--kernel/trace/tracing_map.c83
-rw-r--r--kernel/trace/tracing_map.h7
3 files changed, 6 insertions, 95 deletions
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 1e1558c99d56..712260e72be5 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -340,16 +340,6 @@ static int hist_trigger_elt_comm_alloc(struct tracing_map_elt *elt)
340 return 0; 340 return 0;
341} 341}
342 342
343static void hist_trigger_elt_comm_copy(struct tracing_map_elt *to,
344 struct tracing_map_elt *from)
345{
346 char *comm_from = from->private_data;
347 char *comm_to = to->private_data;
348
349 if (comm_from)
350 memcpy(comm_to, comm_from, TASK_COMM_LEN + 1);
351}
352
353static void hist_trigger_elt_comm_init(struct tracing_map_elt *elt) 343static void hist_trigger_elt_comm_init(struct tracing_map_elt *elt)
354{ 344{
355 char *comm = elt->private_data; 345 char *comm = elt->private_data;
@@ -360,7 +350,6 @@ static void hist_trigger_elt_comm_init(struct tracing_map_elt *elt)
360 350
361static const struct tracing_map_ops hist_trigger_elt_comm_ops = { 351static const struct tracing_map_ops hist_trigger_elt_comm_ops = {
362 .elt_alloc = hist_trigger_elt_comm_alloc, 352 .elt_alloc = hist_trigger_elt_comm_alloc,
363 .elt_copy = hist_trigger_elt_comm_copy,
364 .elt_free = hist_trigger_elt_comm_free, 353 .elt_free = hist_trigger_elt_comm_free,
365 .elt_init = hist_trigger_elt_comm_init, 354 .elt_init = hist_trigger_elt_comm_init,
366}; 355};
diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c
index b30f3439f27f..f47a4d54bcf0 100644
--- a/kernel/trace/tracing_map.c
+++ b/kernel/trace/tracing_map.c
@@ -847,67 +847,15 @@ create_sort_entry(void *key, struct tracing_map_elt *elt)
847 return sort_entry; 847 return sort_entry;
848} 848}
849 849
850static struct tracing_map_elt *copy_elt(struct tracing_map_elt *elt) 850static void detect_dups(struct tracing_map_sort_entry **sort_entries,
851{
852 struct tracing_map_elt *dup_elt;
853 unsigned int i;
854
855 dup_elt = tracing_map_elt_alloc(elt->map);
856 if (IS_ERR(dup_elt))
857 return NULL;
858
859 if (elt->map->ops && elt->map->ops->elt_copy)
860 elt->map->ops->elt_copy(dup_elt, elt);
861
862 dup_elt->private_data = elt->private_data;
863 memcpy(dup_elt->key, elt->key, elt->map->key_size);
864
865 for (i = 0; i < elt->map->n_fields; i++) {
866 atomic64_set(&dup_elt->fields[i].sum,
867 atomic64_read(&elt->fields[i].sum));
868 dup_elt->fields[i].cmp_fn = elt->fields[i].cmp_fn;
869 }
870
871 return dup_elt;
872}
873
874static int merge_dup(struct tracing_map_sort_entry **sort_entries,
875 unsigned int target, unsigned int dup)
876{
877 struct tracing_map_elt *target_elt, *elt;
878 bool first_dup = (target - dup) == 1;
879 int i;
880
881 if (first_dup) {
882 elt = sort_entries[target]->elt;
883 target_elt = copy_elt(elt);
884 if (!target_elt)
885 return -ENOMEM;
886 sort_entries[target]->elt = target_elt;
887 sort_entries[target]->elt_copied = true;
888 } else
889 target_elt = sort_entries[target]->elt;
890
891 elt = sort_entries[dup]->elt;
892
893 for (i = 0; i < elt->map->n_fields; i++)
894 atomic64_add(atomic64_read(&elt->fields[i].sum),
895 &target_elt->fields[i].sum);
896
897 sort_entries[dup]->dup = true;
898
899 return 0;
900}
901
902static int merge_dups(struct tracing_map_sort_entry **sort_entries,
903 int n_entries, unsigned int key_size) 851 int n_entries, unsigned int key_size)
904{ 852{
905 unsigned int dups = 0, total_dups = 0; 853 unsigned int dups = 0, total_dups = 0;
906 int err, i, j; 854 int i;
907 void *key; 855 void *key;
908 856
909 if (n_entries < 2) 857 if (n_entries < 2)
910 return total_dups; 858 return;
911 859
912 sort(sort_entries, n_entries, sizeof(struct tracing_map_sort_entry *), 860 sort(sort_entries, n_entries, sizeof(struct tracing_map_sort_entry *),
913 (int (*)(const void *, const void *))cmp_entries_dup, NULL); 861 (int (*)(const void *, const void *))cmp_entries_dup, NULL);
@@ -916,30 +864,14 @@ static int merge_dups(struct tracing_map_sort_entry **sort_entries,
916 for (i = 1; i < n_entries; i++) { 864 for (i = 1; i < n_entries; i++) {
917 if (!memcmp(sort_entries[i]->key, key, key_size)) { 865 if (!memcmp(sort_entries[i]->key, key, key_size)) {
918 dups++; total_dups++; 866 dups++; total_dups++;
919 err = merge_dup(sort_entries, i - dups, i);
920 if (err)
921 return err;
922 continue; 867 continue;
923 } 868 }
924 key = sort_entries[i]->key; 869 key = sort_entries[i]->key;
925 dups = 0; 870 dups = 0;
926 } 871 }
927 872
928 if (!total_dups) 873 WARN_ONCE(total_dups > 0,
929 return total_dups; 874 "Duplicates detected: %d\n", total_dups);
930
931 for (i = 0, j = 0; i < n_entries; i++) {
932 if (!sort_entries[i]->dup) {
933 sort_entries[j] = sort_entries[i];
934 if (j++ != i)
935 sort_entries[i] = NULL;
936 } else {
937 destroy_sort_entry(sort_entries[i]);
938 sort_entries[i] = NULL;
939 }
940 }
941
942 return total_dups;
943} 875}
944 876
945static bool is_key(struct tracing_map *map, unsigned int field_idx) 877static bool is_key(struct tracing_map *map, unsigned int field_idx)
@@ -1065,10 +997,7 @@ int tracing_map_sort_entries(struct tracing_map *map,
1065 return 1; 997 return 1;
1066 } 998 }
1067 999
1068 ret = merge_dups(entries, n_entries, map->key_size); 1000 detect_dups(entries, n_entries, map->key_size);
1069 if (ret < 0)
1070 goto free;
1071 n_entries -= ret;
1072 1001
1073 if (is_key(map, sort_keys[0].field_idx)) 1002 if (is_key(map, sort_keys[0].field_idx))
1074 cmp_entries_fn = cmp_entries_key; 1003 cmp_entries_fn = cmp_entries_key;
diff --git a/kernel/trace/tracing_map.h b/kernel/trace/tracing_map.h
index 5b5bbf8ae550..de57887c0670 100644
--- a/kernel/trace/tracing_map.h
+++ b/kernel/trace/tracing_map.h
@@ -215,11 +215,6 @@ struct tracing_map {
215 * Element allocation occurs before tracing begins, when the 215 * Element allocation occurs before tracing begins, when the
216 * tracing_map_init() call is made by client code. 216 * tracing_map_init() call is made by client code.
217 * 217 *
218 * @elt_copy: At certain points in the lifetime of an element, it may
219 * need to be copied. The copy should include a copy of the
220 * client-allocated data, which can be copied into the 'to'
221 * element from the 'from' element.
222 *
223 * @elt_free: When a tracing_map_elt is freed, this function is called 218 * @elt_free: When a tracing_map_elt is freed, this function is called
224 * and allows client-allocated per-element data to be freed. 219 * and allows client-allocated per-element data to be freed.
225 * 220 *
@@ -233,8 +228,6 @@ struct tracing_map {
233 */ 228 */
234struct tracing_map_ops { 229struct tracing_map_ops {
235 int (*elt_alloc)(struct tracing_map_elt *elt); 230 int (*elt_alloc)(struct tracing_map_elt *elt);
236 void (*elt_copy)(struct tracing_map_elt *to,
237 struct tracing_map_elt *from);
238 void (*elt_free)(struct tracing_map_elt *elt); 231 void (*elt_free)(struct tracing_map_elt *elt);
239 void (*elt_clear)(struct tracing_map_elt *elt); 232 void (*elt_clear)(struct tracing_map_elt *elt);
240 void (*elt_init)(struct tracing_map_elt *elt); 233 void (*elt_init)(struct tracing_map_elt *elt);