Mi calibrate command: support and validation
[lttng-tools.git] / src / bin / lttng / commands / add_context.c
CommitLineData
d65106b1
DG
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
d14d33bf
AM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
d65106b1
DG
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
d14d33bf
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
d65106b1
DG
16 */
17
18#define _GNU_SOURCE
90b9a268 19#include <ctype.h>
d65106b1
DG
20#include <popt.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26#include <unistd.h>
27
3301e740
DG
28#include <urcu/list.h>
29
c399183f 30#include "../command.h"
d65106b1 31
b13d56d7
MD
32#define PRINT_LINE_LEN 80
33
d65106b1 34static char *opt_channel_name;
5440dc42 35static char *opt_session_name;
55cc08a6 36static int opt_kernel;
d65106b1 37static int opt_userspace;
d78d6610
DG
38static char *opt_type;
39#if 0
40/* Not implemented yet */
eeac7d46 41static char *opt_cmd_name;
d65106b1 42static pid_t opt_pid;
d78d6610 43#endif
d65106b1
DG
44
45enum {
46 OPT_HELP = 1,
47 OPT_TYPE,
eeac7d46 48 OPT_USERSPACE,
679b4943 49 OPT_LIST_OPTIONS,
d65106b1
DG
50};
51
cd80958d
DG
52static struct lttng_handle *handle;
53
90b9a268
DG
54/*
55 * Taken from the LTTng ABI
56 */
57enum context_type {
58 CONTEXT_PID = 0,
aa3514e9 59 CONTEXT_PERF_COUNTER = 1, /* Backward compat. */
95da1297 60 CONTEXT_PROCNAME = 2,
90b9a268
DG
61 CONTEXT_PRIO = 3,
62 CONTEXT_NICE = 4,
63 CONTEXT_VPID = 5,
64 CONTEXT_TID = 6,
65 CONTEXT_VTID = 7,
66 CONTEXT_PPID = 8,
67 CONTEXT_VPPID = 9,
9197c5c4 68 CONTEXT_PTHREAD_ID = 10,
54773d68 69 CONTEXT_HOSTNAME = 11,
7c612c2e 70 CONTEXT_IP = 12,
aa3514e9
MD
71 CONTEXT_PERF_CPU_COUNTER = 13,
72 CONTEXT_PERF_THREAD_COUNTER = 14,
3301e740
DG
73};
74
90b9a268
DG
75/*
76 * Taken from the Perf ABI (all enum perf_*)
77 */
78enum perf_type {
79 PERF_TYPE_HARDWARE = 0,
80 PERF_TYPE_SOFTWARE = 1,
b13d56d7 81 PERF_TYPE_HW_CACHE = 3,
3301e740
DG
82};
83
90b9a268 84enum perf_count_hard {
b13d56d7
MD
85 PERF_COUNT_HW_CPU_CYCLES = 0,
86 PERF_COUNT_HW_INSTRUCTIONS = 1,
87 PERF_COUNT_HW_CACHE_REFERENCES = 2,
88 PERF_COUNT_HW_CACHE_MISSES = 3,
89 PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
90 PERF_COUNT_HW_BRANCH_MISSES = 5,
91 PERF_COUNT_HW_BUS_CYCLES = 6,
92 PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7,
93 PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,
90b9a268
DG
94};
95
96enum perf_count_soft {
97 PERF_COUNT_SW_CPU_CLOCK = 0,
98 PERF_COUNT_SW_TASK_CLOCK = 1,
99 PERF_COUNT_SW_PAGE_FAULTS = 2,
100 PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
101 PERF_COUNT_SW_CPU_MIGRATIONS = 4,
102 PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
103 PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
104 PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
105 PERF_COUNT_SW_EMULATION_FAULTS = 8,
3301e740
DG
106};
107
b13d56d7
MD
108/*
109 * Generalized hardware cache events:
110 *
111 * { L1-D, L1-I, LLC, ITLB, DTLB, BPU } x
112 * { read, write, prefetch } x
113 * { accesses, misses }
114 */
115enum perf_hw_cache_id {
116 PERF_COUNT_HW_CACHE_L1D = 0,
117 PERF_COUNT_HW_CACHE_L1I = 1,
118 PERF_COUNT_HW_CACHE_LL = 2,
119 PERF_COUNT_HW_CACHE_DTLB = 3,
120 PERF_COUNT_HW_CACHE_ITLB = 4,
121 PERF_COUNT_HW_CACHE_BPU = 5,
122
123 PERF_COUNT_HW_CACHE_MAX, /* non-ABI */
124};
125
126enum perf_hw_cache_op_id {
127 PERF_COUNT_HW_CACHE_OP_READ = 0,
128 PERF_COUNT_HW_CACHE_OP_WRITE = 1,
129 PERF_COUNT_HW_CACHE_OP_PREFETCH = 2,
130
131 PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */
132};
133
134enum perf_hw_cache_op_result_id {
135 PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0,
136 PERF_COUNT_HW_CACHE_RESULT_MISS = 1,
137
138 PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */
139};
140
d65106b1
DG
141static struct poptOption long_options[] = {
142 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
143 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
5440dc42 144 {"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
d65106b1 145 {"channel", 'c', POPT_ARG_STRING, &opt_channel_name, 0, 0, 0},
d65106b1 146 {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
d78d6610 147 {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
6caa2bcc 148 {"type", 't', POPT_ARG_STRING, &opt_type, OPT_TYPE, 0, 0},
679b4943 149 {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
d65106b1
DG
150 {0, 0, 0, 0, 0, 0, 0}
151};
152
90b9a268 153/*
b13d56d7 154 * Context options
90b9a268 155 */
aa3514e9 156#define PERF_HW(optstr, name, type, hide) \
b13d56d7 157 { \
aa3514e9 158 optstr, type, hide, \
b13d56d7
MD
159 .u.perf = { PERF_TYPE_HARDWARE, PERF_COUNT_HW_##name, },\
160 }
90b9a268 161
aa3514e9 162#define PERF_SW(optstr, name, type, hide) \
b13d56d7 163 { \
aa3514e9 164 optstr, type, hide, \
b13d56d7
MD
165 .u.perf = { PERF_TYPE_SOFTWARE, PERF_COUNT_SW_##name, },\
166 }
90b9a268 167
aa3514e9 168#define _PERF_HW_CACHE(optstr, name, type, op, result, hide) \
b13d56d7 169 { \
aa3514e9 170 optstr, type, hide, \
b13d56d7
MD
171 .u.perf = { \
172 PERF_TYPE_HW_CACHE, \
173 (uint64_t) PERF_COUNT_HW_CACHE_##name \
18829107
MD
174 | ((uint64_t) PERF_COUNT_HW_CACHE_OP_##op << 8) \
175 | ((uint64_t) PERF_COUNT_HW_CACHE_RESULT_##result << 16), \
b13d56d7
MD
176 }, \
177 }
178
aa3514e9
MD
179#define PERF_HW_CACHE(optstr, name, type, hide) \
180 _PERF_HW_CACHE(optstr "-loads", name, type, \
181 READ, ACCESS, hide), \
182 _PERF_HW_CACHE(optstr "-load-misses", name, type, \
183 READ, MISS, hide), \
184 _PERF_HW_CACHE(optstr "-stores", name, type, \
185 WRITE, ACCESS, hide), \
186 _PERF_HW_CACHE(optstr "-store-misses", name, type, \
187 WRITE, MISS, hide), \
188 _PERF_HW_CACHE(optstr "-prefetches", name, type, \
189 PREFETCH, ACCESS, hide), \
190 _PERF_HW_CACHE(optstr "-prefetch-misses", name, type, \
191 PREFETCH, MISS, hide)
b13d56d7
MD
192
193static
194const struct ctx_opts {
90b9a268 195 char *symbol;
b13d56d7 196 enum context_type ctx_type;
aa3514e9 197 int hide_help; /* Hide from --help */
b13d56d7
MD
198 union {
199 struct {
200 uint32_t type;
201 uint64_t config;
202 } perf;
203 } u;
204} ctx_opts[] = {
205 { "pid", CONTEXT_PID },
95da1297 206 { "procname", CONTEXT_PROCNAME },
b13d56d7
MD
207 { "prio", CONTEXT_PRIO },
208 { "nice", CONTEXT_NICE },
209 { "vpid", CONTEXT_VPID },
210 { "tid", CONTEXT_TID },
9197c5c4 211 { "pthread_id", CONTEXT_PTHREAD_ID },
b13d56d7
MD
212 { "vtid", CONTEXT_VTID },
213 { "ppid", CONTEXT_PPID },
214 { "vppid", CONTEXT_VPPID },
54773d68 215 { "hostname", CONTEXT_HOSTNAME },
7c612c2e 216 { "ip", CONTEXT_IP },
aa3514e9 217
b13d56d7 218 /* Perf options */
aa3514e9
MD
219
220 /* Perf per-CPU counters */
221 PERF_HW("perf:cpu:cpu-cycles", CPU_CYCLES,
222 CONTEXT_PERF_CPU_COUNTER, 0),
223 PERF_HW("perf:cpu:cycles", CPU_CYCLES,
224 CONTEXT_PERF_CPU_COUNTER, 0),
225 PERF_HW("perf:cpu:stalled-cycles-frontend", STALLED_CYCLES_FRONTEND,
226 CONTEXT_PERF_CPU_COUNTER, 0),
227 PERF_HW("perf:cpu:idle-cycles-frontend", STALLED_CYCLES_FRONTEND,
228 CONTEXT_PERF_CPU_COUNTER, 0),
229 PERF_HW("perf:cpu:stalled-cycles-backend", STALLED_CYCLES_BACKEND,
230 CONTEXT_PERF_CPU_COUNTER, 0),
231 PERF_HW("perf:cpu:idle-cycles-backend", STALLED_CYCLES_BACKEND,
232 CONTEXT_PERF_CPU_COUNTER, 0),
233 PERF_HW("perf:cpu:instructions", INSTRUCTIONS,
234 CONTEXT_PERF_CPU_COUNTER, 0),
235 PERF_HW("perf:cpu:cache-references", CACHE_REFERENCES,
236 CONTEXT_PERF_CPU_COUNTER, 0),
237 PERF_HW("perf:cpu:cache-misses", CACHE_MISSES,
238 CONTEXT_PERF_CPU_COUNTER, 0),
239 PERF_HW("perf:cpu:branch-instructions", BRANCH_INSTRUCTIONS,
240 CONTEXT_PERF_CPU_COUNTER, 0),
241 PERF_HW("perf:cpu:branches", BRANCH_INSTRUCTIONS,
242 CONTEXT_PERF_CPU_COUNTER, 0),
243 PERF_HW("perf:cpu:branch-misses", BRANCH_MISSES,
244 CONTEXT_PERF_CPU_COUNTER, 0),
245 PERF_HW("perf:cpu:bus-cycles", BUS_CYCLES,
246 CONTEXT_PERF_CPU_COUNTER, 0),
247
248 PERF_HW_CACHE("perf:cpu:L1-dcache", L1D,
249 CONTEXT_PERF_CPU_COUNTER, 0),
250 PERF_HW_CACHE("perf:cpu:L1-icache", L1I,
251 CONTEXT_PERF_CPU_COUNTER, 0),
252 PERF_HW_CACHE("perf:cpu:LLC", LL,
253 CONTEXT_PERF_CPU_COUNTER, 0),
254 PERF_HW_CACHE("perf:cpu:dTLB", DTLB,
255 CONTEXT_PERF_CPU_COUNTER, 0),
256 _PERF_HW_CACHE("perf:cpu:iTLB-loads", ITLB,
257 CONTEXT_PERF_CPU_COUNTER, READ, ACCESS, 0),
258 _PERF_HW_CACHE("perf:cpu:iTLB-load-misses", ITLB,
259 CONTEXT_PERF_CPU_COUNTER, READ, MISS, 0),
260 _PERF_HW_CACHE("perf:cpu:branch-loads", BPU,
261 CONTEXT_PERF_CPU_COUNTER, READ, ACCESS, 0),
262 _PERF_HW_CACHE("perf:cpu:branch-load-misses", BPU,
263 CONTEXT_PERF_CPU_COUNTER, READ, MISS, 0),
264
265 PERF_SW("perf:cpu:cpu-clock", CPU_CLOCK,
266 CONTEXT_PERF_CPU_COUNTER, 0),
267 PERF_SW("perf:cpu:task-clock", TASK_CLOCK,
268 CONTEXT_PERF_CPU_COUNTER, 0),
269 PERF_SW("perf:cpu:page-fault", PAGE_FAULTS,
270 CONTEXT_PERF_CPU_COUNTER, 0),
271 PERF_SW("perf:cpu:faults", PAGE_FAULTS,
272 CONTEXT_PERF_CPU_COUNTER, 0),
273 PERF_SW("perf:cpu:major-faults", PAGE_FAULTS_MAJ,
274 CONTEXT_PERF_CPU_COUNTER, 0),
275 PERF_SW("perf:cpu:minor-faults", PAGE_FAULTS_MIN,
276 CONTEXT_PERF_CPU_COUNTER, 0),
277 PERF_SW("perf:cpu:context-switches", CONTEXT_SWITCHES,
278 CONTEXT_PERF_CPU_COUNTER, 0),
279 PERF_SW("perf:cpu:cs", CONTEXT_SWITCHES,
280 CONTEXT_PERF_CPU_COUNTER, 0),
281 PERF_SW("perf:cpu:cpu-migrations", CPU_MIGRATIONS,
282 CONTEXT_PERF_CPU_COUNTER, 0),
283 PERF_SW("perf:cpu:migrations", CPU_MIGRATIONS,
284 CONTEXT_PERF_CPU_COUNTER, 0),
285 PERF_SW("perf:cpu:alignment-faults", ALIGNMENT_FAULTS,
286 CONTEXT_PERF_CPU_COUNTER, 0),
287 PERF_SW("perf:cpu:emulation-faults", EMULATION_FAULTS,
288 CONTEXT_PERF_CPU_COUNTER, 0),
289
290 /* Perf per-thread counters */
291 PERF_HW("perf:thread:cpu-cycles", CPU_CYCLES,
292 CONTEXT_PERF_THREAD_COUNTER, 0),
293 PERF_HW("perf:thread:cycles", CPU_CYCLES,
294 CONTEXT_PERF_THREAD_COUNTER, 0),
295 PERF_HW("perf:thread:stalled-cycles-frontend", STALLED_CYCLES_FRONTEND,
296 CONTEXT_PERF_THREAD_COUNTER, 0),
297 PERF_HW("perf:thread:idle-cycles-frontend", STALLED_CYCLES_FRONTEND,
298 CONTEXT_PERF_THREAD_COUNTER, 0),
299 PERF_HW("perf:thread:stalled-cycles-backend", STALLED_CYCLES_BACKEND,
300 CONTEXT_PERF_THREAD_COUNTER, 0),
301 PERF_HW("perf:thread:idle-cycles-backend", STALLED_CYCLES_BACKEND,
302 CONTEXT_PERF_THREAD_COUNTER, 0),
303 PERF_HW("perf:thread:instructions", INSTRUCTIONS,
304 CONTEXT_PERF_THREAD_COUNTER, 0),
305 PERF_HW("perf:thread:cache-references", CACHE_REFERENCES,
306 CONTEXT_PERF_THREAD_COUNTER, 0),
307 PERF_HW("perf:thread:cache-misses", CACHE_MISSES,
308 CONTEXT_PERF_THREAD_COUNTER, 0),
309 PERF_HW("perf:thread:branch-instructions", BRANCH_INSTRUCTIONS,
310 CONTEXT_PERF_THREAD_COUNTER, 0),
311 PERF_HW("perf:thread:branches", BRANCH_INSTRUCTIONS,
312 CONTEXT_PERF_THREAD_COUNTER, 0),
313 PERF_HW("perf:thread:branch-misses", BRANCH_MISSES,
314 CONTEXT_PERF_THREAD_COUNTER, 0),
315 PERF_HW("perf:thread:bus-cycles", BUS_CYCLES,
316 CONTEXT_PERF_THREAD_COUNTER, 0),
317
318 PERF_HW_CACHE("perf:thread:L1-dcache", L1D,
319 CONTEXT_PERF_THREAD_COUNTER, 0),
320 PERF_HW_CACHE("perf:thread:L1-icache", L1I,
321 CONTEXT_PERF_THREAD_COUNTER, 0),
322 PERF_HW_CACHE("perf:thread:LLC", LL,
323 CONTEXT_PERF_THREAD_COUNTER, 0),
324 PERF_HW_CACHE("perf:thread:dTLB", DTLB,
325 CONTEXT_PERF_THREAD_COUNTER, 0),
326 _PERF_HW_CACHE("perf:thread:iTLB-loads", ITLB,
327 CONTEXT_PERF_THREAD_COUNTER, READ, ACCESS, 0),
328 _PERF_HW_CACHE("perf:thread:iTLB-load-misses", ITLB,
329 CONTEXT_PERF_THREAD_COUNTER, READ, MISS, 0),
330 _PERF_HW_CACHE("perf:thread:branch-loads", BPU,
331 CONTEXT_PERF_THREAD_COUNTER, READ, ACCESS, 0),
332 _PERF_HW_CACHE("perf:thread:branch-load-misses", BPU,
333 CONTEXT_PERF_THREAD_COUNTER, READ, MISS, 0),
334
335 PERF_SW("perf:thread:cpu-clock", CPU_CLOCK,
336 CONTEXT_PERF_THREAD_COUNTER, 0),
337 PERF_SW("perf:thread:task-clock", TASK_CLOCK,
338 CONTEXT_PERF_THREAD_COUNTER, 0),
339 PERF_SW("perf:thread:page-fault", PAGE_FAULTS,
340 CONTEXT_PERF_THREAD_COUNTER, 0),
341 PERF_SW("perf:thread:faults", PAGE_FAULTS,
342 CONTEXT_PERF_THREAD_COUNTER, 0),
343 PERF_SW("perf:thread:major-faults", PAGE_FAULTS_MAJ,
344 CONTEXT_PERF_THREAD_COUNTER, 0),
345 PERF_SW("perf:thread:minor-faults", PAGE_FAULTS_MIN,
346 CONTEXT_PERF_THREAD_COUNTER, 0),
347 PERF_SW("perf:thread:context-switches", CONTEXT_SWITCHES,
348 CONTEXT_PERF_THREAD_COUNTER, 0),
349 PERF_SW("perf:thread:cs", CONTEXT_SWITCHES,
350 CONTEXT_PERF_THREAD_COUNTER, 0),
351 PERF_SW("perf:thread:cpu-migrations", CPU_MIGRATIONS,
352 CONTEXT_PERF_THREAD_COUNTER, 0),
353 PERF_SW("perf:thread:migrations", CPU_MIGRATIONS,
354 CONTEXT_PERF_THREAD_COUNTER, 0),
355 PERF_SW("perf:thread:alignment-faults", ALIGNMENT_FAULTS,
356 CONTEXT_PERF_THREAD_COUNTER, 0),
357 PERF_SW("perf:thread:emulation-faults", EMULATION_FAULTS,
358 CONTEXT_PERF_THREAD_COUNTER, 0),
359
360 /*
361 * Perf per-CPU counters, backward compatibilty for names.
362 * Hidden from help listing.
363 */
364 PERF_HW("perf:cpu-cycles", CPU_CYCLES,
365 CONTEXT_PERF_COUNTER, 1),
366 PERF_HW("perf:cycles", CPU_CYCLES,
367 CONTEXT_PERF_COUNTER, 1),
368 PERF_HW("perf:stalled-cycles-frontend", STALLED_CYCLES_FRONTEND,
369 CONTEXT_PERF_COUNTER, 1),
370 PERF_HW("perf:idle-cycles-frontend", STALLED_CYCLES_FRONTEND,
371 CONTEXT_PERF_COUNTER, 1),
372 PERF_HW("perf:stalled-cycles-backend", STALLED_CYCLES_BACKEND,
373 CONTEXT_PERF_COUNTER, 1),
374 PERF_HW("perf:idle-cycles-backend", STALLED_CYCLES_BACKEND,
375 CONTEXT_PERF_COUNTER, 1),
376 PERF_HW("perf:instructions", INSTRUCTIONS,
377 CONTEXT_PERF_COUNTER, 1),
378 PERF_HW("perf:cache-references", CACHE_REFERENCES,
379 CONTEXT_PERF_COUNTER, 1),
380 PERF_HW("perf:cache-misses", CACHE_MISSES,
381 CONTEXT_PERF_COUNTER, 1),
382 PERF_HW("perf:branch-instructions", BRANCH_INSTRUCTIONS,
383 CONTEXT_PERF_COUNTER, 1),
384 PERF_HW("perf:branches", BRANCH_INSTRUCTIONS,
385 CONTEXT_PERF_COUNTER, 1),
386 PERF_HW("perf:branch-misses", BRANCH_MISSES,
387 CONTEXT_PERF_COUNTER, 1),
388 PERF_HW("perf:bus-cycles", BUS_CYCLES,
389 CONTEXT_PERF_COUNTER, 1),
390
391 PERF_HW_CACHE("perf:L1-dcache", L1D,
392 CONTEXT_PERF_COUNTER, 1),
393 PERF_HW_CACHE("perf:L1-icache", L1I,
394 CONTEXT_PERF_COUNTER, 1),
395 PERF_HW_CACHE("perf:LLC", LL,
396 CONTEXT_PERF_COUNTER, 1),
397 PERF_HW_CACHE("perf:dTLB", DTLB,
398 CONTEXT_PERF_COUNTER, 1),
399 _PERF_HW_CACHE("perf:iTLB-loads", ITLB,
400 CONTEXT_PERF_COUNTER, READ, ACCESS, 1),
401 _PERF_HW_CACHE("perf:iTLB-load-misses", ITLB,
402 CONTEXT_PERF_COUNTER, READ, MISS, 1),
403 _PERF_HW_CACHE("perf:branch-loads", BPU,
404 CONTEXT_PERF_COUNTER, READ, ACCESS, 1),
405 _PERF_HW_CACHE("perf:branch-load-misses", BPU,
406 CONTEXT_PERF_COUNTER, READ, MISS, 1),
407
408 PERF_SW("perf:cpu-clock", CPU_CLOCK,
409 CONTEXT_PERF_COUNTER, 1),
410 PERF_SW("perf:task-clock", TASK_CLOCK,
411 CONTEXT_PERF_COUNTER, 1),
412 PERF_SW("perf:page-fault", PAGE_FAULTS,
413 CONTEXT_PERF_COUNTER, 1),
414 PERF_SW("perf:faults", PAGE_FAULTS,
415 CONTEXT_PERF_COUNTER, 1),
416 PERF_SW("perf:major-faults", PAGE_FAULTS_MAJ,
417 CONTEXT_PERF_COUNTER, 1),
418 PERF_SW("perf:minor-faults", PAGE_FAULTS_MIN,
419 CONTEXT_PERF_COUNTER, 1),
420 PERF_SW("perf:context-switches", CONTEXT_SWITCHES,
421 CONTEXT_PERF_COUNTER, 1),
422 PERF_SW("perf:cs", CONTEXT_SWITCHES,
423 CONTEXT_PERF_COUNTER, 1),
424 PERF_SW("perf:cpu-migrations", CPU_MIGRATIONS,
425 CONTEXT_PERF_COUNTER, 1),
426 PERF_SW("perf:migrations", CPU_MIGRATIONS,
427 CONTEXT_PERF_COUNTER, 1),
428 PERF_SW("perf:alignment-faults", ALIGNMENT_FAULTS,
429 CONTEXT_PERF_COUNTER, 1),
430 PERF_SW("perf:emulation-faults", EMULATION_FAULTS,
431 CONTEXT_PERF_COUNTER, 1),
432
b13d56d7 433 { NULL, -1 }, /* Closure */
90b9a268
DG
434};
435
aa3514e9
MD
436#undef PERF_HW_CACHE
437#undef _PERF_HW_CACHE
b13d56d7
MD
438#undef PERF_SW
439#undef PERF_HW
440
90b9a268 441/*
b13d56d7 442 * Context type for command line option parsing.
90b9a268 443 */
b13d56d7
MD
444struct ctx_type {
445 const struct ctx_opts *opt;
446 struct cds_list_head list;
90b9a268
DG
447};
448
449/*
450 * List of context type. Use to enable multiple context on a single command
451 * line entry.
452 */
453struct ctx_type_list {
454 struct cds_list_head head;
455} ctx_type_list = {
456 .head = CDS_LIST_HEAD_INIT(ctx_type_list.head),
457};
458
90b9a268
DG
459/*
460 * Pretty print context type.
461 */
462static void print_ctx_type(FILE *ofp)
463{
b13d56d7
MD
464 const char *indent = " ";
465 int indent_len = strlen(indent);
466 int len, i = 0;
90b9a268 467
76e3c5dd 468 fprintf(ofp, "%s", indent);
b13d56d7 469 len = indent_len;
90b9a268 470 while (ctx_opts[i].symbol != NULL) {
aa3514e9
MD
471 if (!ctx_opts[i].hide_help) {
472 if (len > indent_len) {
473 if (len + strlen(ctx_opts[i].symbol) + 2
474 >= PRINT_LINE_LEN) {
475 fprintf(ofp, ",\n");
476 fprintf(ofp, "%s", indent);
477 len = indent_len;
478 } else {
479 len += fprintf(ofp, ", ");
480 }
90b9a268 481 }
aa3514e9 482 len += fprintf(ofp, "%s", ctx_opts[i].symbol);
90b9a268
DG
483 }
484 i++;
485 }
90b9a268
DG
486}
487
d65106b1
DG
488/*
489 * usage
490 */
491static void usage(FILE *ofp)
492{
32a6298d 493 fprintf(ofp, "usage: lttng add-context -t TYPE [-k|-u] [OPTIONS]\n");
d65106b1 494 fprintf(ofp, "\n");
601d5acf
DG
495 fprintf(ofp, "If no channel is given (-c), the context is added to\n");
496 fprintf(ofp, "all channels.\n");
32a6298d 497 fprintf(ofp, "\n");
601d5acf 498 fprintf(ofp, "Otherwise the context is added only to the channel (-c).\n");
32a6298d
DG
499 fprintf(ofp, "\n");
500 fprintf(ofp, "Exactly one domain (-k or -u) must be specified.\n");
3301e740 501 fprintf(ofp, "\n");
d65106b1
DG
502 fprintf(ofp, "Options:\n");
503 fprintf(ofp, " -h, --help Show this help\n");
679b4943 504 fprintf(ofp, " --list-options Simple listing of options\n");
5eb00805
TD
505 fprintf(ofp, " -s, --session NAME Apply to session name\n");
506 fprintf(ofp, " -c, --channel NAME Apply to channel\n");
af87c45a 507 fprintf(ofp, " -k, --kernel Apply to the kernel tracer\n");
af87c45a 508 fprintf(ofp, " -u, --userspace Apply to the user-space tracer\n");
32a6298d
DG
509 fprintf(ofp, "\n");
510 fprintf(ofp, "Context:\n");
b13d56d7 511 fprintf(ofp, " -t, --type TYPE Context type. You can repeat that option on\n");
af87c45a
DG
512 fprintf(ofp, " the command line to specify multiple contexts at once.\n");
513 fprintf(ofp, " (--kernel preempts --userspace)\n");
b13d56d7 514 fprintf(ofp, " TYPE can be one of the strings below:\n");
90b9a268 515 print_ctx_type(ofp);
d65106b1 516 fprintf(ofp, "\n");
c455d428
FD
517 fprintf(ofp, "Note that the vpid, vppid and vtid context types represent the virtual process id,\n"
518 "virtual parent process id and virtual thread id as seen from the current execution context\n"
519 "as opposed to the pid, ppid and tid which are kernel internal data structures.\n\n");
90b9a268 520 fprintf(ofp, "Example:\n");
aa3514e9
MD
521 fprintf(ofp, "This command will add the context information 'prio' and two per-cpu\n"
522 "perf counters (hardware branch misses and cache misses), to all channels\n"
b13d56d7 523 "in the trace data output:\n");
aa3514e9 524 fprintf(ofp, "# lttng add-context -k -t prio -t perf:cpu:branch-misses -t perf:cpu:cache-misses\n");
d65106b1
DG
525 fprintf(ofp, "\n");
526}
527
90b9a268
DG
528/*
529 * Find context numerical value from string.
530 */
531static int find_ctx_type_idx(const char *opt)
532{
533 int ret = -1, i = 0;
534
535 while (ctx_opts[i].symbol != NULL) {
536 if (strcmp(opt, ctx_opts[i].symbol) == 0) {
537 ret = i;
538 goto end;
539 }
540 i++;
541 }
542
543end:
544 return ret;
545}
546
90b9a268
DG
547/*
548 * Add context to channel or event.
d65106b1 549 */
cd80958d 550static int add_context(char *session_name)
d65106b1 551{
d16c1a4c 552 int ret = CMD_SUCCESS, warn = 0;
7d29a247
DG
553 struct lttng_event_context context;
554 struct lttng_domain dom;
3301e740 555 struct ctx_type *type;
b13d56d7 556 char *ptr;
d65106b1 557
441c16a7
MD
558 memset(&context, 0, sizeof(context));
559 memset(&dom, 0, sizeof(dom));
560
cd80958d
DG
561 if (opt_kernel) {
562 dom.type = LTTNG_DOMAIN_KERNEL;
d78d6610 563 } else if (opt_userspace) {
55cc08a6 564 dom.type = LTTNG_DOMAIN_UST;
55cc08a6 565 } else {
b9dfb167 566 print_missing_domain();
d16c1a4c 567 ret = CMD_ERROR;
55cc08a6 568 goto error;
cd80958d
DG
569 }
570
571 handle = lttng_create_handle(session_name, &dom);
572 if (handle == NULL) {
af87c45a 573 ret = CMD_ERROR;
cd80958d
DG
574 goto error;
575 }
576
5eb00805 577 /* Iterate over all the context types given */
3301e740 578 cds_list_for_each_entry(type, &ctx_type_list.head, list) {
6775595e 579 context.ctx = (enum lttng_event_context_type) type->opt->ctx_type;
aa3514e9
MD
580 switch (context.ctx) {
581 case LTTNG_EVENT_CONTEXT_PERF_COUNTER:
582 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER:
583 case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
b13d56d7
MD
584 context.u.perf_counter.type = type->opt->u.perf.type;
585 context.u.perf_counter.config = type->opt->u.perf.config;
24546386
MD
586 strncpy(context.u.perf_counter.name, type->opt->symbol,
587 LTTNG_SYMBOL_NAME_LEN);
588 context.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
b13d56d7
MD
589 /* Replace : and - by _ */
590 while ((ptr = strchr(context.u.perf_counter.name, '-')) != NULL) {
591 *ptr = '_';
3301e740 592 }
b13d56d7
MD
593 while ((ptr = strchr(context.u.perf_counter.name, ':')) != NULL) {
594 *ptr = '_';
3301e740 595 }
aa3514e9
MD
596 break;
597 default:
598 break;
3301e740 599 }
55cc08a6
DG
600 DBG("Adding context...");
601
601d5acf 602 ret = lttng_add_context(handle, &context, NULL, opt_channel_name);
55cc08a6 603 if (ret < 0) {
b58471ff 604 ERR("%s: %s", type->opt->symbol, lttng_strerror(ret));
d16c1a4c 605 warn = 1;
55cc08a6 606 continue;
d65106b1 607 } else {
601d5acf 608 if (opt_channel_name) {
b58471ff
DG
609 MSG("%s context %s added to channel %s",
610 opt_kernel ? "kernel" : "UST", type->opt->symbol,
611 opt_channel_name);
b58471ff
DG
612 } else {
613 MSG("%s context %s added to all channels",
614 opt_kernel ? "kernel" : "UST", type->opt->symbol)
615 }
d65106b1 616 }
d65106b1
DG
617 }
618
af87c45a
DG
619 ret = CMD_SUCCESS;
620
d65106b1 621error:
cd80958d
DG
622 lttng_destroy_handle(handle);
623
d16c1a4c
DG
624 /*
625 * This means that at least one add_context failed and tells the user to
626 * look on stderr for error(s).
627 */
628 if (warn) {
629 ret = CMD_WARNING;
630 }
d65106b1
DG
631 return ret;
632}
633
634/*
5eb00805 635 * Add context to channel or event.
d65106b1
DG
636 */
637int cmd_add_context(int argc, const char **argv)
638{
90b9a268 639 int index, opt, ret = CMD_SUCCESS;
d65106b1 640 static poptContext pc;
b13d56d7 641 struct ctx_type *type, *tmptype;
cd80958d 642 char *session_name = NULL;
d65106b1 643
636167b6
DG
644 if (argc < 2) {
645 usage(stderr);
5eb00805 646 ret = CMD_ERROR;
636167b6
DG
647 goto end;
648 }
649
c7e35b03
JR
650 /* TODO: mi support */
651 if (lttng_opt_mi) {
652 ret = -LTTNG_ERR_MI_NOT_IMPLEMENTED;
653 ERR("mi option not supported");
654 goto end;
655 }
656
d65106b1
DG
657 pc = poptGetContext(NULL, argc, argv, long_options, 0);
658 poptReadDefaultConfig(pc, 0);
659
660 while ((opt = poptGetNextOpt(pc)) != -1) {
661 switch (opt) {
662 case OPT_HELP:
5eb00805 663 usage(stdout);
d65106b1
DG
664 goto end;
665 case OPT_TYPE:
af87c45a
DG
666 /*
667 * Look up the index of opt_type in ctx_opts[] first, so we don't
668 * have to free(type) on failure.
669 */
6caa2bcc 670 index = find_ctx_type_idx(opt_type);
b13d56d7 671 if (index < 0) {
6caa2bcc 672 ERR("Unknown context type %s", opt_type);
5eb00805 673 ret = CMD_ERROR;
b13d56d7 674 goto end;
90b9a268 675 }
5eb00805
TD
676
677 type = malloc(sizeof(struct ctx_type));
678 if (type == NULL) {
679 perror("malloc ctx_type");
680 ret = CMD_FATAL;
681 goto end;
682 }
683
b13d56d7 684 type->opt = &ctx_opts[index];
109be0da 685 if (type->opt->symbol == NULL) {
6caa2bcc 686 ERR("Unknown context type %s", opt_type);
5eb00805
TD
687 free(type);
688 ret = CMD_ERROR;
689 goto end;
90b9a268 690 } else {
31746f93 691 cds_list_add_tail(&type->list, &ctx_type_list.head);
90b9a268 692 }
d65106b1 693 break;
eeac7d46
MD
694 case OPT_USERSPACE:
695 opt_userspace = 1;
d78d6610 696#if 0
eeac7d46 697 opt_cmd_name = poptGetOptArg(pc);
d78d6610 698#endif
eeac7d46 699 break;
679b4943
SM
700 case OPT_LIST_OPTIONS:
701 list_cmd_options(stdout, long_options);
679b4943 702 goto end;
d65106b1
DG
703 default:
704 usage(stderr);
705 ret = CMD_UNDEFINED;
706 goto end;
707 }
708 }
709
ae856491
DG
710 if (!opt_type) {
711 ERR("Missing mandatory -t TYPE");
712 usage(stderr);
713 ret = CMD_ERROR;
714 goto end;
715 }
716
cd80958d
DG
717 if (!opt_session_name) {
718 session_name = get_session_name();
719 if (session_name == NULL) {
5eb00805 720 ret = CMD_ERROR;
cd80958d
DG
721 goto end;
722 }
723 } else {
724 session_name = opt_session_name;
725 }
726
727 ret = add_context(session_name);
3301e740 728
1256f150
DT
729 if (!opt_session_name) {
730 free(session_name);
731 }
732
5eb00805 733end:
3301e740 734 /* Cleanup allocated memory */
b13d56d7 735 cds_list_for_each_entry_safe(type, tmptype, &ctx_type_list.head, list) {
3301e740
DG
736 free(type);
737 }
738
ca1c3607 739 poptFreeContext(pc);
d65106b1
DG
740 return ret;
741}
This page took 0.11328 seconds and 4 git commands to generate.