public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>, Thomas Gleixner <tglx@linutronix.de>
Cc: Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
	Clark Williams <williams@redhat.com>,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	Adrian Hunter <adrian.hunter@intel.com>
Subject: [PATCH 27/91] perf evlist: Move the sideband thread routines to separate object
Date: Wed,  6 May 2020 12:21:30 -0300	[thread overview]
Message-ID: <20200506152234.21977-28-acme@kernel.org> (raw)
In-Reply-To: <20200506152234.21977-1-acme@kernel.org>

From: Arnaldo Carvalho de Melo <acme@redhat.com>

To avoid dragging more stuff into the perf python binding in the
following csets.

Reported-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/Build             |   1 +
 tools/perf/util/evlist.c          | 117 ----------------------------
 tools/perf/util/sideband_evlist.c | 125 ++++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+), 117 deletions(-)
 create mode 100644 tools/perf/util/sideband_evlist.c

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 229abefed59a..ca07a162d602 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -10,6 +10,7 @@ perf-y += db-export.o
 perf-y += env.o
 perf-y += event.o
 perf-y += evlist.o
+perf-y += sideband_evlist.o
 perf-y += evsel.o
 perf-y += evsel_fprintf.o
 perf-y += perf_event_attr_fprintf.o
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 6fe11f4d856a..6d902c02fd95 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1704,120 +1704,3 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list,
 	}
 	return leader;
 }
