1 // SPDX-License-Identifier: GPL-2.0 2 #include "tests.h" 3 #include <stdio.h> 4 #include "cpumap.h" 5 #include "event.h" 6 #include "util/synthetic-events.h" 7 #include <string.h> 8 #include <linux/bitops.h> 9 #include <perf/cpumap.h> 10 #include "debug.h" 11 12 struct machine; 13 14 static int process_event_mask(struct perf_tool *tool __maybe_unused, 15 union perf_event *event, 16 struct perf_sample *sample __maybe_unused, 17 struct machine *machine __maybe_unused) 18 { 19 struct perf_record_cpu_map *map_event = &event->cpu_map; 20 struct perf_record_record_cpu_map *mask; 21 struct perf_record_cpu_map_data *data; 22 struct perf_cpu_map *map; 23 int i; 24 25 data = &map_event->data; 26 27 TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__MASK); 28 29 mask = (struct perf_record_record_cpu_map *)data->data; 30 31 TEST_ASSERT_VAL("wrong nr", mask->nr == 1); 32 33 for (i = 0; i < 20; i++) { 34 TEST_ASSERT_VAL("wrong cpu", test_bit(i, mask->mask)); 35 } 36 37 map = cpu_map__new_data(data); 38 TEST_ASSERT_VAL("wrong nr", map->nr == 20); 39 40 for (i = 0; i < 20; i++) { 41 TEST_ASSERT_VAL("wrong cpu", map->map[i].cpu == i); 42 } 43 44 perf_cpu_map__put(map); 45 return 0; 46 } 47 48 static int process_event_cpus(struct perf_tool *tool __maybe_unused, 49 union perf_event *event, 50 struct perf_sample *sample __maybe_unused, 51 struct machine *machine __maybe_unused) 52 { 53 struct perf_record_cpu_map *map_event = &event->cpu_map; 54 struct cpu_map_entries *cpus; 55 struct perf_record_cpu_map_data *data; 56 struct perf_cpu_map *map; 57 58 data = &map_event->data; 59 60 TEST_ASSERT_VAL("wrong type", data->type == PERF_CPU_MAP__CPUS); 61 62 cpus = (struct cpu_map_entries *)data->data; 63 64 TEST_ASSERT_VAL("wrong nr", cpus->nr == 2); 65 TEST_ASSERT_VAL("wrong cpu", cpus->cpu[0] == 1); 66 TEST_ASSERT_VAL("wrong cpu", cpus->cpu[1] == 256); 67 68 map = cpu_map__new_data(data); 69 TEST_ASSERT_VAL("wrong nr", map->nr == 2); 70 TEST_ASSERT_VAL("wrong cpu", map->map[0].cpu == 1); 71 TEST_ASSERT_VAL("wrong cpu", map->map[1].cpu == 256); 72 TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1); 73 perf_cpu_map__put(map); 74 return 0; 75 } 76 77 78 static int test__cpu_map_synthesize(struct test_suite *test __maybe_unused, int subtest __maybe_unused) 79 { 80 struct perf_cpu_map *cpus; 81 82 /* This one is better stores in mask. */ 83 cpus = perf_cpu_map__new("0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19"); 84 85 TEST_ASSERT_VAL("failed to synthesize map", 86 !perf_event__synthesize_cpu_map(NULL, cpus, process_event_mask, NULL)); 87 88 perf_cpu_map__put(cpus); 89 90 /* This one is better stores in cpu values. */ 91 cpus = perf_cpu_map__new("1,256"); 92 93 TEST_ASSERT_VAL("failed to synthesize map", 94 !perf_event__synthesize_cpu_map(NULL, cpus, process_event_cpus, NULL)); 95 96 perf_cpu_map__put(cpus); 97 return 0; 98 } 99 100 static int cpu_map_print(const char *str) 101 { 102 struct perf_cpu_map *map = perf_cpu_map__new(str); 103 char buf[100]; 104 105 if (!map) 106 return -1; 107 108 cpu_map__snprint(map, buf, sizeof(buf)); 109 perf_cpu_map__put(map); 110 111 return !strcmp(buf, str); 112 } 113 114 static int test__cpu_map_print(struct test_suite *test __maybe_unused, int subtest __maybe_unused) 115 { 116 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1")); 117 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5")); 118 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3,5,7,9,11,13,15,17,19,21-40")); 119 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("2-5")); 120 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37")); 121 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,3-6,8-10,24,35-37")); 122 TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1-10,12-20,22-30,32-40")); 123 return 0; 124 } 125 126 static int test__cpu_map_merge(struct test_suite *test __maybe_unused, int subtest __maybe_unused) 127 { 128 struct perf_cpu_map *a = perf_cpu_map__new("4,2,1"); 129 struct perf_cpu_map *b = perf_cpu_map__new("4,5,7"); 130 struct perf_cpu_map *c = perf_cpu_map__merge(a, b); 131 char buf[100]; 132 133 TEST_ASSERT_VAL("failed to merge map: bad nr", c->nr == 5); 134 cpu_map__snprint(c, buf, sizeof(buf)); 135 TEST_ASSERT_VAL("failed to merge map: bad result", !strcmp(buf, "1-2,4-5,7")); 136 perf_cpu_map__put(b); 137 perf_cpu_map__put(c); 138 return 0; 139 } 140 141 DEFINE_SUITE("Synthesize cpu map", cpu_map_synthesize); 142 DEFINE_SUITE("Print cpu map", cpu_map_print); 143 DEFINE_SUITE("Merge cpu map", cpu_map_merge); 144