Linux Documentation
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: James Clark <james.clark@linaro.org>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>,
	Mike Leach <mike.leach@arm.com>, Leo Yan <leo.yan@arm.com>,
	Namhyung Kim <namhyung@kernel.org>, Jiri Olsa <jolsa@kernel.org>,
	Ian Rogers <irogers@google.com>, Amir Ayupov <aaupov@meta.com>,
	Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Paschalis Mpeis <Paschalis.Mpeis@arm.com>,
	coresight@lists.linaro.org, linux-perf-users@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	linux-doc@vger.kernel.org
Subject: Re: [PATCH v2 02/18] perf test: Add workload-ctl option
Date: Wed, 3 Jun 2026 16:21:39 -0300	[thread overview]
Message-ID: <aiB-w5V1oQl4a0Sy@x1> (raw)
In-Reply-To: <20260602-james-cs-context-tracking-fix-v2-2-85b5ce6f55c6@linaro.org>

On Tue, Jun 02, 2026 at 03:26:44PM +0100, James Clark wrote:
> Add a --workload-ctl=fifo:ctl-fifo[,ack-fifo] option for 'perf test
> -w'. When set, run_workload() opens the named FIFO, writes enable before
> invoking the builtin workload, writes disable before returning, and
> waits for ack responses when an ack FIFO is provided to ensure that the
> workload doesn't run until the events are enabled.
> 
> This can be used to limit the scope of the recording to only the
> workload execution and avoid recording Perf setup and teardown code if
> Perf record is started with events disabled (-D 1).

I see no mention to the equivalent in 'perf record', from its man page:

----------------------------------------------------------------------
--control=fifo:ctl-fifo[,ack-fifo]::
--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.

Available commands:

  - 'enable'           : enable events
  - 'disable'          : disable events
  - 'enable name'      : enable event 'name'
  - 'disable name'     : disable event 'name'
  - 'snapshot'         : AUX area tracing snapshot).
  - 'stop'             : stop perf record
  - 'ping'             : ping
  - 'evlist [-v|-g|-F] : display all events

                         -F  Show just the sample frequency used for each event.
                         -v  Show all fields.
                         -g  Show event group information.
----------------------------------------------------------------------

Can this be shared code?

- Arnaldo
 
