All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] perf session: Add perf_session__delete_env
@ 2012-11-20  9:31 Feng Tang
  2012-11-20  9:31 ` [PATCH 2/3] perf hists browser: Add option for runtime switching perf data file Feng Tang
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Feng Tang @ 2012-11-20  9:31 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Namhyung Kim, Andi Kleen, linux-kernel
  Cc: Namhyung Kim

From: Namhyung Kim <namhyung.kim@lge.com>

The perf session environment information was saved (so allocated)
during perf_session__open, but was not freed.  As free(3) handles NULL
pointer input properly it won't cause a issue for writing modes -
e.g. perf record.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/session.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ce6f511..e9ce524 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -204,11 +204,30 @@ static void perf_session__delete_threads(struct perf_session *session)
 	machine__delete_threads(&session->host_machine);
 }
 
+static void perf_session__delete_env(struct perf_session *self)
+{
+	struct perf_session_env *env = &self->header.env;
+
+	free(env->hostname);
+	free(env->os_release);
+	free(env->version);
+	free(env->arch);
+	free(env->cpu_desc);
+	free(env->cpuid);
+
+	free(env->cmdline);
+	free(env->sibling_cores);
+	free(env->sibling_threads);
+	free(env->numa_nodes);
+	free(env->pmu_mappings);
+}
+
 void perf_session__delete(struct perf_session *self)
 {
 	perf_session__destroy_kernel_maps(self);
 	perf_session__delete_dead_threads(self);
 	perf_session__delete_threads(self);
+	perf_session__delete_env(self);
 	machine__exit(&self->host_machine);
 	close(self->fd);
 	free(self);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] perf hists browser: Add option for runtime switching perf data file
  2012-11-20  9:31 [PATCH 1/3] perf session: Add perf_session__delete_env Feng Tang
@ 2012-11-20  9:31 ` Feng Tang
  2012-11-20 15:16   ` Arnaldo Carvalho de Melo
  2012-11-20  9:31 ` [PATCH 3/3] perf report: Enable the runtime switching of " Feng Tang
  2012-11-20 15:13 ` [PATCH 1/3] perf session: Add perf_session__delete_env Arnaldo Carvalho de Melo
  2 siblings, 1 reply; 10+ messages in thread
From: Feng Tang @ 2012-11-20  9:31 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Namhyung Kim, Andi Kleen, linux-kernel
  Cc: Feng Tang

Based on perf report/top/scripts browser integration idea from acme.

This will enable user to runtime switch the data file, when this option
is selected, it will popup all the legal data files in current working
directory, and the filename selected by user is saved in the global
variable "input_name", and a new key 'K_SWITCH_INPUT_DATA' will be
passed back to the built-in command which will perform the switch.

This initial version only enables it for 'perf report'.

Signed-off-by: Feng Tang <feng.tang@intel.com>
---
 tools/perf/ui/browsers/hists.c |  113 +++++++++++++++++++++++++++++++++++++++-
 tools/perf/ui/keysyms.h        |    1 +
 2 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index ccc4bd1..c64254b 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1135,6 +1135,97 @@ static inline bool is_report_browser(void *timer)
 	return timer == NULL;
 }
 
+/*
+ * Only runtime switching of perf data file will make "input_name" point
+ * to a malloced buffer. So add "is_input_name_malloced" flag to decide
+ * whether we need to call free() for current "input_name" during the switch.
+ */
+static bool is_input_name_malloced = false;
+
+static int switch_data_file(void)
+{
+	char *pwd, *options[32], *abs_path[32], *tmp;
+	DIR *pwd_dir;
+	int nr_options = 0, choice = -1, ret = -1;
+
+	struct dirent *dent;
+
+	pwd = getenv("PWD");
+	if (!pwd)
+		return ret;
+
+	pwd_dir = opendir(pwd);
+	if (!pwd_dir)
+		return ret;
+
+	memset(options, 0, sizeof(options));
+	memset(options, 0, sizeof(abs_path));
+
+	while ((dent = readdir(pwd_dir))) {
+		char path[PATH_MAX];
+		u64 magic;
+		char *name = dent->d_name;
+		FILE *file;
+
+		if (!(dent->d_type == DT_REG))
+			continue;
+
+		snprintf(path, PATH_MAX, "%s/%s", pwd, name);
+
+		file = fopen(path, "r");
+		if (!file)
+			continue;
+
+		if (fread(&magic, 1, 8, file) < 8)
+			goto close_file_and_continue;
+
+		if (is_perf_magic(magic)) {
+			options[nr_options] = strdup(name);
+			if (!options[nr_options])
+				goto close_file_and_continue;
+
+			abs_path[nr_options] = strdup(path);
+			if (!abs_path[nr_options]) {
+				free(options[nr_options]);
+				ui__warning("Can't search all data files due to memory shortage.\n");
+				fclose(file);
+				break;
+			}
+
+			nr_options++;
+		}
+
+close_file_and_continue:
+		fclose(file);
+		if (nr_options >= 32) {
+			ui__warning("Too many perf data files in PWD!\n"
+				    "Only the first 32 files will be listed.\n");
+			break;
+		}
+	}
+	closedir(pwd_dir);
+
+	if (nr_options) {
+		choice = ui__popup_menu(nr_options, options);
+		if (choice < nr_options && choice >= 0) {
+			tmp = strdup(abs_path[choice]);
+			if (tmp) {
+				if (is_input_name_malloced)
+					free((void *)input_name);
+				input_name = tmp;
+				is_input_name_malloced = true;
+				ret = 0;
+			} else
+				ui__warning("Data switch failed due to memory shortage!\n");
+		}
+	}
+
+	free_popup_options(options, nr_options);
+	free_popup_options(abs_path, nr_options);
+	return ret;
+}
+
+
 static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 				    const char *helpline, const char *ev_name,
 				    bool left_exits,
@@ -1169,7 +1260,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 		int choice = 0,
 		    annotate = -2, zoom_dso = -2, zoom_thread = -2,
 		    annotate_f = -2, annotate_t = -2, browse_map = -2;
-		int scripts_comm = -2, scripts_symbol = -2, scripts_all = -2;
+		int scripts_comm = -2, scripts_symbol = -2,
+		    scripts_all = -2, switch_data = -2;
 
 		nr_options = 0;
 
@@ -1226,6 +1318,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 			if (is_report_browser(hbt))
 				goto do_scripts;
 			continue;
+		case 's':
+			if (is_report_browser(hbt))
+				goto do_data_switch;
+			continue;
 		case K_F1:
 		case 'h':
 		case '?':
@@ -1245,6 +1341,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 					"d             Zoom into current DSO\n"
 					"t             Zoom into current Thread\n"
 					"r             Run available scripts('perf report' only)\n"
+					"s             Switch to another data file in PWD ('perf report' only)\n"
 					"P             Print histograms to perf.hist.N\n"
 					"V             Verbose (DSO names in callchains, etc)\n"
 					"/             Filter symbol by name");
@@ -1352,6 +1449,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 		if (asprintf(&options[nr_options], "Run scripts for all samples") > 0)
 			scripts_all = nr_options++;
 
+		if (is_report_browser(hbt) && asprintf(&options[nr_options],
+				"Switch to another data file in PWD") > 0)
+			switch_data = nr_options++;
 add_exit_option:
 		options[nr_options++] = (char *)"Exit";
 retry_popup_menu:
@@ -1462,6 +1562,16 @@ do_scripts:
 
 			script_browse(script_opt);
 		}
+		/* Switch to another data file */
+		else if (choice == switch_data) {
+do_data_switch:
+			if (!switch_data_file()) {
+				key = K_SWITCH_INPUT_DATA;
+				break;
+			} else
+				ui__warning("Won't switch the data files due to\n"
+					"no valid data file get selected!\n");
+		}
 	}
 out_free_stack:
 	pstack__delete(fstack);
@@ -1578,6 +1688,7 @@ browse_hists:
 						"Do you really want to exit?"))
 					continue;
 				/* Fall thru */
+			case K_SWITCH_INPUT_DATA:
 			case 'q':
 			case CTRL('c'):
 				goto out;
diff --git a/tools/perf/ui/keysyms.h b/tools/perf/ui/keysyms.h
index 809eca5..65092d5 100644
--- a/tools/perf/ui/keysyms.h
+++ b/tools/perf/ui/keysyms.h
@@ -23,5 +23,6 @@
 #define K_TIMER	 -1
 #define K_ERROR	 -2
 #define K_RESIZE -3
+#define K_SWITCH_INPUT_DATA -4
 
 #endif /* _PERF_KEYSYMS_H_ */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] perf report: Enable the runtime switching of perf data file
  2012-11-20  9:31 [PATCH 1/3] perf session: Add perf_session__delete_env Feng Tang
  2012-11-20  9:31 ` [PATCH 2/3] perf hists browser: Add option for runtime switching perf data file Feng Tang
@ 2012-11-20  9:31 ` Feng Tang
  2012-11-20 15:13 ` [PATCH 1/3] perf session: Add perf_session__delete_env Arnaldo Carvalho de Melo
  2 siblings, 0 replies; 10+ messages in thread
From: Feng Tang @ 2012-11-20  9:31 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Namhyung Kim, Andi Kleen, linux-kernel
  Cc: Feng Tang

This is for tui browser only. This patch will check the returned
key of tui hists browser, if it's K_SWITH_INPUT_DATA, then recreate
a session for the new selected data file.

Signed-off-by: Feng Tang <feng.tang@intel.com>
---
 tools/perf/builtin-report.c |   22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index fc25100..5392a8e 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -427,9 +427,17 @@ static int __cmd_report(struct perf_report *rep)
 
 	if (use_browser > 0) {
 		if (use_browser == 1) {
-			perf_evlist__tui_browse_hists(session->evlist, help,
-						      NULL,
-						      &session->header.env);
+			ret = perf_evlist__tui_browse_hists(session->evlist,
+							help,
+							NULL,
+							&session->header.env);
+			/*
+			 * Usually "ret" is the last pressed key, and we only
+			 * care if the key notifies us to switch data file.
+			 */
+			if (ret != K_SWITCH_INPUT_DATA)
+				ret = 0;
+
 		} else if (use_browser == 2) {
 			perf_evlist__gtk_browse_hists(session->evlist, help,
 						      NULL);
@@ -663,6 +671,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 		else
 			input_name = "perf.data";
 	}
+
+repeat:
 	session = perf_session__new(input_name, O_RDONLY,
 				    report.force, false, &report.tool);
 	if (session == NULL)
@@ -763,6 +773,12 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 	}
 
 	ret = __cmd_report(&report);
+	if (ret == K_SWITCH_INPUT_DATA) {
+		perf_session__delete(session);
+		goto repeat;
+	} else
+		ret = 0;
+
 error:
 	perf_session__delete(session);
 	return ret;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] perf session: Add perf_session__delete_env
  2012-11-20  9:31 [PATCH 1/3] perf session: Add perf_session__delete_env Feng Tang
  2012-11-20  9:31 ` [PATCH 2/3] perf hists browser: Add option for runtime switching perf data file Feng Tang
  2012-11-20  9:31 ` [PATCH 3/3] perf report: Enable the runtime switching of " Feng Tang
@ 2012-11-20 15:13 ` Arnaldo Carvalho de Melo
  2012-11-20 15:20   ` Namhyung Kim
  2 siblings, 1 reply; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2012-11-20 15:13 UTC (permalink / raw)
  To: Feng Tang
  Cc: Peter Zijlstra, Ingo Molnar, Namhyung Kim, Andi Kleen,
	linux-kernel, Namhyung Kim

Em Tue, Nov 20, 2012 at 05:31:15PM +0800, Feng Tang escreveu:
> +static void perf_session__delete_env(struct perf_session *self)
> +{
> +	struct perf_session_env *env = &self->header.env;
> +
> +	free(env->hostname);
> +	free(env->os_release);
> +	free(env->version);
> +	free(env->arch);
> +	free(env->cpu_desc);
> +	free(env->cpuid);
> +
> +	free(env->cmdline);
> +	free(env->sibling_cores);
> +	free(env->sibling_threads);
> +	free(env->numa_nodes);
> +	free(env->pmu_mappings);
> +}

The object being deleted is a perf_session_env, so please make it
perf_session_env__delete(struct perf_session_env *env), and avoid using
'self'.

- Arnaldo

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] perf hists browser: Add option for runtime switching perf data file
  2012-11-20  9:31 ` [PATCH 2/3] perf hists browser: Add option for runtime switching perf data file Feng Tang
@ 2012-11-20 15:16   ` Arnaldo Carvalho de Melo
  2012-11-20 16:16     ` Feng Tang
  2012-11-20 16:24     ` Feng Tang
  0 siblings, 2 replies; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2012-11-20 15:16 UTC (permalink / raw)
  To: Feng Tang
  Cc: Peter Zijlstra, Ingo Molnar, Namhyung Kim, Andi Kleen, linux-kernel

Em Tue, Nov 20, 2012 at 05:31:16PM +0800, Feng Tang escreveu:
> Based on perf report/top/scripts browser integration idea from acme.
> 
> This will enable user to runtime switch the data file, when this option
> is selected, it will popup all the legal data files in current working
> directory, and the filename selected by user is saved in the global
> variable "input_name", and a new key 'K_SWITCH_INPUT_DATA' will be
> passed back to the built-in command which will perform the switch.
> 
> This initial version only enables it for 'perf report'.
> 
> Signed-off-by: Feng Tang <feng.tang@intel.com>
> ---
>  tools/perf/ui/browsers/hists.c |  113 +++++++++++++++++++++++++++++++++++++++-
>  tools/perf/ui/keysyms.h        |    1 +
>  2 files changed, 113 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
> index ccc4bd1..c64254b 100644
> --- a/tools/perf/ui/browsers/hists.c
> +++ b/tools/perf/ui/browsers/hists.c
> @@ -1135,6 +1135,97 @@ static inline bool is_report_browser(void *timer)
>  	return timer == NULL;
>  }
>  
> +/*
> + * Only runtime switching of perf data file will make "input_name" point
> + * to a malloced buffer. So add "is_input_name_malloced" flag to decide
> + * whether we need to call free() for current "input_name" during the switch.
> + */
> +static bool is_input_name_malloced = false;
> +
> +static int switch_data_file(void)
> +{
> +	char *pwd, *options[32], *abs_path[32], *tmp;
> +	DIR *pwd_dir;
> +	int nr_options = 0, choice = -1, ret = -1;
> +

no need for this empty line

> +	struct dirent *dent;
> +
> +	pwd = getenv("PWD");
> +	if (!pwd)
> +		return ret;
> +
> +	pwd_dir = opendir(pwd);
> +	if (!pwd_dir)
> +		return ret;
> +
> +	memset(options, 0, sizeof(options));
> +	memset(options, 0, sizeof(abs_path));
> +
> +	while ((dent = readdir(pwd_dir))) {
> +		char path[PATH_MAX];
> +		u64 magic;
> +		char *name = dent->d_name;
> +		FILE *file;
> +
> +		if (!(dent->d_type == DT_REG))
> +			continue;
> +
> +		snprintf(path, PATH_MAX, "%s/%s", pwd, name);

                       sizeof(path)
> +
> +		file = fopen(path, "r");
> +		if (!file)
> +			continue;
> +
> +		if (fread(&magic, 1, 8, file) < 8)
> +			goto close_file_and_continue;
> +
> +		if (is_perf_magic(magic)) {
> +			options[nr_options] = strdup(name);
> +			if (!options[nr_options])
> +				goto close_file_and_continue;
> +
> +			abs_path[nr_options] = strdup(path);
> +			if (!abs_path[nr_options]) {
> +				free(options[nr_options]);
> +				ui__warning("Can't search all data files due to memory shortage.\n");
> +				fclose(file);
> +				break;
> +			}
> +
> +			nr_options++;
> +		}
> +
> +close_file_and_continue:
> +		fclose(file);
> +		if (nr_options >= 32) {
> +			ui__warning("Too many perf data files in PWD!\n"
> +				    "Only the first 32 files will be listed.\n");
> +			break;
> +		}
> +	}
> +	closedir(pwd_dir);
> +
> +	if (nr_options) {
> +		choice = ui__popup_menu(nr_options, options);
> +		if (choice < nr_options && choice >= 0) {
> +			tmp = strdup(abs_path[choice]);
> +			if (tmp) {
> +				if (is_input_name_malloced)
> +					free((void *)input_name);
> +				input_name = tmp;
> +				is_input_name_malloced = true;
> +				ret = 0;
> +			} else
> +				ui__warning("Data switch failed due to memory shortage!\n");
> +		}
> +	}
> +
> +	free_popup_options(options, nr_options);
> +	free_popup_options(abs_path, nr_options);
> +	return ret;
> +}
> +
> +
>  static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
>  				    const char *helpline, const char *ev_name,
>  				    bool left_exits,
> @@ -1169,7 +1260,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
>  		int choice = 0,
>  		    annotate = -2, zoom_dso = -2, zoom_thread = -2,
>  		    annotate_f = -2, annotate_t = -2, browse_map = -2;
> -		int scripts_comm = -2, scripts_symbol = -2, scripts_all = -2;
> +		int scripts_comm = -2, scripts_symbol = -2,
> +		    scripts_all = -2, switch_data = -2;
>  
>  		nr_options = 0;
>  
> @@ -1226,6 +1318,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
>  			if (is_report_browser(hbt))
>  				goto do_scripts;
>  			continue;
> +		case 's':
> +			if (is_report_browser(hbt))
> +				goto do_data_switch;
> +			continue;
>  		case K_F1:
>  		case 'h':
>  		case '?':
> @@ -1245,6 +1341,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
>  					"d             Zoom into current DSO\n"
>  					"t             Zoom into current Thread\n"
>  					"r             Run available scripts('perf report' only)\n"
> +					"s             Switch to another data file in PWD ('perf report' only)\n"
>  					"P             Print histograms to perf.hist.N\n"
>  					"V             Verbose (DSO names in callchains, etc)\n"
>  					"/             Filter symbol by name");
> @@ -1352,6 +1449,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
>  		if (asprintf(&options[nr_options], "Run scripts for all samples") > 0)
>  			scripts_all = nr_options++;
>  
> +		if (is_report_browser(hbt) && asprintf(&options[nr_options],
> +				"Switch to another data file in PWD") > 0)
> +			switch_data = nr_options++;
>  add_exit_option:
>  		options[nr_options++] = (char *)"Exit";
>  retry_popup_menu:
> @@ -1462,6 +1562,16 @@ do_scripts:
>  
>  			script_browse(script_opt);
>  		}
> +		/* Switch to another data file */
> +		else if (choice == switch_data) {
> +do_data_switch:
> +			if (!switch_data_file()) {
> +				key = K_SWITCH_INPUT_DATA;
> +				break;
> +			} else
> +				ui__warning("Won't switch the data files due to\n"
> +					"no valid data file get selected!\n");
> +		}
>  	}
>  out_free_stack:
>  	pstack__delete(fstack);
> @@ -1578,6 +1688,7 @@ browse_hists:
>  						"Do you really want to exit?"))
>  					continue;
>  				/* Fall thru */
> +			case K_SWITCH_INPUT_DATA:
>  			case 'q':
>  			case CTRL('c'):
>  				goto out;
> diff --git a/tools/perf/ui/keysyms.h b/tools/perf/ui/keysyms.h
> index 809eca5..65092d5 100644
> --- a/tools/perf/ui/keysyms.h
> +++ b/tools/perf/ui/keysyms.h
> @@ -23,5 +23,6 @@
>  #define K_TIMER	 -1
>  #define K_ERROR	 -2
>  #define K_RESIZE -3
> +#define K_SWITCH_INPUT_DATA -4
>  
>  #endif /* _PERF_KEYSYMS_H_ */
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] perf session: Add perf_session__delete_env
  2012-11-20 15:13 ` [PATCH 1/3] perf session: Add perf_session__delete_env Arnaldo Carvalho de Melo
@ 2012-11-20 15:20   ` Namhyung Kim
  2012-11-21  4:43     ` [PATCH v2 1/3] perf session: Free environment information when deleting session Namhyung Kim
  0 siblings, 1 reply; 10+ messages in thread
From: Namhyung Kim @ 2012-11-20 15:20 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Feng Tang, Peter Zijlstra, Ingo Molnar, Andi Kleen, linux-kernel,
	Namhyung Kim

2012-11-20 (화), 12:13 -0300, Arnaldo Carvalho de Melo:
> Em Tue, Nov 20, 2012 at 05:31:15PM +0800, Feng Tang escreveu:
> > +static void perf_session__delete_env(struct perf_session *self)
> > +{
> > +	struct perf_session_env *env = &self->header.env;
> > +
> > +	free(env->hostname);
> > +	free(env->os_release);
> > +	free(env->version);
> > +	free(env->arch);
> > +	free(env->cpu_desc);
> > +	free(env->cpuid);
> > +
> > +	free(env->cmdline);
> > +	free(env->sibling_cores);
> > +	free(env->sibling_threads);
> > +	free(env->numa_nodes);
> > +	free(env->pmu_mappings);
> > +}
> 
> The object being deleted is a perf_session_env, so please make it
> perf_session_env__delete(struct perf_session_env *env), and avoid using
> 'self'.

Okay, will do.

Thanks,
Namhyung



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] perf hists browser: Add option for runtime switching perf data file
  2012-11-20 15:16   ` Arnaldo Carvalho de Melo
@ 2012-11-20 16:16     ` Feng Tang
  2012-11-20 16:24     ` Feng Tang
  1 sibling, 0 replies; 10+ messages in thread
From: Feng Tang @ 2012-11-20 16:16 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Namhyung Kim, Andi Kleen, linux-kernel

Hi Arnaldo,

On Tue, Nov 20, 2012 at 12:16:44PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, Nov 20, 2012 at 05:31:16PM +0800, Feng Tang escreveu:
> > +static int switch_data_file(void)
> > +{
> > +	char *pwd, *options[32], *abs_path[32], *tmp;
> > +	DIR *pwd_dir;
> > +	int nr_options = 0, choice = -1, ret = -1;
> > +
> 
> no need for this empty line
> 
> > +	while ((dent = readdir(pwd_dir))) {
> > +		char path[PATH_MAX];
> > +		u64 magic;
> > +		char *name = dent->d_name;
> > +		FILE *file;
> > +
> > +		if (!(dent->d_type == DT_REG))
> > +			continue;
> > +
> > +		snprintf(path, PATH_MAX, "%s/%s", pwd, name);
> 
>                        sizeof(path)

Thanks for the review, here is the updated one:


>From 6e3259cf652af9f3c41bdc76c71190b7a723f702 Mon Sep 17 00:00:00 2001
From: Feng Tang <feng.tang@intel.com>
Date: Tue, 20 Nov 2012 16:21:10 +0800
Subject: [PATCH 2/3] perf hists browser: Add option for runtime switching
 perf data file

Based on perf report/top/scripts browser integration idea from acme.

This will enable user to runtime switch the data file, when this option
is selected, it will popup all the legal data files in current working
directory, and the filename selected by user is saved in the global
variable "input_name", and a new key 'K_SWITCH_INPUT_DATA' will be
passed back to the built-in command which will perform the switch.

This initial version only enables it for 'perf report'.

Signed-off-by: Feng Tang <feng.tang@intel.com>
---
 tools/perf/ui/browsers/hists.c |  113 +++++++++++++++++++++++++++++++++++++++-
 tools/perf/ui/keysyms.h        |    1 +
 2 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index ccc4bd1..c64254b 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1135,6 +1135,97 @@ static inline bool is_report_browser(void *timer)
 	return timer == NULL;
 }
 
+/*
+ * Only runtime switching of perf data file will make "input_name" point
+ * to a malloced buffer. So add "is_input_name_malloced" flag to decide
+ * whether we need to call free() for current "input_name" during the switch.
+ */
+static bool is_input_name_malloced = false;
+
+static int switch_data_file(void)
+{
+	char *pwd, *options[32], *abs_path[32], *tmp;
+	DIR *pwd_dir;
+	int nr_options = 0, choice = -1, ret = -1;
+
+	struct dirent *dent;
+
+	pwd = getenv("PWD");
+	if (!pwd)
+		return ret;
+
+	pwd_dir = opendir(pwd);
+	if (!pwd_dir)
+		return ret;
+
+	memset(options, 0, sizeof(options));
+	memset(options, 0, sizeof(abs_path));
+
+	while ((dent = readdir(pwd_dir))) {
+		char path[PATH_MAX];
+		u64 magic;
+		char *name = dent->d_name;
+		FILE *file;
+
+		if (!(dent->d_type == DT_REG))
+			continue;
+
+		snprintf(path, PATH_MAX, "%s/%s", pwd, name);
+
+		file = fopen(path, "r");
+		if (!file)
+			continue;
+
+		if (fread(&magic, 1, 8, file) < 8)
+			goto close_file_and_continue;
+
+		if (is_perf_magic(magic)) {
+			options[nr_options] = strdup(name);
+			if (!options[nr_options])
+				goto close_file_and_continue;
+
+			abs_path[nr_options] = strdup(path);
+			if (!abs_path[nr_options]) {
+				free(options[nr_options]);
+				ui__warning("Can't search all data files due to memory shortage.\n");
+				fclose(file);
+				break;
+			}
+
+			nr_options++;
+		}
+
+close_file_and_continue:
+		fclose(file);
+		if (nr_options >= 32) {
+			ui__warning("Too many perf data files in PWD!\n"
+				    "Only the first 32 files will be listed.\n");
+			break;
+		}
+	}
+	closedir(pwd_dir);
+
+	if (nr_options) {
+		choice = ui__popup_menu(nr_options, options);
+		if (choice < nr_options && choice >= 0) {
+			tmp = strdup(abs_path[choice]);
+			if (tmp) {
+				if (is_input_name_malloced)
+					free((void *)input_name);
+				input_name = tmp;
+				is_input_name_malloced = true;
+				ret = 0;
+			} else
+				ui__warning("Data switch failed due to memory shortage!\n");
+		}
+	}
+
+	free_popup_options(options, nr_options);
+	free_popup_options(abs_path, nr_options);
+	return ret;
+}
+
+
 static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 				    const char *helpline, const char *ev_name,
 				    bool left_exits,
@@ -1169,7 +1260,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 		int choice = 0,
 		    annotate = -2, zoom_dso = -2, zoom_thread = -2,
 		    annotate_f = -2, annotate_t = -2, browse_map = -2;
-		int scripts_comm = -2, scripts_symbol = -2, scripts_all = -2;
+		int scripts_comm = -2, scripts_symbol = -2,
+		    scripts_all = -2, switch_data = -2;
 
 		nr_options = 0;
 
@@ -1226,6 +1318,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 			if (is_report_browser(hbt))
 				goto do_scripts;
 			continue;
+		case 's':
+			if (is_report_browser(hbt))
+				goto do_data_switch;
+			continue;
 		case K_F1:
 		case 'h':
 		case '?':
@@ -1245,6 +1341,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 					"d             Zoom into current DSO\n"
 					"t             Zoom into current Thread\n"
 					"r             Run available scripts('perf report' only)\n"
+					"s             Switch to another data file in PWD ('perf report' only)\n"
 					"P             Print histograms to perf.hist.N\n"
 					"V             Verbose (DSO names in callchains, etc)\n"
 					"/             Filter symbol by name");
@@ -1352,6 +1449,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 		if (asprintf(&options[nr_options], "Run scripts for all samples") > 0)
 			scripts_all = nr_options++;
 
+		if (is_report_browser(hbt) && asprintf(&options[nr_options],
+				"Switch to another data file in PWD") > 0)
+			switch_data = nr_options++;
 add_exit_option:
 		options[nr_options++] = (char *)"Exit";
 retry_popup_menu:
@@ -1462,6 +1562,16 @@ do_scripts:
 
 			script_browse(script_opt);
 		}
+		/* Switch to another data file */
+		else if (choice == switch_data) {
+do_data_switch:
+			if (!switch_data_file()) {
+				key = K_SWITCH_INPUT_DATA;
+				break;
+			} else
+				ui__warning("Won't switch the data files due to\n"
+					"no valid data file get selected!\n");
+		}
 	}
 out_free_stack:
 	pstack__delete(fstack);
@@ -1578,6 +1688,7 @@ browse_hists:
 						"Do you really want to exit?"))
 					continue;
 				/* Fall thru */
+			case K_SWITCH_INPUT_DATA:
 			case 'q':
 			case CTRL('c'):
 				goto out;
diff --git a/tools/perf/ui/keysyms.h b/tools/perf/ui/keysyms.h
index 809eca5..65092d5 100644
--- a/tools/perf/ui/keysyms.h
+++ b/tools/perf/ui/keysyms.h
@@ -23,5 +23,6 @@
 #define K_TIMER	 -1
 #define K_ERROR	 -2
 #define K_RESIZE -3
+#define K_SWITCH_INPUT_DATA -4
 
 #endif /* _PERF_KEYSYMS_H_ */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] perf hists browser: Add option for runtime switching perf data file
  2012-11-20 15:16   ` Arnaldo Carvalho de Melo
  2012-11-20 16:16     ` Feng Tang
@ 2012-11-20 16:24     ` Feng Tang
  1 sibling, 0 replies; 10+ messages in thread
From: Feng Tang @ 2012-11-20 16:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Namhyung Kim, Andi Kleen, linux-kernel

Sorry, just repost the old patch by mistake. should not do patch
work in midnight :), here is real updated one.


>From 0045aab3beeb39f119e44a4f5980cca71b599468 Mon Sep 17 00:00:00 2001
From: Feng Tang <feng.tang@intel.com>
Date: Tue, 20 Nov 2012 16:21:10 +0800
Subject: [PATCH 2/3] perf hists browser: Add option for runtime switching
 perf data file

Based on perf report/top/scripts browser integration idea from acme.

This will enable user to runtime switch the data file, when this option
is selected, it will popup all the legal data files in current working
directory, and the filename selected by user is saved in the global
variable "input_name", and a new key 'K_SWITCH_INPUT_DATA' will be
passed back to the built-in command which will perform the switch.

This initial version only enables it for 'perf report'.

Signed-off-by: Feng Tang <feng.tang@intel.com>
---
 tools/perf/ui/browsers/hists.c |  112 +++++++++++++++++++++++++++++++++++++++-
 tools/perf/ui/keysyms.h        |    1 +
 2 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index ccc4bd1..83c66a1 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1135,6 +1135,96 @@ static inline bool is_report_browser(void *timer)
 	return timer == NULL;
 }
 
+/*
+ * Only runtime switching of perf data file will make "input_name" point
+ * to a malloced buffer. So add "is_input_name_malloced" flag to decide
+ * whether we need to call free() for current "input_name" during the switch.
+ */
+static bool is_input_name_malloced = false;
+
+static int switch_data_file(void)
+{
+	char *pwd, *options[32], *abs_path[32], *tmp;
+	DIR *pwd_dir;
+	int nr_options = 0, choice = -1, ret = -1;
+	struct dirent *dent;
+
+	pwd = getenv("PWD");
+	if (!pwd)
+		return ret;
+
+	pwd_dir = opendir(pwd);
+	if (!pwd_dir)
+		return ret;
+
+	memset(options, 0, sizeof(options));
+	memset(options, 0, sizeof(abs_path));
+
+	while ((dent = readdir(pwd_dir))) {
+		char path[PATH_MAX];
+		u64 magic;
+		char *name = dent->d_name;
+		FILE *file;
+
+		if (!(dent->d_type == DT_REG))
+			continue;
+
+		snprintf(path, sizeof(path), "%s/%s", pwd, name);
+
+		file = fopen(path, "r");
+		if (!file)
+			continue;
+
+		if (fread(&magic, 1, 8, file) < 8)
+			goto close_file_and_continue;
+
+		if (is_perf_magic(magic)) {
+			options[nr_options] = strdup(name);
+			if (!options[nr_options])
+				goto close_file_and_continue;
+
+			abs_path[nr_options] = strdup(path);
+			if (!abs_path[nr_options]) {
+				free(options[nr_options]);
+				ui__warning("Can't search all data files due to memory shortage.\n");
+				fclose(file);
+				break;
+			}
+
+			nr_options++;
+		}
+
+close_file_and_continue:
+		fclose(file);
+		if (nr_options >= 32) {
+			ui__warning("Too many perf data files in PWD!\n"
+				    "Only the first 32 files will be listed.\n");
+			break;
+		}
+	}
+	closedir(pwd_dir);
+
+	if (nr_options) {
+		choice = ui__popup_menu(nr_options, options);
+		if (choice < nr_options && choice >= 0) {
+			tmp = strdup(abs_path[choice]);
+			if (tmp) {
+				if (is_input_name_malloced)
+					free((void *)input_name);
+				input_name = tmp;
+				is_input_name_malloced = true;
+				ret = 0;
+			} else
+				ui__warning("Data switch failed due to memory shortage!\n");
+		}
+	}
+
+	free_popup_options(options, nr_options);
+	free_popup_options(abs_path, nr_options);
+	return ret;
+}
+
+
 static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 				    const char *helpline, const char *ev_name,
 				    bool left_exits,
@@ -1169,7 +1259,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 		int choice = 0,
 		    annotate = -2, zoom_dso = -2, zoom_thread = -2,
 		    annotate_f = -2, annotate_t = -2, browse_map = -2;
-		int scripts_comm = -2, scripts_symbol = -2, scripts_all = -2;
+		int scripts_comm = -2, scripts_symbol = -2,
+		    scripts_all = -2, switch_data = -2;
 
 		nr_options = 0;
 
@@ -1226,6 +1317,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 			if (is_report_browser(hbt))
 				goto do_scripts;
 			continue;
+		case 's':
+			if (is_report_browser(hbt))
+				goto do_data_switch;
+			continue;
 		case K_F1:
 		case 'h':
 		case '?':
@@ -1245,6 +1340,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 					"d             Zoom into current DSO\n"
 					"t             Zoom into current Thread\n"
 					"r             Run available scripts('perf report' only)\n"
+					"s             Switch to another data file in PWD ('perf report' only)\n"
 					"P             Print histograms to perf.hist.N\n"
 					"V             Verbose (DSO names in callchains, etc)\n"
 					"/             Filter symbol by name");
@@ -1352,6 +1448,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 		if (asprintf(&options[nr_options], "Run scripts for all samples") > 0)
 			scripts_all = nr_options++;
 
+		if (is_report_browser(hbt) && asprintf(&options[nr_options],
+				"Switch to another data file in PWD") > 0)
+			switch_data = nr_options++;
 add_exit_option:
 		options[nr_options++] = (char *)"Exit";
 retry_popup_menu:
@@ -1462,6 +1561,16 @@ do_scripts:
 
 			script_browse(script_opt);
 		}
+		/* Switch to another data file */
+		else if (choice == switch_data) {
+do_data_switch:
+			if (!switch_data_file()) {
+				key = K_SWITCH_INPUT_DATA;
+				break;
+			} else
+				ui__warning("Won't switch the data files due to\n"
+					"no valid data file get selected!\n");
+		}
 	}
 out_free_stack:
 	pstack__delete(fstack);
@@ -1578,6 +1687,7 @@ browse_hists:
 						"Do you really want to exit?"))
 					continue;
 				/* Fall thru */
+			case K_SWITCH_INPUT_DATA:
 			case 'q':
 			case CTRL('c'):
 				goto out;
diff --git a/tools/perf/ui/keysyms.h b/tools/perf/ui/keysyms.h
index 809eca5..65092d5 100644
--- a/tools/perf/ui/keysyms.h
+++ b/tools/perf/ui/keysyms.h
@@ -23,5 +23,6 @@
 #define K_TIMER	 -1
 #define K_ERROR	 -2
 #define K_RESIZE -3
+#define K_SWITCH_INPUT_DATA -4
 
 #endif /* _PERF_KEYSYMS_H_ */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 1/3] perf session: Free environment information when deleting session
  2012-11-20 15:20   ` Namhyung Kim
@ 2012-11-21  4:43     ` Namhyung Kim
  2013-01-24 18:39       ` [tip:perf/core] " tip-bot for Namhyung Kim
  0 siblings, 1 reply; 10+ messages in thread
From: Namhyung Kim @ 2012-11-21  4:43 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Feng Tang, Peter Zijlstra, Ingo Molnar, Andi Kleen, LKML, Namhyung Kim

From: Namhyung Kim <namhyung.kim@lge.com>

The perf session environment information was saved (so allocated)
during perf_session__open, but was not freed.  As free(3) handles NULL
pointer input properly it won't cause a issue for writing modes -
e.g. perf record

Cc: Feng Tang <feng.tang@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/session.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ce6f51162386..d5fb60760bac 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -204,11 +204,28 @@ static void perf_session__delete_threads(struct perf_session *session)
 	machine__delete_threads(&session->host_machine);
 }
 
+static void perf_session_env__delete(struct perf_session_env *env)
+{
+	free(env->hostname);
+	free(env->os_release);
+	free(env->version);
+	free(env->arch);
+	free(env->cpu_desc);
+	free(env->cpuid);
+
+	free(env->cmdline);
+	free(env->sibling_cores);
+	free(env->sibling_threads);
+	free(env->numa_nodes);
+	free(env->pmu_mappings);
+}
+
 void perf_session__delete(struct perf_session *self)
 {
 	perf_session__destroy_kernel_maps(self);
 	perf_session__delete_dead_threads(self);
 	perf_session__delete_threads(self);
+	perf_session_env__delete(&self->header.env);
 	machine__exit(&self->host_machine);
 	close(self->fd);
 	free(self);
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [tip:perf/core] perf session: Free environment information when deleting session
  2012-11-21  4:43     ` [PATCH v2 1/3] perf session: Free environment information when deleting session Namhyung Kim
@ 2013-01-24 18:39       ` tip-bot for Namhyung Kim
  0 siblings, 0 replies; 10+ messages in thread
From: tip-bot for Namhyung Kim @ 2013-01-24 18:39 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, hpa, mingo, andi, peterz, namhyung.kim,
	namhyung, tglx, feng.tang

Commit-ID:  03cd20949964f5cda600a56e12ffac39dfec4cb0
Gitweb:     http://git.kernel.org/tip/03cd20949964f5cda600a56e12ffac39dfec4cb0
Author:     Namhyung Kim <namhyung.kim@lge.com>
AuthorDate: Wed, 21 Nov 2012 13:43:19 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Sun, 9 Dec 2012 08:46:05 -0300

perf session: Free environment information when deleting session

The perf session environment information was saved (so allocated) during
perf_session__open, but was not freed.  As free(3) handles NULL pointer
input properly it won't cause a issue for writing modes - e.g. perf
record

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Feng Tang <feng.tang@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1353472999-23042-1-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/session.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ce6f511..d5fb607 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -204,11 +204,28 @@ static void perf_session__delete_threads(struct perf_session *session)
 	machine__delete_threads(&session->host_machine);
 }
 
+static void perf_session_env__delete(struct perf_session_env *env)
+{
+	free(env->hostname);
+	free(env->os_release);
+	free(env->version);
+	free(env->arch);
+	free(env->cpu_desc);
+	free(env->cpuid);
+
+	free(env->cmdline);
+	free(env->sibling_cores);
+	free(env->sibling_threads);
+	free(env->numa_nodes);
+	free(env->pmu_mappings);
+}
+
 void perf_session__delete(struct perf_session *self)
 {
 	perf_session__destroy_kernel_maps(self);
 	perf_session__delete_dead_threads(self);
 	perf_session__delete_threads(self);
+	perf_session_env__delete(&self->header.env);
 	machine__exit(&self->host_machine);
 	close(self->fd);
 	free(self);

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-01-24 18:40 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-20  9:31 [PATCH 1/3] perf session: Add perf_session__delete_env Feng Tang
2012-11-20  9:31 ` [PATCH 2/3] perf hists browser: Add option for runtime switching perf data file Feng Tang
2012-11-20 15:16   ` Arnaldo Carvalho de Melo
2012-11-20 16:16     ` Feng Tang
2012-11-20 16:24     ` Feng Tang
2012-11-20  9:31 ` [PATCH 3/3] perf report: Enable the runtime switching of " Feng Tang
2012-11-20 15:13 ` [PATCH 1/3] perf session: Add perf_session__delete_env Arnaldo Carvalho de Melo
2012-11-20 15:20   ` Namhyung Kim
2012-11-21  4:43     ` [PATCH v2 1/3] perf session: Free environment information when deleting session Namhyung Kim
2013-01-24 18:39       ` [tip:perf/core] " tip-bot for Namhyung Kim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.