Linux Perf Users
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	 Arnaldo Carvalho de Melo <acme@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
	 Adrian Hunter <adrian.hunter@intel.com>,
	James Clark <james.clark@linaro.org>,
	 linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v1 15/26] perf expr: Use generic hashmap for expr_ids
Date: Fri, 13 Nov 2026 13:48:39 -0800	[thread overview]
Message-ID: <20261113214850.3329699-16-irogers@google.com> (raw)
In-Reply-To: <20261113214850.3329699-1-irogers@google.com>

Convert expr_parse_ctx::ids and ids__* helpers across util/expr.{c,h,y},
util/metricgroup.c, tests/expr.c, and tests/pmu-events.c to
DECLARE_HASHMAP(expr_ids_map, const char *, struct expr_id_data *).

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/tests/expr.c       |  2 +-
 tools/perf/tests/pmu-events.c | 16 +++---
 tools/perf/util/expr.c        | 99 +++++++++++++++++------------------
 tools/perf/util/expr.h        | 18 ++++---
 tools/perf/util/expr.y        |  2 +-
 tools/perf/util/metricgroup.c | 28 +++++-----
 6 files changed, 83 insertions(+), 82 deletions(-)

diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c
index 726cf8d4da28..a2c7dc4d71c9 100644
--- a/tools/perf/tests/expr.c
+++ b/tools/perf/tests/expr.c
@@ -15,7 +15,7 @@
 
 static int test_ids_union(void)
 {
-	struct hashmap *ids1, *ids2;
+	struct expr_ids_map *ids1, *ids2;
 
 	/* Empty union. */
 	ids1 = ids__new();
diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c
index e6e4f4cf1fa2..42862501f0bf 100644
--- a/tools/perf/tests/pmu-events.c
+++ b/tools/perf/tests/pmu-events.c
@@ -964,10 +964,10 @@ static struct test_metric metrics[] = {
 static int metric_parse_fake(const char *metric_name, const char *str)
 {
 	struct expr_parse_ctx *ctx;
-	struct hashmap_entry *cur;
+	const char *key;
+	struct expr_id_data *val;
 	double result;
 	int ret = -1;
-	size_t bkt;
 	int i;
 
 	pr_debug("parsing '%s': '%s'\n", metric_name, str);
@@ -989,11 +989,11 @@ static int metric_parse_fake(const char *metric_name, const char *str)
 	 * make them unique.
 	 */
 	i = 1;
-	hashmap__for_each_entry(ctx->ids, cur, bkt)
-		expr__add_id_val(ctx, strdup(cur->pkey), i++);
+	hashmap__for_each(ctx->ids, key, val)
+		expr__add_id_val(ctx, strdup(key), i++);
 
-	hashmap__for_each_entry(ctx->ids, cur, bkt) {
-		if (check_parse_fake(cur->pkey)) {
+	hashmap__for_each(ctx->ids, key, val) {
+		if (check_parse_fake(key)) {
 			pr_err("check_parse_fake failed\n");
 			goto out;
 		}
@@ -1006,8 +1006,8 @@ static int metric_parse_fake(const char *metric_name, const char *str)
 		 * resolve divide by zero issues.
 		 */
 		i = 1024;
-		hashmap__for_each_entry(ctx->ids, cur, bkt)
-			expr__add_id_val(ctx, strdup(cur->pkey), i--);
+		hashmap__for_each(ctx->ids, key, val)
+			expr__add_id_val(ctx, strdup(key), i--);
 		if (expr__parse(&result, ctx, str)) {
 			pr_err("expr__parse failed for %s\n", metric_name);
 			/* The following have hard to avoid divide by zero. */
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index ac0243576def..d548ae5a4ec9 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -64,48 +64,46 @@ static bool key_equal(long key1, long key2, void *ctx __maybe_unused)
 	return !strcmp((const char *)key1, (const char *)key2);
 }
 
-struct hashmap *ids__new(void)
+struct expr_ids_map *ids__new(void)
 {
-	return hashmap__new(key_hash, key_equal, NULL);
+	return expr_ids_map__new(key_hash, key_equal, NULL);
 }
 
-void ids__free(struct hashmap *ids)
+void ids__free(struct expr_ids_map *ids)
 {
-	struct hashmap_entry *cur;
-	size_t bkt;
+	const char *key;
+	struct expr_id_data *val;
 
 	if (ids == NULL)
 		return;
 
-	hashmap__for_each_entry(ids, cur, bkt) {
-		zfree(&cur->pkey);
-		zfree(&cur->pvalue);
+	hashmap__for_each(ids, key, val) {
+		free((char *)key);
+		free(val);
 	}
 
-	hashmap__free(ids);
+	expr_ids_map__free(ids);
 }
 
-int ids__insert(struct hashmap *ids, const char *id)
+int ids__insert(struct expr_ids_map *ids, const char *id)
 {
 	struct expr_id_data *data_ptr = NULL, *old_data = NULL;
-	char *old_key = NULL;
+	const char *old_key = NULL;
 	int ret;
 
 	ret = hashmap__set(ids, id, data_ptr, &old_key, &old_data);
 	if (ret)
 		free(data_ptr);
-	free(old_key);
+	free((char *)old_key);
 	free(old_data);
 	return ret;
 }
 
-struct hashmap *ids__union(struct hashmap *ids1, struct hashmap *ids2)
+struct expr_ids_map *ids__union(struct expr_ids_map *ids1, struct expr_ids_map *ids2)
 {
-	size_t bkt;
-	struct hashmap_entry *cur;
+	const char *key, *old_key = NULL;
+	struct expr_id_data *val, *old_data = NULL;
 	int ret;
-	struct expr_id_data *old_data = NULL;
-	char *old_key = NULL;
 
 	if (!ids1)
 		return ids2;
@@ -113,24 +111,24 @@ struct hashmap *ids__union(struct hashmap *ids1, struct hashmap *ids2)
 	if (!ids2)
 		return ids1;
 
-	if (hashmap__size(ids1) <  hashmap__size(ids2)) {
-		struct hashmap *tmp = ids1;
+	if (hashmap__size(ids1) < hashmap__size(ids2)) {
+		struct expr_ids_map *tmp = ids1;
 
 		ids1 = ids2;
 		ids2 = tmp;
 	}
-	hashmap__for_each_entry(ids2, cur, bkt) {
-		ret = hashmap__set(ids1, cur->key, cur->value, &old_key, &old_data);
-		free(old_key);
+	hashmap__for_each(ids2, key, val) {
+		ret = hashmap__set(ids1, key, val, &old_key, &old_data);
+		free((char *)old_key);
 		free(old_data);
 
 		if (ret) {
-			hashmap__free(ids1);
-			hashmap__free(ids2);
+			expr_ids_map__free(ids1);
+			expr_ids_map__free(ids2);
 			return NULL;
 		}
 	}
-	hashmap__free(ids2);
+	expr_ids_map__free(ids2);
 	return ids1;
 }
 
@@ -151,7 +149,7 @@ int expr__add_id_val_source_count_aggr_nr(struct expr_parse_ctx *ctx, const char
 					  double val, int source_count, int aggr_nr)
 {
 	struct expr_id_data *data_ptr = NULL, *old_data = NULL;
-	char *old_key = NULL;
+	const char *old_key = NULL;
 	int ret;
 
 	data_ptr = malloc(sizeof(*data_ptr));
@@ -170,7 +168,7 @@ int expr__add_id_val_source_count_aggr_nr(struct expr_parse_ctx *ctx, const char
 		data_ptr->val.source_count += old_data->val.source_count;
 		data_ptr->val.aggr_nr += old_data->val.aggr_nr;
 	}
-	free(old_key);
+	free((char *)old_key);
 	free(old_data);
 	return ret;
 }
@@ -185,7 +183,7 @@ int expr__add_id_val_source_count(struct expr_parse_ctx *ctx, const char *id,
 int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref)
 {
 	struct expr_id_data *data_ptr = NULL, *old_data = NULL;
-	char *old_key = NULL;
+	const char *old_key = NULL;
 	char *name;
 	int ret;
 
@@ -210,13 +208,15 @@ int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref)
 	data_ptr->kind = EXPR_ID_DATA__REF;
 
 	ret = hashmap__set(ctx->ids, name, data_ptr, &old_key, &old_data);
-	if (ret)
+	if (ret) {
 		free(data_ptr);
+		free(name);
+	}
 
 	pr_debug2("adding ref metric %s: %s\n",
 		  ref->metric_name, ref->metric_expr);
 
-	free(old_key);
+	free((char *)old_key);
 	free(old_data);
 	return ret;
 }
@@ -232,12 +232,11 @@ int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
 bool expr__subset_of_ids(struct expr_parse_ctx *haystack,
 			 struct expr_parse_ctx *needles)
 {
-	struct hashmap_entry *cur;
-	size_t bkt;
-	struct expr_id_data *data;
+	const char *key;
+	struct expr_id_data *val, *data;
 
-	hashmap__for_each_entry(needles->ids, cur, bkt) {
-		if (expr__get_id(haystack, cur->pkey, &data))
+	hashmap__for_each(needles->ids, key, val) {
+		if (expr__get_id(haystack, key, &data))
 			return false;
 	}
 	return true;
@@ -285,10 +284,10 @@ int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
 void expr__del_id(struct expr_parse_ctx *ctx, const char *id)
 {
 	struct expr_id_data *old_val = NULL;
-	char *old_key = NULL;
+	const char *old_key = NULL;
 
 	hashmap__delete(ctx->ids, id, &old_key, &old_val);
-	free(old_key);
+	free((char *)old_key);
 	free(old_val);
 }
 
@@ -300,7 +299,7 @@ struct expr_parse_ctx *expr__ctx_new(void)
 	if (!ctx)
 		return NULL;
 
-	ctx->ids = hashmap__new(key_hash, key_equal, NULL);
+	ctx->ids = expr_ids_map__new(key_hash, key_equal, NULL);
 	if (!ctx->ids) {
 		free(ctx);
 		return NULL;
@@ -311,30 +310,30 @@ struct expr_parse_ctx *expr__ctx_new(void)
 
 void expr__ctx_clear(struct expr_parse_ctx *ctx)
 {
-	struct hashmap_entry *cur;
-	size_t bkt;
+	const char *key;
+	struct expr_id_data *val;
 
-	hashmap__for_each_entry(ctx->ids, cur, bkt) {
-		zfree(&cur->pkey);
-		zfree(&cur->pvalue);
+	hashmap__for_each(ctx->ids, key, val) {
+		free((char *)key);
+		free(val);
 	}
 	hashmap__clear(ctx->ids);
 }
 
 void expr__ctx_free(struct expr_parse_ctx *ctx)
 {
-	struct hashmap_entry *cur;
-	size_t bkt;
+	const char *key;
+	struct expr_id_data *val;
 
 	if (!ctx)
 		return;
 
 	zfree(&ctx->sctx.user_requested_cpu_list);
-	hashmap__for_each_entry(ctx->ids, cur, bkt) {
-		zfree(&cur->pkey);
-		zfree(&cur->pvalue);
+	hashmap__for_each(ctx->ids, key, val) {
+		free((char *)key);
+		free(val);
 	}
-	hashmap__free(ctx->ids);
+	expr_ids_map__free(ctx->ids);
 	free(ctx);
 }
 
@@ -438,7 +437,7 @@ double expr__has_event(const struct expr_parse_ctx *ctx, bool compute_ids, const
 	struct evlist *tmp;
 	double ret;
 
-	if (hashmap__find(ctx->ids, id, /*value=*/NULL))
+	if (hashmap__find(ctx->ids, id, /*value_ptr=*/NULL))
 		return 1.0;
 
 	if (!compute_ids)
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index ed12e4007d2d..57edcb3f70ea 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -2,9 +2,13 @@
 #ifndef PARSE_CTX_H
 #define PARSE_CTX_H 1
 
-struct hashmap;
+#include "hashmap.h"
+
+struct expr_id_data;
 struct metric_ref;
 
+DECLARE_HASHMAP(expr_ids_map, const char *, struct expr_id_data *);
+
 struct expr_scanner_ctx {
 	char *user_requested_cpu_list;
 	int runtime;
@@ -13,20 +17,18 @@ struct expr_scanner_ctx {
 };
 
 struct expr_parse_ctx {
-	struct hashmap	*ids;
+	struct expr_ids_map	*ids;
 	struct expr_scanner_ctx sctx;
 };
 
-struct expr_id_data;
-
-struct hashmap *ids__new(void);
-void ids__free(struct hashmap *ids);
-int ids__insert(struct hashmap *ids, const char *id);
+struct expr_ids_map *ids__new(void);
+void ids__free(struct expr_ids_map *ids);
+int ids__insert(struct expr_ids_map *ids, const char *id);
 /*
  * Union two sets of ids (hashmaps) and construct a third, freeing ids1 and
  * ids2.
  */
-struct hashmap *ids__union(struct hashmap *ids1, struct hashmap *ids2);
+struct expr_ids_map *ids__union(struct expr_ids_map *ids1, struct expr_ids_map *ids2);
 
 struct expr_parse_ctx *expr__ctx_new(void);
 void expr__ctx_clear(struct expr_parse_ctx *ctx);
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index e20f649354cf..d39ba27d75bc 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -29,7 +29,7 @@ int expr_lex(YYSTYPE * yylval_param , void *yyscanner);
 		 * When creating ids, holds the working set of event ids. NULL
 		 * implies the set is empty.
 		 */
-		struct hashmap *ids;
+		struct expr_ids_map *ids;
 		/*
 		 * The metric value. When not creating ids this is the value
 		 * read from a counter, a constant or some computed value. When
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
index 779fe56fe8d0..41887fad4968 100644
--- a/tools/perf/util/metricgroup.c
+++ b/tools/perf/util/metricgroup.c
@@ -289,7 +289,7 @@ static bool contains_metric_id(struct evsel **metric_events, int num_events,
  * @metric_evlist: the list of perf events.
  * @out_metric_events: holds the created metric events array.
  */
-static int setup_metric_events(const char *pmu, struct hashmap *ids,
+static int setup_metric_events(const char *pmu, struct expr_ids_map *ids,
 			       struct evlist *metric_evlist,
 			       struct evsel ***out_metric_events)
 {
@@ -563,16 +563,16 @@ static int metricgroup__build_event_string(struct strbuf *events,
 					   const char *modifier,
 					   bool group_events)
 {
-	struct hashmap_entry *cur;
-	size_t bkt;
+	const char *id;
+	struct expr_id_data *val;
 	bool no_group = true, has_tool_events = false;
 	bool tool_events[TOOL_PMU__EVENT_MAX] = {false};
 	int ret = 0;
 
 #define RETURN_IF_NON_ZERO(x) do { if (x) return x; } while (0)
 
-	hashmap__for_each_entry(ctx->ids, cur, bkt) {
-		const char *sep, *rsep, *id = cur->pkey;
+	hashmap__for_each(ctx->ids, id, val) {
+		const char *sep, *rsep;
 		enum tool_pmu_event ev;
 
 		pr_debug("found event %s\n", id);
@@ -748,8 +748,8 @@ static int resolve_metric(struct list_head *metric_list,
 			  const struct visited_metric *visited,
 			  const struct pmu_metrics_table *table)
 {
-	struct hashmap_entry *cur;
-	size_t bkt;
+	const char *key;
+	struct expr_id_data *val;
 	struct to_resolve {
 		/* The metric to resolve. */
 		struct pmu_metric pm;
@@ -765,10 +765,10 @@ static int resolve_metric(struct list_head *metric_list,
 	 * Iterate all the parsed IDs and if there's a matching metric and it to
 	 * the pending array.
 	 */
-	hashmap__for_each_entry(root_metric->pctx->ids, cur, bkt) {
+	hashmap__for_each(root_metric->pctx->ids, key, val) {
 		struct pmu_metric pm;
 
-		if (pmu_metrics_table__find_metric(table, pmu, cur->pkey,
+		if (pmu_metrics_table__find_metric(table, pmu, key,
 						   metricgroup__find_metric_callback,
 						   &pm) != PMU_METRICS__NOT_FOUND) {
 			pending = realloc(pending,
@@ -777,7 +777,7 @@ static int resolve_metric(struct list_head *metric_list,
 				return -ENOMEM;
 
 			memcpy(&pending[pending_cnt].pm, &pm, sizeof(pm));
-			pending[pending_cnt].key = cur->pkey;
+			pending[pending_cnt].key = key;
 			pending_cnt++;
 		}
 	}
@@ -1229,8 +1229,8 @@ static void find_tool_events(const struct list_head *metric_list,
 static int build_combined_expr_ctx(const struct list_head *metric_list,
 				   struct expr_parse_ctx **combined)
 {
-	struct hashmap_entry *cur;
-	size_t bkt;
+	const char *key;
+	struct expr_id_data *val;
 	struct metric *m;
 	char *dup;
 	int ret;
@@ -1241,8 +1241,8 @@ static int build_combined_expr_ctx(const struct list_head *metric_list,
 
 	list_for_each_entry(m, metric_list, nd) {
 		if (!m->group_events && !m->modifier) {
-			hashmap__for_each_entry(m->pctx->ids, cur, bkt) {
-				dup = strdup(cur->pkey);
+			hashmap__for_each(m->pctx->ids, key, val) {
+				dup = strdup(key);
 				if (!dup) {
 					ret = -ENOMEM;
 					goto err_out;
-- 
2.56.1.703.gf848ed807c-goog


  parent reply	other threads:[~2026-11-13 21:49 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-13 21:48 [PATCH v1 00/26] perf hashmap: Fix undefined behavior, remove ERR_PTR, and add type-safe generic hashmaps Ian Rogers
2026-11-13 21:48 ` [PATCH v1 01/26] perf threads: Fix uninitialized pointer put when thread removal misses Ian Rogers
2026-11-13 21:56   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 02/26] perf annotate: Fix sym_hist_entry memory leak when zeroing histograms Ian Rogers
2026-11-13 21:59   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 03/26] perf stat: Fix per_pkg_mask key leak on hashmap__add failure Ian Rogers
2026-11-13 21:55   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 04/26] perf build: Don't check difference of perf and libbpf hashmap Ian Rogers
2026-11-13 21:54   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 05/26] perf hashmap: Always build perf's hashmap and avoid libbpf symbol conflict Ian Rogers
2026-11-13 21:55   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 06/26] perf hashmap: Fix strict aliasing violations in hashmap Ian Rogers
2026-11-13 21:56   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 07/26] perf hashmap: Remove errptr usage from hashmap Ian Rogers
2026-11-13 22:01   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 08/26] perf hashmap: Introduce generic types and macros Ian Rogers
2026-11-13 22:01   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 09/26] perf fncache: Use generic hashmap for fncache Ian Rogers
2026-11-13 21:56   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 10/26] perf ftrace: Use generic hashmap for profile_hash Ian Rogers
2026-11-13 21:57   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 11/26] perf trace: Use generic hashmap for syscall_stats Ian Rogers
2026-11-13 22:04   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 12/26] perf trace: Use generic hashmap for bpf-trace-summary Ian Rogers
2026-11-13 21:58   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 13/26] perf lock: Use generic hashmap for slab_hash Ian Rogers
2026-11-13 21:57   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 14/26] perf stat: Use generic hashmap for per_pkg_mask Ian Rogers
2026-11-13 21:57   ` sashiko-bot
2026-11-13 21:48 ` Ian Rogers [this message]
2026-11-13 22:02   ` [PATCH v1 15/26] perf expr: Use generic hashmap for expr_ids sashiko-bot
2026-11-13 21:48 ` [PATCH v1 16/26] perf pmu: Use generic hashmap for pmu aliases Ian Rogers
2026-11-13 22:04   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 17/26] perf hwmon_pmu: Use generic hashmap for hwmon events Ian Rogers
2026-11-13 21:58   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 18/26] perf s390: Use generic hashmap for counter name cache Ian Rogers
2026-11-13 21:59   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 19/26] perf threads: Use generic hashmap for thread shards Ian Rogers
2026-11-13 22:01   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 20/26] perf annotate: Use generic hashmap for sym_samples Ian Rogers
2026-11-13 22:08   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 21/26] perf annotate: Use generic hashmap for browser type_hash Ian Rogers
2026-11-13 21:59   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 22/26] perf annotate-data: Use generic hashmap for type_hist samples Ian Rogers
2026-11-13 22:00   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 23/26] perf inject: Use generic hashmap for aslr remap_addresses Ian Rogers
2026-11-13 21:59   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 24/26] perf inject: Use generic hashmap for aslr top_addresses Ian Rogers
2026-11-13 21:59   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 25/26] perf inject: Use generic hashmap for aslr evsel_orig_attrs Ian Rogers
2026-11-13 22:00   ` sashiko-bot
2026-11-13 21:48 ` [PATCH v1 26/26] perf hashmap: Remove untyped struct hashmap API Ian Rogers
2026-11-13 22:01   ` sashiko-bot

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=20261113214850.3329699-16-irogers@google.com \
    --to=irogers@google.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.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=namhyung@kernel.org \
    --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