]> git.karo-electronics.de Git - karo-tx-linux.git/blob - tools/perf/util/util.c
perf tools: Move path related functions to util/path.h
[karo-tx-linux.git] / tools / perf / util / util.c
1 #include "../perf.h"
2 #include "util.h"
3 #include "debug.h"
4 #include <api/fs/fs.h>
5 #include <sys/mman.h>
6 #include <sys/utsname.h>
7 #ifdef HAVE_BACKTRACE_SUPPORT
8 #include <execinfo.h>
9 #endif
10 #include <inttypes.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <limits.h>
16 #include <byteswap.h>
17 #include <linux/kernel.h>
18 #include <linux/log2.h>
19 #include <linux/time64.h>
20 #include <unistd.h>
21 #include "callchain.h"
22 #include "strlist.h"
23
24 #define CALLCHAIN_PARAM_DEFAULT                 \
25         .mode           = CHAIN_GRAPH_ABS,      \
26         .min_percent    = 0.5,                  \
27         .order          = ORDER_CALLEE,         \
28         .key            = CCKEY_FUNCTION,       \
29         .value          = CCVAL_PERCENT,        \
30
31 struct callchain_param callchain_param = {
32         CALLCHAIN_PARAM_DEFAULT
33 };
34
35 struct callchain_param callchain_param_default = {
36         CALLCHAIN_PARAM_DEFAULT
37 };
38
39 /*
40  * XXX We need to find a better place for these things...
41  */
42 unsigned int page_size;
43 int cacheline_size;
44
45 int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH;
46 int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK;
47
48 bool test_attr__enabled;
49
50 bool perf_host  = true;
51 bool perf_guest = false;
52
53 void event_attr_init(struct perf_event_attr *attr)
54 {
55         if (!perf_host)
56                 attr->exclude_host  = 1;
57         if (!perf_guest)
58                 attr->exclude_guest = 1;
59         /* to capture ABI version */
60         attr->size = sizeof(*attr);
61 }
62
63 int mkdir_p(char *path, mode_t mode)
64 {
65         struct stat st;
66         int err;
67         char *d = path;
68
69         if (*d != '/')
70                 return -1;
71
72         if (stat(path, &st) == 0)
73                 return 0;
74
75         while (*++d == '/');
76
77         while ((d = strchr(d, '/'))) {
78                 *d = '\0';
79                 err = stat(path, &st) && mkdir(path, mode);
80                 *d++ = '/';
81                 if (err)
82                         return -1;
83                 while (*d == '/')
84                         ++d;
85         }
86         return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
87 }
88
89 int rm_rf(const char *path)
90 {
91         DIR *dir;
92         int ret = 0;
93         struct dirent *d;
94         char namebuf[PATH_MAX];
95
96         dir = opendir(path);
97         if (dir == NULL)
98                 return 0;
99
100         while ((d = readdir(dir)) != NULL && !ret) {
101                 struct stat statbuf;
102
103                 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
104                         continue;
105
106                 scnprintf(namebuf, sizeof(namebuf), "%s/%s",
107                           path, d->d_name);
108
109                 /* We have to check symbolic link itself */
110                 ret = lstat(namebuf, &statbuf);
111                 if (ret < 0) {
112                         pr_debug("stat failed: %s\n", namebuf);
113                         break;
114                 }
115
116                 if (S_ISDIR(statbuf.st_mode))
117                         ret = rm_rf(namebuf);
118                 else
119                         ret = unlink(namebuf);
120         }
121         closedir(dir);
122
123         if (ret < 0)
124                 return ret;
125
126         return rmdir(path);
127 }
128
129 /* A filter which removes dot files */
130 bool lsdir_no_dot_filter(const char *name __maybe_unused, struct dirent *d)
131 {
132         return d->d_name[0] != '.';
133 }
134
135 /* lsdir reads a directory and store it in strlist */
136 struct strlist *lsdir(const char *name,
137                       bool (*filter)(const char *, struct dirent *))
138 {
139         struct strlist *list = NULL;
140         DIR *dir;
141         struct dirent *d;
142
143         dir = opendir(name);
144         if (!dir)
145                 return NULL;
146
147         list = strlist__new(NULL, NULL);
148         if (!list) {
149                 errno = ENOMEM;
150                 goto out;
151         }
152
153         while ((d = readdir(dir)) != NULL) {
154                 if (!filter || filter(name, d))
155                         strlist__add(list, d->d_name);
156         }
157
158 out:
159         closedir(dir);
160         return list;
161 }
162
163 static int slow_copyfile(const char *from, const char *to)
164 {
165         int err = -1;
166         char *line = NULL;
167         size_t n;
168         FILE *from_fp = fopen(from, "r"), *to_fp;
169
170         if (from_fp == NULL)
171                 goto out;
172
173         to_fp = fopen(to, "w");
174         if (to_fp == NULL)
175                 goto out_fclose_from;
176
177         while (getline(&line, &n, from_fp) > 0)
178                 if (fputs(line, to_fp) == EOF)
179                         goto out_fclose_to;
180         err = 0;
181 out_fclose_to:
182         fclose(to_fp);
183         free(line);
184 out_fclose_from:
185         fclose(from_fp);
186 out:
187         return err;
188 }
189
190 int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size)
191 {
192         void *ptr;
193         loff_t pgoff;
194
195         pgoff = off_in & ~(page_size - 1);
196         off_in -= pgoff;
197
198         ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff);
199         if (ptr == MAP_FAILED)
200                 return -1;
201
202         while (size) {
203                 ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out);
204                 if (ret < 0 && errno == EINTR)
205                         continue;
206                 if (ret <= 0)
207                         break;
208
209                 size -= ret;
210                 off_in += ret;
211                 off_out -= ret;
212         }
213         munmap(ptr, off_in + size);
214
215         return size ? -1 : 0;
216 }
217
218 int copyfile_mode(const char *from, const char *to, mode_t mode)
219 {
220         int fromfd, tofd;
221         struct stat st;
222         int err = -1;
223         char *tmp = NULL, *ptr = NULL;
224
225         if (stat(from, &st))
226                 goto out;
227
228         /* extra 'x' at the end is to reserve space for '.' */
229         if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) {
230                 tmp = NULL;
231                 goto out;
232         }
233         ptr = strrchr(tmp, '/');
234         if (!ptr)
235                 goto out;
236         ptr = memmove(ptr + 1, ptr, strlen(ptr) - 1);
237         *ptr = '.';
238
239         tofd = mkstemp(tmp);
240         if (tofd < 0)
241                 goto out;
242
243         if (fchmod(tofd, mode))
244                 goto out_close_to;
245
246         if (st.st_size == 0) { /* /proc? do it slowly... */
247                 err = slow_copyfile(from, tmp);
248                 goto out_close_to;
249         }
250
251         fromfd = open(from, O_RDONLY);
252         if (fromfd < 0)
253                 goto out_close_to;
254
255         err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size);
256
257         close(fromfd);
258 out_close_to:
259         close(tofd);
260         if (!err)
261                 err = link(tmp, to);
262         unlink(tmp);
263 out:
264         free(tmp);
265         return err;
266 }
267
268 int copyfile(const char *from, const char *to)
269 {
270         return copyfile_mode(from, to, 0755);
271 }
272
273 unsigned long convert_unit(unsigned long value, char *unit)
274 {
275         *unit = ' ';
276
277         if (value > 1000) {
278                 value /= 1000;
279                 *unit = 'K';
280         }
281
282         if (value > 1000) {
283                 value /= 1000;
284                 *unit = 'M';
285         }
286
287         if (value > 1000) {
288                 value /= 1000;
289                 *unit = 'G';
290         }
291
292         return value;
293 }
294
295 static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
296 {
297         void *buf_start = buf;
298         size_t left = n;
299
300         while (left) {
301                 ssize_t ret = is_read ? read(fd, buf, left) :
302                                         write(fd, buf, left);
303
304                 if (ret < 0 && errno == EINTR)
305                         continue;
306                 if (ret <= 0)
307                         return ret;
308
309                 left -= ret;
310                 buf  += ret;
311         }
312
313         BUG_ON((size_t)(buf - buf_start) != n);
314         return n;
315 }
316
317 /*
318  * Read exactly 'n' bytes or return an error.
319  */
320 ssize_t readn(int fd, void *buf, size_t n)
321 {
322         return ion(true, fd, buf, n);
323 }
324
325 /*
326  * Write exactly 'n' bytes or return an error.
327  */
328 ssize_t writen(int fd, void *buf, size_t n)
329 {
330         return ion(false, fd, buf, n);
331 }
332
333 size_t hex_width(u64 v)
334 {
335         size_t n = 1;
336
337         while ((v >>= 4))
338                 ++n;
339
340         return n;
341 }
342
343 static int hex(char ch)
344 {
345         if ((ch >= '0') && (ch <= '9'))
346                 return ch - '0';
347         if ((ch >= 'a') && (ch <= 'f'))
348                 return ch - 'a' + 10;
349         if ((ch >= 'A') && (ch <= 'F'))
350                 return ch - 'A' + 10;
351         return -1;
352 }
353
354 /*
355  * While we find nice hex chars, build a long_val.
356  * Return number of chars processed.
357  */
358 int hex2u64(const char *ptr, u64 *long_val)
359 {
360         const char *p = ptr;
361         *long_val = 0;
362
363         while (*p) {
364                 const int hex_val = hex(*p);
365
366                 if (hex_val < 0)
367                         break;
368
369                 *long_val = (*long_val << 4) | hex_val;
370                 p++;
371         }
372
373         return p - ptr;
374 }
375
376 /* Obtain a backtrace and print it to stdout. */
377 #ifdef HAVE_BACKTRACE_SUPPORT
378 void dump_stack(void)
379 {
380         void *array[16];
381         size_t size = backtrace(array, ARRAY_SIZE(array));
382         char **strings = backtrace_symbols(array, size);
383         size_t i;
384
385         printf("Obtained %zd stack frames.\n", size);
386
387         for (i = 0; i < size; i++)
388                 printf("%s\n", strings[i]);
389
390         free(strings);
391 }
392 #else
393 void dump_stack(void) {}
394 #endif
395
396 void sighandler_dump_stack(int sig)
397 {
398         psignal(sig, "perf");
399         dump_stack();
400         signal(sig, SIG_DFL);
401         raise(sig);
402 }
403
404 int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz)
405 {
406         u64  sec = timestamp / NSEC_PER_SEC;
407         u64 usec = (timestamp % NSEC_PER_SEC) / NSEC_PER_USEC;
408
409         return scnprintf(buf, sz, "%"PRIu64".%06"PRIu64, sec, usec);
410 }
411
412 unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
413 {
414         struct parse_tag *i = tags;
415
416         while (i->tag) {
417                 char *s;
418
419                 s = strchr(str, i->tag);
420                 if (s) {
421                         unsigned long int value;
422                         char *endptr;
423
424                         value = strtoul(str, &endptr, 10);
425                         if (s != endptr)
426                                 break;
427
428                         if (value > ULONG_MAX / i->mult)
429                                 break;
430                         value *= i->mult;
431                         return value;
432                 }
433                 i++;
434         }
435
436         return (unsigned long) -1;
437 }
438
439 int get_stack_size(const char *str, unsigned long *_size)
440 {
441         char *endptr;
442         unsigned long size;
443         unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
444
445         size = strtoul(str, &endptr, 0);
446
447         do {
448                 if (*endptr)
449                         break;
450
451                 size = round_up(size, sizeof(u64));
452                 if (!size || size > max_size)
453                         break;
454
455                 *_size = size;
456                 return 0;
457
458         } while (0);
459
460         pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
461                max_size, str);
462         return -1;
463 }
464
465 int parse_callchain_record(const char *arg, struct callchain_param *param)
466 {
467         char *tok, *name, *saveptr = NULL;
468         char *buf;
469         int ret = -1;
470
471         /* We need buffer that we know we can write to. */
472         buf = malloc(strlen(arg) + 1);
473         if (!buf)
474                 return -ENOMEM;
475
476         strcpy(buf, arg);
477
478         tok = strtok_r((char *)buf, ",", &saveptr);
479         name = tok ? : (char *)buf;
480
481         do {
482                 /* Framepointer style */
483                 if (!strncmp(name, "fp", sizeof("fp"))) {
484                         if (!strtok_r(NULL, ",", &saveptr)) {
485                                 param->record_mode = CALLCHAIN_FP;
486                                 ret = 0;
487                         } else
488                                 pr_err("callchain: No more arguments "
489                                        "needed for --call-graph fp\n");
490                         break;
491
492                 /* Dwarf style */
493                 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
494                         const unsigned long default_stack_dump_size = 8192;
495
496                         ret = 0;
497                         param->record_mode = CALLCHAIN_DWARF;
498                         param->dump_size = default_stack_dump_size;
499
500                         tok = strtok_r(NULL, ",", &saveptr);
501                         if (tok) {
502                                 unsigned long size = 0;
503
504                                 ret = get_stack_size(tok, &size);
505                                 param->dump_size = size;
506                         }
507                 } else if (!strncmp(name, "lbr", sizeof("lbr"))) {
508                         if (!strtok_r(NULL, ",", &saveptr)) {
509                                 param->record_mode = CALLCHAIN_LBR;
510                                 ret = 0;
511                         } else
512                                 pr_err("callchain: No more arguments "
513                                         "needed for --call-graph lbr\n");
514                         break;
515                 } else {
516                         pr_err("callchain: Unknown --call-graph option "
517                                "value: %s\n", arg);
518                         break;
519                 }
520
521         } while (0);
522
523         free(buf);
524         return ret;
525 }
526
527 const char *get_filename_for_perf_kvm(void)
528 {
529         const char *filename;
530
531         if (perf_host && !perf_guest)
532                 filename = strdup("perf.data.host");
533         else if (!perf_host && perf_guest)
534                 filename = strdup("perf.data.guest");
535         else
536                 filename = strdup("perf.data.kvm");
537
538         return filename;
539 }
540
541 int perf_event_paranoid(void)
542 {
543         int value;
544
545         if (sysctl__read_int("kernel/perf_event_paranoid", &value))
546                 return INT_MAX;
547
548         return value;
549 }
550
551 void mem_bswap_32(void *src, int byte_size)
552 {
553         u32 *m = src;
554         while (byte_size > 0) {
555                 *m = bswap_32(*m);
556                 byte_size -= sizeof(u32);
557                 ++m;
558         }
559 }
560
561 void mem_bswap_64(void *src, int byte_size)
562 {
563         u64 *m = src;
564
565         while (byte_size > 0) {
566                 *m = bswap_64(*m);
567                 byte_size -= sizeof(u64);
568                 ++m;
569         }
570 }
571
572 bool find_process(const char *name)
573 {
574         size_t len = strlen(name);
575         DIR *dir;
576         struct dirent *d;
577         int ret = -1;
578
579         dir = opendir(procfs__mountpoint());
580         if (!dir)
581                 return false;
582
583         /* Walk through the directory. */
584         while (ret && (d = readdir(dir)) != NULL) {
585                 char path[PATH_MAX];
586                 char *data;
587                 size_t size;
588
589                 if ((d->d_type != DT_DIR) ||
590                      !strcmp(".", d->d_name) ||
591                      !strcmp("..", d->d_name))
592                         continue;
593
594                 scnprintf(path, sizeof(path), "%s/%s/comm",
595                           procfs__mountpoint(), d->d_name);
596
597                 if (filename__read_str(path, &data, &size))
598                         continue;
599
600                 ret = strncmp(name, data, len);
601                 free(data);
602         }
603
604         closedir(dir);
605         return ret ? false : true;
606 }
607
608 static int
609 fetch_ubuntu_kernel_version(unsigned int *puint)
610 {
611         ssize_t len;
612         size_t line_len = 0;
613         char *ptr, *line = NULL;
614         int version, patchlevel, sublevel, err;
615         FILE *vsig = fopen("/proc/version_signature", "r");
616
617         if (!vsig) {
618                 pr_debug("Open /proc/version_signature failed: %s\n",
619                          strerror(errno));
620                 return -1;
621         }
622
623         len = getline(&line, &line_len, vsig);
624         fclose(vsig);
625         err = -1;
626         if (len <= 0) {
627                 pr_debug("Reading from /proc/version_signature failed: %s\n",
628                          strerror(errno));
629                 goto errout;
630         }
631
632         ptr = strrchr(line, ' ');
633         if (!ptr) {
634                 pr_debug("Parsing /proc/version_signature failed: %s\n", line);
635                 goto errout;
636         }
637
638         err = sscanf(ptr + 1, "%d.%d.%d",
639                      &version, &patchlevel, &sublevel);
640         if (err != 3) {
641                 pr_debug("Unable to get kernel version from /proc/version_signature '%s'\n",
642                          line);
643                 goto errout;
644         }
645
646         if (puint)
647                 *puint = (version << 16) + (patchlevel << 8) + sublevel;
648         err = 0;
649 errout:
650         free(line);
651         return err;
652 }
653
654 int
655 fetch_kernel_version(unsigned int *puint, char *str,
656                      size_t str_size)
657 {
658         struct utsname utsname;
659         int version, patchlevel, sublevel, err;
660         bool int_ver_ready = false;
661
662         if (access("/proc/version_signature", R_OK) == 0)
663                 if (!fetch_ubuntu_kernel_version(puint))
664                         int_ver_ready = true;
665
666         if (uname(&utsname))
667                 return -1;
668
669         if (str && str_size) {
670                 strncpy(str, utsname.release, str_size);
671                 str[str_size - 1] = '\0';
672         }
673
674         err = sscanf(utsname.release, "%d.%d.%d",
675                      &version, &patchlevel, &sublevel);
676
677         if (err != 3) {
678                 pr_debug("Unable to get kernel version from uname '%s'\n",
679                          utsname.release);
680                 return -1;
681         }
682
683         if (puint && !int_ver_ready)
684                 *puint = (version << 16) + (patchlevel << 8) + sublevel;
685         return 0;
686 }
687
688 const char *perf_tip(const char *dirpath)
689 {
690         struct strlist *tips;
691         struct str_node *node;
692         char *tip = NULL;
693         struct strlist_config conf = {
694                 .dirname = dirpath,
695                 .file_only = true,
696         };
697
698         tips = strlist__new("tips.txt", &conf);
699         if (tips == NULL)
700                 return errno == ENOENT ? NULL :
701                         "Tip: check path of tips.txt or get more memory! ;-p";
702
703         if (strlist__nr_entries(tips) == 0)
704                 goto out;
705
706         node = strlist__entry(tips, random() % strlist__nr_entries(tips));
707         if (asprintf(&tip, "Tip: %s", node->s) < 0)
708                 tip = (char *)"Tip: get more memory! ;-)";
709
710 out:
711         strlist__delete(tips);
712
713         return tip;
714 }
715
716 int fetch_current_timestamp(char *buf, size_t sz)
717 {
718         struct timeval tv;
719         struct tm tm;
720         char dt[32];
721
722         if (gettimeofday(&tv, NULL) || !localtime_r(&tv.tv_sec, &tm))
723                 return -1;
724
725         if (!strftime(dt, sizeof(dt), "%Y%m%d%H%M%S", &tm))
726                 return -1;
727
728         scnprintf(buf, sz, "%s%02u", dt, (unsigned)tv.tv_usec / 10000);
729
730         return 0;
731 }
732
733 int unit_number__scnprintf(char *buf, size_t size, u64 n)
734 {
735         char unit[4] = "BKMG";
736         int i = 0;
737
738         while (((n / 1024) > 1) && (i < 3)) {
739                 n /= 1024;
740                 i++;
741         }
742
743         return scnprintf(buf, size, "%" PRIu64 "%c", n, unit[i]);
744 }