mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@kernel.org>
To: Ian Rogers <irogers@google.com>
Cc: acme@kernel.org, howardchu95@gmail.com, adrian.hunter@intel.com,
	james.clark@linaro.org, jolsa@kernel.org,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	mingo@redhat.com, peterz@infradead.org
Subject: Re: [PATCH v5 12/23] perf trace: Filter events in BPF and avoid tracepoint vetoes
Date: Thu, 24 Sep 2026 19:59:30 -0700	[thread overview]
Message-ID: <arXjkuLjHO826tXy@z2> (raw)
In-Reply-To: <b77523973d8012f1cdc36eca15021b204a42aaac.1790145937.git.irogers@google.com>

On Wed, Sep 23, 2026 at 12:13:52AM -0700, Ian Rogers wrote:
> The BPF augmented_raw_syscalls sys_enter and sys_exit programs returned
> 0 for syscalls that were not of interest. Returning 0 from a tracepoint
> BPF program vetoes the event for the whole system, so an unrelated
> concurrent perf trace, perf record or ftrace session listening to
> raw_syscalls would silently lose events. This is a cross-session side
> effect and shows up as flaky failures when perf tests run in parallel.

Right.

This is what I wanted to fix in my earlier attempt.

https://lore.kernel.org/r/20250814071754.193265-1-namhyung@kernel.org/

> 
> Furthermore, syscall_unaugmented previously returned 1 without writing
> anything to the __augmented_syscalls__ ring buffer. This forced
> userspace perf trace to listen to both raw_syscalls:sys_enter and
> __augmented_syscalls__ in its evlist, requiring userspace event
> deduplication.
> 
> Address these issues:
> 1. In augmented_raw_syscalls.bpf.c, never return 0 from tracepoint
>    handlers: return 1 so non-traced syscalls pass through without
>    vetoing other concurrent listeners.

Ok.


> 2. Introduce pids_to_trace and syscalls_to_trace BPF hash maps to
>    perform targeted filtering directly in BPF. Unselected syscalls or
>    PIDs return 1 immediately without writing to the buffer.

Can you please do this in a separate patch?  I think it's better to
minimize the patch and focus on the core changes.


> 3. In syscall_unaugmented, output the unaugmented enter payload into
>    __augmented_syscalls__ and return 1. Change its section from
>    SEC("tp/raw_syscalls/sys_enter") to
>    SEC("tp/syscalls/sys_enter_unaugmented") so libbpf does not attempt
>    to auto-attach it to raw_syscalls:sys_enter.

Ok, but also can be done in a separate patch.


> 4. In bpf_trace_augment.c, add helpers to configure target PIDs and
>    syscalls in the BPF maps, setting the activation flags
>    (has_pids_to_trace, has_syscalls_to_trace) only after the maps are
>    fully populated so already-attached BPF programs do not filter against
>    a half-filled map. Explicitly attach only sys_enter and sys_exit via
>    an attach_prog() helper that saves -errno before calling pr_debug()
>    or bpf_link__destroy().

Sounds like it should be done with step 2 above.

> 
>    Destroy the skeleton on every failure path. Leaving a loaded but
>    unusable skeleton behind is not inert: the setters called later from
>    trace__run() would program its maps, and a partial attach would leave
>    a BPF program live on raw_syscalls for a session that never starts.
>    Since augmented_syscalls__{prepare,create_bpf_output}() failures fall
>    back to unaugmented tracing rather than aborting, those setters have
>    to become no-ops, which they only do once skel is NULL again.
> 
>    errno is used directly here, so include <errno.h> rather than relying
>    on it arriving via another header, which it does not under musl.

Can be a separate change as well.


> 5. In builtin-trace.c, hook trace__set_ev_qualifier_filter() and PID
>    filtering into the BPF maps. When __augmented_syscalls__ is active,
>    remove raw_syscalls:sys_enter from trace.evlist since all traced enter
>    events (both augmented and unaugmented) are now emitted by BPF into
>    __augmented_syscalls__. Identify that evsel by comparing against
>    trace.syscalls.events.sys_enter rather than by a strstr() of its
>    name. The substring "syscalls:sys_enter" also matches the per
>    syscall syscalls:sys_enter_SYSCALL tracepoints, which a user can ask
>    for by name, and now that the match decides what is taken out of the
>    evlist, claiming one of those would drop an event that was asked for
>    and would describe __augmented_syscalls__ with its format rather
>    than the raw one's. Restore tracking on the remaining evsel via
>    evlist__set_tracking_event() so PERF_RECORD_COMM and tracking events
>    continue to be recorded. Errors from
>    augmented_syscalls__set_target_syscalls() are reported and
>    propagated, the tracepoint filter string is freed on every exit path,
>    and an allocation failure in trace__set_filter_pids() now returns
>    -ENOMEM instead of being silently ignored.
> 
>    Note that in trace__set_filter_pids() the target pids and the filtered
>    pids are two independent axes and both have to be programmed. Naming
>    pids to leave out with --filter-pids does not widen -p/-t or a workload
>    to the whole system, and a BPF tracepoint program is attached system
>    wide rather than to the target's file descriptors, so pids_to_trace is
>    the only thing keeping other tasks out.

Right, it's confusing that we have both --filter-pids and -p.


> 6. Add --syscall-augment option (defaulting to true) to allow users to
>    explicitly use --no-syscall-augment to run perf trace in the classic
>    unaugmented tracepoint mode without BPF. When BPF is unavailable or
>    disabled, ensure the non-augmented tracepoint path cleanly configures
>    sys_enter and sys_exit without duplicate entries.

What's the benefit to users of disabling syscall augmentation?  Is it
only for debugging?  Anyway, I think this should be added as a separate
patch.

> 
>    In trace__run(), add those tracepoints only when neither of them is
>    in the evlist already. trace__add_syscall_newtp() adds the pair
>    whatever is there, and cmd_trace() may have left either or both
>    behind: both when it prepared augmentation and then gave up on it,
>    the exit one alone when __augmented_syscalls__ took over the enters.
>    Neither is covered by trace.raw_augmented_syscalls, which is only
>    set when the exit evsel is named raw_syscalls:sys_exit, and not on a
>    kernel old enough for perf_evsel__raw_syscall_newtp() to have fallen
>    back to syscalls:sys_exit. Adding the pair again reports the events
>    that were there twice, which the fallback after a bpf-output failure
>    already did before this.
> 
>    Act on trace__add_syscall_newtp()'s result in cmd_trace() rather
>    than discarding it. Those tracepoints are what the augmented events
>    are described and paired with, so without them there is nothing to
>    augment: the skeleton is dropped and the session carries on with
>    plain tracepoints, which is what the bpf-output failure beside it
>    already does, and what lets the evlist test above rely on the exit
>    tracepoint being there whenever the bpf-output event is.
> 
> A target that does not fit in the map is not a reason to give up on the
> session. bpf_map__update_elem() answers -E2BIG once max_entries keys are
> present, so a target with more threads than pids_to_trace has room for
> would take the whole of perf trace down with it, on exactly the large
> workloads where there is least else to reach for. The tasks that fit are
> added, a warning says how many did not, and the ones left out are in the
> position they would have been in had they been created once the map was
> already full, which sched_process_fork() has to allow for regardless.
> 
> Report a failure to program the pid filters with the error that caused
> it. trace__run() sent everything trace__set_filter_pids() returned to
> out_error_mem, which prints "Not enough memory to run!". That was
> already a guess, and becomes a wrong one now that the function also
> writes BPF maps, which fail for reasons of their own that have nothing
> to do with memory and that the message gives the user no way to act on.
> 
> Report a failure to program the syscall filters the same way. The
> pr_err() in trace__set_ev_qualifier_filter() ran before trace__run()
> reached out_errno and printed "%m", and anything called in between
> could have changed errno by then, so the two did not have to agree.
> The inner report becomes a pr_debug() and the caller prints the error
> it was given, which leaves out_errno without a user and it is removed.

It'd be great if you can shorten the commit message..

Thanks,
Namhyung

> 
> Assisted-by: Antigravity:gemini-3.1-pro
> Signed-off-by: Ian Rogers <irogers@google.com>
> ---
>  tools/perf/Documentation/perf-trace.txt       |   5 +
>  tools/perf/builtin-trace.c                    | 222 +++++++++++++++---
>  .../bpf_skel/augmented_raw_syscalls.bpf.c     | 133 +++++++++--
>  tools/perf/util/bpf_trace_augment.c           | 169 ++++++++++++-
>  tools/perf/util/trace_augment.h               |  34 +++
>  5 files changed, 511 insertions(+), 52 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
> index d20b43ea3d37..4680c69160d7 100644
> --- a/tools/perf/Documentation/perf-trace.txt
> +++ b/tools/perf/Documentation/perf-trace.txt
> @@ -260,6 +260,11 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
>  	Maximum number of lines in the summary mode.  Note that this applies to
>  	each entry (thread or cgroup).
>  
> +--syscall-augment::
> +	Augment syscalls with BPF. Enabled by default when BPF support is available.
> +	Use --no-syscall-augment to disable BPF augmentation and fall back to the
> +	unaugmented tracepoint approach.
> +
>  
>  PAGEFAULTS
>  ----------
> diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
> index 0ae14ecd9f00..f7226331c311 100644
> --- a/tools/perf/builtin-trace.c
> +++ b/tools/perf/builtin-trace.c
> @@ -200,6 +200,7 @@ struct trace {
>  	int			max_summary;
>  	int			raw_augmented_syscalls_args_size;
>  	bool			raw_augmented_syscalls;
> +	bool			syscall_augment;
>  	bool			fd_path_disabled;
>  	bool			sort_events;
>  	bool			not_ev_qualifier;
> @@ -2071,6 +2072,23 @@ static int trace__process_event(struct trace *trace, struct machine *machine,
>  			      "LOST %" PRIu64 " events!\n", (u64)event->lost.lost);
>  		ret = machine__process_lost_event(machine, event, sample);
>  		break;
> +	case PERF_RECORD_FORK:
> +		if (trace->raw_augmented_syscalls &&
> +		    (augmented_syscalls__has_target_pid(event->fork.ppid) ||
> +		     augmented_syscalls__has_target_pid(event->fork.ptid))) {
> +			augmented_syscalls__add_target_pid(event->fork.pid);
> +		}
> +		ret = machine__process_fork_event(machine, event, sample);
> +		break;
> +	case PERF_RECORD_EXIT:
> +		if (trace->raw_augmented_syscalls) {
> +			if (event->fork.pid == event->fork.tid)
> +				augmented_syscalls__del_target_pid(event->fork.pid);
> +			else
> +				augmented_syscalls__del_target_pid(event->fork.tid);
> +		}
> +		ret = machine__process_exit_event(machine, event, sample);
> +		break;
>  	default:
>  		ret = machine__process_event(machine, event, sample);
>  		break;
> @@ -4102,7 +4120,7 @@ static int trace__add_syscall_newtp(struct trace *trace)
>  
>  static int trace__set_ev_qualifier_tp_filter(struct trace *trace)
>  {
> -	int err = -1;
> +	int err = 0;
>  	struct evsel *sys_exit;
>  	char *filter = asprintf_expr_inout_ints("id", !trace->not_ev_qualifier,
>  						trace->ev_qualifier_ids.nr,
> @@ -4111,15 +4129,27 @@ static int trace__set_ev_qualifier_tp_filter(struct trace *trace)
>  	if (filter == NULL)
>  		goto out_enomem;
>  
> -	if (!evsel__append_tp_filter(trace->syscalls.events.sys_enter, filter)) {
> -		sys_exit = trace->syscalls.events.sys_exit;
> +	/*
> +	 * With BPF augmentation sys_enter is filtered in BPF and removed from
> +	 * the evlist, so only apply the tracepoint filter to the events that
> +	 * are actually present.
> +	 */
> +	if (trace->syscalls.events.sys_enter)
> +		err = evsel__append_tp_filter(trace->syscalls.events.sys_enter, filter);
> +
> +	sys_exit = trace->syscalls.events.sys_exit;
> +	if (!err && sys_exit)
>  		err = evsel__append_tp_filter(sys_exit, filter);
> -	}
>  
>  	free(filter);
>  out:
>  	return err;
>  out_enomem:
> +	/*
> +	 * err defaults to 0 because either tracepoint may legitimately be
> +	 * absent, so the error has to be set explicitly here.
> +	 */
> +	err = -ENOMEM;
>  	errno = ENOMEM;
>  	goto out;
>  }
> @@ -4561,7 +4591,27 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace __maybe_
>  
>  static int trace__set_ev_qualifier_filter(struct trace *trace)
>  {
> -	if (trace->syscalls.events.sys_enter)
> +	/*
> +	 * Synchronize syscall filter with BPF augmenter map:
> +	 * Pass trace->not_ev_qualifier to indicate blacklist mode ('!' prefix,
> +	 * e.g., -e !open,close) vs whitelist mode (-e open,close).
> +	 *
> +	 * A failure here would leave the BPF program filtering on a partially
> +	 * populated map, silently dropping or emitting the wrong syscalls, so
> +	 * propagate the error rather than continuing.
> +	 */
> +	if (trace->ev_qualifier_ids.nr > 0) {
> +		int err = augmented_syscalls__set_target_syscalls(trace->ev_qualifier_ids.nr,
> +								  trace->ev_qualifier_ids.entries,
> +								  trace->not_ev_qualifier);
> +
> +		if (err) {
> +			pr_debug("Failed to set the syscalls to trace in the BPF map: %d\n", err);
> +			return err;
> +		}
> +	}
> +
> +	if (trace->syscalls.events.sys_enter || trace->syscalls.events.sys_exit)
>  		return trace__set_ev_qualifier_tp_filter(trace);
>  	return 0;
>  }
> @@ -4602,13 +4652,21 @@ static int trace__set_filter_loop_pids(struct trace *trace)
>  
>  static int trace__set_filter_pids(struct trace *trace)
>  {
> -	int err = 0;
> +	struct perf_thread_map *threads = evlist__core(trace->evlist)->threads;
>  	/*
>  	 * Better not use !target__has_task() here because we need to cover the
>  	 * case where no threads were specified in the command line, but a
>  	 * workload was, and in that case we will fill in the thread_map when
>  	 * we fork the workload in evlist__prepare_workload.
>  	 */
> +	bool has_target = perf_thread_map__pid(threads, 0) != -1;
> +	int err = 0;
> +
> +	/*
> +	 * The exclusion list: --filter-pids names tasks to never report, and
> +	 * with no target at all we instead exclude perf itself so that tracing
> +	 * does not feed back into itself.
> +	 */
>  	if (trace->filter_pids.nr > 0) {
>  		err = evlist__append_tp_filter_pids(trace->evlist, trace->filter_pids.nr,
>  						    trace->filter_pids.entries);
> @@ -4616,10 +4674,37 @@ static int trace__set_filter_pids(struct trace *trace)
>  			err = augmented_syscalls__set_filter_pids(trace->filter_pids.nr,
>  						       trace->filter_pids.entries);
>  		}
> -	} else if (perf_thread_map__pid(evlist__core(trace->evlist)->threads, 0) == -1) {
> +	} else if (!has_target) {
>  		err = trace__set_filter_loop_pids(trace);
>  	}
>  
> +	if (err)
> +		return err;
> +
> +	/*
> +	 * The inclusion list, which is a separate axis from the exclusion list
> +	 * above and so must be programmed even when --filter-pids was given:
> +	 * naming tasks to leave out does not widen -p/-t or a workload to the
> +	 * whole system.
> +	 *
> +	 * This matters more than it does on the tracepoint only path. A BPF
> +	 * tracepoint program is attached system wide rather than to the
> +	 * target's file descriptors, so pids_to_trace is the only thing
> +	 * keeping other tasks out.
> +	 */
> +	if (has_target) {
> +		int nr = perf_thread_map__nr(threads);
> +		pid_t *pids = malloc(nr * sizeof(pid_t));
> +
> +		if (pids == NULL)
> +			return -ENOMEM;
> +
> +		for (int i = 0; i < nr; i++)
> +			pids[i] = perf_thread_map__pid(threads, i);
> +		err = augmented_syscalls__set_target_pids(nr, pids);
> +		free(pids);
> +	}
> +
>  	return err;
>  }
>  
> @@ -4846,7 +4931,20 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
>  	}
>  
>  	if (!trace->raw_augmented_syscalls) {
> -		if (trace->trace_syscalls && trace__add_syscall_newtp(trace))
> +		/*
> +		 * The syscall tracepoints may be in the evlist already:
> +		 * cmd_trace() adds the pair whenever it prepares BPF
> +		 * augmentation, and it then either keeps them, gives up on
> +		 * augmentation and leaves them behind, or has
> +		 * __augmented_syscalls__ take over the enters and removes only
> +		 * the enter one. trace__add_syscall_newtp() adds the pair
> +		 * whatever is there, so it is called only when neither is, and
> +		 * every event it adds is one the evlist does not already have.
> +		 */
> +		bool have_syscall_tp = trace->syscalls.events.sys_enter != NULL ||
> +				       trace->syscalls.events.sys_exit != NULL;
> +
> +		if (trace->trace_syscalls && !have_syscall_tp && trace__add_syscall_newtp(trace))
>  			goto out_error_raw_syscalls;
>  
>  		if (trace->trace_syscalls)
> @@ -4941,7 +5039,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
>  
>  	err = trace__set_filter_pids(trace);
>  	if (err < 0)
> -		goto out_error_mem;
> +		goto out_error_filter_pids;
>  
>  	/*
>  	 * TODO: Initialize for all host binary machine types, not just
> @@ -4952,7 +5050,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
>  	if (trace->ev_qualifier_ids.nr > 0) {
>  		err = trace__set_ev_qualifier_filter(trace);
>  		if (err < 0)
> -			goto out_errno;
> +			goto out_error_ev_qualifier;
>  
>  		if (trace->syscalls.events.sys_exit) {
>  			pr_debug("event qualifier tracepoint filter: %s\n",
> @@ -5132,14 +5230,32 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
>  		"Failed to set filter \"%s\" on event %s: %m\n",
>  		evsel->filter, evsel__name(evsel));
>  	goto out_put_evlist;
> +
> +out_error_filter_pids:
> +	/*
> +	 * Report what actually went wrong. Programming the pid filters
> +	 * allocates, but it also writes BPF maps, which fails for reasons of
> +	 * its own: -E2BIG when the target has more threads than pids_to_trace
> +	 * has room for, say.
> +	 */
> +	fprintf(trace->output, "Failed to set the pid filters: %s\n",
> +		str_error_r(-err, errbuf, sizeof(errbuf)));
> +	goto out_put_evlist;
> +
> +out_error_ev_qualifier:
> +	/*
> +	 * Use the returned error, not errno. Reporting the failure on the way
> +	 * out of trace__set_ev_qualifier_filter() goes through the formatted
> +	 * output functions, which are free to leave errno describing
> +	 * something else by the time it is read here.
> +	 */
> +	fprintf(trace->output, "Failed to set the syscall filters: %s\n",
> +		str_error_r(-err, errbuf, sizeof(errbuf)));
> +	goto out_put_evlist;
>  }
>  out_error_mem:
>  	fprintf(trace->output, "Not enough memory to run!\n");
>  	goto out_put_evlist;
> -
> -out_errno:
> -	fprintf(trace->output, "%m\n");
> -	goto out_put_evlist;
>  }
>  
>  static int trace__replay(struct trace *trace)
> @@ -5854,6 +5970,7 @@ int cmd_trace(int argc, const char **argv)
>  		.show_arg_names = true,
>  		.args_alignment = 70,
>  		.trace_syscalls = false,
> +		.syscall_augment = true,
>  		.kernel_syscallchains = false,
>  		.max_stack = UINT_MAX,
>  		.max_events = ULONG_MAX,
> @@ -5909,6 +6026,8 @@ int cmd_trace(int argc, const char **argv)
>  	OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min",
>  		     "Trace pagefaults", parse_pagefaults, "maj"),
>  	OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
> +	OPT_BOOLEAN(0, "syscall-augment", &trace.syscall_augment,
> +		    "Augment syscalls with BPF"),
>  	OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"),
>  	OPT_CALLBACK(0, "call-graph", &trace.opts,
>  		     "record_mode[,record_size]", record_callchain_help,
> @@ -6031,7 +6150,7 @@ int cmd_trace(int argc, const char **argv)
>  				       "cgroup monitoring only available in system-wide mode");
>  	}
>  
> -	if (!trace.trace_syscalls)
> +	if (!trace.trace_syscalls || !trace.syscall_augment)
>  		goto skip_augmentation;
>  
>  	if ((argc >= 1) && (strcmp(argv[0], "record") == 0)) {
> @@ -6053,11 +6172,34 @@ int cmd_trace(int argc, const char **argv)
>  	if (err < 0)
>  		goto skip_augmentation;
>  
> -	trace__add_syscall_newtp(&trace);
> +	/*
> +	 * The syscall tracepoints are what the augmented events are described
> +	 * and paired with: the enter one supplies the format
> +	 * __augmented_syscalls__ is read with, and the exit one reports the
> +	 * returns, since BPF only takes over the enters. Without them there is
> +	 * nothing to augment, so drop the skeleton and carry on with plain
> +	 * tracepoints, as the bpf-output failure below does.
> +	 */
> +	if (trace__add_syscall_newtp(&trace)) {
> +		pr_debug("Failed to set up the syscall tracepoints, disabling augmentation\n");
> +		augmented_syscalls__cleanup();
> +		goto skip_augmentation;
> +	}
>  
>  	err = augmented_syscalls__create_bpf_output(trace.evlist);
> -	if (err == 0)
> +	if (err == 0) {
>  		trace.syscalls.events.bpf_output = evlist__last(trace.evlist);
> +	} else {
> +		/*
> +		 * augmented_syscalls__prepare() already attached sys_enter and
> +		 * sys_exit, which are system wide. Falling through to
> +		 * skip_augmentation without undoing that would run a BPF
> +		 * program for every syscall on the machine, for the whole
> +		 * session, with nothing consuming the output.
> +		 */
> +		pr_debug("Failed to create the augmented syscalls bpf-output event, disabling augmentation\n");
> +		augmented_syscalls__cleanup();
> +	}
>  
>  skip_augmentation:
>  	err = -1;
> @@ -6113,7 +6255,9 @@ int cmd_trace(int argc, const char **argv)
>  	 * syscall.
>  	 */
>  	if (trace.syscalls.events.bpf_output) {
> -		evlist__for_each_entry(trace.evlist, evsel) {
> +		struct evsel *n;
> +
> +		evlist__for_each_entry_safe(trace.evlist, n, evsel) {
>  			bool raw_syscalls_sys_exit = evsel__name_is(evsel, "raw_syscalls:sys_exit");
>  
>  			if (raw_syscalls_sys_exit) {
> @@ -6121,28 +6265,44 @@ int cmd_trace(int argc, const char **argv)
>  				goto init_augmented_syscall_tp;
>  			}
>  
> -			if (trace.syscalls.events.bpf_output->priv == NULL &&
> -			    strstr(evsel__name(evsel), "syscalls:sys_enter")) {
> +			/*
> +			 * Match the evsel trace__add_syscall_newtp() made by
> +			 * identity rather than by name. It is called
> +			 * raw_syscalls:sys_enter, or syscalls:sys_enter on
> +			 * kernels too old to have the raw variant, and a
> +			 * substring test for the latter also matches the
> +			 * per syscall syscalls:sys_enter_SYSCALL tracepoints
> +			 * a user can ask for by name. Claiming one of those
> +			 * here would take the event the user asked for out of
> +			 * the evlist below and describe __augmented_syscalls__
> +			 * with the wrong tracefs format.
> +			 */
> +			if (evsel == trace.syscalls.events.sys_enter) {
>  				struct evsel *augmented = trace.syscalls.events.bpf_output;
>  				if (evsel__init_augmented_syscall_tp(augmented, evsel) ||
>  				    evsel__init_augmented_syscall_tp_args(augmented))
>  					goto out;
>  				/*
> -				 * Augmented is __augmented_syscalls__ BPF_OUTPUT event
> +				 * Augmented is __augmented_syscalls__ BPF_OUTPUT event.
>  				 * Above we made sure we can get from the payload the tp fields
>  				 * that we get from syscalls:sys_enter tracefs format file.
> +				 * Since BPF outputs all enter events (both augmented and
> +				 * unaugmented) into __augmented_syscalls__, we remove the raw
> +				 * sys_enter evsel from evlist so that perf trace only listens
> +				 * to __augmented_syscalls__, avoiding duplicate events and
> +				 * avoiding kernel tracepoint vetoes.
> +				 *
> +				 * Because evlist__remove() removes the first evsel (which had
> +				 * tracking=true by default), re-designate the tracking event
> +				 * so PERF_RECORD_COMM and fork tracking continue to be enabled.
>  				 */
>  				augmented->handler = trace__sys_enter;
> -				/*
> -				 * Now we do the same for the *syscalls:sys_enter event so that
> -				 * if we handle it directly, i.e. if the BPF prog returns 0 so
> -				 * as not to filter it, then we'll handle it just like we would
> -				 * for the BPF_OUTPUT one:
> -				 */
> -				if (evsel__init_augmented_syscall_tp(evsel, evsel) ||
> -				    evsel__init_augmented_syscall_tp_args(evsel))
> -					goto out;
> -				evsel->handler = trace__sys_enter;
> +				evlist__remove(trace.evlist, evsel);
> +				evsel__put_and_free_priv(evsel);
> +				trace.syscalls.events.sys_enter = NULL;
> +				evlist__set_tracking_event(trace.evlist,
> +					trace.syscalls.events.sys_exit ?: augmented);
> +				continue;
>  			}
>  
>  			if (strstarts(evsel__name(evsel), "syscalls:sys_exit_")) {
> diff --git a/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c b/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c
> index 18904bebf672..f16299c1d311 100644
> --- a/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c
> +++ b/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c
> @@ -114,6 +114,41 @@ struct pids_filtered {
>  	__uint(max_entries, 64);
>  } pids_filtered SEC(".maps");
>  
> +/*
> + * Optional hash map containing specific PIDs/TGIDs to trace (e.g., when
> + * attached to a process with -p or tracing a specific command workload).
> + *
> + * has_pids_to_trace: Set to true if target PID filtering is active.
> + *                    When false, all processes are eligible for tracing.
> + */
> +struct pids_to_trace {
> +	__uint(type, BPF_MAP_TYPE_HASH);
> +	__type(key, pid_t);
> +	__type(value, bool);
> +	__uint(max_entries, 1024);
> +} pids_to_trace SEC(".maps");
> +
> +bool has_pids_to_trace;
> +
> +/*
> + * Hash map storing syscall IDs for filtering (via 'perf trace -e ...').
> + *
> + * has_syscalls_to_trace: Set to true if any syscall filter is active.
> + * not_syscalls_to_trace: Inverts matching when '!' prefix is used in -e
> + *                        (e.g., -e !open,close means trace everything EXCEPT
> + *                        open and close; an exclusion blacklist rather than
> + *                        an inclusion whitelist).
> + */
> +struct syscalls_to_trace {
> +	__uint(type, BPF_MAP_TYPE_HASH);
> +	__type(key, int);
> +	__type(value, bool);
> +	__uint(max_entries, 1024);
> +} syscalls_to_trace SEC(".maps");
> +
> +bool has_syscalls_to_trace;
> +bool not_syscalls_to_trace;
> +
>  struct augmented_args_payload {
>  	struct syscall_enter_args args;
>  	struct augmented_arg arg, arg2; // We have to reserve space for two arguments (rename, etc)
> @@ -154,8 +189,8 @@ static inline struct augmented_args_payload *augmented_args_payload(void)
>  
>  static inline int augmented__output(void *ctx, struct augmented_args_payload *args, int len)
>  {
> -	/* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */
> -	return bpf_perf_event_output(ctx, &__augmented_syscalls__, BPF_F_CURRENT_CPU, args, len);
> +	bpf_perf_event_output(ctx, &__augmented_syscalls__, BPF_F_CURRENT_CPU, args, len);
> +	return 1;
>  }
>  
>  static inline int augmented__beauty_output(void *ctx, void *data, int len)
> @@ -191,10 +226,21 @@ unsigned int augmented_arg__read_str(struct augmented_arg *augmented_arg, const
>  	return augmented_len;
>  }
>  
> -SEC("tp/raw_syscalls/sys_enter")
> +/*
> + * Default sys_enter program for syscalls without pointer argument augmentation.
> + * Writes the raw struct syscall_enter_args payload into __augmented_syscalls__
> + * and returns 1 so the tracepoint is never vetoed in the kernel.
> + */
> +SEC("tp/syscalls/sys_enter_unaugmented")
>  int syscall_unaugmented(struct syscall_enter_args *args)
>  {
> -	return 1;
> +	struct augmented_args_payload *augmented_args = augmented_args_payload();
> +
> +	if (augmented_args == NULL)
> +		return 1;
> +
> +	bpf_probe_read_kernel(&augmented_args->args, sizeof(augmented_args->args), args);
> +	return augmented__output(args, augmented_args, sizeof(augmented_args->args));
>  }
>  
>  /*
> @@ -454,11 +500,41 @@ static pid_t getpid(void)
>  	return bpf_get_current_pid_tgid();
>  }
>  
> +/*
> + * Returns true if a PID is explicitly excluded/filtered out (e.g., via --filter-pids).
> + */
>  static bool pid_filter__has(struct pids_filtered *pids, pid_t pid)
>  {
>  	return bpf_map_lookup_elem(pids, &pid) != NULL;
>  }
>  
> +/*
> + * Checks if the current task (thread PID or process TGID) is targeted for tracing.
> + * Checks both PID (thread ID) and TGID (process ID) so that all threads of a
> + * target process match.
> + */
> +static inline bool pid_to_trace__has(pid_t pid)
> +{
> +	pid_t tgid = bpf_get_current_pid_tgid() >> 32;
> +
> +	return bpf_map_lookup_elem(&pids_to_trace, &pid) != NULL ||
> +	       bpf_map_lookup_elem(&pids_to_trace, &tgid) != NULL;
> +}
> +
> +/*
> + * Determines if a syscall should be traced based on the filter map:
> + * - When not_syscalls_to_trace is true: blacklist mode (trace if NOT in map).
> + * - When not_syscalls_to_trace is false: whitelist mode (trace ONLY if IN map).
> + */
> +static inline bool syscall_to_trace__enabled(int id)
> +{
> +	bool in_map = bpf_map_lookup_elem(&syscalls_to_trace, &id) != NULL;
> +
> +	if (not_syscalls_to_trace)
> +		return !in_map;
> +	return in_map;
> +}
> +
>  u64 ZERO = 0;
>  
>  /*
> @@ -604,6 +680,11 @@ static int augment_sys_enter(void *ctx, struct syscall_enter_args *args)
>  	return augmented__beauty_output(ctx, payload, sizeof(struct syscall_enter_args) + output);
>  }
>  
> +/*
> + * Main raw_syscalls:sys_enter tracepoint handler.
> + * Always returns 1 so the tracepoint is never vetoed in the kernel for
> + * other concurrent listeners. Filtered events simply do not output to the ring buffer.
> + */
>  SEC("tp/raw_syscalls/sys_enter")
>  int sys_enter(struct syscall_enter_args *args)
>  {
> @@ -618,8 +699,11 @@ int sys_enter(struct syscall_enter_args *args)
>  	 * initial, non-augmented raw_syscalls:sys_enter payload.
>  	 */
>  
> +	if (has_pids_to_trace && !pid_to_trace__has(getpid()))
> +		return 1;
> +
>  	if (pid_filter__has(&pids_filtered, getpid()))
> -		return 0;
> +		return 1;
>  
>  	augmented_args = augmented_args_payload();
>  	if (augmented_args == NULL)
> @@ -627,25 +711,41 @@ int sys_enter(struct syscall_enter_args *args)
>  
>  	bpf_probe_read_kernel(&augmented_args->args, sizeof(augmented_args->args), args);
>  
> +	if (has_syscalls_to_trace && !syscall_to_trace__enabled(augmented_args->args.syscall_nr))
> +		return 1;
> +
>  	/*
> -	 * Jump to syscall specific augmenter, even if the default one,
> -	 * "!raw_syscalls:unaugmented" that will just return 1 to return the
> -	 * unaugmented tracepoint payload.
> +	 * Jump to syscall specific augmenter. If augmented, augment_sys_enter()
> +	 * outputs the payload to __augmented_syscalls__ and returns 0.
> +	 * Return 1 so we never veto the kernel tracepoint for other listeners.
>  	 */
> -	if (augment_sys_enter(args, &augmented_args->args))
> -		bpf_tail_call(args, &syscalls_sys_enter, augmented_args->args.syscall_nr);
> +	if (augment_sys_enter(args, &augmented_args->args) == 0)
> +		return 1;
>  
> -	// If not found on the PROG_ARRAY syscalls map, then we're filtering it:
> -	return 0;
> +	bpf_tail_call(args, &syscalls_sys_enter, augmented_args->args.syscall_nr);
> +
> +	/*
> +	 * If not found on the PROG_ARRAY syscalls map, return 1 so we
> +	 * don't veto the tracepoint event system-wide for other concurrent
> +	 * listeners.
> +	 */
> +	return 1;
>  }
>  
> +/*
> + * Main raw_syscalls:sys_exit tracepoint handler.
> + * Always returns 1 so the tracepoint is never vetoed in the kernel.
> + */
>  SEC("tp/raw_syscalls/sys_exit")
>  int sys_exit(struct syscall_exit_args *args)
>  {
>  	struct syscall_exit_args exit_args;
>  
> +	if (has_pids_to_trace && !pid_to_trace__has(getpid()))
> +		return 1;
> +
>  	if (pid_filter__has(&pids_filtered, getpid()))
> -		return 0;
> +		return 1;
>  
>  	bpf_probe_read_kernel(&exit_args, sizeof(exit_args), args);
>  	/*
> @@ -655,9 +755,12 @@ int sys_exit(struct syscall_exit_args *args)
>  	 */
>  	bpf_tail_call(args, &syscalls_sys_exit, exit_args.syscall_nr);
>  	/*
> -	 * If not found on the PROG_ARRAY syscalls map, then we're filtering it:
> +	 * If not found on the PROG_ARRAY syscalls map, return 1 so we
> +	 * don't veto the tracepoint event system-wide for other concurrent
> +	 * listeners. perf trace's own evsel filter will discard non-matching
> +	 * syscalls.
>  	 */
> -	return 0;
> +	return 1;
>  }
>  
>  char _license[] SEC("license") = "GPL";
> diff --git a/tools/perf/util/bpf_trace_augment.c b/tools/perf/util/bpf_trace_augment.c
> index ebb26225fb04..5f15b27264e9 100644
> --- a/tools/perf/util/bpf_trace_augment.c
> +++ b/tools/perf/util/bpf_trace_augment.c
> @@ -1,5 +1,6 @@
>  #include <assert.h>
>  #include <bpf/libbpf.h>
> +#include <errno.h>
>  #include <internal/xyarray.h>
>  #include <string.h>
>  
> @@ -12,6 +13,23 @@
>  static struct augmented_raw_syscalls_bpf *skel;
>  static struct evsel *bpf_output;
>  
> +/* Set by attach_prog() so the first failure is what gets reported. */
> +static int attach_err;
> +
> +static int attach_prog(struct bpf_link **link, struct bpf_program *prog, const char *name)
> +{
> +	*link = bpf_program__attach(prog);
> +	if (*link)
> +		return 0;
> +	/*
> +	 * Save errno before pr_debug(), which formats and writes output and so
> +	 * can overwrite it.
> +	 */
> +	attach_err = -errno;
> +	pr_debug("Failed to attach %s BPF program\n", name);
> +	return attach_err;
> +}
> +
>  int augmented_syscalls__prepare(void)
>  {
>  	struct bpf_program *prog;
> @@ -37,11 +55,35 @@ int augmented_syscalls__prepare(void)
>  	if (err < 0) {
>  		libbpf_strerror(err, buf, sizeof(buf));
>  		pr_debug("Failed to load augmented syscalls BPF skeleton: %s\n", buf);
> +		/*
> +		 * Tear the skeleton down rather than leaving a half initialized
> +		 * one behind. The caller falls back to unaugmented tracing and
> +		 * still calls the setters below, which must then do nothing
> +		 * instead of failing against a skeleton with no maps.
> +		 */
> +		augmented_syscalls__cleanup();
>  		return err;
>  	}
>  
> -	augmented_raw_syscalls_bpf__attach(skel);
> +	/*
> +	 * Only sys_enter and sys_exit are attached, the remaining programs are
> +	 * reached by tail calls. Attach them explicitly and, on failure, undo
> +	 * any partial attachment: leaving sys_enter live on
> +	 * raw_syscalls:sys_enter would keep running a BPF program for every
> +	 * syscall on the system for a perf trace session that never starts.
> +	 */
> +	if (attach_prog(&skel->links.sys_enter, skel->progs.sys_enter, "sys_enter"))
> +		goto out_cleanup;
> +	if (attach_prog(&skel->links.sys_exit, skel->progs.sys_exit, "sys_exit"))
> +		goto out_cleanup;
> +
>  	return 0;
> +
> +out_cleanup:
> +	err = attach_err;
> +	/* Destroys every link attached above along with the skeleton. */
> +	augmented_syscalls__cleanup();
> +	return err;
>  }
>  
>  int augmented_syscalls__create_bpf_output(struct evlist *evlist)
> @@ -82,22 +124,136 @@ void augmented_syscalls__setup_bpf_output(void)
>  	}
>  }
>  
> +/*
> + * Add every pid to a pid keyed filter map.
> + *
> + * A map with no room left is not treated as a failure. bpf_map__update_elem()
> + * answers -E2BIG once max_entries keys are present, and a task that did not
> + * fit is then one the filter does not know about, which is exactly the
> + * position it would be in had it been created after the map filled up.
> + * Refusing to trace at all instead would make perf trace unusable against the
> + * very large targets that are the only way to reach the limit, so say how many
> + * missed out and carry on with those that did fit.
> + */
> +static int add_pids_to_map(struct bpf_map *map, const char *missing_out_on,
> +			   unsigned int nr, pid_t *pids)
> +{
> +	unsigned int nr_no_room = 0;
> +	bool value = true;
> +
> +	for (unsigned int i = 0; i < nr; ++i) {
> +		int err = bpf_map__update_elem(map, &pids[i], sizeof(*pids),
> +					       &value, sizeof(value), BPF_ANY);
> +
> +		if (err == -E2BIG) {
> +			nr_no_room++;
> +			continue;
> +		}
> +		if (err)
> +			return err;
> +	}
> +
> +	if (nr_no_room) {
> +		pr_warning("Only %u of %u tasks fit in the %s BPF map, %u will not be %s.\n",
> +			   nr - nr_no_room, nr, bpf_map__name(map), nr_no_room,
> +			   missing_out_on);
> +	}
> +
> +	return 0;
> +}
> +
>  int augmented_syscalls__set_filter_pids(unsigned int nr, pid_t *pids)
> +{
> +	if (skel == NULL)
> +		return 0;
> +
> +	return add_pids_to_map(skel->maps.pids_filtered, "filtered out", nr, pids);
> +}
> +
> +/*
> + * Populate target PIDs in the BPF pids_to_trace map (e.g., for -p <PID> or
> + * when tracing a specified command workload).
> + */
> +int augmented_syscalls__set_target_pids(unsigned int nr, pid_t *pids)
> +{
> +	int err;
> +
> +	if (skel == NULL || nr == 0)
> +		return 0;
> +
> +	err = add_pids_to_map(skel->maps.pids_to_trace, "traced", nr, pids);
> +	if (err)
> +		return err;
> +
> +	/*
> +	 * Set the flag only once every target is in the map. The BPF programs
> +	 * are attached by this point, so flipping it first would have them
> +	 * filter against a partially populated map and drop syscalls made by
> +	 * the targets that had not been added yet.
> +	 */
> +	skel->bss->has_pids_to_trace = true;
> +	return 0;
> +}
> +
> +int augmented_syscalls__add_target_pid(pid_t pid)
> +{
> +	bool value = true;
> +
> +	if (skel == NULL || !skel->bss->has_pids_to_trace || skel->maps.pids_to_trace == NULL)
> +		return 0;
> +
> +	return bpf_map__update_elem(skel->maps.pids_to_trace, &pid, sizeof(pid),
> +				    &value, sizeof(value), BPF_ANY);
> +}
> +
> +int augmented_syscalls__del_target_pid(pid_t pid)
> +{
> +	if (skel == NULL || !skel->bss->has_pids_to_trace || skel->maps.pids_to_trace == NULL)
> +		return 0;
> +
> +	return bpf_map__delete_elem(skel->maps.pids_to_trace, &pid, sizeof(pid), 0);
> +}
> +
> +bool augmented_syscalls__has_target_pid(pid_t pid)
> +{
> +	bool value;
> +
> +	if (skel == NULL || !skel->bss->has_pids_to_trace || skel->maps.pids_to_trace == NULL)
> +		return false;
> +
> +	return bpf_map__lookup_elem(skel->maps.pids_to_trace, &pid, sizeof(pid),
> +				    &value, sizeof(value), 0) == 0;
> +}
> +
> +/*
> + * Populate syscalls in the BPF syscalls_to_trace map:
> + * - not_syscalls: true if '!' prefix was specified (blacklist mode: trace
> + *   all syscalls EXCEPT these).
> + *   false if whitelist mode (trace ONLY these syscalls).
> + */
> +int augmented_syscalls__set_target_syscalls(unsigned int nr, int *syscall_ids, bool not_syscalls)
>  {
>  	bool value = true;
>  	int err = 0;
>  
> -	if (skel == NULL)
> +	if (skel == NULL || nr == 0)
>  		return 0;
>  
> +	skel->bss->not_syscalls_to_trace = not_syscalls;
>  	for (size_t i = 0; i < nr; ++i) {
> -		err = bpf_map__update_elem(skel->maps.pids_filtered, &pids[i],
> -					   sizeof(*pids), &value, sizeof(value),
> +		err = bpf_map__update_elem(skel->maps.syscalls_to_trace, &syscall_ids[i],
> +					   sizeof(int), &value, sizeof(value),
>  					   BPF_ANY);
>  		if (err)
> -			break;
> +			return err;
>  	}
> -	return err;
> +	/*
> +	 * As for the pid maps, publish the filter only once it is complete:
> +	 * in whitelist mode a half filled map would drop syscalls that were
> +	 * asked for but not added yet.
> +	 */
> +	skel->bss->has_syscalls_to_trace = true;
> +	return 0;
>  }
>  
>  int augmented_syscalls__get_map_fds(int *enter_fd, int *exit_fd, int *beauty_fd)
> @@ -142,4 +298,5 @@ struct bpf_program *augmented_syscalls__find_by_title(const char *name)
>  void augmented_syscalls__cleanup(void)
>  {
>  	augmented_raw_syscalls_bpf__destroy(skel);
> +	skel = NULL;
>  }
> diff --git a/tools/perf/util/trace_augment.h b/tools/perf/util/trace_augment.h
> index a1cd9a5e0213..5702eda3b469 100644
> --- a/tools/perf/util/trace_augment.h
> +++ b/tools/perf/util/trace_augment.h
> @@ -2,6 +2,7 @@
>  #define TRACE_AUGMENT_H
>  
>  #include <linux/compiler.h>
> +#include <stdbool.h>
>  #include <sys/types.h>
>  
>  struct bpf_program;
> @@ -13,6 +14,11 @@ int augmented_syscalls__prepare(void);
>  int augmented_syscalls__create_bpf_output(struct evlist *evlist);
>  void augmented_syscalls__setup_bpf_output(void);
>  int augmented_syscalls__set_filter_pids(unsigned int nr, pid_t *pids);
> +int augmented_syscalls__set_target_pids(unsigned int nr, pid_t *pids);
> +int augmented_syscalls__add_target_pid(pid_t pid);
> +int augmented_syscalls__del_target_pid(pid_t pid);
> +bool augmented_syscalls__has_target_pid(pid_t pid);
> +int augmented_syscalls__set_target_syscalls(unsigned int nr, int *syscall_ids, bool not_syscalls);
>  int augmented_syscalls__get_map_fds(int *enter_fd, int *exit_fd, int *beauty_fd);
>  struct bpf_program *augmented_syscalls__find_by_title(const char *name);
>  struct bpf_program *augmented_syscalls__unaugmented(void);
> @@ -40,6 +46,34 @@ static inline int augmented_syscalls__set_filter_pids(unsigned int nr __maybe_un
>  	return 0;
>  }
>  
> +static inline int augmented_syscalls__set_target_pids(unsigned int nr __maybe_unused,
> +						      pid_t *pids __maybe_unused)
> +{
> +	return 0;
> +}
> +
> +static inline int augmented_syscalls__add_target_pid(pid_t pid __maybe_unused)
> +{
> +	return 0;
> +}
> +
> +static inline int augmented_syscalls__del_target_pid(pid_t pid __maybe_unused)
> +{
> +	return 0;
> +}
> +
> +static inline bool augmented_syscalls__has_target_pid(pid_t pid __maybe_unused)
> +{
> +	return false;
> +}
> +
> +static inline int augmented_syscalls__set_target_syscalls(unsigned int nr __maybe_unused,
> +							  int *syscall_ids __maybe_unused,
> +							  bool not_syscalls __maybe_unused)
> +{
> +	return 0;
> +}
> +
>  static inline int augmented_syscalls__get_map_fds(int *enter_fd __maybe_unused,
>  						  int *exit_fd __maybe_unused,
>  						  int *beauty_fd __maybe_unused)
> -- 
> 2.56.0.rc1.315.gc6ed9934b7-goog
> 

  reply	other threads:[~2026-09-25  2:59 UTC|newest]

Thread overview: 99+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-17  6:42 [PATCH v1 00/13] perf trace: Fix BPF filtering and make tracing tests non-exclusive Ian Rogers
2026-09-17  6:42 ` [PATCH v1 01/13] perf trace: Start BPF summary before starting workload Ian Rogers
2026-09-17  6:42 ` [PATCH v1 02/13] perf trace: Skip internal tracepoint fields in formatting and beauty map Ian Rogers
2026-09-17  6:42 ` [PATCH v1 03/13] perf trace: Do not set unaugmented BPF program on sys_exit map Ian Rogers
2026-09-17  6:42 ` [PATCH v1 04/13] perf trace: Filter events in BPF and avoid tracepoint vetoes Ian Rogers
2026-09-17  6:42 ` [PATCH v1 05/13] perf trace: Handle fork and exit directly in BPF filter maps Ian Rogers
2026-09-17  6:42 ` [PATCH v1 06/13] perf test test_task_analyzer: Isolate in temporary directory and make non-exclusive Ian Rogers
2026-09-17  6:42 ` [PATCH v1 07/13] perf test common: Do not globally disable tracing events in clear_all_probes Ian Rogers
2026-09-17  6:42 ` [PATCH v1 08/13] perf test probe_vfs_getname: Scope probe name to PID and make non-exclusive Ian Rogers
2026-09-17  6:42 ` [PATCH v1 09/13] perf test record+probe_libc_inet_pton: Scope event to PID, add retries, " Ian Rogers
2026-09-17  6:42 ` [PATCH v1 10/13] perf test trace_summary: Improve error diagnostics Ian Rogers
2026-09-17  6:42 ` [PATCH v1 11/13] perf test trace_btf_general: Drop --max-events=1 and make non-exclusive Ian Rogers
2026-09-17  6:42 ` [PATCH v1 12/13] perf test trace_summary: Make non-exclusive Ian Rogers
2026-09-17  6:42 ` [PATCH v1 13/13] perf test uprobe_from_different_cu: Scope probe name to PID Ian Rogers
2026-09-17 16:38 ` [PATCH v2 00/14] perf trace: Fix BPF filtering and make tracing tests non-exclusive Ian Rogers
2026-09-17 16:38   ` [PATCH v2 01/14] perf trace: Include the headers declaring pid_t and strcmp Ian Rogers
2026-09-17 16:38   ` [PATCH v2 02/14] perf trace: Start BPF summary before starting workload Ian Rogers
2026-09-17 16:38   ` [PATCH v2 03/14] perf trace: Skip internal tracepoint fields in formatting and beauty map Ian Rogers
2026-09-17 16:38   ` [PATCH v2 04/14] perf trace: Do not set unaugmented BPF program on sys_exit map Ian Rogers
2026-09-17 16:38   ` [PATCH v2 05/14] perf trace: Filter events in BPF and avoid tracepoint vetoes Ian Rogers
2026-09-17 16:38   ` [PATCH v2 06/14] perf trace: Handle fork and exit directly in BPF filter maps Ian Rogers
2026-09-17 16:38   ` [PATCH v2 07/14] perf test test_task_analyzer: Isolate in temporary directory and make non-exclusive Ian Rogers
2026-09-17 16:38   ` [PATCH v2 08/14] perf test common: Do not globally disable tracing events in clear_all_probes Ian Rogers
2026-09-17 16:38   ` [PATCH v2 09/14] perf test probe_vfs_getname: Scope probe name to PID and make non-exclusive Ian Rogers
2026-09-17 16:38   ` [PATCH v2 10/14] perf test record+probe_libc_inet_pton: Scope event to PID, add retries, " Ian Rogers
2026-09-17 16:38   ` [PATCH v2 11/14] perf test trace_summary: Improve error diagnostics Ian Rogers
2026-09-17 16:39   ` [PATCH v2 12/14] perf test trace_btf_general: Drop --max-events=1 and make non-exclusive Ian Rogers
2026-09-17 16:39   ` [PATCH v2 13/14] perf test trace_summary: Make non-exclusive Ian Rogers
2026-09-17 16:39   ` [PATCH v2 14/14] perf test uprobe_from_different_cu: Scope probe name to PID Ian Rogers
2026-09-18 14:06   ` [PATCH v3 00/16] perf trace: Fix BPF filtering and make tracing tests non-exclusive Ian Rogers
2026-09-18 14:06     ` [PATCH v3 01/16] perf trace: Include the headers declaring pid_t, strcmp and assert Ian Rogers
2026-09-18 14:06     ` [PATCH v3 02/16] perf trace: Free the whole evsel_trace in evsel__put_and_free_priv Ian Rogers
2026-09-18 14:06     ` [PATCH v3 03/16] perf trace: Start BPF summary before starting workload Ian Rogers
2026-09-18 14:06     ` [PATCH v3 04/16] perf trace: Skip internal tracepoint fields in formatting and beauty map Ian Rogers
2026-09-18 14:06     ` [PATCH v3 05/16] perf trace: Do not set unaugmented BPF program on sys_exit map Ian Rogers
2026-09-18 14:06     ` [PATCH v3 06/16] perf trace: Filter events in BPF and avoid tracepoint vetoes Ian Rogers
2026-09-18 14:06     ` [PATCH v3 07/16] perf trace: Handle fork and exit directly in BPF filter maps Ian Rogers
2026-09-18 14:06     ` [PATCH v3 08/16] perf trace: Enumerate the target again once BPF is attached Ian Rogers
2026-09-18 14:06     ` [PATCH v3 09/16] perf test test_task_analyzer: Isolate in temporary directory and make non-exclusive Ian Rogers
2026-09-18 14:06     ` [PATCH v3 10/16] perf test common: Only disable probes in clear_all_probes Ian Rogers
2026-09-18 14:06     ` [PATCH v3 11/16] perf test probe_vfs_getname: Scope probe name to PID and make non-exclusive Ian Rogers
2026-09-18 14:06     ` [PATCH v3 12/16] perf test record+probe_libc_inet_pton: Scope event to PID, add retries, " Ian Rogers
2026-09-18 14:06     ` [PATCH v3 13/16] perf test trace_summary: Improve error diagnostics Ian Rogers
2026-09-18 14:06     ` [PATCH v3 14/16] perf test trace_btf_general: Drop --max-events=1 and make non-exclusive Ian Rogers
2026-09-18 14:06     ` [PATCH v3 15/16] perf test trace_summary: Make non-exclusive Ian Rogers
2026-09-18 14:06     ` [PATCH v3 16/16] perf test uprobe_from_different_cu: Scope probe name to PID Ian Rogers
2026-09-18 21:19     ` [PATCH v4 00/18] perf trace: Fix BPF filtering and make tracing tests non-exclusive Ian Rogers
2026-09-18 21:19       ` [PATCH v4 01/18] perf trace: Include the headers declaring pid_t, strcmp and assert Ian Rogers
2026-09-18 21:19       ` [PATCH v4 02/18] perf trace: Free the whole evsel_trace in evsel__put_and_free_priv Ian Rogers
2026-09-18 21:19       ` [PATCH v4 03/18] perf evsel: Report an allocation failure as ENOMEM when setting filters Ian Rogers
2026-09-18 21:19       ` [PATCH v4 04/18] perf trace: Start BPF summary before starting workload Ian Rogers
2026-09-18 21:19       ` [PATCH v4 05/18] perf trace: Skip internal tracepoint fields in formatting and beauty map Ian Rogers
2026-09-18 21:19       ` [PATCH v4 06/18] perf trace: Do not set unaugmented BPF program on sys_exit map Ian Rogers
2026-09-18 21:19       ` [PATCH v4 07/18] perf trace: Filter events in BPF and avoid tracepoint vetoes Ian Rogers
2026-09-18 21:19       ` [PATCH v4 08/18] perf trace: Handle fork and exit directly in BPF filter maps Ian Rogers
2026-09-18 21:19       ` [PATCH v4 09/18] perf trace: Enumerate the target again once BPF is attached Ian Rogers
2026-09-18 21:19       ` [PATCH v4 10/18] perf trace: Drop targets that died before they were filtered Ian Rogers
2026-09-18 21:19       ` [PATCH v4 11/18] perf test test_task_analyzer: Isolate in temporary directory and make non-exclusive Ian Rogers
2026-09-18 21:19       ` [PATCH v4 12/18] perf test common: Only disable probes in clear_all_probes Ian Rogers
2026-09-18 21:19       ` [PATCH v4 13/18] perf test probe_vfs_getname: Scope probe name to PID and make non-exclusive Ian Rogers
2026-09-18 21:19       ` [PATCH v4 14/18] perf test record+probe_libc_inet_pton: Scope event to PID, add retries, " Ian Rogers
2026-09-18 21:19       ` [PATCH v4 15/18] perf test trace_summary: Improve error diagnostics Ian Rogers
2026-09-18 21:19       ` [PATCH v4 16/18] perf test trace_btf_general: Drop --max-events=1 and make non-exclusive Ian Rogers
2026-09-18 21:19       ` [PATCH v4 17/18] perf test trace_summary: Make non-exclusive Ian Rogers
2026-09-18 21:19       ` [PATCH v4 18/18] perf test uprobe_from_different_cu: Scope probe name to PID Ian Rogers
2026-09-22 13:11       ` [PATCH v4 00/18] perf trace: Fix BPF filtering and make tracing tests non-exclusive Arnaldo Carvalho de Melo
2026-09-22 22:43         ` Ian Rogers
2026-09-23  7:13       ` [PATCH v5 00/23] " Ian Rogers
2026-09-23  7:13         ` [PATCH v5 01/23] perf trace: Set the augmented arg header in the augmenters that omit it Ian Rogers
2026-09-24  5:39           ` Namhyung Kim
2026-09-23  7:13         ` [PATCH v5 02/23] perf trace: Include the augmented arg header in nanosleep's payload length Ian Rogers
2026-09-23  7:13         ` [PATCH v5 03/23] perf trace: Include the headers declaring pid_t, strcmp and assert Ian Rogers
2026-09-24  5:44           ` Namhyung Kim
2026-09-23  7:13         ` [PATCH v5 04/23] perf trace: Free the whole evsel_trace in evsel__put_and_free_priv Ian Rogers
2026-09-23  7:13         ` [PATCH v5 05/23] perf evsel: Report an allocation failure as ENOMEM when setting filters Ian Rogers
2026-09-23  7:13         ` [PATCH v5 06/23] perf trace: Start BPF summary before starting workload Ian Rogers
2026-09-23  7:13         ` [PATCH v5 07/23] perf trace: Skip internal tracepoint fields in formatting and beauty map Ian Rogers
2026-09-24  6:44           ` Namhyung Kim
2026-09-23  7:13         ` [PATCH v5 08/23] perf trace: Bounds check augmented arguments before reading them Ian Rogers
2026-09-24  6:58           ` Namhyung Kim
2026-09-23  7:13         ` [PATCH v5 09/23] perf trace: Bound the fixed size augmented argument beautifiers Ian Rogers
2026-09-23  7:13         ` [PATCH v5 10/23] perf trace: Do not read sample padding as an augmented argument Ian Rogers
2026-09-23  7:13         ` [PATCH v5 11/23] perf trace: Do not set unaugmented BPF program on sys_exit map Ian Rogers
2026-09-24 22:49           ` Namhyung Kim
2026-09-23  7:13         ` [PATCH v5 12/23] perf trace: Filter events in BPF and avoid tracepoint vetoes Ian Rogers
2026-09-25  2:59           ` Namhyung Kim [this message]
2026-09-25  4:10             ` Ian Rogers
2026-09-23  7:13         ` [PATCH v5 13/23] perf trace: Handle fork and exit directly in BPF filter maps Ian Rogers
2026-09-23  7:13         ` [PATCH v5 14/23] perf trace: Enumerate the target again once BPF is attached Ian Rogers
2026-09-23  7:13         ` [PATCH v5 15/23] perf trace: Drop targets that died before they were filtered Ian Rogers
2026-09-23  7:13         ` [PATCH v5 16/23] perf test test_task_analyzer: Isolate in temporary directory and make non-exclusive Ian Rogers
2026-09-23  7:13         ` [PATCH v5 17/23] perf test common: Only disable probes in clear_all_probes Ian Rogers
2026-09-23  7:13         ` [PATCH v5 18/23] perf test probe_vfs_getname: Scope probe name to PID and make non-exclusive Ian Rogers
2026-09-23  7:13         ` [PATCH v5 19/23] perf test record+probe_libc_inet_pton: Scope event to PID, add retries, " Ian Rogers
2026-09-23  7:14         ` [PATCH v5 20/23] perf test trace_summary: Improve error diagnostics Ian Rogers
2026-09-23  7:14         ` [PATCH v5 21/23] perf test trace_btf_general: Drop --max-events=1 and make non-exclusive Ian Rogers
2026-09-23  7:14         ` [PATCH v5 22/23] perf test trace_summary: Make non-exclusive Ian Rogers
2026-09-23  7:14         ` [PATCH v5 23/23] perf test uprobe_from_different_cu: Scope probe name to PID Ian Rogers
2026-09-24  7:05         ` [PATCH v5 00/23] perf trace: Fix BPF filtering and make tracing tests non-exclusive Namhyung Kim

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=arXjkuLjHO826tXy@z2 \
    --to=namhyung@kernel.org \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=howardchu95@gmail.com \
    --cc=irogers@google.com \
    --cc=james.clark@linaro.org \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    /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

all inboxes | Powered by JetHome®