From: Ian Rogers <irogers@google.com>
To: irogers@google.com, acme@kernel.org, namhyung@kernel.org
Cc: adrian.hunter@intel.com, bvanassche@acm.org, elver@google.com,
james.clark@linaro.org, jolsa@kernel.org,
justinstitt@google.com, linux-kernel@vger.kernel.org,
linux-perf-users@vger.kernel.org, llvm@lists.linux.dev,
mingo@redhat.com, morbo@google.com, nathan@kernel.org,
ndesaulniers@google.com, peterz@infradead.org
Subject: [PATCH v10 20/20] perf maps: Add context analysis annotations
Date: Thu, 5 Nov 2026 23:03:44 -0800 [thread overview]
Message-ID: <20261106070344.329897-21-irogers@google.com> (raw)
In-Reply-To: <20261106070344.329897-1-irogers@google.com>
Add __returns_ctx_lock() to maps__lock(), annotate DECLARE_RC_STRUCT(maps)
members protected by lock with __guarded_by(&lock), and annotate
internal maps helpers with __must_hold() and __must_hold_shared().
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/util/maps.c | 119 ++++++++++++++++++++++++++---------------
1 file changed, 77 insertions(+), 42 deletions(-)
diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
index e6a53b31006f..6c4a20864db8 100644
--- a/tools/perf/util/maps.c
+++ b/tools/perf/util/maps.c
@@ -31,12 +31,12 @@ DECLARE_RC_STRUCT(maps) {
* @maps_by_address: array of maps sorted by their starting address if
* maps_by_address_sorted is true.
*/
- struct map **maps_by_address;
+ struct map **maps_by_address __guarded_by(&lock);
/**
* @maps_by_name: optional array of maps sorted by their dso name if
* maps_by_name_sorted is true.
*/
- struct map **maps_by_name;
+ struct map **maps_by_name __guarded_by(&lock);
struct machine *machine;
#ifdef HAVE_LIBUNWIND_SUPPORT
void *addr_space;
@@ -51,26 +51,33 @@ DECLARE_RC_STRUCT(maps) {
* @nr_maps: number of maps_by_address, and possibly maps_by_name,
* entries that contain maps.
*/
- unsigned int nr_maps;
+ unsigned int nr_maps __guarded_by(&lock);
/**
* @nr_maps_allocated: number of entries in maps_by_address and possibly
* maps_by_name.
*/
- unsigned int nr_maps_allocated;
+ unsigned int nr_maps_allocated __guarded_by(&lock);
/**
* @last_search_by_name_idx: cache of last found by name entry's index
* as frequent searches for the same dso name are common.
*/
unsigned int last_search_by_name_idx;
/** @maps_by_address_sorted: is maps_by_address sorted. */
- bool maps_by_address_sorted;
+ bool maps_by_address_sorted __guarded_by(&lock);
/** @maps_by_name_sorted: is maps_by_name sorted. */
- bool maps_by_name_sorted;
+ bool maps_by_name_sorted __guarded_by(&lock);
/** @ends_broken: does the map contain a map where end values are unset/unsorted? */
- bool ends_broken;
+ bool ends_broken __guarded_by(&lock);
};
+static struct rw_semaphore *maps__lock(const struct maps *maps)
+ __returns_ctx_lock(&RC_CHK_ACCESS(maps)->lock)
+{
+ return (struct rw_semaphore *)&RC_CHK_ACCESS(maps)->lock;
+}
+
static void check_invariants(const struct maps *maps __maybe_unused)
+ __must_hold_shared(maps__lock(maps))
{
#ifndef NDEBUG
assert(RC_CHK_ACCESS(maps)->nr_maps <= RC_CHK_ACCESS(maps)->nr_maps_allocated);
@@ -120,55 +127,65 @@ static void check_invariants(const struct maps *maps __maybe_unused)
}
static struct map **maps__maps_by_address(const struct maps *maps)
+ __must_hold_shared(maps__lock(maps))
{
return RC_CHK_ACCESS(maps)->maps_by_address;
}
static void maps__set_maps_by_address(struct maps *maps, struct map **new)
+ __must_hold(maps__lock(maps))
{
RC_CHK_ACCESS(maps)->maps_by_address = new;
}
static void maps__set_nr_maps_allocated(struct maps *maps, unsigned int nr_maps_allocated)
+ __must_hold(maps__lock(maps))
{
RC_CHK_ACCESS(maps)->nr_maps_allocated = nr_maps_allocated;
}
static void maps__set_nr_maps(struct maps *maps, unsigned int nr_maps)
+ __must_hold(maps__lock(maps))
{
RC_CHK_ACCESS(maps)->nr_maps = nr_maps;
}
/* Not in the header, to aid reference counting. */
static struct map **maps__maps_by_name(const struct maps *maps)
+ __must_hold_shared(maps__lock(maps))
{
return RC_CHK_ACCESS(maps)->maps_by_name;
}
static void maps__set_maps_by_name(struct maps *maps, struct map **new)
+ __must_hold(maps__lock(maps))
{
RC_CHK_ACCESS(maps)->maps_by_name = new;
}
static bool maps__maps_by_address_sorted(const struct maps *maps)
+ __must_hold_shared(maps__lock(maps))
{
return RC_CHK_ACCESS(maps)->maps_by_address_sorted;
}
static void maps__set_maps_by_address_sorted(struct maps *maps, bool value)
+ __must_hold(maps__lock(maps))
{
RC_CHK_ACCESS(maps)->maps_by_address_sorted = value;
}
static bool maps__maps_by_name_sorted(const struct maps *maps)
+ __must_hold_shared(maps__lock(maps))
{
return RC_CHK_ACCESS(maps)->maps_by_name_sorted;
}
static void maps__set_maps_by_name_sorted(struct maps *maps, bool value)
+ __must_hold(maps__lock(maps))
{
RC_CHK_ACCESS(maps)->maps_by_name_sorted = value;
}
@@ -178,11 +195,22 @@ struct machine *maps__machine(const struct maps *maps)
return RC_CHK_ACCESS(maps)->machine;
}
-unsigned int maps__nr_maps(const struct maps *maps)
+static unsigned int __maps__nr_maps(const struct maps *maps)
+ __must_hold_shared(maps__lock(maps))
{
return RC_CHK_ACCESS(maps)->nr_maps;
}
+unsigned int maps__nr_maps(const struct maps *maps)
+{
+ unsigned int nr;
+
+ down_read(maps__lock(maps));
+ nr = __maps__nr_maps(maps);
+ up_read(maps__lock(maps));
+ return nr;
+}
+
refcount_t *maps__refcnt(struct maps *maps)
{
return &RC_CHK_ACCESS(maps)->refcnt;
@@ -221,12 +249,8 @@ void maps__set_libdw_addr_space_dwfl(struct maps *maps, void *dwfl)
}
#endif
-static struct rw_semaphore *maps__lock(struct maps *maps)
-{
- return &RC_CHK_ACCESS(maps)->lock;
-}
-
static void maps__init(struct maps *maps, struct machine *machine)
+ __context_unsafe(/* initialization */)
{
init_rwsem(maps__lock(maps));
RC_CHK_ACCESS(maps)->maps_by_address = NULL;
@@ -248,11 +272,12 @@ static void maps__init(struct maps *maps, struct machine *machine)
}
static void maps__exit(struct maps *maps)
+ __context_unsafe(/* teardown */)
{
struct map **maps_by_address = maps__maps_by_address(maps);
struct map **maps_by_name = maps__maps_by_name(maps);
- for (unsigned int i = 0; i < maps__nr_maps(maps); i++) {
+ for (unsigned int i = 0; i < __maps__nr_maps(maps); i++) {
map__zput(maps_by_address[i]);
if (maps_by_name)
map__zput(maps_by_name[i]);
@@ -301,6 +326,7 @@ void maps__put(struct maps *maps)
}
static void __maps__free_maps_by_name(struct maps *maps)
+ __must_hold(maps__lock(maps))
{
if (!maps__maps_by_name(maps))
return;
@@ -308,7 +334,7 @@ static void __maps__free_maps_by_name(struct maps *maps)
/*
* Free everything to try to do it from the rbtree in the next search
*/
- for (unsigned int i = 0; i < maps__nr_maps(maps); i++)
+ for (unsigned int i = 0; i < __maps__nr_maps(maps); i++)
map__put(maps__maps_by_name(maps)[i]);
zfree(&RC_CHK_ACCESS(maps)->maps_by_name);
@@ -341,12 +367,13 @@ static int map__start_cmp(const void *a, const void *b)
}
static void __maps__sort_by_address(struct maps *maps)
+ __must_hold(maps__lock(maps))
{
if (maps__maps_by_address_sorted(maps))
return;
qsort(maps__maps_by_address(maps),
- maps__nr_maps(maps),
+ __maps__nr_maps(maps),
sizeof(struct map *),
map__start_cmp);
maps__set_maps_by_address_sorted(maps, true);
@@ -389,7 +416,7 @@ static int maps__sort_by_name(struct maps *maps)
err = -ENOMEM;
else {
struct map **maps_by_address = maps__maps_by_address(maps);
- unsigned int n = maps__nr_maps(maps);
+ unsigned int n = __maps__nr_maps(maps);
maps__set_maps_by_name(maps, maps_by_name);
for (unsigned int i = 0; i < n; i++)
@@ -398,7 +425,7 @@ static int maps__sort_by_name(struct maps *maps)
}
if (!err) {
qsort(maps_by_name,
- maps__nr_maps(maps),
+ __maps__nr_maps(maps),
sizeof(struct map *),
map__strcmp);
maps__set_maps_by_name_sorted(maps, true);
@@ -410,9 +437,10 @@ static int maps__sort_by_name(struct maps *maps)
}
static unsigned int maps__by_address_index(const struct maps *maps, const struct map *map)
+ __must_hold_shared(maps__lock(maps))
{
struct map **maps_by_address = maps__maps_by_address(maps);
- unsigned int nr_maps = maps__nr_maps(maps);
+ unsigned int nr_maps = __maps__nr_maps(maps);
if (nr_maps && maps__maps_by_address_sorted(maps)) {
struct map **mapp =
@@ -431,9 +459,10 @@ static unsigned int maps__by_address_index(const struct maps *maps, const struct
}
static unsigned int maps__by_name_index(const struct maps *maps, const struct map *map)
+ __must_hold_shared(maps__lock(maps))
{
struct map **maps_by_name = maps__maps_by_name(maps);
- unsigned int nr_maps = maps__nr_maps(maps);
+ unsigned int nr_maps = __maps__nr_maps(maps);
if (!maps_by_name)
return -1;
@@ -474,10 +503,11 @@ static void map__set_kmap_maps(struct map *map, struct maps *maps)
}
static int __maps__insert(struct maps *maps, struct map *new)
+ __must_hold(maps__lock(maps))
{
struct map **maps_by_address = maps__maps_by_address(maps);
struct map **maps_by_name = maps__maps_by_name(maps);
- unsigned int nr_maps = maps__nr_maps(maps);
+ unsigned int nr_maps = __maps__nr_maps(maps);
unsigned int nr_allocate = RC_CHK_ACCESS(maps)->nr_maps_allocated;
if (nr_maps + 1 > nr_allocate) {
@@ -545,10 +575,11 @@ int maps__insert(struct maps *maps, struct map *map)
}
static void __maps__remove_at(struct maps *maps, unsigned int address_idx)
+ __must_hold(maps__lock(maps))
{
struct map **maps_by_address = maps__maps_by_address(maps);
struct map **maps_by_name = maps__maps_by_name(maps);
- unsigned int nr_maps = maps__nr_maps(maps);
+ unsigned int nr_maps = __maps__nr_maps(maps);
struct map *map;
if (address_idx >= nr_maps)
@@ -578,6 +609,7 @@ static void __maps__remove_at(struct maps *maps, unsigned int address_idx)
}
static void __maps__remove(struct maps *maps, struct map *map)
+ __must_hold(maps__lock(maps))
{
__maps__remove_at(maps, maps__by_address_index(maps, map));
}
@@ -640,7 +672,7 @@ bool maps__empty(struct maps *maps)
bool res;
down_read(maps__lock(maps));
- res = maps__nr_maps(maps) == 0;
+ res = __maps__nr_maps(maps) == 0;
up_read(maps__lock(maps));
return res;
@@ -668,7 +700,7 @@ int maps__for_each_map(struct maps *maps, int (*cb)(struct map *map, void *data)
* the array - this may cause maps to be skipped or
* repeated.
*/
- for (unsigned int i = 0; i < maps__nr_maps(maps); i++) {
+ for (unsigned int i = 0; i < __maps__nr_maps(maps); i++) {
struct map **maps_by_address = maps__maps_by_address(maps);
struct map *map = maps_by_address[i];
@@ -695,7 +727,7 @@ int maps__load_maps(struct maps *maps)
return 0;
down_read(maps__lock(maps));
- nr_maps = maps__nr_maps(maps);
+ nr_maps = __maps__nr_maps(maps);
if (nr_maps == 0) {
up_read(maps__lock(maps));
return 0;
@@ -728,7 +760,7 @@ void maps__remove_maps(struct maps *maps, bool (*cb)(struct map *map, void *data
down_write(maps__lock(maps));
maps_by_address = maps__maps_by_address(maps);
- for (unsigned int i = 0; i < maps__nr_maps(maps);) {
+ for (unsigned int i = 0; i < __maps__nr_maps(maps);) {
if (cb(maps_by_address[i], data)) {
__maps__remove_at(maps, i);
removed = true;
@@ -782,7 +814,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, st
* This prevents deadlocking if iteration triggers further map insertions.
*/
down_read(maps__lock(maps));
- nr_maps = maps__nr_maps(maps);
+ nr_maps = __maps__nr_maps(maps);
maps_copy = calloc(nr_maps, sizeof(*maps_copy));
if (maps_copy) {
for (unsigned int i = 0; i < nr_maps; i++) {
@@ -867,9 +899,10 @@ size_t maps__fprintf(struct maps *maps, FILE *fp)
* Same as find_vma() in kernel.
*/
static unsigned int first_ending_after(struct maps *maps, const struct map *map)
+ __must_hold_shared(maps__lock(maps))
{
struct map **maps_by_address = maps__maps_by_address(maps);
- int low = 0, high = (int)maps__nr_maps(maps) - 1, first = high + 1;
+ int low = 0, high = (int)__maps__nr_maps(maps) - 1, first = high + 1;
assert(maps__maps_by_address_sorted(maps));
if (low <= high && map__end(maps_by_address[0]) > map__start(map))
@@ -894,10 +927,11 @@ static unsigned int first_ending_after(struct maps *maps, const struct map *map)
static int __maps__insert_sorted(struct maps *maps, unsigned int first_after_index,
struct map *new1, struct map *new2)
+ __must_hold(maps__lock(maps))
{
struct map **maps_by_address = maps__maps_by_address(maps);
struct map **maps_by_name = maps__maps_by_name(maps);
- unsigned int nr_maps = maps__nr_maps(maps);
+ unsigned int nr_maps = __maps__nr_maps(maps);
unsigned int nr_allocate = RC_CHK_ACCESS(maps)->nr_maps_allocated;
unsigned int to_add = new2 ? 2 : 1;
@@ -954,6 +988,7 @@ static int __maps__insert_sorted(struct maps *maps, unsigned int first_after_ind
* adjusted or removed so that new fits without overlapping any entries.
*/
static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)
+ __must_hold(maps__lock(maps))
{
int err = 0;
unsigned int i, ni = INT_MAX; // Some gcc complain, but depends on maps_by_name...
@@ -965,7 +1000,7 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)
* Iterate through entries where the end of the existing entry is
* greater-than the new map's start.
*/
- for (i = first_ending_after(maps, new); i < maps__nr_maps(maps); ) {
+ for (i = first_ending_after(maps, new); i < __maps__nr_maps(maps); ) {
struct map **maps_by_address = maps__maps_by_address(maps);
struct map **maps_by_name = maps__maps_by_name(maps);
struct map *pos = maps_by_address[i];
@@ -1076,7 +1111,7 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)
return err;
} else {
struct map *next = NULL;
- unsigned int nr_maps = maps__nr_maps(maps);
+ unsigned int nr_maps = __maps__nr_maps(maps);
if (i + 1 < nr_maps)
next = maps_by_address[i + 1];
@@ -1160,8 +1195,8 @@ int maps__copy_from(struct maps *dest, struct maps *parent)
}
#endif
parent_maps_by_address = maps__maps_by_address(parent);
- n = maps__nr_maps(parent);
- if (maps__nr_maps(dest) == 0) {
+ n = __maps__nr_maps(parent);
+ if (__maps__nr_maps(dest) == 0) {
/* No existing mappings so just copy from parent to avoid reallocs in insert. */
unsigned int nr_maps_allocated = RC_CHK_ACCESS(parent)->nr_maps_allocated;
struct map **dest_maps_by_address =
@@ -1245,7 +1280,7 @@ struct map *maps__find(struct maps *maps, u64 ip)
if (maps__maps_by_address_sorted(maps)) {
struct map **mapp = NULL;
struct map **maps_by_address = maps__maps_by_address(maps);
- unsigned int nr_maps = maps__nr_maps(maps);
+ unsigned int nr_maps = __maps__nr_maps(maps);
if (maps_by_address && nr_maps)
mapp = bsearch(&ip, maps_by_address, nr_maps, sizeof(*mapp),
@@ -1281,7 +1316,7 @@ struct map *maps__find_by_name(struct maps *maps, const char *name)
/* First check last found entry. */
i = RC_CHK_ACCESS(maps)->last_search_by_name_idx;
- if (i < maps__nr_maps(maps) && maps__maps_by_name(maps)) {
+ if (i < __maps__nr_maps(maps) && maps__maps_by_name(maps)) {
struct dso *dso = map__dso(maps__maps_by_name(maps)[i]);
if (dso && strcmp(dso__short_name(dso), name) == 0) {
@@ -1293,7 +1328,7 @@ struct map *maps__find_by_name(struct maps *maps, const char *name)
/* Second search sorted array. */
if (!done && maps__maps_by_name_sorted(maps)) {
struct map **mapp =
- bsearch(name, maps__maps_by_name(maps), maps__nr_maps(maps),
+ bsearch(name, maps__maps_by_name(maps), __maps__nr_maps(maps),
sizeof(*mapp), map__strcmp_name);
if (mapp) {
@@ -1316,7 +1351,7 @@ struct map *maps__find_by_name(struct maps *maps, const char *name)
down_read(maps__lock(maps));
maps_by_address = maps__maps_by_address(maps);
- n = maps__nr_maps(maps);
+ n = __maps__nr_maps(maps);
for (i = 0; i < n; i++) {
struct map *pos = maps_by_address[i];
struct dso *dso = map__dso(pos);
@@ -1346,7 +1381,7 @@ struct map *maps__find_next_entry(struct maps *maps, struct map *map)
down_read(maps__lock(maps));
}
i = maps__by_address_index(maps, map);
- nr_maps = maps__nr_maps(maps);
+ nr_maps = __maps__nr_maps(maps);
if (i < nr_maps && ++i < nr_maps)
result = map__get(maps__maps_by_address(maps)[i]);
@@ -1365,7 +1400,7 @@ void maps__fixup_end(struct maps *maps)
__maps__sort_by_address(maps);
maps_by_address = maps__maps_by_address(maps);
- n = maps__nr_maps(maps);
+ n = __maps__nr_maps(maps);
for (unsigned int i = 1; i < n; i++) {
struct map *prev = maps_by_address[i - 1];
struct map *curr = maps_by_address[i];
@@ -1423,7 +1458,7 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map)
first_after_ = first_ending_after(kmaps, new_map);
kmaps_maps_by_address = maps__maps_by_address(kmaps);
- if (first_after_ >= maps__nr_maps(kmaps) ||
+ if (first_after_ >= __maps__nr_maps(kmaps) ||
map__start(kmaps_maps_by_address[first_after_]) >= map__end(new_map)) {
/* No overlap so regular insert suffices. */
up_read(maps__lock(kmaps));
@@ -1438,7 +1473,7 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map)
first_after_ = first_ending_after(kmaps, new_map);
kmaps_maps_by_address = maps__maps_by_address(kmaps);
- kmaps__nr_maps = maps__nr_maps(kmaps);
+ kmaps__nr_maps = __maps__nr_maps(kmaps);
if (first_after_ >= kmaps__nr_maps ||
map__start(kmaps_maps_by_address[first_after_]) >= map__end(new_map)) {
@@ -1492,7 +1527,7 @@ void maps__load_first(struct maps *maps)
struct map *first = NULL;
down_read(maps__lock(maps));
- if (maps__nr_maps(maps) > 0)
+ if (__maps__nr_maps(maps) > 0)
first = map__get(maps__maps_by_address(maps)[0]);
up_read(maps__lock(maps));
--
2.56.0.455.g6c5a503b38-goog
prev parent reply other threads:[~2026-11-06 7:04 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 7:03 [PATCH v10 00/20] tools/perf: Adopt kernel compiler-context-analysis.h annotations Ian Rogers
2026-11-06 7:03 ` [PATCH v10 01/20] compiler-context-analysis: Avoid unused parameter warning in _context_unsafe_alias() Ian Rogers
2026-11-06 7:03 ` [PATCH v10 02/20] tools headers compiler: Synchronize compiler_types.h with the kernel sources Ian Rogers
2026-11-06 7:03 ` [PATCH v10 03/20] tools headers: Synchronize linux/compiler-context-analysis.h " Ian Rogers
2026-11-06 7:03 ` [PATCH v10 04/20] perf mutex: Use kernel style compiler-context-analysis.h annotations Ian Rogers
2026-11-06 7:03 ` [PATCH v10 05/20] perf build: Enable additional Clang thread-safety flags Ian Rogers
2026-11-06 7:03 ` [PATCH v10 06/20] perf comm: Add __guarded_by annotations to struct comm_strs Ian Rogers
2026-11-06 7:03 ` [PATCH v10 07/20] perf vdso: Fix unlocked __dsos__add() and race in __machine__addnew_vdso() Ian Rogers
2026-11-06 7:03 ` [PATCH v10 08/20] perf dsos: Skip BPF and OOL DSOs in dsos__find_kernel_dso() Ian Rogers
2026-11-06 7:03 ` [PATCH v10 09/20] perf dsos: Ensure DSOs in auxtrace, machine, and symbol are in dsos Ian Rogers
2026-11-06 7:03 ` [PATCH v10 10/20] perf dso: Pass dso_data to close_data_fd() and dso__list_del() Ian Rogers
2026-11-06 7:03 ` [PATCH v10 11/20] perf dso: Use DEFINE_MUTEX for dso__data_open_lock Ian Rogers
2026-11-06 7:03 ` [PATCH v10 12/20] perf dsos: Use read lock fast path in dsos__findnew_id() Ian Rogers
2026-11-06 7:03 ` [PATCH v10 13/20] perf dso: Expand context analysis annotations Ian Rogers
2026-11-06 7:03 ` [PATCH v10 14/20] perf thread: Expand context analysis annotations to threads and namespaces_lock Ian Rogers
2026-11-06 7:03 ` [PATCH v10 15/20] perf intel-tpebs: Fix race in tpebs_stop() and tpebs_cmd.out fd handling Ian Rogers
2026-11-06 7:03 ` [PATCH v10 16/20] perf intel-tpebs: Use DEFINE_MUTEX for tpebs_mtx Ian Rogers
2026-11-06 7:03 ` [PATCH v10 17/20] perf config, intel-tpebs, env: Add __guarded_by and __must_hold annotations Ian Rogers
2026-11-06 7:03 ` [PATCH v10 18/20] perf maps: Fix lock inversion in maps__load_first() Ian Rogers
2026-11-06 7:03 ` [PATCH v10 19/20] perf maps: Fix map index lookup fallback and removal Ian Rogers
2026-11-06 7:03 ` Ian Rogers [this message]
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=20261106070344.329897-21-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=bvanassche@acm.org \
--cc=elver@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=justinstitt@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=mingo@redhat.com \
--cc=morbo@google.com \
--cc=namhyung@kernel.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.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®