diff options
Diffstat (limited to 'tools/perf/builtin-record.c')
| -rw-r--r-- | tools/perf/builtin-record.c | 68 | 
1 files changed, 34 insertions, 34 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 772f1057647f..adf311d15d3d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1593,6 +1593,16 @@ static int record__init_clock(struct record *rec)  	return 0;  } +static void hit_auxtrace_snapshot_trigger(struct record *rec) +{ +	if (trigger_is_ready(&auxtrace_snapshot_trigger)) { +		trigger_hit(&auxtrace_snapshot_trigger); +		auxtrace_record__snapshot_started = 1; +		if (auxtrace_record__snapshot_start(rec->itr)) +			trigger_error(&auxtrace_snapshot_trigger); +	} +} +  static int __cmd_record(struct record *rec, int argc, const char **argv)  {  	int err; @@ -1937,6 +1947,10 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)  			case EVLIST_CTL_CMD_DISABLE:  				pr_info(EVLIST_DISABLED_MSG);  				break; +			case EVLIST_CTL_CMD_SNAPSHOT: +				hit_auxtrace_snapshot_trigger(rec); +				evlist__ctlfd_ack(rec->evlist); +				break;  			case EVLIST_CTL_CMD_ACK:  			case EVLIST_CTL_CMD_UNSUPPORTED:  			default: @@ -2234,27 +2248,9 @@ static int parse_control_option(const struct option *opt,  				const char *str,  				int unset __maybe_unused)  { -	char *comma = NULL, *endptr = NULL; -	struct record_opts *config = (struct record_opts *)opt->value; - -	if (strncmp(str, "fd:", 3)) -		return -EINVAL; - -	config->ctl_fd = strtoul(&str[3], &endptr, 0); -	if (endptr == &str[3]) -		return -EINVAL; - -	comma = strchr(str, ','); -	if (comma) { -		if (endptr != comma) -			return -EINVAL; - -		config->ctl_fd_ack = strtoul(comma + 1, &endptr, 0); -		if (endptr == comma + 1 || *endptr != '\0') -			return -EINVAL; -	} +	struct record_opts *opts = opt->value; -	return 0; +	return evlist__parse_control(str, &opts->ctl_fd, &opts->ctl_fd_ack, &opts->ctl_fd_close);  }  static void switch_output_size_warn(struct record *rec) @@ -2596,9 +2592,11 @@ static struct option __record_options[] = {  		"libpfm4 event selector. use 'perf list' to list available events",  		parse_libpfm_events_option),  #endif -	OPT_CALLBACK(0, "control", &record.opts, "fd:ctl-fd[,ack-fd]", -		     "Listen on ctl-fd descriptor for command to control measurement ('enable': enable events, 'disable': disable events).\n" -		     "\t\t\t  Optionally send control command completion ('ack\\n') to ack-fd descriptor.", +	OPT_CALLBACK(0, "control", &record.opts, "fd:ctl-fd[,ack-fd] or fifo:ctl-fifo[,ack-fifo]", +		     "Listen on ctl-fd descriptor for command to control measurement ('enable': enable events, 'disable': disable events,\n" +		     "\t\t\t  'snapshot': AUX area tracing snapshot).\n" +		     "\t\t\t  Optionally send control command completion ('ack\\n') to ack-fd descriptor.\n" +		     "\t\t\t  Alternatively, ctl-fifo / ack-fifo will be opened and used as ctl-fd / ack-fd.",  		      parse_control_option),  	OPT_END()  }; @@ -2671,12 +2669,14 @@ int cmd_record(int argc, const char **argv)  	    !perf_can_record_switch_events()) {  		ui__error("kernel does not support recording context switch events\n");  		parse_options_usage(record_usage, record_options, "switch-events", 0); -		return -EINVAL; +		err = -EINVAL; +		goto out_opts;  	}  	if (switch_output_setup(rec)) {  		parse_options_usage(record_usage, record_options, "switch-output", 0); -		return -EINVAL; +		err = -EINVAL; +		goto out_opts;  	}  	if (rec->switch_output.time) { @@ -2687,8 +2687,10 @@ int cmd_record(int argc, const char **argv)  	if (rec->switch_output.num_files) {  		rec->switch_output.filenames = calloc(sizeof(char *),  						      rec->switch_output.num_files); -		if (!rec->switch_output.filenames) -			return -EINVAL; +		if (!rec->switch_output.filenames) { +			err = -EINVAL; +			goto out_opts; +		}  	}  	/* @@ -2704,7 +2706,8 @@ int cmd_record(int argc, const char **argv)  		rec->affinity_mask.bits = bitmap_alloc(rec->affinity_mask.nbits);  		if (!rec->affinity_mask.bits) {  			pr_err("Failed to allocate thread mask for %zd cpus\n", rec->affinity_mask.nbits); -			return -ENOMEM; +			err = -ENOMEM; +			goto out_opts;  		}  		pr_debug2("thread mask[%zd]: empty\n", rec->affinity_mask.nbits);  	} @@ -2835,6 +2838,8 @@ out:  	evlist__delete(rec->evlist);  	symbol__exit();  	auxtrace_record__free(rec->itr); +out_opts: +	evlist__close_control(rec->opts.ctl_fd, rec->opts.ctl_fd_ack, &rec->opts.ctl_fd_close);  	return err;  } @@ -2842,12 +2847,7 @@ static void snapshot_sig_handler(int sig __maybe_unused)  {  	struct record *rec = &record; -	if (trigger_is_ready(&auxtrace_snapshot_trigger)) { -		trigger_hit(&auxtrace_snapshot_trigger); -		auxtrace_record__snapshot_started = 1; -		if (auxtrace_record__snapshot_start(record.itr)) -			trigger_error(&auxtrace_snapshot_trigger); -	} +	hit_auxtrace_snapshot_trigger(rec);  	if (switch_output_signal(rec))  		trigger_hit(&switch_output_trigger);  | 
