On 01.09.2020 12:37, Adrian Hunter wrote:
> Add 'snapshot' control command to create an AUX area tracing snapshot the
> same as if sending SIGUSR2. The advantage of the FIFO is that access is
> governed by access to the FIFO.
> 
> Example:
> 
>  $ mkfifo perf.control
>  $ mkfifo perf.ack
>  $ cat perf.ack &
>  [1] 15235
>  $ sudo ~/bin/perf record --control fifo:perf.control,perf.ack -S -e 
> intel_pt//u -- sleep 60 &
>  [2] 15243
>  $ ps -e | grep perf
>   15244 pts/1    00:00:00 perf
>  $ kill -USR2 15244
>  bash: kill: (15244) - Operation not permitted
>  $ echo snapshot > perf.control
>  ack
> 
> Signed-off-by: Adrian Hunter <adrian.hun...@intel.com>
> ---
>  tools/perf/Documentation/perf-record.txt |  8 ++++----
>  tools/perf/builtin-record.c              | 24 +++++++++++++++++-------
>  tools/perf/builtin-stat.c                |  1 +
>  tools/perf/util/evlist.c                 | 11 +++++++++--
>  tools/perf/util/evlist.h                 |  5 ++++-
>  5 files changed, 35 insertions(+), 14 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-record.txt 
> b/tools/perf/Documentation/perf-record.txt
> index 2ffc1196d2b8..588e6191bf39 100644
> --- a/tools/perf/Documentation/perf-record.txt
> +++ b/tools/perf/Documentation/perf-record.txt
> @@ -631,10 +631,10 @@ endif::HAVE_LIBPFM[]
>  --control=fd:ctl-fd[,ack-fd]::
>  ctl-fifo / ack-fifo are opened and used as ctl-fd / ack-fd as follows.
>  Listen on ctl-fd descriptor for command to control measurement ('enable': 
> enable events,
> -'disable': disable events). Measurements can be started with events disabled 
> using
> ---delay=-1 option. Optionally send control command completion ('ack\n') to 
> ack-fd descriptor
> -to synchronize with the controlling process. Example of bash shell script to 
> enable and
> -disable events during measurements:
> +'disable': disable events, 'snapshot': AUX area tracing snapshot). 
> Measurements can be
> +started with events disabled using --delay=-1 option. Optionally send 
> control command
> +completion ('ack\n') to ack-fd descriptor to synchronize with the 
> controlling process.
> +Example of bash shell script to enable and disable events during 
> measurements:
>  
>   #!/bin/bash
>  
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index 117dd180f780..476b34ff3152 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);

Could possibly print a messages to console that snapshot taking has started,
similar to enabling and disabling of events.

Acked-by: Alexei Budankov <alexey.budan...@linux.intel.com>

Regards,
Alexei

> +                             evlist__ctlfd_ack(rec->evlist);
> +                             break;
>                       case EVLIST_CTL_CMD_ACK:
>                       case EVLIST_CTL_CMD_UNSUPPORTED:
>                       default:
> @@ -2589,7 +2603,8 @@ static struct option __record_options[] = {
>               parse_libpfm_events_option),
>  #endif
>       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"
> +                  "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),
> @@ -2842,12 +2857,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);
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index 6170226d44f9..21424ed0734b 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -578,6 +578,7 @@ static void process_evlist(struct evlist *evlist, 
> unsigned int interval)
>                               process_interval();
>                       pr_info(EVLIST_DISABLED_MSG);
>                       break;
> +             case EVLIST_CTL_CMD_SNAPSHOT:
>               case EVLIST_CTL_CMD_ACK:
>               case EVLIST_CTL_CMD_UNSUPPORTED:
>               default:
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index b74e85bc683e..8cd53dbb0357 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -1885,13 +1885,17 @@ static int evlist__ctlfd_recv(struct evlist *evlist, 
> enum evlist_ctl_cmd *cmd,
>               } else if (!strncmp(cmd_data, EVLIST_CTL_CMD_DISABLE_TAG,
>                                   (sizeof(EVLIST_CTL_CMD_DISABLE_TAG)-1))) {
>                       *cmd = EVLIST_CTL_CMD_DISABLE;
> +             } else if (!strncmp(cmd_data, EVLIST_CTL_CMD_SNAPSHOT_TAG,
> +                                 (sizeof(EVLIST_CTL_CMD_SNAPSHOT_TAG)-1))) {
> +                     *cmd = EVLIST_CTL_CMD_SNAPSHOT;
> +                     pr_debug("is snapshot\n");
>               }
>       }
>  
>       return bytes_read ? (int)bytes_read : err;
>  }
>  
> -static int evlist__ctlfd_ack(struct evlist *evlist)
> +int evlist__ctlfd_ack(struct evlist *evlist)
>  {
>       int err;
>  
> @@ -1927,13 +1931,16 @@ int evlist__ctlfd_process(struct evlist *evlist, enum 
> evlist_ctl_cmd *cmd)
>                       case EVLIST_CTL_CMD_DISABLE:
>                               evlist__disable(evlist);
>                               break;
> +                     case EVLIST_CTL_CMD_SNAPSHOT:
> +                             break;
>                       case EVLIST_CTL_CMD_ACK:
>                       case EVLIST_CTL_CMD_UNSUPPORTED:
>                       default:
>                               pr_debug("ctlfd: unsupported %d\n", *cmd);
>                               break;
>                       }
> -                     if (!(*cmd == EVLIST_CTL_CMD_ACK || *cmd == 
> EVLIST_CTL_CMD_UNSUPPORTED))
> +                     if (!(*cmd == EVLIST_CTL_CMD_ACK || *cmd == 
> EVLIST_CTL_CMD_UNSUPPORTED ||
> +                           *cmd == EVLIST_CTL_CMD_SNAPSHOT))
>                               evlist__ctlfd_ack(evlist);
>               }
>       }
> diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
> index a5678eb5ee60..91d1da6e1fe3 100644
> --- a/tools/perf/util/evlist.h
> +++ b/tools/perf/util/evlist.h
> @@ -363,6 +363,7 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist 
> *evlist,
>  #define EVLIST_CTL_CMD_ENABLE_TAG  "enable"
>  #define EVLIST_CTL_CMD_DISABLE_TAG "disable"
>  #define EVLIST_CTL_CMD_ACK_TAG     "ack\n"
> +#define EVLIST_CTL_CMD_SNAPSHOT_TAG "snapshot"
>  
>  #define EVLIST_CTL_CMD_MAX_LEN 64
>  
> @@ -370,7 +371,8 @@ enum evlist_ctl_cmd {
>       EVLIST_CTL_CMD_UNSUPPORTED = 0,
>       EVLIST_CTL_CMD_ENABLE,
>       EVLIST_CTL_CMD_DISABLE,
> -     EVLIST_CTL_CMD_ACK
> +     EVLIST_CTL_CMD_ACK,
> +     EVLIST_CTL_CMD_SNAPSHOT,
>  };
>  
>  int evlist__parse_control(const char *str, int *ctl_fd, int *ctl_fd_ack, 
> bool *ctl_fd_close);
> @@ -378,6 +380,7 @@ int evlist__initialize_ctlfd(struct evlist *evlist, int 
> ctl_fd, int ctl_fd_ack);
>  int evlist__finalize_ctlfd(struct evlist *evlist);
>  bool evlist__ctlfd_initialized(struct evlist *evlist);
>  int evlist__ctlfd_process(struct evlist *evlist, enum evlist_ctl_cmd *cmd);
> +int evlist__ctlfd_ack(struct evlist *evlist);
>  
>  #define EVLIST_ENABLED_MSG "Events enabled\n"
>  #define EVLIST_DISABLED_MSG "Events disabled\n"
> 

Reply via email to