From: Arnaldo Carvalho de Melo <acme@infradead.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org,
Arnaldo Carvalho de Melo <acme@redhat.com>,
David Ahern <dsahern@gmail.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Jiri Olsa <jolsa@redhat.com>, Mike Galbraith <efault@gmx.de>,
Namhyung Kim <namhyung@gmail.com>,
Paul Mackerras <paulus@samba.org>,
Peter Zijlstra <peterz@infradead.org>,
Stephane Eranian <eranian@google.com>
Subject: [PATCH 17/18] perf sched: Use perf_evsel__{int,str}val
Date: Tue, 11 Sep 2012 20:53:09 -0300 [thread overview]
Message-ID: <1347407590-30960-18-git-send-email-acme@infradead.org> (raw)
In-Reply-To: <1347407590-30960-1-git-send-email-acme@infradead.org>
From: Arnaldo Carvalho de Melo <acme@redhat.com>
This patch also stops reading the common fields, as they were not being used except
for one ->common_pid case that was replaced by sample->tid, i.e. the info is already
in the perf_sample struct.
Also it only fills the _event structures when there is a handler.
[root@sandy ~]# perf sched record sleep 30s
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 8.585 MB perf.data (~375063 samples) ]
Before:
[root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
Performance counter stats for 'perf sched lat' (10 runs):
129.117838 task-clock # 0.994 CPUs utilized ( +- 0.28% )
14 context-switches # 0.111 K/sec ( +- 2.10% )
0 cpu-migrations # 0.002 K/sec ( +- 66.67% )
7,654 page-faults # 0.059 M/sec ( +- 0.67% )
438,121,661 cycles # 3.393 GHz ( +- 0.06% ) [83.06%]
150,808,605 stalled-cycles-frontend # 34.42% frontend cycles idle ( +- 0.14% ) [83.10%]
80,748,941 stalled-cycles-backend # 18.43% backend cycles idle ( +- 0.64% ) [66.73%]
758,605,879 instructions # 1.73 insns per cycle
# 0.20 stalled cycles per insn ( +- 0.08% ) [83.54%]
162,164,321 branches # 1255.940 M/sec ( +- 0.10% ) [83.70%]
1,609,903 branch-misses # 0.99% of all branches ( +- 0.08% ) [83.62%]
0.129949153 seconds time elapsed ( +- 0.28% )
After:
[root@sandy ~]# perf stat -r 10 perf sched lat > /dev/null
Performance counter stats for 'perf sched lat' (10 runs):
103.592215 task-clock # 0.993 CPUs utilized ( +- 0.33% )
12 context-switches # 0.114 K/sec ( +- 3.29% )
0 cpu-migrations # 0.000 K/sec
7,605 page-faults # 0.073 M/sec ( +- 0.00% )
345,796,112 cycles # 3.338 GHz ( +- 0.07% ) [82.90%]
106,876,796 stalled-cycles-frontend # 30.91% frontend cycles idle ( +- 0.38% ) [83.23%]
62,060,877 stalled-cycles-backend # 17.95% backend cycles idle ( +- 0.80% ) [67.14%]
628,246,586 instructions # 1.82 insns per cycle
# 0.17 stalled cycles per insn ( +- 0.04% ) [83.64%]
134,962,057 branches # 1302.820 M/sec ( +- 0.10% ) [83.64%]
1,233,037 branch-misses # 0.91% of all branches ( +- 0.29% ) [83.41%]
0.104333272 seconds time elapsed ( +- 0.33% )
[root@sandy ~]#
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-weu9t63zkrfrazkn0gxj48xy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/builtin-sched.c | 249 ++++++++++++++++----------------------------
1 file changed, 90 insertions(+), 159 deletions(-)
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 79f88fa..0df5e7a 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -98,82 +98,40 @@ struct work_atoms {
typedef int (*sort_fn_t)(struct work_atoms *, struct work_atoms *);
struct trace_switch_event {
- u32 size;
-
- u16 common_type;
- u8 common_flags;
- u8 common_preempt_count;
- u32 common_pid;
- u32 common_tgid;
-
- char prev_comm[16];
+ char *prev_comm;
u32 prev_pid;
u32 prev_prio;
u64 prev_state;
- char next_comm[16];
+ char *next_comm;
u32 next_pid;
u32 next_prio;
};
struct trace_runtime_event {
- u32 size;
-
- u16 common_type;
- u8 common_flags;
- u8 common_preempt_count;
- u32 common_pid;
- u32 common_tgid;
-
- char comm[16];
+ char *comm;
u32 pid;
u64 runtime;
u64 vruntime;
};
struct trace_wakeup_event {
- u32 size;
-
- u16 common_type;
- u8 common_flags;
- u8 common_preempt_count;
- u32 common_pid;
- u32 common_tgid;
-
- char comm[16];
+ char *comm;
u32 pid;
-
u32 prio;
u32 success;
u32 cpu;
};
struct trace_fork_event {
- u32 size;
-
- u16 common_type;
- u8 common_flags;
- u8 common_preempt_count;
- u32 common_pid;
- u32 common_tgid;
-
- char parent_comm[16];
+ char *parent_comm;
u32 parent_pid;
- char child_comm[16];
+ char *child_comm;
u32 child_pid;
};
struct trace_migrate_task_event {
- u32 size;
-
- u16 common_type;
- u8 common_flags;
- u8 common_preempt_count;
- u32 common_pid;
- u32 common_tgid;
-
- char comm[16];
+ char *comm;
u32 pid;
-
u32 prio;
u32 cpu;
};
@@ -184,7 +142,7 @@ struct trace_sched_handler {
int (*switch_event)(struct perf_sched *sched,
struct trace_switch_event *event,
struct machine *machine,
- struct event_format *tp_format,
+ struct perf_evsel *evsel,
struct perf_sample *sample);
int (*runtime_event)(struct perf_sched *sched,
@@ -195,12 +153,12 @@ struct trace_sched_handler {
int (*wakeup_event)(struct perf_sched *sched,
struct trace_wakeup_event *event,
struct machine *machine,
- struct event_format *tp_format,
+ struct perf_evsel *evsel,
struct perf_sample *sample);
int (*fork_event)(struct perf_sched *sched,
struct trace_fork_event *event,
- struct event_format *tp_format);
+ struct perf_evsel *evsel);
int (*migrate_task_event)(struct perf_sched *sched,
struct trace_migrate_task_event *event,
@@ -740,40 +698,22 @@ static void test_calibrations(struct perf_sched *sched)
printf("the sleep test took %" PRIu64 " nsecs\n", T1 - T0);
}
-#define FILL_FIELD(ptr, field, event, data) \
- ptr.field = (typeof(ptr.field)) raw_field_value(event, #field, data)
-
-#define FILL_ARRAY(ptr, array, event, data) \
-do { \
- void *__array = raw_field_ptr(event, #array, data); \
- memcpy(ptr.array, __array, sizeof(ptr.array)); \
-} while(0)
-
-#define FILL_COMMON_FIELDS(ptr, event, data) \
-do { \
- FILL_FIELD(ptr, common_type, event, data); \
- FILL_FIELD(ptr, common_flags, event, data); \
- FILL_FIELD(ptr, common_preempt_count, event, data); \
- FILL_FIELD(ptr, common_pid, event, data); \
- FILL_FIELD(ptr, common_tgid, event, data); \
-} while (0)
-
static int
replay_wakeup_event(struct perf_sched *sched,
struct trace_wakeup_event *wakeup_event,
struct machine *machine __maybe_unused,
- struct event_format *event, struct perf_sample *sample)
+ struct perf_evsel *evsel, struct perf_sample *sample)
{
struct task_desc *waker, *wakee;
if (verbose) {
- printf("sched_wakeup event %p\n", event);
+ printf("sched_wakeup event %p\n", evsel);
printf(" ... pid %d woke up %s/%d\n",
- wakeup_event->common_pid, wakeup_event->comm, wakeup_event->pid);
+ sample->tid, wakeup_event->comm, wakeup_event->pid);
}
- waker = register_pid(sched, wakeup_event->common_pid, "<unknown>");
+ waker = register_pid(sched, sample->tid, "<unknown>");
wakee = register_pid(sched, wakeup_event->pid, wakeup_event->comm);
add_sched_event_wakeup(sched, waker, sample->time, wakee);
@@ -784,7 +724,7 @@ static int
replay_switch_event(struct perf_sched *sched,
struct trace_switch_event *switch_event,
struct machine *machine __maybe_unused,
- struct event_format *event,
+ struct perf_evsel *evsel,
struct perf_sample *sample)
{
struct task_desc *prev, __maybe_unused *next;
@@ -793,7 +733,7 @@ replay_switch_event(struct perf_sched *sched,
s64 delta;
if (verbose)
- printf("sched_switch event %p\n", event);
+ printf("sched_switch event %p\n", evsel);
if (cpu >= MAX_CPUS || cpu < 0)
return 0;
@@ -829,10 +769,10 @@ replay_switch_event(struct perf_sched *sched,
static int
replay_fork_event(struct perf_sched *sched, struct trace_fork_event *fork_event,
- struct event_format *event)
+ struct perf_evsel *evsel)
{
if (verbose) {
- printf("sched_fork event %p\n", event);
+ printf("sched_fork event %p\n", evsel);
printf("... parent: %s/%d\n", fork_event->parent_comm, fork_event->parent_pid);
printf("... child: %s/%d\n", fork_event->child_comm, fork_event->child_pid);
}
@@ -931,7 +871,7 @@ static int thread_atoms_insert(struct perf_sched *sched, struct thread *thread)
static int latency_fork_event(struct perf_sched *sched __maybe_unused,
struct trace_fork_event *fork_event __maybe_unused,
- struct event_format *event __maybe_unused)
+ struct perf_evsel *evsel __maybe_unused)
{
/* should insert the newcomer */
return 0;
@@ -1015,7 +955,7 @@ static int
latency_switch_event(struct perf_sched *sched,
struct trace_switch_event *switch_event,
struct machine *machine,
- struct event_format *event __maybe_unused,
+ struct perf_evsel *evsel __maybe_unused,
struct perf_sample *sample)
{
struct work_atoms *out_events, *in_events;
@@ -1106,7 +1046,7 @@ static int
latency_wakeup_event(struct perf_sched *sched,
struct trace_wakeup_event *wakeup_event,
struct machine *machine,
- struct event_format *event __maybe_unused,
+ struct perf_evsel *evsel __maybe_unused,
struct perf_sample *sample)
{
struct work_atoms *atoms;
@@ -1350,34 +1290,32 @@ static void perf_sched__sort_lat(struct perf_sched *sched)
}
static int process_sched_wakeup_event(struct perf_tool *tool,
- struct event_format *event,
+ struct perf_evsel *evsel,
struct perf_sample *sample,
struct machine *machine)
{
struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
- void *data = sample->raw_data;
- struct trace_wakeup_event wakeup_event;
- int err = 0;
-
- FILL_COMMON_FIELDS(wakeup_event, event, data);
- FILL_ARRAY(wakeup_event, comm, event, data);
- FILL_FIELD(wakeup_event, pid, event, data);
- FILL_FIELD(wakeup_event, prio, event, data);
- FILL_FIELD(wakeup_event, success, event, data);
- FILL_FIELD(wakeup_event, cpu, event, data);
+ if (sched->tp_handler->wakeup_event) {
+ struct trace_wakeup_event event = {
+ .comm = perf_evsel__strval(evsel, sample, "comm"),
+ .pid = perf_evsel__intval(evsel, sample, "pid"),
+ .prio = perf_evsel__intval(evsel, sample, "prio"),
+ .success = perf_evsel__intval(evsel, sample, "success"),
+ .cpu = perf_evsel__intval(evsel, sample, "cpu"),
+ };
- if (sched->tp_handler->wakeup_event)
- err = sched->tp_handler->wakeup_event(sched, &wakeup_event, machine, event, sample);
+ return sched->tp_handler->wakeup_event(sched, &event, machine, evsel, sample);
+ }
- return err;
+ return 0;
}
static int
map_switch_event(struct perf_sched *sched,
struct trace_switch_event *switch_event,
struct machine *machine,
- struct event_format *event __maybe_unused,
+ struct perf_evsel *evsel __maybe_unused,
struct perf_sample *sample)
{
struct thread *sched_out __maybe_unused, *sched_in;
@@ -1455,120 +1393,113 @@ map_switch_event(struct perf_sched *sched,
}
static int process_sched_switch_event(struct perf_tool *tool,
- struct event_format *event,
+ struct perf_evsel *evsel,
struct perf_sample *sample,
struct machine *machine)
{
struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
int this_cpu = sample->cpu, err = 0;
- void *data = sample->raw_data;
- struct trace_switch_event switch_event;
-
- FILL_COMMON_FIELDS(switch_event, event, data);
-
- FILL_ARRAY(switch_event, prev_comm, event, data);
- FILL_FIELD(switch_event, prev_pid, event, data);
- FILL_FIELD(switch_event, prev_prio, event, data);
- FILL_FIELD(switch_event, prev_state, event, data);
- FILL_ARRAY(switch_event, next_comm, event, data);
- FILL_FIELD(switch_event, next_pid, event, data);
- FILL_FIELD(switch_event, next_prio, event, data);
+ u32 prev_pid = perf_evsel__intval(evsel, sample, "prev_pid"),
+ next_pid = perf_evsel__intval(evsel, sample, "next_pid");
if (sched->curr_pid[this_cpu] != (u32)-1) {
/*
* Are we trying to switch away a PID that is
* not current?
*/
- if (sched->curr_pid[this_cpu] != switch_event.prev_pid)
+ if (sched->curr_pid[this_cpu] != prev_pid)
sched->nr_context_switch_bugs++;
}
- if (sched->tp_handler->switch_event)
- err = sched->tp_handler->switch_event(sched, &switch_event, machine, event, sample);
- sched->curr_pid[this_cpu] = switch_event.next_pid;
+ if (sched->tp_handler->switch_event) {
+ struct trace_switch_event event = {
+ .prev_comm = perf_evsel__strval(evsel, sample, "prev_comm"),
+ .prev_pid = prev_pid,
+ .prev_prio = perf_evsel__intval(evsel, sample, "prev_prio"),
+ .prev_state = perf_evsel__intval(evsel, sample, "prev_state"),
+ .next_comm = perf_evsel__strval(evsel, sample, "next_comm"),
+ .next_pid = next_pid,
+ .next_prio = perf_evsel__intval(evsel, sample, "next_prio"),
+ };
+
+ err = sched->tp_handler->switch_event(sched, &event, machine, evsel, sample);
+ }
+
+ sched->curr_pid[this_cpu] = next_pid;
return err;
}
static int process_sched_runtime_event(struct perf_tool *tool,
- struct event_format *event,
+ struct perf_evsel *evsel,
struct perf_sample *sample,
struct machine *machine)
{
struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
- void *data = sample->raw_data;
- struct trace_runtime_event runtime_event;
- int err = 0;
- FILL_ARRAY(runtime_event, comm, event, data);
- FILL_FIELD(runtime_event, pid, event, data);
- FILL_FIELD(runtime_event, runtime, event, data);
- FILL_FIELD(runtime_event, vruntime, event, data);
-
- if (sched->tp_handler->runtime_event)
- err = sched->tp_handler->runtime_event(sched, &runtime_event, machine, sample);
+ if (sched->tp_handler->runtime_event) {
+ struct trace_runtime_event event = {
+ .comm = perf_evsel__strval(evsel, sample, "comm"),
+ .pid = perf_evsel__intval(evsel, sample, "pid"),
+ .runtime = perf_evsel__intval(evsel, sample, "runtime"),
+ .vruntime = perf_evsel__intval(evsel, sample, "vruntime"),
+ };
+ return sched->tp_handler->runtime_event(sched, &event, machine, sample);
+ }
- return err;
+ return 0;
}
static int process_sched_fork_event(struct perf_tool *tool,
- struct event_format *event,
+ struct perf_evsel *evsel,
struct perf_sample *sample,
struct machine *machine __maybe_unused)
{
struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
- void *data = sample->raw_data;
- struct trace_fork_event fork_event;
- int err = 0;
-
- FILL_COMMON_FIELDS(fork_event, event, data);
- FILL_ARRAY(fork_event, parent_comm, event, data);
- FILL_FIELD(fork_event, parent_pid, event, data);
- FILL_ARRAY(fork_event, child_comm, event, data);
- FILL_FIELD(fork_event, child_pid, event, data);
-
- if (sched->tp_handler->fork_event)
- err = sched->tp_handler->fork_event(sched, &fork_event, event);
+ if (sched->tp_handler->fork_event) {
+ struct trace_fork_event event = {
+ .parent_comm = perf_evsel__strval(evsel, sample, "parent_comm"),
+ .child_comm = perf_evsel__strval(evsel, sample, "child_comm"),
+ .parent_pid = perf_evsel__intval(evsel, sample, "parent_pid"),
+ .child_pid = perf_evsel__intval(evsel, sample, "child_pid"),
+ };
+ return sched->tp_handler->fork_event(sched, &event, evsel);
+ }
- return err;
+ return 0;
}
static int process_sched_exit_event(struct perf_tool *tool __maybe_unused,
- struct event_format *event,
+ struct perf_evsel *evsel,
struct perf_sample *sample __maybe_unused,
struct machine *machine __maybe_unused)
{
- if (verbose)
- printf("sched_exit event %p\n", event);
-
+ pr_debug("sched_exit event %p\n", evsel);
return 0;
}
static int process_sched_migrate_task_event(struct perf_tool *tool,
- struct event_format *event,
+ struct perf_evsel *evsel,
struct perf_sample *sample,
struct machine *machine)
{
struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
- void *data = sample->raw_data;
- struct trace_migrate_task_event migrate_task_event;
- int err = 0;
- FILL_COMMON_FIELDS(migrate_task_event, event, data);
-
- FILL_ARRAY(migrate_task_event, comm, event, data);
- FILL_FIELD(migrate_task_event, pid, event, data);
- FILL_FIELD(migrate_task_event, prio, event, data);
- FILL_FIELD(migrate_task_event, cpu, event, data);
-
- if (sched->tp_handler->migrate_task_event)
- err = sched->tp_handler->migrate_task_event(sched, &migrate_task_event, machine, sample);
+ if (sched->tp_handler->migrate_task_event) {
+ struct trace_migrate_task_event event = {
+ .comm = perf_evsel__strval(evsel, sample, "comm"),
+ .pid = perf_evsel__intval(evsel, sample, "pid"),
+ .prio = perf_evsel__intval(evsel, sample, "prio"),
+ .cpu = perf_evsel__intval(evsel, sample, "cpu"),
+ };
+ return sched->tp_handler->migrate_task_event(sched, &event, machine, sample);
+ }
- return err;
+ return 0;
}
typedef int (*tracepoint_handler)(struct perf_tool *tool,
- struct event_format *tp_format,
+ struct perf_evsel *evsel,
struct perf_sample *sample,
struct machine *machine);
@@ -1592,7 +1523,7 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool __maybe_
if (evsel->handler.func != NULL) {
tracepoint_handler f = evsel->handler.func;
- err = f(tool, evsel->tp_format, sample, machine);
+ err = f(tool, evsel, sample, machine);
}
return err;
--
1.7.9.2.358.g22243
next prev parent reply other threads:[~2012-09-11 23:53 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-11 23:52 [GIT PULL 00/20] perf/core improvements and fixes Arnaldo Carvalho de Melo
2012-09-11 23:52 ` [PATCH 01/18] perf test: Remove die() calls Arnaldo Carvalho de Melo
2012-09-12 0:24 ` Namhyung Kim
2012-09-12 1:03 ` Arnaldo Carvalho de Melo
2012-09-12 1:17 ` Namhyung Kim
2012-09-11 23:52 ` [PATCH 02/18] perf sched: " Arnaldo Carvalho de Melo
2012-09-12 0:37 ` Namhyung Kim
2012-09-11 23:52 ` [PATCH 03/18] perf kmem: " Arnaldo Carvalho de Melo
2012-09-11 23:52 ` [PATCH 04/18] perf tools: include wrapper for magic.h Arnaldo Carvalho de Melo
2012-09-11 23:52 ` [PATCH 05/18] perf tools: Add missing perf_regs.h file to MANIFEST Arnaldo Carvalho de Melo
2012-09-11 23:52 ` [PATCH 06/18] perf tools: Update types definitions for Android Arnaldo Carvalho de Melo
2012-09-11 23:52 ` [PATCH 07/18] perf tools: include __WORDSIZE definition Arnaldo Carvalho de Melo
2012-09-11 23:53 ` [PATCH 08/18] perf tools: fix ALIGN redefinition in system headers Arnaldo Carvalho de Melo
2012-09-11 23:53 ` [PATCH 09/18] perf tools: Do backtrace post unwind only if we regs and stack were captured Arnaldo Carvalho de Melo
2012-09-11 23:53 ` [PATCH 10/18] perf tools: Add memdup function Arnaldo Carvalho de Melo
2012-09-11 23:53 ` [PATCH 11/18] perf symbols: Make dsos__find function globally available Arnaldo Carvalho de Melo
2012-09-11 23:53 ` [PATCH 12/18] perf tools: Back [vdso] DSO with real data Arnaldo Carvalho de Melo
2012-09-11 23:53 ` [PATCH 13/18] perf tools: Use __maybe_used for unused variables Arnaldo Carvalho de Melo
2012-09-11 23:53 ` [PATCH 14/18] perf sched: Remove unused thread parameter Arnaldo Carvalho de Melo
2012-09-11 23:53 ` [PATCH 15/18] perf sched: Use perf_tool as ancestor Arnaldo Carvalho de Melo
2012-09-12 1:04 ` Namhyung Kim
2012-09-11 23:53 ` [PATCH 16/18] perf evsel: Introduce perf_evsel__{str,int}val methods Arnaldo Carvalho de Melo
2012-09-12 1:40 ` Namhyung Kim
2012-09-12 13:47 ` Arnaldo Carvalho de Melo
2012-09-12 2:21 ` Namhyung Kim
2012-09-12 13:48 ` Arnaldo Carvalho de Melo
2012-09-11 23:53 ` Arnaldo Carvalho de Melo [this message]
2012-09-11 23:53 ` [PATCH 18/18] perf sched: Don't read all tracepoint variables in advance Arnaldo Carvalho de Melo
2012-09-13 15:15 ` [GIT PULL 00/20] perf/core improvements and fixes Ingo Molnar
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=1347407590-30960-18-git-send-email-acme@infradead.org \
--to=acme@infradead.org \
--cc=acme@redhat.com \
--cc=dsahern@gmail.com \
--cc=efault@gmx.de \
--cc=eranian@google.com \
--cc=fweisbec@gmail.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@gmail.com \
--cc=paulus@samba.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;
as well as URLs for NNTP newsgroup(s).