Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddb2f58f authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo
Browse files

perf probe: Introduce probe_conf global configs



Introduce probe_conf global configuration parameters for probe-event and
probe-finder, and removes related parameters from APIs.

Signed-off-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20150508010330.24812.21095.stgit@localhost.localdomain


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 44225521
Loading
Loading
Loading
Loading
+7 −14
Original line number Diff line number Diff line
@@ -50,8 +50,6 @@
static struct {
	int command;	/* Command short_name */
	bool list_events;
	bool force_add;
	bool show_ext_vars;
	bool uprobes;
	bool quiet;
	bool target_used;
@@ -59,7 +57,6 @@ static struct {
	struct perf_probe_event events[MAX_PROBES];
	struct line_range line_range;
	char *target;
	int max_probe_points;
	struct strfilter *filter;
} params;

@@ -364,7 +361,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
		"\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
#endif
		opt_add_probe_event),
	OPT_BOOLEAN('f', "force", &params.force_add, "forcibly add events"
	OPT_BOOLEAN('f', "force", &probe_conf.force_add, "forcibly add events"
		    " with existing name"),
#ifdef HAVE_DWARF_SUPPORT
	OPT_CALLBACK('L', "line", NULL,
@@ -373,7 +370,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
	OPT_CALLBACK('V', "vars", NULL,
		     "FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT",
		     "Show accessible variables on PROBEDEF", opt_show_vars),
	OPT_BOOLEAN('\0', "externs", &params.show_ext_vars,
	OPT_BOOLEAN('\0', "externs", &probe_conf.show_ext_vars,
		    "Show external variables too (with --vars only)"),
	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
		   "file", "vmlinux pathname"),
@@ -384,7 +381,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
		opt_set_target),
#endif
	OPT__DRY_RUN(&probe_event_dry_run),
	OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
	OPT_INTEGER('\0', "max-probes", &probe_conf.max_probes,
		 "Set how many probe points can be found for a probe."),
	OPT_CALLBACK_DEFAULT('F', "funcs", NULL, "[FILTER]",
			     "Show potential probe-able functions.",
@@ -440,8 +437,8 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
		verbose = -1;
	}

	if (params.max_probe_points == 0)
		params.max_probe_points = MAX_PROBES;
	if (probe_conf.max_probes == 0)
		probe_conf.max_probes = MAX_PROBES;

	/*
	 * Only consider the user's kernel image path if given.
@@ -477,9 +474,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
						       NULL);

		ret = show_available_vars(params.events, params.nevents,
					  params.max_probe_points,
					  params.filter,
					  params.show_ext_vars);
					  params.filter);
		if (ret < 0)
			pr_err_with_code("  Error: Failed to show vars.", ret);
		return ret;
@@ -498,9 +493,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
			usage_with_options(probe_usage, options);
		}

		ret = add_perf_probe_events(params.events, params.nevents,
					    params.max_probe_points,
					    params.force_add);
		ret = add_perf_probe_events(params.events, params.nevents);
		if (ret < 0) {
			pr_err_with_code("  Error: Failed to add events.", ret);
			return ret;
+22 −31
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@
#define PERFPROBE_GROUP "probe"

bool probe_event_dry_run;	/* Dry run flag */
struct probe_conf probe_conf;

#define semantic_error(msg ...) pr_err("Semantic error :" msg)

@@ -599,8 +600,7 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs,

/* Try to find perf_probe_event with debuginfo */
static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
					  struct probe_trace_event **tevs,
					  int max_tevs)
					  struct probe_trace_event **tevs)
{
	bool need_dwarf = perf_probe_event_need_dwarf(pev);
	struct perf_probe_point tmp;
@@ -617,13 +617,12 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,

	pr_debug("Try to find probe point from debuginfo.\n");
	/* Searching trace events corresponding to a probe event */
	ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs);
	ntevs = debuginfo__find_trace_events(dinfo, pev, tevs);

	if (ntevs == 0)	{  /* Not found, retry with an alternative */
		ret = get_alternative_probe_event(dinfo, pev, &tmp);
		if (!ret) {
			ntevs = debuginfo__find_trace_events(dinfo, pev,
							     tevs, max_tevs);
			ntevs = debuginfo__find_trace_events(dinfo, pev, tevs);
			/*
			 * Write back to the original probe_event for
			 * setting appropriate (user given) event name
@@ -821,8 +820,7 @@ int show_line_range(struct line_range *lr, const char *module, bool user)

static int show_available_vars_at(struct debuginfo *dinfo,
				  struct perf_probe_event *pev,
				  int max_vls, struct strfilter *_filter,
				  bool externs)
				  struct strfilter *_filter)
{
	char *buf;
	int ret, i, nvars;
@@ -836,13 +834,12 @@ static int show_available_vars_at(struct debuginfo *dinfo,
		return -EINVAL;
	pr_debug("Searching variables at %s\n", buf);

	ret = debuginfo__find_available_vars_at(dinfo, pev, &vls,
						max_vls, externs);
	ret = debuginfo__find_available_vars_at(dinfo, pev, &vls);
	if (!ret) {  /* Not found, retry with an alternative */
		ret = get_alternative_probe_event(dinfo, pev, &tmp);
		if (!ret) {
			ret = debuginfo__find_available_vars_at(dinfo, pev,
						&vls, max_vls, externs);
								&vls);
			/* Release the old probe_point */
			clear_perf_probe_point(&tmp);
		}
@@ -889,7 +886,7 @@ static int show_available_vars_at(struct debuginfo *dinfo,

/* Show available variables on given probe point */
int show_available_vars(struct perf_probe_event *pevs, int npevs,
			int max_vls, struct strfilter *_filter, bool externs)
			struct strfilter *_filter)
{
	int i, ret = 0;
	struct debuginfo *dinfo;
@@ -907,8 +904,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
	setup_pager();

	for (i = 0; i < npevs && ret >= 0; i++)
		ret = show_available_vars_at(dinfo, &pevs[i], max_vls, _filter,
					     externs);
		ret = show_available_vars_at(dinfo, &pevs[i], _filter);

	debuginfo__delete(dinfo);
out:
@@ -927,8 +923,7 @@ find_perf_probe_point_from_dwarf(struct probe_trace_point *tp __maybe_unused,
}

static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
				struct probe_trace_event **tevs __maybe_unused,
				int max_tevs __maybe_unused)
				struct probe_trace_event **tevs __maybe_unused)
{
	if (perf_probe_event_need_dwarf(pev)) {
		pr_warning("Debuginfo-analysis is not supported.\n");
@@ -947,9 +942,8 @@ int show_line_range(struct line_range *lr __maybe_unused,
}

int show_available_vars(struct perf_probe_event *pevs __maybe_unused,
			int npevs __maybe_unused, int max_vls __maybe_unused,
			struct strfilter *filter __maybe_unused,
			bool externs __maybe_unused)
			int npevs __maybe_unused,
			struct strfilter *filter __maybe_unused)
{
	pr_warning("Debuginfo-analysis is not supported.\n");
	return -ENOSYS;
@@ -2514,8 +2508,7 @@ void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused,
 * Return an error or the number of found probe_trace_event
 */
static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
					    struct probe_trace_event **tevs,
					    int max_tevs)
					    struct probe_trace_event **tevs)
{
	struct map *map = NULL;
	struct ref_reloc_sym *reloc_sym = NULL;
@@ -2542,7 +2535,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
			pev->target ? : "kernel");
		ret = -ENOENT;
		goto out;
	} else if (num_matched_functions > max_tevs) {
	} else if (num_matched_functions > probe_conf.max_probes) {
		pr_err("Too many functions matched in %s\n",
			pev->target ? : "kernel");
		ret = -E2BIG;
@@ -2634,8 +2627,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
bool __weak arch__prefers_symtab(void) { return false; }

static int convert_to_probe_trace_events(struct perf_probe_event *pev,
					  struct probe_trace_event **tevs,
					  int max_tevs)
					 struct probe_trace_event **tevs)
{
	int ret;

@@ -2649,17 +2641,17 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
	}

	if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
		ret = find_probe_trace_events_from_map(pev, tevs, max_tevs);
		ret = find_probe_trace_events_from_map(pev, tevs);
		if (ret > 0)
			return ret; /* Found in symbol table */
	}

	/* Convert perf_probe_event with debuginfo */
	ret = try_to_find_probe_trace_events(pev, tevs, max_tevs);
	ret = try_to_find_probe_trace_events(pev, tevs);
	if (ret != 0)
		return ret;	/* Found in debuginfo or got an error */

	return find_probe_trace_events_from_map(pev, tevs, max_tevs);
	return find_probe_trace_events_from_map(pev, tevs);
}

struct __event_package {
@@ -2668,8 +2660,7 @@ struct __event_package {
	int				ntevs;
};

int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
			  int max_tevs, bool force_add)
int add_perf_probe_events(struct perf_probe_event *pevs, int npevs)
{
	int i, j, ret;
	struct __event_package *pkgs;
@@ -2691,8 +2682,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
		pkgs[i].pev = &pevs[i];
		/* Convert with or without debuginfo */
		ret  = convert_to_probe_trace_events(pkgs[i].pev,
						     &pkgs[i].tevs,
						     max_tevs);
						     &pkgs[i].tevs);
		if (ret < 0)
			goto end;
		pkgs[i].ntevs = ret;
@@ -2701,7 +2691,8 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
	/* Loop 2: add all events */
	for (i = 0; i < npevs; i++) {
		ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs,
						pkgs[i].ntevs, force_add);
					       pkgs[i].ntevs,
					       probe_conf.force_add);
		if (ret < 0)
			break;
	}
+9 −4
Original line number Diff line number Diff line
@@ -6,6 +6,13 @@
#include "strlist.h"
#include "strfilter.h"

/* Probe related configurations */
struct probe_conf {
	bool	show_ext_vars;
	bool	force_add;
	int	max_probes;
};
extern struct probe_conf probe_conf;
extern bool probe_event_dry_run;

/* kprobe-tracer and uprobe-tracer tracing point */
@@ -124,15 +131,13 @@ extern int line_range__init(struct line_range *lr);
/* Internal use: Return kernel/module path */
extern const char *kernel_get_module_path(const char *module);

extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
				 int max_probe_points, bool force_add);
extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
extern int del_perf_probe_events(struct strfilter *filter);
extern int show_perf_probe_events(struct strfilter *filter);
extern int show_line_range(struct line_range *lr, const char *module,
			   bool user);
extern int show_available_vars(struct perf_probe_event *pevs, int npevs,
			       int max_probe_points, struct strfilter *filter,
			       bool externs);
			       struct strfilter *filter);
extern int show_available_funcs(const char *module, struct strfilter *filter,
				bool user);
bool arch__prefers_symtab(void);
+8 −9
Original line number Diff line number Diff line
@@ -1214,15 +1214,15 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
/* Find probe_trace_events specified by perf_probe_event from debuginfo */
int debuginfo__find_trace_events(struct debuginfo *dbg,
				 struct perf_probe_event *pev,
				 struct probe_trace_event **tevs, int max_tevs)
				 struct probe_trace_event **tevs)
{
	struct trace_event_finder tf = {
			.pf = {.pev = pev, .callback = add_probe_trace_event},
			.mod = dbg->mod, .max_tevs = max_tevs};
			.max_tevs = probe_conf.max_probes, .mod = dbg->mod};
	int ret;

	/* Allocate result tevs array */
	*tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs);
	*tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs);
	if (*tevs == NULL)
		return -ENOMEM;

@@ -1303,9 +1303,9 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
	die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem);

	/* Find external variables */
	if (!af->externs)
	if (!probe_conf.show_ext_vars)
		goto out;
	/* Don't need to search child DIE for externs. */
	/* Don't need to search child DIE for external vars. */
	af->child = false;
	die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem);

@@ -1325,17 +1325,16 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
 */
int debuginfo__find_available_vars_at(struct debuginfo *dbg,
				      struct perf_probe_event *pev,
				      struct variable_list **vls,
				      int max_vls, bool externs)
				      struct variable_list **vls)
{
	struct available_var_finder af = {
			.pf = {.pev = pev, .callback = add_available_vars},
			.mod = dbg->mod,
			.max_vls = max_vls, .externs = externs};
			.max_vls = probe_conf.max_probes};
	int ret;

	/* Allocate result vls array */
	*vls = zalloc(sizeof(struct variable_list) * max_vls);
	*vls = zalloc(sizeof(struct variable_list) * af.max_vls);
	if (*vls == NULL)
		return -ENOMEM;

+2 −5
Original line number Diff line number Diff line
@@ -40,8 +40,7 @@ extern void debuginfo__delete(struct debuginfo *dbg);
/* Find probe_trace_events specified by perf_probe_event from debuginfo */
extern int debuginfo__find_trace_events(struct debuginfo *dbg,
					struct perf_probe_event *pev,
					struct probe_trace_event **tevs,
					int max_tevs);
					struct probe_trace_event **tevs);

/* Find a perf_probe_point from debuginfo */
extern int debuginfo__find_probe_point(struct debuginfo *dbg,
@@ -55,8 +54,7 @@ extern int debuginfo__find_line_range(struct debuginfo *dbg,
/* Find available variables */
extern int debuginfo__find_available_vars_at(struct debuginfo *dbg,
					     struct perf_probe_event *pev,
					     struct variable_list **vls,
					     int max_points, bool externs);
					     struct variable_list **vls);

/* Find a src file from a DWARF tag path */
int get_real_path(const char *raw_path, const char *comp_dir,
@@ -99,7 +97,6 @@ struct available_var_finder {
	struct variable_list	*vls;		/* Found variable lists */
	int			nvls;		/* Number of variable lists */
	int			max_vls;	/* Max no. of variable lists */
	bool			externs;	/* Find external vars too */
	bool			child;		/* Search child scopes */
};