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:22:48 -0300 [thread overview]
Message-ID: <aiB_CMMF-NZi1-ud@x1> (raw)
In-Reply-To: <aiB-w5V1oQl4a0Sy@x1>
On Wed, Jun 03, 2026 at 04:21:44PM -0300, Arnaldo Carvalho de Melo wrote:
> 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:
Nevermind, I should've read it completely :-\
- Arnaldo
> ----------------------------------------------------------------------
> --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
next prev parent reply other threads:[~2026-06-03 19:22 UTC|newest]
Thread overview: 66+ 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-02 14:43 ` sashiko-bot
2026-06-03 9:37 ` 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-02 14:40 ` sashiko-bot
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
2026-06-03 19:22 ` Arnaldo Carvalho de Melo [this message]
2026-06-02 14:26 ` [PATCH v2 03/18] perf test: Add a workload that forces context switches James Clark
2026-06-02 14:38 ` sashiko-bot
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-02 14:49 ` sashiko-bot
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-04 13:21 ` James Clark
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-02 15:01 ` sashiko-bot
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-02 15:01 ` sashiko-bot
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-02 15:05 ` sashiko-bot
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-04 13:31 ` James Clark
2026-06-04 13:34 ` James Clark
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-04 12:18 ` James Clark
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-02 15:26 ` sashiko-bot
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
2026-06-04 12:22 ` James Clark
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_CMMF-NZi1-ud@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 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.