-
-int perf_evlist__add_sb_event(struct evlist *evlist,
-			      struct perf_event_attr *attr,
-			      perf_evsel__sb_cb_t cb,
-			      void *data)
-{
-	struct evsel *evsel;
-
-	if (!attr->sample_id_all) {
-		pr_warning("enabling sample_id_all for all side band events\n");
-		attr->sample_id_all = 1;
-	}
-
-	evsel = perf_evsel__new_idx(attr, evlist->core.nr_entries);
-	if (!evsel)
-		return -1;
-
-	evsel->side_band.cb = cb;
-	evsel->side_band.data = data;
-	evlist__add(evlist, evsel);
-	return 0;
-}
-
-static void *perf_evlist__poll_thread(void *arg)
-{
-	struct evlist *evlist = arg;
-	bool draining = false;
-	int i, done = 0;
-	/*
-	 * In order to read symbols from other namespaces perf to needs to call
-	 * setns(2).  This isn't permitted if the struct_fs has multiple users.
-	 * unshare(2) the fs so that we may continue to setns into namespaces
-	 * that we're observing when, for instance, reading the build-ids at
-	 * the end of a 'perf record' session.
-	 */
-	unshare(CLONE_FS);
-
-	while (!done) {
-		bool got_data = false;
-
-		if (evlist->thread.done)
-			draining = true;
-
-		if (!draining)
-			evlist__poll(evlist, 1000);
-
-		for (i = 0; i < evlist->core.nr_mmaps; i++) {
-			struct mmap *map = &evlist->mmap[i];
-			union perf_event *event;
-
-			if (perf_mmap__read_init(&map->core))
-				continue;
-			while ((event = perf_mmap__read_event(&map->core)) != NULL) {
-				struct evsel *evsel = perf_evlist__event2evsel(evlist, event);
-
-				if (evsel && evsel->side_band.cb)
-					evsel->side_band.cb(event, evsel->side_band.data);
-				else
-					pr_warning("cannot locate proper evsel for the side band event\n");
-
-				perf_mmap__consume(&map->core);
-				got_data = true;
-			}
-			perf_mmap__read_done(&map->core);
-		}
-
-		if (draining && !got_data)
-			break;
-	}
-	return NULL;
-}
-
-int perf_evlist__start_sb_thread(struct evlist *evlist,
-				 struct target *target)
-{
-	struct evsel *counter;
-
-	if (!evlist)
-		return 0;
-
-	if (perf_evlist__create_maps(evlist, target))
-		goto out_delete_evlist;
-
-	evlist__for_each_entry(evlist, counter) {
-		if (evsel__open(counter, evlist->core.cpus,
-				     evlist->core.threads) < 0)
-			goto out_delete_evlist;
-	}
-
-	if (evlist__mmap(evlist, UINT_MAX))
-		goto out_delete_evlist;
-
-	evlist__for_each_entry(evlist, counter) {
-		if (evsel__enable(counter))
-			goto out_delete_evlist;
-	}
-
-	evlist->thread.done = 0;
-	if (pthread_create(&evlist->thread.th, NULL, perf_evlist__poll_thread, evlist))
-		goto out_delete_evlist;
-
-	return 0;
-
-out_delete_evlist:
-	evlist__delete(evlist);
-	evlist = NULL;
-	return -1;
-}
-
-void perf_evlist__stop_sb_thread(struct evlist *evlist)
-{
-	if (!evlist)
-		return;
-	evlist->thread.done = 1;
-	pthread_join(evlist->thread.th, NULL);
-	evlist__delete(evlist);
-}
diff --git a/tools/perf/util/sideband_evlist.c b/tools/perf/util/sideband_evlist.c
new file mode 100644
index 000000000000..073d201bb6ea
--- /dev/null
+++ b/tools/perf/util/sideband_evlist.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "util/debug.h"
+#include "util/evlist.h"
+#include "util/evsel.h"
+#include "util/mmap.h"
+#include <perf/mmap.h>
+#include <linux/perf_event.h>
+#include <limits.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stdbool.h>
+
+int perf_evlist__add_sb_event(struct evlist *evlist, struct perf_event_attr *attr,
+			      perf_evsel__sb_cb_t cb, void *data)
+{
+	struct evsel *evsel;
+
+	if (!attr->sample_id_all) {
+		pr_warning("enabling sample_id_all for all side band events\n");
+		attr->sample_id_all = 1;
+	}
+
+	evsel = perf_evsel__new_idx(attr, evlist->core.nr_entries);
+	if (!evsel)
+		return -1;
+
+	evsel->side_band.cb = cb;
+	evsel->side_band.data = data;
+	evlist__add(evlist, evsel);
+	return 0;
+}
+
+static void *perf_evlist__poll_thread(void *arg)
+{
+	struct evlist *evlist = arg;
+	bool draining = false;
+	int i, done = 0;
+	/*
+	 * In order to read symbols from other namespaces perf to needs to call
+	 * setns(2).  This isn't permitted if the struct_fs has multiple users.
+	 * unshare(2) the fs so that we may continue to setns into namespaces
+	 * that we're observing when, for instance, reading the build-ids at
+	 * the end of a 'perf record' session.
+	 */
+	unshare(CLONE_FS);
+
+	while (!done) {
+		bool got_data = false;
+
+		if (evlist->thread.done)
+			draining = true;
+
+		if (!draining)
+			evlist__poll(evlist, 1000);
+
+		for (i = 0; i < evlist->core.nr_mmaps; i++) {
+			struct mmap *map = &evlist->mmap[i];
+			union perf_event *event;
+
+			if (perf_mmap__read_init(&map->core))
+				continue;
+			while ((event = perf_mmap__read_event(&map->core)) != NULL) {
+				struct evsel *evsel = perf_evlist__event2evsel(evlist, event);
+
+				if (evsel && evsel->side_band.cb)
+					evsel->side_band.cb(event, evsel->side_band.data);
+				else
+					pr_warning("cannot locate proper evsel for the side band event\n");
+
+				perf_mmap__consume(&map->core);
+				got_data = true;
+			}
+			perf_mmap__read_done(&map->core);
+		}
+
+		if (draining && !got_data)
+			break;
+	}
+	return NULL;
+}
+
+int perf_evlist__start_sb_thread(struct evlist *evlist, struct target *target)
+{
+	struct evsel *counter;
+
+	if (!evlist)
+		return 0;
+
+	if (perf_evlist__create_maps(evlist, target))
+		goto out_delete_evlist;
+
+	evlist__for_each_entry(evlist, counter) {
+		if (evsel__open(counter, evlist->core.cpus, evlist->core.threads) < 0)
+			goto out_delete_evlist;
+	}
+
+	if (evlist__mmap(evlist, UINT_MAX))
+		goto out_delete_evlist;
+
+	evlist__for_each_entry(evlist, counter) {
+		if (evsel__enable(counter))
+			goto out_delete_evlist;
+	}
+
+	evlist->thread.done = 0;
+	if (pthread_create(&evlist->thread.th, NULL, perf_evlist__poll_thread, evlist))
+		goto out_delete_evlist;
+
+	return 0;
+
+out_delete_evlist:
+	evlist__delete(evlist);
+	evlist = NULL;
+	return -1;
+}
+
+void perf_evlist__stop_sb_thread(struct evlist *evlist)
+{
+	if (!evlist)
+		return;
+	evlist->thread.done = 1;
+	pthread_join(evlist->thread.th, NULL);
+	evlist__delete(evlist);
+}
-- 
2.21.1


  parent reply	other threads:[~2020-05-06 15:24 UTC|newest]