> Assisted-by: Codex:GPT-5.5
> Signed-off-by: James Clark <james.clark@linaro.org>
> ---
>  tools/perf/Documentation/perf-test.txt |   6 ++
>  tools/perf/tests/builtin-test.c        | 184 ++++++++++++++++++++++++++++++++-
>  2 files changed, 188 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt
> index 32da0d1fa86a..1faf30d4a7be 100644
> --- a/tools/perf/Documentation/perf-test.txt
> +++ b/tools/perf/Documentation/perf-test.txt
> @@ -69,3 +69,9 @@ OPTIONS
>  
>  --list-workloads::
>  	List the available workloads to use with -w/--workload.
> +
> +--workload-ctl=fifo:ctl-fifo[,ack-fifo]::
> +	Write 'enable' to ctl-fifo before running the workload and 'disable'
> +	before returning. If ack-fifo is provided, the workload runner waits for
> +	an 'ack' response after each command. This scopes the recording to only
> +	the workload if used with 'perf record -D 1 --control ...'.
> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> index f2c135891477..d5df3efdce3b 100644
> --- a/tools/perf/tests/builtin-test.c
> +++ b/tools/perf/tests/builtin-test.c
> @@ -50,6 +50,7 @@ static bool sequential;
>  static unsigned int runs_per_test = 1;
>  const char *dso_to_test;
>  const char *test_objdump_path = "objdump";
> +static const char *workload_control;
>  
>  /*
>   * List of architecture specific tests. Not a weak symbol as the array length is
> @@ -161,6 +162,11 @@ static struct test_workload *workloads[] = {
>  #endif
>  };
>  
> +struct workload_control {
> +	int ctl_fd;
> +	int ack_fd;
> +};
> +
>  #define workloads__for_each(workload) \
>  	for (unsigned i = 0; i < ARRAY_SIZE(workloads) && ({ workload = workloads[i]; 1; }); i++)
>  
> @@ -711,13 +717,185 @@ static int workloads__fprintf_list(FILE *fp)
>  	return printed;
>  }
>  
> +static int perf_control_open_fifo(struct workload_control *ctl, const char *str)
> +{
> +	char *s, *p;
> +	int ret;
> +
> +	if (strncmp(str, "fifo:", 5))
> +		return -EINVAL;
> +
> +	str += 5;
> +	if (!*str || *str == ',')
> +		return -EINVAL;
> +
> +	s = strdup(str);
> +	if (!s)
> +		return -ENOMEM;
> +
> +	p = strchr(s, ',');
> +	if (p)
> +		*p = '\0';
> +
> +	ctl->ctl_fd = open(s, O_WRONLY | O_CLOEXEC);
> +	if (ctl->ctl_fd < 0) {
> +		ret = -errno;
> +		pr_err("Failed to open workload control FIFO '%s': %m\n", s);
> +		free(s);
> +		return ret;
> +	}
> +
> +	if (p && *++p) {
> +		ctl->ack_fd = open(p, O_RDONLY | O_CLOEXEC);
> +		if (ctl->ack_fd < 0) {
> +			ret = -errno;
> +			pr_err("Failed to open workload control ack FIFO '%s': %m\n", p);
> +			close(ctl->ctl_fd);
> +			ctl->ctl_fd = -1;
> +			free(s);
> +			return ret;
> +		}
> +	}
> +
> +	free(s);
> +	return 0;
> +}
> +
> +static int perf_control_open(struct workload_control *ctl)
> +{
> +	int ret;
> +
> +	if (!workload_control)
> +		return 0;
> +
> +	ret = perf_control_open_fifo(ctl, workload_control);
> +
> +	if (ret == -EINVAL) {
> +		pr_err("Unsupported workload control spec '%s', expected fifo:ctl-fifo[,ack-fifo]\n",
> +			workload_control);
> +	}
> +
> +	return ret;
> +}
> +
> +static void perf_control_close(struct workload_control *ctl)
> +{
> +	if (ctl->ctl_fd >= 0) {
> +		close(ctl->ctl_fd);
> +		ctl->ctl_fd = -1;
> +	}
> +	if (ctl->ack_fd >= 0) {
> +		close(ctl->ack_fd);
> +		ctl->ack_fd = -1;
> +	}
> +}
> +
> +static int perf_control_write_cmd(int fd, const char *cmd)
> +{
> +	size_t len = strlen(cmd);
> +	ssize_t ret;
> +
> +	while (len) {
> +		ret = write(fd, cmd, len);
> +		if (ret < 0) {
> +			if (errno == EINTR)
> +				continue;
> +			pr_err("Failed to write perf control command '%s': %m\n", cmd);
> +			return -1;
> +		}
> +
> +		if (!ret) {
> +			pr_err("Failed to write perf control command '%s': short write\n", cmd);
> +			return -1;
> +		}
> +
> +		cmd += ret;
> +		len -= ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int perf_control_read_ack(int fd)
> +{
> +	char buf[16];
> +	ssize_t ret;
> +
> +	do {
> +		ret = read(fd, buf, sizeof(buf) - 1);
> +	} while (ret < 0 && errno == EINTR);
> +
> +	if (ret < 0) {
> +		pr_err("Failed to read perf control ack: %m\n");
> +		return -1;
> +	}
> +
> +	if (!ret) {
> +		pr_err("Unexpected EOF while reading perf control ack\n");
> +		return -1;
> +	}
> +
> +	buf[ret] = '\0';
> +	for (ssize_t i = 0; i < ret; i++) {
> +		if (buf[i] == '\n' || buf[i] == '\0') {
> +			buf[i] = '\0';
> +			break;
> +		}
> +	}
> +
> +	if (strcmp(buf, "ack")) {
> +		pr_err("Unexpected perf control ack: %s\n", buf);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int perf_control_send(struct workload_control *ctl, const char *cmd)
> +{
> +	if (ctl->ctl_fd < 0)
> +		return 0;
> +
> +	if (perf_control_write_cmd(ctl->ctl_fd, cmd))
> +		return -1;
> +
> +	if (ctl->ack_fd >= 0 && perf_control_read_ack(ctl->ack_fd))
> +		return -1;
> +
> +	return 0;
> +}
> +
>  static int run_workload(const char *work, int argc, const char **argv)
>  {
>  	struct test_workload *twl;
>  
>  	workloads__for_each(twl) {
> -		if (!strcmp(twl->name, work))
> -			return twl->func(argc, argv);
> +		struct workload_control ctl = {
> +			.ctl_fd = -1,
> +			.ack_fd = -1,
> +		};
> +		int control_ret, ret;
> +
> +		if (strcmp(twl->name, work))
> +			continue;
> +
> +		ret = perf_control_open(&ctl);
> +		if (ret)
> +			return ret;
> +
> +		if (perf_control_send(&ctl, "enable\n")) {
> +			perf_control_close(&ctl);
> +			return -1;
> +		}
> +
> +		ret = twl->func(argc, argv);
> +
> +		control_ret = perf_control_send(&ctl, "disable\n");
> +		perf_control_close(&ctl);
> +		if (control_ret)
> +			return -1;
> +
> +		return ret;
>  	}
>  
>  	pr_info("No workload found: %s\n", work);
> @@ -799,6 +977,8 @@ int cmd_test(int argc, const char **argv)
>  	OPT_UINTEGER('r', "runs-per-test", &runs_per_test,
>  		     "Run each test the given number of times, default 1"),
>  	OPT_STRING('w', "workload", &workload, "work", "workload to run for testing, use '--list-workloads' to list the available ones."),
> +	OPT_STRING(0, "workload-ctl", &workload_control, "fifo:ctl-fifo[,ack-fifo]",
> +		   "Write enable to the fifo just before running the workload and disable after, with optional ack from ack-fifo"),
>  	OPT_BOOLEAN(0, "list-workloads", &list_workloads, "List the available builtin workloads to use with -w/--workload"),
>  	OPT_STRING(0, "dso", &dso_to_test, "dso", "dso to test"),
>  	OPT_STRING(0, "objdump", &test_objdump_path, "path",
> 
> -- 
> 2.34.1

  parent reply	other threads:[~2026-06-03 19:21 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-02 14:26 [PATCH v2 00/18] perf cs-etm: Queue context packets for frontend James Clark
2026-06-02 14:26 ` [PATCH v2 01/18] " James Clark
2026-06-03  9:08   ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 02/18] perf test: Add workload-ctl option James Clark
2026-06-03 10:40   ` Leo Yan
2026-06-03 10:46     ` James Clark
2026-06-03 10:50     ` Leo Yan
2026-06-03 19:21   ` Arnaldo Carvalho de Melo [this message]
2026-06-03 19:22     ` Arnaldo Carvalho de Melo
2026-06-02 14:26 ` [PATCH v2 03/18] perf test: Add a workload that forces context switches James Clark
2026-06-03 11:06   ` Leo Yan
2026-06-03 11:17     ` James Clark
2026-06-02 14:26 ` [PATCH v2 04/18] perf test cs-etm: Test process attribution James Clark
2026-06-03 11:10   ` Leo Yan
2026-06-03 11:20     ` James Clark
2026-06-02 14:26 ` [PATCH v2 05/18] perf test: Add deterministic workload James Clark
2026-06-03 11:27   ` Leo Yan
2026-06-03 13:10     ` James Clark
2026-06-03 13:43       ` Leo Yan
2026-06-03 15:53         ` James Clark
2026-06-02 14:26 ` [PATCH v2 06/18] perf test cs-etm: Replace unroll loop thread with deterministic decode test James Clark
2026-06-03 14:08   ` Leo Yan
2026-06-03 16:01     ` James Clark
2026-06-03 17:08       ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 07/18] perf test cs-etm: Remove asm_pure_loop test James Clark
2026-06-03 14:10   ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 08/18] perf test cs-etm: Replace memcpy test with raw dump stress test James Clark
2026-06-03 14:36   ` Leo Yan
2026-06-03 16:11     ` James Clark
2026-06-03 18:16       ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 09/18] perf test: Add named_threads workload James Clark
2026-06-03 14:54   ` Leo Yan
2026-06-03 16:12     ` James Clark
2026-06-03 17:36       ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 10/18] perf test cs-etm: Test decoding for concurrent threads test James Clark
2026-06-03 14:56   ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 11/18] perf test cs-etm: Remove duplicate branch tests James Clark
2026-06-03 17:11   ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 12/18] perf test cs-etm: Reduce snapshot size James Clark
2026-06-03 17:12   ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 13/18] perf test cs-etm: Speed up basic test James Clark
2026-06-03 17:17   ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 14/18] perf test cs-etm: Remove unused Coresight workloads James Clark
2026-06-03 17:25   ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 15/18] perf test cs-etm: Make disassembly test use kcore James Clark
2026-06-03 17:32   ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 16/18] perf test cs-etm: Add all branch instructions to test James Clark
2026-06-03 17:49   ` Leo Yan
2026-06-02 14:26 ` [PATCH v2 17/18] perf test cs-etm: Speed up disassembly test James Clark
2026-06-03 17:50   ` Leo Yan
2026-06-02 14:27 ` [PATCH v2 18/18] perf test cs-etm: Move existing tests to coresight folder James Clark
2026-06-03 18:02   ` Leo Yan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aiB-w5V1oQl4a0Sy@x1 \
    --to=acme@kernel.org \
    --cc=Paschalis.Mpeis@arm.com \
    --cc=aaupov@meta.com \
    --cc=acme@redhat.com \
    --cc=corbet@lwn.net \
    --cc=coresight@lists.linaro.org \
    --cc=irogers@google.com \
    --cc=james.clark@linaro.org \
    --cc=jolsa@kernel.org \
    --cc=leo.yan@arm.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mike.leach@arm.com \
    --cc=namhyung@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=suzuki.poulose@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox