tools/perf/builtin-ftrace.c | 5 +++++ 1 file changed, 5 insertions(+)
I've realized that it didn't set up the tracing files when BPF is used
so poll() just returns immediately. It ends up with calling poll()
unnecessarily in a loop.
BPF still needs the loop to wait for the target process exiting or a
signal from users. Let's sleep for 1 msec and check that.
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/builtin-ftrace.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
index 4f881a40c311ae52..e61b9de11e1e41c7 100644
--- a/tools/perf/builtin-ftrace.c
+++ b/tools/perf/builtin-ftrace.c
@@ -1146,6 +1146,11 @@ static int __cmd_latency(struct perf_ftrace *ftrace)
line[0] = '\0';
while (!done) {
+ if (ftrace->target.use_bpf) {
+ usleep(1000);
+ continue;
+ }
+
if (poll(&pollfd, 1, -1) < 0)
break;
--
2.55.0.897.gb25b4bd76c-goog
On Wed, Aug 26, 2026 at 11:58 AM Namhyung Kim <namhyung@kernel.org> wrote:
>
> I've realized that it didn't set up the tracing files when BPF is used
> so poll() just returns immediately. It ends up with calling poll()
> unnecessarily in a loop.
>
> BPF still needs the loop to wait for the target process exiting or a
> signal from users. Let's sleep for 1 msec and check that.
>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: Masami Hiramatsu <mhiramat@kernel.org>
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> ---
> tools/perf/builtin-ftrace.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
> index 4f881a40c311ae52..e61b9de11e1e41c7 100644
> --- a/tools/perf/builtin-ftrace.c
> +++ b/tools/perf/builtin-ftrace.c
> @@ -1146,6 +1146,11 @@ static int __cmd_latency(struct perf_ftrace *ftrace)
>
> line[0] = '\0';
> while (!done) {
> + if (ftrace->target.use_bpf) {
> + usleep(1000);
> + continue;
> + }
> +
To avoid the busy waiting could we:
```
// Globaly:
sem_t sig_sem;
...
// Prior to setting up the signal handler:
sem_init(&sig_sem, 0, 0);
...
// Here:
if (ftrace->target.use_bpf) {
sem_wait(&sig_sem);
} else {
while (!done) {
...
}
// In the signal handler:
if (ftrace->target.use_bpf) {
sem_post(&sig_sem);
}
...
// After removing the signal handler:
sem_destroy(&sig_sem);
```
Thanks,
Ian
> if (poll(&pollfd, 1, -1) < 0)
> break;
>
> --
> 2.55.0.897.gb25b4bd76c-goog
>
Hi Ian,
On Wed, Aug 26, 2026 at 02:36:27PM -0700, Ian Rogers wrote:
> On Wed, Aug 26, 2026 at 11:58 AM Namhyung Kim <namhyung@kernel.org> wrote:
> >
> > I've realized that it didn't set up the tracing files when BPF is used
> > so poll() just returns immediately. It ends up with calling poll()
> > unnecessarily in a loop.
> >
> > BPF still needs the loop to wait for the target process exiting or a
> > signal from users. Let's sleep for 1 msec and check that.
> >
> > Cc: Steven Rostedt <rostedt@goodmis.org>
> > Cc: Masami Hiramatsu <mhiramat@kernel.org>
> > Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> > ---
> > tools/perf/builtin-ftrace.c | 5 +++++
> > 1 file changed, 5 insertions(+)
> >
> > diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
> > index 4f881a40c311ae52..e61b9de11e1e41c7 100644
> > --- a/tools/perf/builtin-ftrace.c
> > +++ b/tools/perf/builtin-ftrace.c
> > @@ -1146,6 +1146,11 @@ static int __cmd_latency(struct perf_ftrace *ftrace)
> >
> > line[0] = '\0';
> > while (!done) {
> > + if (ftrace->target.use_bpf) {
> > + usleep(1000);
> > + continue;
> > + }
> > +
>
> To avoid the busy waiting could we:
> ```
> // Globaly:
> sem_t sig_sem;
> ...
> // Prior to setting up the signal handler:
> sem_init(&sig_sem, 0, 0);
> ...
> // Here:
> if (ftrace->target.use_bpf) {
> sem_wait(&sig_sem);
> } else {
> while (!done) {
> ...
> }
> // In the signal handler:
> if (ftrace->target.use_bpf) {
> sem_post(&sig_sem);
> }
> ...
> // After removing the signal handler:
> sem_destroy(&sig_sem);
> ```
Looks better, will check.
Thanks,
Namhyung
© 2016 - 2026 Red Hat, Inc.