Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.13-rc2 238 lines 5.4 kB view raw
1#include <linux/compiler.h> 2#include <errno.h> 3#include <inttypes.h> 4#include <string.h> 5#include <sys/wait.h> 6#include "tests.h" 7#include "evlist.h" 8#include "evsel.h" 9#include "util.h" 10#include "debug.h" 11#include "thread_map.h" 12#include "target.h" 13 14static int attach__enable_on_exec(struct perf_evlist *evlist) 15{ 16 struct perf_evsel *evsel = perf_evlist__last(evlist); 17 struct target target = { 18 .uid = UINT_MAX, 19 }; 20 const char *argv[] = { "true", NULL, }; 21 char sbuf[STRERR_BUFSIZE]; 22 int err; 23 24 pr_debug("attaching to spawned child, enable on exec\n"); 25 26 err = perf_evlist__create_maps(evlist, &target); 27 if (err < 0) { 28 pr_debug("Not enough memory to create thread/cpu maps\n"); 29 return err; 30 } 31 32 err = perf_evlist__prepare_workload(evlist, &target, argv, false, NULL); 33 if (err < 0) { 34 pr_debug("Couldn't run the workload!\n"); 35 return err; 36 } 37 38 evsel->attr.enable_on_exec = 1; 39 40 err = perf_evlist__open(evlist); 41 if (err < 0) { 42 pr_debug("perf_evlist__open: %s\n", 43 str_error_r(errno, sbuf, sizeof(sbuf))); 44 return err; 45 } 46 47 return perf_evlist__start_workload(evlist) == 1 ? TEST_OK : TEST_FAIL; 48} 49 50static int detach__enable_on_exec(struct perf_evlist *evlist) 51{ 52 waitpid(evlist->workload.pid, NULL, 0); 53 return 0; 54} 55 56static int attach__current_disabled(struct perf_evlist *evlist) 57{ 58 struct perf_evsel *evsel = perf_evlist__last(evlist); 59 struct thread_map *threads; 60 int err; 61 62 pr_debug("attaching to current thread as disabled\n"); 63 64 threads = thread_map__new(-1, getpid(), UINT_MAX); 65 if (threads == NULL) { 66 pr_debug("thread_map__new\n"); 67 return -1; 68 } 69 70 evsel->attr.disabled = 1; 71 72 err = perf_evsel__open_per_thread(evsel, threads); 73 if (err) { 74 pr_debug("Failed to open event cpu-clock:u\n"); 75 return err; 76 } 77 78 thread_map__put(threads); 79 return perf_evsel__enable(evsel) == 0 ? TEST_OK : TEST_FAIL; 80} 81 82static int attach__current_enabled(struct perf_evlist *evlist) 83{ 84 struct perf_evsel *evsel = perf_evlist__last(evlist); 85 struct thread_map *threads; 86 int err; 87 88 pr_debug("attaching to current thread as enabled\n"); 89 90 threads = thread_map__new(-1, getpid(), UINT_MAX); 91 if (threads == NULL) { 92 pr_debug("failed to call thread_map__new\n"); 93 return -1; 94 } 95 96 err = perf_evsel__open_per_thread(evsel, threads); 97 98 thread_map__put(threads); 99 return err == 0 ? TEST_OK : TEST_FAIL; 100} 101 102static int detach__disable(struct perf_evlist *evlist) 103{ 104 struct perf_evsel *evsel = perf_evlist__last(evlist); 105 106 return perf_evsel__enable(evsel); 107} 108 109static int attach__cpu_disabled(struct perf_evlist *evlist) 110{ 111 struct perf_evsel *evsel = perf_evlist__last(evlist); 112 struct cpu_map *cpus; 113 int err; 114 115 pr_debug("attaching to CPU 0 as enabled\n"); 116 117 cpus = cpu_map__new("0"); 118 if (cpus == NULL) { 119 pr_debug("failed to call cpu_map__new\n"); 120 return -1; 121 } 122 123 evsel->attr.disabled = 1; 124 125 err = perf_evsel__open_per_cpu(evsel, cpus); 126 if (err) { 127 if (err == -EACCES) 128 return TEST_SKIP; 129 130 pr_debug("Failed to open event cpu-clock:u\n"); 131 return err; 132 } 133 134 cpu_map__put(cpus); 135 return perf_evsel__enable(evsel); 136} 137 138static int attach__cpu_enabled(struct perf_evlist *evlist) 139{ 140 struct perf_evsel *evsel = perf_evlist__last(evlist); 141 struct cpu_map *cpus; 142 int err; 143 144 pr_debug("attaching to CPU 0 as enabled\n"); 145 146 cpus = cpu_map__new("0"); 147 if (cpus == NULL) { 148 pr_debug("failed to call cpu_map__new\n"); 149 return -1; 150 } 151 152 err = perf_evsel__open_per_cpu(evsel, cpus); 153 if (err == -EACCES) 154 return TEST_SKIP; 155 156 cpu_map__put(cpus); 157 return err ? TEST_FAIL : TEST_OK; 158} 159 160static int test_times(int (attach)(struct perf_evlist *), 161 int (detach)(struct perf_evlist *)) 162{ 163 struct perf_counts_values count; 164 struct perf_evlist *evlist = NULL; 165 struct perf_evsel *evsel; 166 int err = -1, i; 167 168 evlist = perf_evlist__new(); 169 if (!evlist) { 170 pr_debug("failed to create event list\n"); 171 goto out_err; 172 } 173 174 err = parse_events(evlist, "cpu-clock:u", NULL); 175 if (err) { 176 pr_debug("failed to parse event cpu-clock:u\n"); 177 goto out_err; 178 } 179 180 evsel = perf_evlist__last(evlist); 181 evsel->attr.read_format |= 182 PERF_FORMAT_TOTAL_TIME_ENABLED | 183 PERF_FORMAT_TOTAL_TIME_RUNNING; 184 185 err = attach(evlist); 186 if (err == TEST_SKIP) { 187 pr_debug(" SKIP : not enough rights\n"); 188 return err; 189 } 190 191 TEST_ASSERT_VAL("failed to attach", !err); 192 193 for (i = 0; i < 100000000; i++) { } 194 195 TEST_ASSERT_VAL("failed to detach", !detach(evlist)); 196 197 perf_evsel__read(evsel, 0, 0, &count); 198 199 err = !(count.ena == count.run); 200 201 pr_debug(" %s: ena %" PRIu64", run %" PRIu64"\n", 202 !err ? "OK " : "FAILED", 203 count.ena, count.run); 204 205out_err: 206 perf_evlist__delete(evlist); 207 return !err ? TEST_OK : TEST_FAIL; 208} 209 210/* 211 * This test creates software event 'cpu-clock' 212 * attaches it in several ways (explained below) 213 * and checks that enabled and running times 214 * match. 215 */ 216int test__event_times(int subtest __maybe_unused) 217{ 218 int err, ret = 0; 219 220#define _T(attach, detach) \ 221 err = test_times(attach, detach); \ 222 if (err && (ret == TEST_OK || ret == TEST_SKIP)) \ 223 ret = err; 224 225 /* attach on newly spawned process after exec */ 226 _T(attach__enable_on_exec, detach__enable_on_exec) 227 /* attach on current process as enabled */ 228 _T(attach__current_enabled, detach__disable) 229 /* attach on current process as disabled */ 230 _T(attach__current_disabled, detach__disable) 231 /* attach on cpu as disabled */ 232 _T(attach__cpu_disabled, detach__disable) 233 /* attach on cpu as enabled */ 234 _T(attach__cpu_enabled, detach__disable) 235 236#undef _T 237 return ret; 238}