probe-event.c (db66e32e0d2ae1f5070faa589aa460b75780ab47) | probe-event.c (4605eab3487dc818b1f3cbee2cd139cca3564be7) |
---|---|
1/* 2 * probe-event.c : perf-probe definition to probe_events format converter 3 * 4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 26 unchanged lines hidden (view full) --- 35#include "util.h" 36#include "event.h" 37#include "strlist.h" 38#include "debug.h" 39#include "cache.h" 40#include "color.h" 41#include "symbol.h" 42#include "thread.h" | 1/* 2 * probe-event.c : perf-probe definition to probe_events format converter 3 * 4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 26 unchanged lines hidden (view full) --- 35#include "util.h" 36#include "event.h" 37#include "strlist.h" 38#include "debug.h" 39#include "cache.h" 40#include "color.h" 41#include "symbol.h" 42#include "thread.h" |
43#include <api/fs/debugfs.h> 44#include <api/fs/tracefs.h> | 43#include <api/fs/fs.h> |
45#include "trace-event.h" /* For __maybe_unused */ 46#include "probe-event.h" 47#include "probe-finder.h" 48#include "probe-file.h" 49#include "session.h" 50 51#define MAX_CMDLEN 256 52#define PERFPROBE_GROUP "probe" --- 1996 unchanged lines hidden (view full) --- 2049 free(node->symbol); 2050 free(node); 2051 } 2052} 2053 2054static int kprobe_blacklist__load(struct list_head *blacklist) 2055{ 2056 struct kprobe_blacklist_node *node; | 44#include "trace-event.h" /* For __maybe_unused */ 45#include "probe-event.h" 46#include "probe-finder.h" 47#include "probe-file.h" 48#include "session.h" 49 50#define MAX_CMDLEN 256 51#define PERFPROBE_GROUP "probe" --- 1996 unchanged lines hidden (view full) --- 2048 free(node->symbol); 2049 free(node); 2050 } 2051} 2052 2053static int kprobe_blacklist__load(struct list_head *blacklist) 2054{ 2055 struct kprobe_blacklist_node *node; |
2057 const char *__debugfs = debugfs_find_mountpoint(); | 2056 const char *__debugfs = debugfs__mountpoint(); |
2058 char buf[PATH_MAX], *p; 2059 FILE *fp; 2060 int ret; 2061 2062 if (__debugfs == NULL) 2063 return -ENOTSUP; 2064 2065 ret = e_snprintf(buf, PATH_MAX, "%s/kprobes/blacklist", __debugfs); --- 109 unchanged lines hidden (view full) --- 2175 } 2176 strbuf_addch(result, ')'); 2177out: 2178 free(place); 2179 return ret; 2180} 2181 2182/* Show an event */ | 2057 char buf[PATH_MAX], *p; 2058 FILE *fp; 2059 int ret; 2060 2061 if (__debugfs == NULL) 2062 return -ENOTSUP; 2063 2064 ret = e_snprintf(buf, PATH_MAX, "%s/kprobes/blacklist", __debugfs); --- 109 unchanged lines hidden (view full) --- 2174 } 2175 strbuf_addch(result, ')'); 2176out: 2177 free(place); 2178 return ret; 2179} 2180 2181/* Show an event */ |
2183static int show_perf_probe_event(const char *group, const char *event, 2184 struct perf_probe_event *pev, 2185 const char *module, bool use_stdout) | 2182int show_perf_probe_event(const char *group, const char *event, 2183 struct perf_probe_event *pev, 2184 const char *module, bool use_stdout) |
2186{ 2187 struct strbuf buf = STRBUF_INIT; 2188 int ret; 2189 2190 ret = perf_probe_event__sprintf(group, event, pev, module, &buf); 2191 if (ret >= 0) { 2192 if (use_stdout) 2193 printf("%s\n", buf.buf); --- 200 unchanged lines hidden (view full) --- 2394} 2395 2396static int __add_probe_trace_events(struct perf_probe_event *pev, 2397 struct probe_trace_event *tevs, 2398 int ntevs, bool allow_suffix) 2399{ 2400 int i, fd, ret; 2401 struct probe_trace_event *tev = NULL; | 2185{ 2186 struct strbuf buf = STRBUF_INIT; 2187 int ret; 2188 2189 ret = perf_probe_event__sprintf(group, event, pev, module, &buf); 2190 if (ret >= 0) { 2191 if (use_stdout) 2192 printf("%s\n", buf.buf); --- 200 unchanged lines hidden (view full) --- 2393} 2394 2395static int __add_probe_trace_events(struct perf_probe_event *pev, 2396 struct probe_trace_event *tevs, 2397 int ntevs, bool allow_suffix) 2398{ 2399 int i, fd, ret; 2400 struct probe_trace_event *tev = NULL; |
2402 const char *event = NULL, *group = NULL; | |
2403 struct strlist *namelist; 2404 2405 fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0)); 2406 if (fd < 0) 2407 return fd; 2408 2409 /* Get current event names */ 2410 namelist = probe_file__get_namelist(fd); 2411 if (!namelist) { 2412 pr_debug("Failed to get current event list.\n"); 2413 ret = -ENOMEM; 2414 goto close_out; 2415 } 2416 2417 ret = 0; | 2401 struct strlist *namelist; 2402 2403 fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0)); 2404 if (fd < 0) 2405 return fd; 2406 2407 /* Get current event names */ 2408 namelist = probe_file__get_namelist(fd); 2409 if (!namelist) { 2410 pr_debug("Failed to get current event list.\n"); 2411 ret = -ENOMEM; 2412 goto close_out; 2413 } 2414 2415 ret = 0; |
2418 pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":"); | |
2419 for (i = 0; i < ntevs; i++) { 2420 tev = &tevs[i]; 2421 /* Skip if the symbol is out of .text or blacklisted */ 2422 if (!tev->point.symbol) 2423 continue; 2424 2425 /* Set new name for tev (and update namelist) */ 2426 ret = probe_trace_event__set_name(tev, pev, namelist, 2427 allow_suffix); 2428 if (ret < 0) 2429 break; 2430 2431 ret = probe_file__add_event(fd, tev); 2432 if (ret < 0) 2433 break; 2434 | 2416 for (i = 0; i < ntevs; i++) { 2417 tev = &tevs[i]; 2418 /* Skip if the symbol is out of .text or blacklisted */ 2419 if (!tev->point.symbol) 2420 continue; 2421 2422 /* Set new name for tev (and update namelist) */ 2423 ret = probe_trace_event__set_name(tev, pev, namelist, 2424 allow_suffix); 2425 if (ret < 0) 2426 break; 2427 2428 ret = probe_file__add_event(fd, tev); 2429 if (ret < 0) 2430 break; 2431 |
2435 /* We use tev's name for showing new events */ 2436 show_perf_probe_event(tev->group, tev->event, pev, 2437 tev->point.module, false); 2438 /* Save the last valid name */ 2439 event = tev->event; 2440 group = tev->group; 2441 | |
2442 /* 2443 * Probes after the first probe which comes from same 2444 * user input are always allowed to add suffix, because 2445 * there might be several addresses corresponding to 2446 * one code line. 2447 */ 2448 allow_suffix = true; 2449 } 2450 if (ret == -EINVAL && pev->uprobes) 2451 warn_uprobe_event_compat(tev); 2452 | 2432 /* 2433 * Probes after the first probe which comes from same 2434 * user input are always allowed to add suffix, because 2435 * there might be several addresses corresponding to 2436 * one code line. 2437 */ 2438 allow_suffix = true; 2439 } 2440 if (ret == -EINVAL && pev->uprobes) 2441 warn_uprobe_event_compat(tev); 2442 |
2453 /* Note that it is possible to skip all events because of blacklist */ 2454 if (ret >= 0 && event) { 2455 /* Show how to use the event. */ 2456 pr_info("\nYou can now use it in all perf tools, such as:\n\n"); 2457 pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", group, event); 2458 } 2459 | |
2460 strlist__delete(namelist); 2461close_out: 2462 close(fd); 2463 return ret; 2464} 2465 2466static int find_probe_functions(struct map *map, char *name, 2467 struct symbol **syms) --- 286 unchanged lines hidden (view full) --- 2754 /* Convert perf_probe_event with debuginfo */ 2755 ret = try_to_find_probe_trace_events(pev, tevs); 2756 if (ret != 0) 2757 return ret; /* Found in debuginfo or got an error */ 2758 2759 return find_probe_trace_events_from_map(pev, tevs); 2760} 2761 | 2443 strlist__delete(namelist); 2444close_out: 2445 close(fd); 2446 return ret; 2447} 2448 2449static int find_probe_functions(struct map *map, char *name, 2450 struct symbol **syms) --- 286 unchanged lines hidden (view full) --- 2737 /* Convert perf_probe_event with debuginfo */ 2738 ret = try_to_find_probe_trace_events(pev, tevs); 2739 if (ret != 0) 2740 return ret; /* Found in debuginfo or got an error */ 2741 2742 return find_probe_trace_events_from_map(pev, tevs); 2743} 2744 |
2762struct __event_package { 2763 struct perf_probe_event *pev; 2764 struct probe_trace_event *tevs; 2765 int ntevs; 2766}; 2767 2768int add_perf_probe_events(struct perf_probe_event *pevs, int npevs) | 2745int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs) |
2769{ | 2746{ |
2770 int i, j, ret; 2771 struct __event_package *pkgs; | 2747 int i, ret; |
2772 | 2748 |
2773 ret = 0; 2774 pkgs = zalloc(sizeof(struct __event_package) * npevs); 2775 2776 if (pkgs == NULL) 2777 return -ENOMEM; 2778 | |
2779 ret = init_symbol_maps(pevs->uprobes); | 2749 ret = init_symbol_maps(pevs->uprobes); |
2780 if (ret < 0) { 2781 free(pkgs); | 2750 if (ret < 0) |
2782 return ret; | 2751 return ret; |
2783 } | |
2784 2785 /* Loop 1: convert all events */ 2786 for (i = 0; i < npevs; i++) { | 2752 2753 /* Loop 1: convert all events */ 2754 for (i = 0; i < npevs; i++) { |
2787 pkgs[i].pev = &pevs[i]; | |
2788 /* Init kprobe blacklist if needed */ | 2755 /* Init kprobe blacklist if needed */ |
2789 if (!pkgs[i].pev->uprobes) | 2756 if (!pevs[i].uprobes) |
2790 kprobe_blacklist__init(); 2791 /* Convert with or without debuginfo */ | 2757 kprobe_blacklist__init(); 2758 /* Convert with or without debuginfo */ |
2792 ret = convert_to_probe_trace_events(pkgs[i].pev, 2793 &pkgs[i].tevs); | 2759 ret = convert_to_probe_trace_events(&pevs[i], &pevs[i].tevs); |
2794 if (ret < 0) | 2760 if (ret < 0) |
2795 goto end; 2796 pkgs[i].ntevs = ret; | 2761 return ret; 2762 pevs[i].ntevs = ret; |
2797 } 2798 /* This just release blacklist only if allocated */ 2799 kprobe_blacklist__release(); 2800 | 2763 } 2764 /* This just release blacklist only if allocated */ 2765 kprobe_blacklist__release(); 2766 |
2767 return 0; 2768} 2769 2770int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs) 2771{ 2772 int i, ret = 0; 2773 |
|
2801 /* Loop 2: add all events */ 2802 for (i = 0; i < npevs; i++) { | 2774 /* Loop 2: add all events */ 2775 for (i = 0; i < npevs; i++) { |
2803 ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs, 2804 pkgs[i].ntevs, | 2776 ret = __add_probe_trace_events(&pevs[i], pevs[i].tevs, 2777 pevs[i].ntevs, |
2805 probe_conf.force_add); 2806 if (ret < 0) 2807 break; 2808 } | 2778 probe_conf.force_add); 2779 if (ret < 0) 2780 break; 2781 } |
2809end: | 2782 return ret; 2783} 2784 2785void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs) 2786{ 2787 int i, j; 2788 |
2810 /* Loop 3: cleanup and free trace events */ 2811 for (i = 0; i < npevs; i++) { | 2789 /* Loop 3: cleanup and free trace events */ 2790 for (i = 0; i < npevs; i++) { |
2812 for (j = 0; j < pkgs[i].ntevs; j++) 2813 clear_probe_trace_event(&pkgs[i].tevs[j]); 2814 zfree(&pkgs[i].tevs); | 2791 for (j = 0; j < pevs[i].ntevs; j++) 2792 clear_probe_trace_event(&pevs[i].tevs[j]); 2793 zfree(&pevs[i].tevs); 2794 pevs[i].ntevs = 0; |
2815 } | 2795 } |
2816 free(pkgs); | 2796 |
2817 exit_symbol_maps(); | 2797 exit_symbol_maps(); |
2798} |
|
2818 | 2799 |
2800int add_perf_probe_events(struct perf_probe_event *pevs, int npevs) 2801{ 2802 int ret; 2803 2804 ret = convert_perf_probe_events(pevs, npevs); 2805 if (ret == 0) 2806 ret = apply_perf_probe_events(pevs, npevs); 2807 2808 cleanup_perf_probe_events(pevs, npevs); 2809 |
|
2819 return ret; 2820} 2821 2822int del_perf_probe_events(struct strfilter *filter) 2823{ 2824 int ret, ret2, ufd = -1, kfd = -1; 2825 char *str = strfilter__string(filter); 2826 2827 if (!str) 2828 return -EINVAL; 2829 | 2810 return ret; 2811} 2812 2813int del_perf_probe_events(struct strfilter *filter) 2814{ 2815 int ret, ret2, ufd = -1, kfd = -1; 2816 char *str = strfilter__string(filter); 2817 2818 if (!str) 2819 return -EINVAL; 2820 |
2830 pr_debug("Delete filter: \'%s\'\n", str); 2831 | |
2832 /* Get current event names */ 2833 ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW); 2834 if (ret < 0) 2835 goto out; 2836 2837 ret = probe_file__del_events(kfd, filter); 2838 if (ret < 0 && ret != -ENOENT) 2839 goto error; 2840 2841 ret2 = probe_file__del_events(ufd, filter); 2842 if (ret2 < 0 && ret2 != -ENOENT) { 2843 ret = ret2; 2844 goto error; 2845 } | 2821 /* Get current event names */ 2822 ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW); 2823 if (ret < 0) 2824 goto out; 2825 2826 ret = probe_file__del_events(kfd, filter); 2827 if (ret < 0 && ret != -ENOENT) 2828 goto error; 2829 2830 ret2 = probe_file__del_events(ufd, filter); 2831 if (ret2 < 0 && ret2 != -ENOENT) { 2832 ret = ret2; 2833 goto error; 2834 } |
2846 if (ret == -ENOENT && ret2 == -ENOENT) 2847 pr_debug("\"%s\" does not hit any event.\n", str); 2848 /* Note that this is silently ignored */ | |
2849 ret = 0; 2850 2851error: 2852 if (kfd >= 0) 2853 close(kfd); 2854 if (ufd >= 0) 2855 close(ufd); 2856out: --- 80 unchanged lines hidden --- | 2835 ret = 0; 2836 2837error: 2838 if (kfd >= 0) 2839 close(kfd); 2840 if (ufd >= 0) 2841 close(ufd); 2842out: --- 80 unchanged lines hidden --- |