Thread overview: 92+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-06 15:21 [GIT PULL] perf/core improvements and fixes Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 01/91] perf cgroup: Avoid needless closing of unopened fd Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 02/91] perf bench: Fix div-by-zero if runtime is zero Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 03/91] perf evlist: Remove duplicate headers Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 04/91] perf script: Avoid NULL dereference on symbol Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 05/91] perf stat: Zero all the 'ena' and 'run' array slot stats for interval mode Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 06/91] perf stat: Improve runtime stat " Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 07/91] perf test session topology: Fix data path Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 08/91] perf record: Add num-synthesize-threads option Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 09/91] perf bench: Add a multi-threaded synthesize benchmark Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 10/91] tools api: Add a lightweight buffered reading api Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 11/91] perf synthetic events: Remove use of sscanf from /proc reading Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 12/91] perf script: Remove extraneous newline in perf_sample__fprintf_regs() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 13/91] libtraceevent: Remove unneeded semicolon Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 14/91] perf c2c: " Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 15/91] perf tools: Remove unneeded semicolons Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 16/91] perf report: Fix warning assignment of 0/1 to bool variable Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 17/91] perf pmu: Fix function name in comment, its get_cpuid_str(), not get_cpustr() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 18/91] perf metricgroups: Enhance JSON/metric infrastructure to handle "?" Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 19/91] perf tests expr: Added test for runtime param in metric expression Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 20/91] perf tools: Enable Hz/hz prinitg for --metric-only option Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 21/91] perf vendor events power9: Add hv_24x7 socket/chip level metric events Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 22/91] perf tools: Move routines that probe for perf API features to separate file Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 23/91] perf record: Move sb_evlist to 'struct record' Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 24/91] perf top: Move sb_evlist to 'struct perf_top' Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 25/91] perf bpf: Decouple creating the evlist from adding the SB event Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 26/91] perf parse-events: Add parse_events_option() variant that creates evlist Arnaldo Carvalho de Melo
2020-05-06 15:21 ` Arnaldo Carvalho de Melo [this message]
2020-05-06 15:21 ` [PATCH 28/91] perf evlist: Allow reusing the side band thread for more purposes Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 29/91] libsubcmd: Introduce OPT_CALLBACK_SET() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 30/91] perf record: Introduce --switch-output-event Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 31/91] perf record: Move side band evlist setup to separate routine Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 32/91] libperf: Add NULL pointer check for cpu_map iteration and NULL assignment for all_cpus Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 33/91] perf parse-events: Fix memory leaks found on parse_events Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 34/91] " Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 35/91] perf parse-events: Fix another memory leaks found on parse_events() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 36/91] libperf evlist: Fix a refcount leak Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 37/91] perf tools: Fix reading new topology attribute "core_cpus" Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 38/91] perf tools: Simplify checking if SMT is active Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 39/91] perf thread-stack: Add branch stack support Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 40/91] perf intel-pt: Consolidate thread-stack use condition Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 41/91] perf intel-pt: Change branch stack support to use thread-stacks Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 42/91] perf auxtrace: Add option to synthesize branch stack for regular events Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 43/91] perf evsel: Add support for synthesized branch stack sample type Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 44/91] perf thread-stack: Add thread_stack__br_sample_late() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 45/91] perf intel-pt: Add support for synthesizing branch stacks for regular events Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 46/91] perf intel-pt: Update documentation about itrace G and L options Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 47/91] perf intel-pt: Update documentation about using /proc/kcore Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 48/91] perf evsel: Rename 'struct perf_evsel__sb_cb_t' to 'struct evsel__sb_cb_t' Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 49/91] perf evsel: Rename perf_evsel__nr_cpus() to evsel__nr_cpus() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 50/91] perf evsel: Rename perf_evsel__compute_deltas() to evsel__compute_deltas() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 51/91] perf evsel: Rename perf_evsel__find_pmu() to evsel__find_pmu() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 52/91] perf evsel: Rename perf_evsel__is_aux_event() to evsel__is_aux_event() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 53/91] perf evsel: Rename perf_evsel__exit() to evsel__exit() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 54/91] perf evsel: Rename perf_evsel__config*() to evsel__config*() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 55/91] perf evsel: Rename perf_evsel__calc_id_pos() to evsel__calc_id_pos() Arnaldo Carvalho de Melo
2020-05-06 15:21 ` [PATCH 56/91] perf evsel: Rename __perf_evsel__sample_size() to __evsel__sample_size() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 57/91] perf evsel: Rename *perf_evsel__*name() to *evsel__*name() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 58/91] perf evsel: Rename perf_evsel__group_desc() to evsel__group_desc() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 59/91] perf evsel: Rename *perf_evsel__*set_sample_*() to *evsel__*set_sample_*() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 60/91] perf evsel: Rename perf_evsel__*filter*() to evsel__*filter*() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 61/91] perf evsel: Rename perf_evsel__open_per_*() to evsel__open_per_*() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 62/91] perf evsel: Rename perf_evsel__{str,int}val() and other tracepoint field metehods to to evsel__*() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 63/91] perf mem2node: Avoid double free related to realloc Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 64/91] perf doc: Pass ASCIIDOC_EXTRA as an argument Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 65/91] tools feature: Add support for detecting libpfm4 Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 66/91] perf pmu: Add perf_pmu__find_by_type helper Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 67/91] perf evsel: Rename perf_evsel__is_*() to evsel__is*() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 68/91] perf evsel: Ditch perf_evsel__cmp(), not used for quite a while Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 69/91] perf evsel: Rename *perf_evsel__read*() to *evsel__read() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 70/91] perf evsel: Rename perf_evsel__parse_sample*() to evsel__parse_sample*() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 71/91] perf evsel: Rename perf_evsel__{prev,next}() to evsel__{prev,next}() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 72/91] perf evsel: Rename perf_evsel__has*() to evsel__has*() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 73/91] perf evsel: Rename perf_evsel__fallback() to evsel__fallback() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 74/91] perf evsel: Rename perf_evsel__group_idx() to evsel__group_idx() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 75/91] perf evsel: Rename perf_evsel__env() to evsel__env() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 76/91] perf evsel: Rename perf_evsel__store_ids() to evsel__store_id() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 77/91] perf stat: Rename perf_evsel__*() operating on 'struct evsel *' to evsel__*() Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 78/91] perf kmem: " Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 79/91] perf lock: " Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 80/91] perf sched: " Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 81/91] perf script: " Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 82/91] perf trace: " Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 83/91] perf annotate: " Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 84/91] perf inject: " Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 85/91] perf symbol: Fix kernel symbol address display Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 86/91] perf: cs-etm: Update to build with latest opencsd version Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 87/91] perf bench: Add kallsyms parsing Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 88/91] libsymbols kallsyms: Parse using io api Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 89/91] libsymbols kallsyms: Move hex2u64 out of header Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 90/91] perf cs-etm: Move definition of 'traceid_list' global variable from header file Arnaldo Carvalho de Melo
2020-05-06 15:22 ` [PATCH 91/91] perf flamegraph: Use /bin/bash for report and record scripts Arnaldo Carvalho de Melo

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=20200506152234.21977-28-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=williams@redhat.com \
    /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