^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * probe-file.c : operate ftrace k/uprobe events files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sys/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "namespaces.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "strlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "strfilter.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "dso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "color.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "strbuf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <api/fs/tracing_path.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "probe-event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "probe-file.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "perf_regs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "string2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* 4096 - 2 ('\n' + '\0') */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MAX_CMDLEN 4094
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void print_open_warning(int err, bool uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (err == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) const char *config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) config = "CONFIG_UPROBE_EVENTS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) config = "CONFIG_KPROBE_EVENTS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) pr_warning("%cprobe_events file does not exist"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) " - please rebuild kernel with %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) uprobe ? 'u' : 'k', config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) } else if (err == -ENOTSUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) pr_warning("Tracefs or debugfs is not mounted.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) pr_warning("Failed to open %cprobe_events: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) uprobe ? 'u' : 'k',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) str_error_r(-err, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static void print_both_open_warning(int kerr, int uerr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Both kprobes and uprobes are disabled, warn it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (kerr == -ENOTSUP && uerr == -ENOTSUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) pr_warning("Tracefs or debugfs is not mounted.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) else if (kerr == -ENOENT && uerr == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "or/and CONFIG_UPROBE_EVENTS.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) pr_warning("Failed to open kprobe events: %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) str_error_r(-kerr, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) pr_warning("Failed to open uprobe events: %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) str_error_r(-uerr, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int open_trace_file(const char *trace_file, bool readwrite)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) char buf[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ret = e_snprintf(buf, PATH_MAX, "%s/%s", tracing_path_mount(), trace_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) pr_debug("Opening %s write=%d\n", buf, readwrite);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (readwrite && !probe_event_dry_run)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) ret = open(buf, O_RDWR | O_APPEND, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ret = open(buf, O_RDONLY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int open_kprobe_events(bool readwrite)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return open_trace_file("kprobe_events", readwrite);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int open_uprobe_events(bool readwrite)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return open_trace_file("uprobe_events", readwrite);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int probe_file__open(int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (flag & PF_FL_UPROBE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) fd = open_uprobe_events(flag & PF_FL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) fd = open_kprobe_events(flag & PF_FL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) print_open_warning(fd, flag & PF_FL_UPROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int probe_file__open_both(int *kfd, int *ufd, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (!kfd || !ufd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *kfd = open_kprobe_events(flag & PF_FL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *ufd = open_uprobe_events(flag & PF_FL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (*kfd < 0 && *ufd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) print_both_open_warning(*kfd, *ufd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return *kfd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Get raw string list of current kprobe_events or uprobe_events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct strlist *probe_file__get_rawlist(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int ret, idx, fddup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) char buf[MAX_CMDLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct strlist *sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) sl = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (sl == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) fddup = dup(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (fddup < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) goto out_free_sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) fp = fdopen(fddup, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (!fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto out_close_fddup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) while (!feof(fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) p = fgets(buf, MAX_CMDLEN, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) idx = strlen(p) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (p[idx] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) p[idx] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ret = strlist__add(sl, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) pr_debug("strlist__add failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) goto out_close_fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) out_close_fp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) goto out_free_sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) out_close_fddup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) close(fddup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) out_free_sl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) strlist__delete(sl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static struct strlist *__probe_file__get_namelist(int fd, bool include_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) char buf[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct strlist *sl, *rawlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct str_node *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct probe_trace_event tev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) memset(&tev, 0, sizeof(tev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) rawlist = probe_file__get_rawlist(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!rawlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) sl = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) strlist__for_each_entry(ent, rawlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ret = parse_probe_trace_command(ent->s, &tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (include_group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ret = e_snprintf(buf, 128, "%s:%s", tev.group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) tev.event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ret = strlist__add(sl, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = strlist__add(sl, tev.event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) clear_probe_trace_event(&tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* Skip if there is same name multi-probe event in the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (ret == -EEXIST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) strlist__delete(rawlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) strlist__delete(sl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return sl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Get current perf-probe event names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct strlist *probe_file__get_namelist(int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return __probe_file__get_namelist(fd, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int probe_file__add_event(int fd, struct probe_trace_event *tev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) char *buf = synthesize_probe_trace_command(tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) pr_debug("Failed to synthesize probe trace event.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) pr_debug("Writing event: %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!probe_event_dry_run) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (write(fd, buf, strlen(buf)) < (int)strlen(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) pr_warning("Failed to write event: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) str_error_r(errno, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int __del_trace_probe_event(int fd, struct str_node *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) char buf[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Convert from perf-probe event to trace-probe event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ret = e_snprintf(buf, 128, "-:%s", ent->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) p = strchr(buf + 2, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) pr_debug("Internal error: %s should have ':' but not.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ent->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret = -ENOTSUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *p = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) pr_debug("Writing event: %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ret = write(fd, buf, strlen(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) pr_warning("Failed to delete event: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) str_error_r(-ret, buf, sizeof(buf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int probe_file__get_events(int fd, struct strfilter *filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct strlist *plist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct strlist *namelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct str_node *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (!plist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) namelist = __probe_file__get_namelist(fd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!namelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) strlist__for_each_entry(ent, namelist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) p = strchr(ent->s, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if ((p && strfilter__compare(filter, p + 1)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) strfilter__compare(filter, ent->s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ret = strlist__add(plist, ent->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (ret == -ENOMEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) pr_err("strlist__add failed with -ENOMEM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) strlist__delete(namelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int probe_file__del_strlist(int fd, struct strlist *namelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct str_node *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) strlist__for_each_entry(ent, namelist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ret = __del_trace_probe_event(fd, ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int probe_file__del_events(int fd, struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct strlist *namelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) namelist = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (!namelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ret = probe_file__get_events(fd, filter, namelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = probe_file__del_strlist(fd, namelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) strlist__delete(namelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* Caller must ensure to remove this entry from list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static void probe_cache_entry__delete(struct probe_cache_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) BUG_ON(!list_empty(&entry->node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) strlist__delete(entry->tevlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) clear_perf_probe_event(&entry->pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) zfree(&entry->spev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) free(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static struct probe_cache_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) probe_cache_entry__new(struct perf_probe_event *pev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct probe_cache_entry *entry = zalloc(sizeof(*entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) INIT_LIST_HEAD(&entry->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) entry->tevlist = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!entry->tevlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) zfree(&entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) else if (pev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) entry->spev = synthesize_perf_probe_command(pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (!entry->spev ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) perf_probe_event__copy(&entry->pev, pev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) probe_cache_entry__delete(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int probe_cache_entry__get_event(struct probe_cache_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct probe_trace_event **tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct probe_trace_event *tev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct str_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = strlist__nr_entries(entry->tevlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (ret > probe_conf.max_probes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *tevs = zalloc(ret * sizeof(*tev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (!*tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) strlist__for_each_entry(node, entry->tevlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) tev = &(*tevs)[i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ret = parse_probe_trace_command(node->s, tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int probe_cache__open(struct probe_cache *pcache, const char *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct nsinfo *nsi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) char cpath[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) char sbuildid[SBUILD_ID_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) char *dir_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) bool is_kallsyms = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int ret, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct nscookie nsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (target && build_id_cache__cached(target)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /* This is a cached buildid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) strlcpy(sbuildid, target, SBUILD_ID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dir_name = build_id_cache__linkname(sbuildid, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) target = DSO__NAME_KALLSYMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) is_kallsyms = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ret = sysfs__sprintf_build_id("/", sbuildid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) nsinfo__mountns_enter(nsi, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ret = filename__sprintf_build_id(target, sbuildid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) pr_debug("Failed to get build-id from %s.\n", target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* If we have no buildid cache, make it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (!build_id_cache__cached(sbuildid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ret = build_id_cache__add_s(sbuildid, target, nsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) is_kallsyms, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) pr_debug("Failed to add build-id cache: %s\n", target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dir_name = build_id_cache__cachedir(sbuildid, target, nsi, is_kallsyms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!dir_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) pr_debug("Failed to get cache from %s\n", target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) snprintf(cpath, PATH_MAX, "%s/probes", dir_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) fd = open(cpath, O_CREAT | O_RDWR, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) pr_debug("Failed to open cache(%d): %s\n", fd, cpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) free(dir_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) pcache->fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static int probe_cache__load(struct probe_cache *pcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct probe_cache_entry *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) char buf[MAX_CMDLEN], *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int ret = 0, fddup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) fddup = dup(pcache->fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (fddup < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) fp = fdopen(fddup, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (!fp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) close(fddup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) while (!feof(fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!fgets(buf, MAX_CMDLEN, fp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) p = strchr(buf, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) *p = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /* #perf_probe_event or %sdt_event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (buf[0] == '#' || buf[0] == '%') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) entry = probe_cache_entry__new(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (buf[0] == '%')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) entry->sdt = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) entry->spev = strdup(buf + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (entry->spev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret = parse_perf_probe_command(buf + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) &entry->pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) probe_cache_entry__delete(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) list_add_tail(&entry->node, &pcache->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) } else { /* trace_probe_event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ret = strlist__add(entry->tevlist, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (ret == -ENOMEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) pr_err("strlist__add failed with -ENOMEM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static struct probe_cache *probe_cache__alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct probe_cache *pcache = zalloc(sizeof(*pcache));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (pcache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) INIT_LIST_HEAD(&pcache->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) pcache->fd = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return pcache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) void probe_cache__purge(struct probe_cache *pcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct probe_cache_entry *entry, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) list_for_each_entry_safe(entry, n, &pcache->entries, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) list_del_init(&entry->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) probe_cache_entry__delete(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) void probe_cache__delete(struct probe_cache *pcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (!pcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) probe_cache__purge(pcache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (pcache->fd > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) close(pcache->fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) free(pcache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct probe_cache *probe_cache__new(const char *target, struct nsinfo *nsi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct probe_cache *pcache = probe_cache__alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (!pcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ret = probe_cache__open(pcache, target, nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) pr_debug("Cache open error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ret = probe_cache__load(pcache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) pr_debug("Cache read error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return pcache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) probe_cache__delete(pcache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static bool streql(const char *a, const char *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (a == b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (!a || !b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return !strcmp(a, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct probe_cache_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct probe_cache_entry *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) char *cmd = synthesize_perf_probe_command(pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) for_each_probe_cache_entry(entry, pcache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (pev->sdt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (entry->pev.event &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) streql(entry->pev.event, pev->event) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) (!pev->group ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) streql(entry->pev.group, pev->group)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* Hit if same event name or same command-string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if ((pev->event &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) (streql(entry->pev.group, pev->group) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) streql(entry->pev.event, pev->event))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) (!strcmp(entry->spev, cmd)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) free(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct probe_cache_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) probe_cache__find_by_name(struct probe_cache *pcache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) const char *group, const char *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct probe_cache_entry *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) for_each_probe_cache_entry(entry, pcache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /* Hit if same event name or same command-string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (streql(entry->pev.group, group) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) streql(entry->pev.event, event))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int probe_cache__add_entry(struct probe_cache *pcache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct probe_trace_event *tevs, int ntevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct probe_cache_entry *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) char *command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (!pcache || !pev || !tevs || ntevs <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* Remove old cache entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) entry = probe_cache__find(pcache, pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) list_del_init(&entry->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) probe_cache_entry__delete(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) entry = probe_cache_entry__new(pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) for (i = 0; i < ntevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (!tevs[i].point.symbol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) command = synthesize_probe_trace_command(&tevs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (!command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ret = strlist__add(entry->tevlist, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (ret == -ENOMEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) pr_err("strlist__add failed with -ENOMEM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) free(command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) list_add_tail(&entry->node, &pcache->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) pr_debug("Added probe cache: %d\n", ntevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) pr_debug("Failed to add probe caches\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) probe_cache_entry__delete(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) #ifdef HAVE_GELF_GETNOTE_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static unsigned long long sdt_note__get_addr(struct sdt_note *note)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return note->bit32 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) (unsigned long long)note->addr.a32[SDT_NOTE_IDX_LOC] :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) (unsigned long long)note->addr.a64[SDT_NOTE_IDX_LOC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static unsigned long long sdt_note__get_ref_ctr_offset(struct sdt_note *note)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return note->bit32 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) (unsigned long long)note->addr.a32[SDT_NOTE_IDX_REFCTR] :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) (unsigned long long)note->addr.a64[SDT_NOTE_IDX_REFCTR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static const char * const type_to_suffix[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ":s64", "", "", "", ":s32", "", ":s16", ":s8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) "", ":u8", ":u16", "", ":u32", "", "", "", ":u64"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * Isolate the string number and convert it into a decimal value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * this will be an index to get suffix of the uprobe name (defining
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * the type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static int sdt_arg_parse_size(char *n_ptr, const char **suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) long type_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) type_idx = strtol(n_ptr, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (type_idx < -8 || type_idx > 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) pr_debug4("Failed to get a valid sdt type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) *suffix = type_to_suffix[type_idx + 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) char *op, *desc = strdup(arg), *new_op = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) const char *suffix = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (desc == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) pr_debug4("Allocation error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * Argument is in N@OP format. N is size of the argument and OP is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * the actual assembly operand. N can be omitted; in that case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * argument is just OP(without @).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) op = strchr(desc, '@');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) op[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) op++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (sdt_arg_parse_size(desc, &suffix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) op = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ret = arch_sdt_arg_parse_op(op, &new_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (ret == SDT_ARG_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ret = strbuf_addf(buf, " arg%d=%s%s", i + 1, new_op, suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) free(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) free(new_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static char *synthesize_sdt_probe_command(struct sdt_note *note,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) const char *pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) const char *sdtgrp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct strbuf buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) char *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) int i, args_count, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) unsigned long long ref_ctr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (strbuf_init(&buf, 32) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) err = strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) sdtgrp, note->name, pathname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) sdt_note__get_addr(note));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ref_ctr_offset = sdt_note__get_ref_ctr_offset(note);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (ref_ctr_offset && err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) err = strbuf_addf(&buf, "(0x%llx)", ref_ctr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (!note->args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (note->args) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) char **args = argv_split(note->args, &args_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (args == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) for (i = 0; i < args_count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) argv_free(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) argv_free(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ret = strbuf_detach(&buf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) strbuf_release(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct probe_cache_entry *entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct list_head sdtlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct sdt_note *note;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) char sdtgrp[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) INIT_LIST_HEAD(&sdtlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) ret = get_sdt_note_list(&sdtlist, pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) pr_debug4("Failed to get sdt note: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) list_for_each_entry(note, &sdtlist, note_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ret = snprintf(sdtgrp, 64, "sdt_%s", note->provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /* Try to find same-name entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) entry = probe_cache__find_by_name(pcache, sdtgrp, note->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) entry = probe_cache_entry__new(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) entry->sdt = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) ret = asprintf(&entry->spev, "%s:%s=%s", sdtgrp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) note->name, note->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) entry->pev.event = strdup(note->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) entry->pev.group = strdup(sdtgrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) list_add_tail(&entry->node, &pcache->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) buf = synthesize_sdt_probe_command(note, pathname, sdtgrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ret = strlist__add(entry->tevlist, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (ret == -ENOMEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) pr_err("strlist__add failed with -ENOMEM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) list_del_init(&entry->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) probe_cache_entry__delete(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) cleanup_sdt_note_list(&sdtlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct str_node *snode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct iovec iov[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) const char *prefix = entry->sdt ? "%" : "#";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* Save stat for rollback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ret = fstat(fd, &st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) pr_debug("Writing cache: %s%s\n", prefix, entry->spev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) iov[0].iov_base = (void *)prefix; iov[0].iov_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) iov[1].iov_base = entry->spev; iov[1].iov_len = strlen(entry->spev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ret = writev(fd, iov, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (ret < (int)iov[1].iov_len + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) goto rollback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) strlist__for_each_entry(snode, entry->tevlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) iov[0].iov_base = (void *)snode->s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) iov[0].iov_len = strlen(snode->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) iov[1].iov_base = (void *)"\n"; iov[1].iov_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ret = writev(fd, iov, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (ret < (int)iov[0].iov_len + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) goto rollback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) rollback:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* Rollback to avoid cache file corruption */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (ftruncate(fd, st.st_size) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ret = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) int probe_cache__commit(struct probe_cache *pcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) struct probe_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) /* TBD: if we do not update existing entries, skip it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) ret = lseek(pcache->fd, 0, SEEK_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ret = ftruncate(pcache->fd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) for_each_probe_cache_entry(entry, pcache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ret = probe_cache_entry__write(entry, pcache->fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) pr_debug("Cache committed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static bool probe_cache_entry__compare(struct probe_cache_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) char buf[128], *ptr = entry->spev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (entry->pev.event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) ptr = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return strfilter__compare(filter, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) int probe_cache__filter_purge(struct probe_cache *pcache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) struct probe_cache_entry *entry, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) list_for_each_entry_safe(entry, tmp, &pcache->entries, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (probe_cache_entry__compare(entry, filter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) pr_info("Removed cached event: %s\n", entry->spev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) list_del_init(&entry->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) probe_cache_entry__delete(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) static int probe_cache__show_entries(struct probe_cache *pcache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct probe_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) for_each_probe_cache_entry(entry, pcache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (probe_cache_entry__compare(entry, filter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) printf("%s\n", entry->spev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) /* Show all cached probes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) int probe_cache__show_all_caches(struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct probe_cache *pcache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) struct strlist *bidlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct str_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) char *buf = strfilter__string(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) pr_debug("list cache with filter: %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) bidlist = build_id_cache__list_all(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (!bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) pr_debug("Failed to get buildids: %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) strlist__for_each_entry(nd, bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) pcache = probe_cache__new(nd->s, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (!pcache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (!list_empty(&pcache->entries)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) buf = build_id_cache__origname(nd->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) printf("%s (%s):\n", buf, nd->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) probe_cache__show_entries(pcache, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) probe_cache__delete(pcache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) strlist__delete(bidlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) enum ftrace_readme {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) FTRACE_README_PROBE_TYPE_X = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) FTRACE_README_KRETPROBE_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) FTRACE_README_UPROBE_REF_CTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) FTRACE_README_USER_ACCESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) FTRACE_README_MULTIPROBE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) FTRACE_README_IMMEDIATE_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) FTRACE_README_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) const char *pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) bool avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) } ftrace_readme_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) #define DEFINE_TYPE(idx, pat) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) [idx] = {.pattern = pat, .avail = false}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) DEFINE_TYPE(FTRACE_README_USER_ACCESS, "*u]<offset>*"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) DEFINE_TYPE(FTRACE_README_MULTIPROBE_EVENT, "*Create/append/*"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) DEFINE_TYPE(FTRACE_README_IMMEDIATE_VALUE, "*\\imm-value,*"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static bool scan_ftrace_readme(enum ftrace_readme type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) char *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) size_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static bool scanned = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (scanned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) goto result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) fd = open_trace_file("README", false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) fp = fdopen(fd, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (!fp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) while (getline(&buf, &len, fp) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) for (enum ftrace_readme i = 0; i < FTRACE_README_END; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (!ftrace_readme_table[i].avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) ftrace_readme_table[i].avail =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) strglobmatch(buf, ftrace_readme_table[i].pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) scanned = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (type >= FTRACE_README_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) return ftrace_readme_table[type].avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) bool probe_type_is_available(enum probe_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (type >= PROBE_TYPE_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) else if (type == PROBE_TYPE_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return scan_ftrace_readme(FTRACE_README_PROBE_TYPE_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) bool kretprobe_offset_is_supported(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) bool uprobe_ref_ctr_is_supported(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) bool user_access_is_supported(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return scan_ftrace_readme(FTRACE_README_USER_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) bool multiprobe_event_is_supported(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return scan_ftrace_readme(FTRACE_README_MULTIPROBE_EVENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) bool immediate_value_is_supported(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return scan_ftrace_readme(FTRACE_README_IMMEDIATE_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }