mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	perf record: Synthesize unit/scale/... in event update
Move the code to synthesize event updates for scale/unit/cpus to a common utility file, and use it both from stat and record. This allows to access scale and other extra qualifiers from perf script. Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: http://lkml.kernel.org/r/20171117214300.32746-2-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
		
							parent
							
								
									4ca69ca9db
								
							
						
					
					
						commit
						bfd8f72c27
					
				
					 4 changed files with 86 additions and 58 deletions
				
			
		| 
						 | 
					@ -372,6 +372,8 @@ static int record__open(struct record *rec)
 | 
				
			||||||
			ui__error("%s\n", msg);
 | 
								ui__error("%s\n", msg);
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pos->supported = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (perf_evlist__apply_filters(evlist, &pos)) {
 | 
						if (perf_evlist__apply_filters(evlist, &pos)) {
 | 
				
			||||||
| 
						 | 
					@ -784,6 +786,13 @@ static int record__synthesize(struct record *rec, bool tail)
 | 
				
			||||||
					 perf_event__synthesize_guest_os, tool);
 | 
										 perf_event__synthesize_guest_os, tool);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = perf_event__synthesize_extra_attr(&rec->tool,
 | 
				
			||||||
 | 
											rec->evlist,
 | 
				
			||||||
 | 
											process_synthesized_event,
 | 
				
			||||||
 | 
											data->is_pipe);
 | 
				
			||||||
 | 
						if (err)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
 | 
						err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads,
 | 
				
			||||||
					    process_synthesized_event, opts->sample_address,
 | 
										    process_synthesized_event, opts->sample_address,
 | 
				
			||||||
					    opts->proc_map_timeout, 1);
 | 
										    opts->proc_map_timeout, 1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -458,19 +458,8 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf
 | 
				
			||||||
	workload_exec_errno = info->si_value.sival_int;
 | 
						workload_exec_errno = info->si_value.sival_int;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool has_unit(struct perf_evsel *counter)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return counter->unit && *counter->unit;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool has_scale(struct perf_evsel *counter)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return counter->scale != 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int perf_stat_synthesize_config(bool is_pipe)
 | 
					static int perf_stat_synthesize_config(bool is_pipe)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct perf_evsel *counter;
 | 
					 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (is_pipe) {
 | 
						if (is_pipe) {
 | 
				
			||||||
| 
						 | 
					@ -482,53 +471,10 @@ static int perf_stat_synthesize_config(bool is_pipe)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						err = perf_event__synthesize_extra_attr(NULL,
 | 
				
			||||||
	 * Synthesize other events stuff not carried within
 | 
											evsel_list,
 | 
				
			||||||
	 * attr event - unit, scale, name
 | 
											process_synthesized_event,
 | 
				
			||||||
	 */
 | 
											is_pipe);
 | 
				
			||||||
	evlist__for_each_entry(evsel_list, counter) {
 | 
					 | 
				
			||||||
		if (!counter->supported)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * Synthesize unit and scale only if it's defined.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (has_unit(counter)) {
 | 
					 | 
				
			||||||
			err = perf_event__synthesize_event_update_unit(NULL, counter, process_synthesized_event);
 | 
					 | 
				
			||||||
			if (err < 0) {
 | 
					 | 
				
			||||||
				pr_err("Couldn't synthesize evsel unit.\n");
 | 
					 | 
				
			||||||
				return err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (has_scale(counter)) {
 | 
					 | 
				
			||||||
			err = perf_event__synthesize_event_update_scale(NULL, counter, process_synthesized_event);
 | 
					 | 
				
			||||||
			if (err < 0) {
 | 
					 | 
				
			||||||
				pr_err("Couldn't synthesize evsel scale.\n");
 | 
					 | 
				
			||||||
				return err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (counter->own_cpus) {
 | 
					 | 
				
			||||||
			err = perf_event__synthesize_event_update_cpus(NULL, counter, process_synthesized_event);
 | 
					 | 
				
			||||||
			if (err < 0) {
 | 
					 | 
				
			||||||
				pr_err("Couldn't synthesize evsel scale.\n");
 | 
					 | 
				
			||||||
				return err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * Name is needed only for pipe output,
 | 
					 | 
				
			||||||
		 * perf.data carries event names.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (is_pipe) {
 | 
					 | 
				
			||||||
			err = perf_event__synthesize_event_update_name(NULL, counter, process_synthesized_event);
 | 
					 | 
				
			||||||
			if (err < 0) {
 | 
					 | 
				
			||||||
				pr_err("Couldn't synthesize evsel name.\n");
 | 
					 | 
				
			||||||
				return err;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = perf_event__synthesize_thread_map2(NULL, evsel_list->threads,
 | 
						err = perf_event__synthesize_thread_map2(NULL, evsel_list->threads,
 | 
				
			||||||
						process_synthesized_event,
 | 
											process_synthesized_event,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3258,6 +3258,74 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool has_unit(struct perf_evsel *counter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return counter->unit && *counter->unit;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool has_scale(struct perf_evsel *counter)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return counter->scale != 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int perf_event__synthesize_extra_attr(struct perf_tool *tool,
 | 
				
			||||||
 | 
									      struct perf_evlist *evsel_list,
 | 
				
			||||||
 | 
									      perf_event__handler_t process,
 | 
				
			||||||
 | 
									      bool is_pipe)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct perf_evsel *counter;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Synthesize other events stuff not carried within
 | 
				
			||||||
 | 
						 * attr event - unit, scale, name
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						evlist__for_each_entry(evsel_list, counter) {
 | 
				
			||||||
 | 
							if (!counter->supported)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Synthesize unit and scale only if it's defined.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (has_unit(counter)) {
 | 
				
			||||||
 | 
								err = perf_event__synthesize_event_update_unit(tool, counter, process);
 | 
				
			||||||
 | 
								if (err < 0) {
 | 
				
			||||||
 | 
									pr_err("Couldn't synthesize evsel unit.\n");
 | 
				
			||||||
 | 
									return err;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (has_scale(counter)) {
 | 
				
			||||||
 | 
								err = perf_event__synthesize_event_update_scale(tool, counter, process);
 | 
				
			||||||
 | 
								if (err < 0) {
 | 
				
			||||||
 | 
									pr_err("Couldn't synthesize evsel counter.\n");
 | 
				
			||||||
 | 
									return err;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (counter->own_cpus) {
 | 
				
			||||||
 | 
								err = perf_event__synthesize_event_update_cpus(tool, counter, process);
 | 
				
			||||||
 | 
								if (err < 0) {
 | 
				
			||||||
 | 
									pr_err("Couldn't synthesize evsel cpus.\n");
 | 
				
			||||||
 | 
									return err;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Name is needed only for pipe output,
 | 
				
			||||||
 | 
							 * perf.data carries event names.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (is_pipe) {
 | 
				
			||||||
 | 
								err = perf_event__synthesize_event_update_name(tool, counter, process);
 | 
				
			||||||
 | 
								if (err < 0) {
 | 
				
			||||||
 | 
									pr_err("Couldn't synthesize evsel name.\n");
 | 
				
			||||||
 | 
									return err;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int perf_event__process_attr(struct perf_tool *tool __maybe_unused,
 | 
					int perf_event__process_attr(struct perf_tool *tool __maybe_unused,
 | 
				
			||||||
			     union perf_event *event,
 | 
								     union perf_event *event,
 | 
				
			||||||
			     struct perf_evlist **pevlist)
 | 
								     struct perf_evlist **pevlist)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,11 @@ int perf_event__synthesize_features(struct perf_tool *tool,
 | 
				
			||||||
				    struct perf_evlist *evlist,
 | 
									    struct perf_evlist *evlist,
 | 
				
			||||||
				    perf_event__handler_t process);
 | 
									    perf_event__handler_t process);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int perf_event__synthesize_extra_attr(struct perf_tool *tool,
 | 
				
			||||||
 | 
									      struct perf_evlist *evsel_list,
 | 
				
			||||||
 | 
									      perf_event__handler_t process,
 | 
				
			||||||
 | 
									      bool is_pipe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int perf_event__process_feature(struct perf_tool *tool,
 | 
					int perf_event__process_feature(struct perf_tool *tool,
 | 
				
			||||||
				union perf_event *event,
 | 
									union perf_event *event,
 | 
				
			||||||
				struct perf_session *session);
 | 
									struct perf_session *session);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue