On Fri, 27 Dec 2024 13:08:18 +0900 "Masami Hiramatsu (Google)" <mhiramat@xxxxxxxxxx> wrote: > From: Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx> > > Add a testcase for poll() on hist file. This introduces a helper binary > to the ftracetest, because there is no good way to reliably execute > poll() on hist file. > > Signed-off-by: Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx> > Reviewed-by: Shuah Khan <skhan@xxxxxxxxxxxxxxxxxxx> > --- > Changes in v7: > - Add comm histogram filter for specifying test sleep command. I found I forgot to refresh the patch. (just not committed) Sorry. > --- > tools/testing/selftests/ftrace/Makefile | 2 + > tools/testing/selftests/ftrace/poll.c | 74 ++++++++++++++++++++ > .../ftrace/test.d/trigger/trigger-hist-poll.tc | 74 ++++++++++++++++++++ > 3 files changed, 150 insertions(+) > create mode 100644 tools/testing/selftests/ftrace/poll.c > create mode 100644 tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-poll.tc > > diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile > index a1e955d2de4c..49d96bb16355 100644 > --- a/tools/testing/selftests/ftrace/Makefile > +++ b/tools/testing/selftests/ftrace/Makefile > @@ -6,4 +6,6 @@ TEST_PROGS := ftracetest-ktap > TEST_FILES := test.d settings > EXTRA_CLEAN := $(OUTPUT)/logs/* > > +TEST_GEN_PROGS = poll > + > include ../lib.mk > diff --git a/tools/testing/selftests/ftrace/poll.c b/tools/testing/selftests/ftrace/poll.c > new file mode 100644 > index 000000000000..53258f7515e7 > --- /dev/null > +++ b/tools/testing/selftests/ftrace/poll.c > @@ -0,0 +1,74 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Simple poll on a file. > + * > + * Copyright (c) 2024 Google LLC. > + */ > + > +#include <errno.h> > +#include <fcntl.h> > +#include <poll.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <unistd.h> > + > +#define BUFSIZE 4096 > + > +/* > + * Usage: > + * poll [-I|-P] [-t timeout] FILE > + */ > +int main(int argc, char *argv[]) > +{ > + struct pollfd pfd = {.events = POLLIN}; > + char buf[BUFSIZE]; > + int timeout = -1; > + int ret, opt; > + > + while ((opt = getopt(argc, argv, "IPt:")) != -1) { > + switch (opt) { > + case 'I': > + pfd.events = POLLIN; > + break; > + case 'P': > + pfd.events = POLLPRI; > + break; > + case 't': > + timeout = atoi(optarg); > + break; > + default: > + fprintf(stderr, "Usage: %s [-I|-P] [-t timeout] FILE\n", > + argv[0]); > + return -1; > + } > + } > + if (optind >= argc) { > + fprintf(stderr, "Error: Polling file is not specified\n"); > + return -1; > + } > + > + pfd.fd = open(argv[optind], O_RDONLY); > + if (pfd.fd < 0) { > + fprintf(stderr, "failed to open %s", argv[optind]); > + perror("open"); > + return -1; > + } > + > + /* Reset poll by read if POLLIN is specified. */ > + if (pfd.events & POLLIN) > + do {} while (read(pfd.fd, buf, BUFSIZE) == BUFSIZE); > + > + ret = poll(&pfd, 1, timeout); > + if (ret < 0 && errno != EINTR) { > + perror("poll"); > + return -1; > + } > + close(pfd.fd); > + > + /* If timeout happned (ret == 0), exit code is 1 */ > + if (ret == 0) > + return 1; > + > + return 0; > +} > diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-poll.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-poll.tc > new file mode 100644 > index 000000000000..cbd01a71ecad > --- /dev/null > +++ b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-poll.tc > @@ -0,0 +1,74 @@ > +#!/bin/sh > +# SPDX-License-Identifier: GPL-2.0 > +# description: event trigger - test poll wait on histogram > +# requires: set_event events/sched/sched_process_free/trigger events/sched/sched_process_free/hist > +# flags: instance > + > +POLL=${FTRACETEST_ROOT}/poll > + > +if [ ! -x ${POLL} ]; then > + echo "poll program is not compiled!" > + exit_unresolved > +fi > + > +EVENT=events/sched/sched_process_free/ > + > +# Check poll ops is supported. Before implementing poll on hist file, it > +# returns soon with POLLIN | POLLOUT, but not POLLPRI. > + > +# This must wait >1 sec and return 1 (timeout). > +set +e > +${POLL} -I -t 1000 ${EVENT}/hist > +ret=$? > +set -e > +if [ ${ret} != 1 ]; then > + echo "poll on hist file is not supported" > + exit_unsupported > +fi > + > +# Test POLLIN > +echo > trace > +echo "hist:key=comm" > ${EVENT}/trigger > +echo 1 > ${EVENT}/enable > + > +# This sleep command will exit after 2 seconds. > +sleep 2 & > +BGPID=$! > +# if timeout happens, poll returns 1. > +${POLL} -I -t 4000 ${EVENT}/hist > +echo 0 > tracing_on > + > +if [ -d /proc/${BGPID} ]; then > + echo "poll exits too soon" > + kill -KILL ${BGPID} ||: > + exit_fail > +fi > + > +if ! grep -qw "sleep" trace; then > + echo "poll exits before event happens" > + exit_fail > +fi > + > +# Test POLLPRI > +echo > trace > +echo 1 > tracing_on > + > +# This sleep command will exit after 2 seconds. > +sleep 2 & > +BGPID=$! > +# if timeout happens, poll returns 1. > +${POLL} -P -t 4000 ${EVENT}/hist > +echo 0 > tracing_on > + > +if [ -d /proc/${BGPID} ]; then > + echo "poll exits too soon" > + kill -KILL ${BGPID} ||: > + exit_fail > +fi > + > +if ! grep -qw "sleep" trace; then > + echo "poll exits before event happens" > + exit_fail > +fi > + > +exit_pass > -- Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx>