From: David Carlier <devnexen@gmail.com>
To: Tejun Heo <tj@kernel.org>, David Vernet <void@manifault.com>,
Andrea Righi <arighi@nvidia.com>
Cc: linux-kernel@vger.kernel.org, David Carlier <devnexen@gmail.com>
Subject: [PATCH v2] sched_ext/selftests: Fix bpf_link leak on assertion failure
Date: Tue, 17 Mar 2026 18:28:07 +0000 [thread overview]
Message-ID: <20260317182807.51392-1-devnexen@gmail.com> (raw)
In-Reply-To: <20260317174402.48082-1-devnexen@gmail.com>
The SCX_EQ/SCX_ASSERT/SCX_FAIL_IF macros expand to return
SCX_TEST_FAIL on failure. When an assertion fires after
bpf_map__attach_struct_ops() but before bpf_link__destroy(), the
link leaks. Since the test runner is a single process, the leaked
link keeps the BPF scheduler attached, causing subsequent tests to
fail to attach their own scheduler -- cascading test failures from
a single bug.
Fix by introducing an __autolink cleanup attribute, as suggested
by Tejun, that auto-destroys the bpf_link when the variable goes
out of scope, covering both normal and early return paths. This
avoids the need to reorder bpf_link__destroy() before assertions,
which would break tests that assert SCX_EXIT_NONE (where the
scheduler is still running and bpf_link__destroy() would trigger
unregistration, changing uei.kind to SCX_EXIT_UNREG).
---
tools/testing/selftests/sched_ext/allowed_cpus.c | 3 +--
tools/testing/selftests/sched_ext/ddsp_bogus_dsq_fail.c | 3 +--
tools/testing/selftests/sched_ext/ddsp_vtimelocal_fail.c | 3 +--
tools/testing/selftests/sched_ext/dequeue.c | 3 ++-
tools/testing/selftests/sched_ext/enq_last_no_enq_fails.c | 4 +---
tools/testing/selftests/sched_ext/enq_select_cpu.c | 3 +--
tools/testing/selftests/sched_ext/exit.c | 3 +--
tools/testing/selftests/sched_ext/hotplug.c | 6 ++----
tools/testing/selftests/sched_ext/numa.c | 3 +--
tools/testing/selftests/sched_ext/peek_dsq.c | 8 +-------
tools/testing/selftests/sched_ext/prog_run.c | 3 +--
tools/testing/selftests/sched_ext/rt_stall.c | 6 ++----
tools/testing/selftests/sched_ext/scx_test.h | 8 ++++++++
tools/testing/selftests/sched_ext/select_cpu_dfl.c | 4 +---
.../selftests/sched_ext/select_cpu_dfl_nodispatch.c | 4 +---
tools/testing/selftests/sched_ext/select_cpu_dispatch.c | 4 +---
.../selftests/sched_ext/select_cpu_dispatch_bad_dsq.c | 3 +--
.../selftests/sched_ext/select_cpu_dispatch_dbl_dsp.c | 3 +--
tools/testing/selftests/sched_ext/select_cpu_vtime.c | 4 +---
19 files changed, 29 insertions(+), 49 deletions(-)
diff --git a/tools/testing/selftests/sched_ext/allowed_cpus.c b/tools/testing/selftests/sched_ext/allowed_cpus.c
index 093f285ab4ba..33fe9cb77159 100644
--- a/tools/testing/selftests/sched_ext/allowed_cpus.c
+++ b/tools/testing/selftests/sched_ext/allowed_cpus.c
@@ -50,7 +50,7 @@ static int test_select_cpu_from_user(const struct allowed_cpus *skel)
static enum scx_test_status run(void *ctx)
{
struct allowed_cpus *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
link = bpf_map__attach_struct_ops(skel->maps.allowed_cpus_ops);
SCX_FAIL_IF(!link, "Failed to attach scheduler");
@@ -62,7 +62,6 @@ static enum scx_test_status run(void *ctx)
sleep(1);
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_NONE));
- bpf_link__destroy(link);
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/ddsp_bogus_dsq_fail.c b/tools/testing/selftests/sched_ext/ddsp_bogus_dsq_fail.c
index b6d13496b24e..62ca2d57eb6e 100644
--- a/tools/testing/selftests/sched_ext/ddsp_bogus_dsq_fail.c
+++ b/tools/testing/selftests/sched_ext/ddsp_bogus_dsq_fail.c
@@ -28,7 +28,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct ddsp_bogus_dsq_fail *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
link = bpf_map__attach_struct_ops(skel->maps.ddsp_bogus_dsq_fail_ops);
SCX_FAIL_IF(!link, "Failed to attach struct_ops");
@@ -36,7 +36,6 @@ static enum scx_test_status run(void *ctx)
sleep(1);
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_ERROR));
- bpf_link__destroy(link);
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/ddsp_vtimelocal_fail.c b/tools/testing/selftests/sched_ext/ddsp_vtimelocal_fail.c
index af9ce4ee8baa..f66056450a81 100644
--- a/tools/testing/selftests/sched_ext/ddsp_vtimelocal_fail.c
+++ b/tools/testing/selftests/sched_ext/ddsp_vtimelocal_fail.c
@@ -27,7 +27,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct ddsp_vtimelocal_fail *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
link = bpf_map__attach_struct_ops(skel->maps.ddsp_vtimelocal_fail_ops);
SCX_FAIL_IF(!link, "Failed to attach struct_ops");
@@ -35,7 +35,6 @@ static enum scx_test_status run(void *ctx)
sleep(1);
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_ERROR));
- bpf_link__destroy(link);
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/dequeue.c b/tools/testing/selftests/sched_ext/dequeue.c
index 4e93262703ca..b7dec70213c7 100644
--- a/tools/testing/selftests/sched_ext/dequeue.c
+++ b/tools/testing/selftests/sched_ext/dequeue.c
@@ -80,7 +80,7 @@ static void *affinity_hammer_fn(void *arg)
static enum scx_test_status run_scenario(struct dequeue *skel, u32 scenario,
const char *scenario_name)
{
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
pid_t pids[NUM_WORKERS];
pthread_t hammer;
@@ -132,6 +132,7 @@ static enum scx_test_status run_scenario(struct dequeue *skel, u32 scenario,
}
bpf_link__destroy(link);
+ link = NULL;
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_UNREG));
diff --git a/tools/testing/selftests/sched_ext/enq_last_no_enq_fails.c b/tools/testing/selftests/sched_ext/enq_last_no_enq_fails.c
index d3387ae03679..22a8312223f6 100644
--- a/tools/testing/selftests/sched_ext/enq_last_no_enq_fails.c
+++ b/tools/testing/selftests/sched_ext/enq_last_no_enq_fails.c
@@ -28,7 +28,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct enq_last_no_enq_fails *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
link = bpf_map__attach_struct_ops(skel->maps.enq_last_no_enq_fails_ops);
if (!link) {
@@ -40,8 +40,6 @@ static enum scx_test_status run(void *ctx)
return SCX_TEST_FAIL;
}
- bpf_link__destroy(link);
-
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/enq_select_cpu.c b/tools/testing/selftests/sched_ext/enq_select_cpu.c
index 340c6f8b86da..5d220ee0442b 100644
--- a/tools/testing/selftests/sched_ext/enq_select_cpu.c
+++ b/tools/testing/selftests/sched_ext/enq_select_cpu.c
@@ -52,7 +52,7 @@ static int test_select_cpu_from_user(const struct enq_select_cpu *skel)
static enum scx_test_status run(void *ctx)
{
struct enq_select_cpu *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
link = bpf_map__attach_struct_ops(skel->maps.enq_select_cpu_ops);
if (!link) {
@@ -66,7 +66,6 @@ static enum scx_test_status run(void *ctx)
sleep(1);
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_NONE));
- bpf_link__destroy(link);
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/exit.c b/tools/testing/selftests/sched_ext/exit.c
index b987611789d1..9c0e528bcc11 100644
--- a/tools/testing/selftests/sched_ext/exit.c
+++ b/tools/testing/selftests/sched_ext/exit.c
@@ -19,7 +19,7 @@ static enum scx_test_status run(void *ctx)
for (tc = 0; tc < NUM_EXITS; tc++) {
struct exit *skel;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
char buf[16];
/*
@@ -49,7 +49,6 @@ static enum scx_test_status run(void *ctx)
SCX_EQ(skel->data->uei.exit_code, tc);
sprintf(buf, "%d", tc);
SCX_ASSERT(!strcmp(skel->data->uei.msg, buf));
- bpf_link__destroy(link);
exit__destroy(skel);
}
diff --git a/tools/testing/selftests/sched_ext/hotplug.c b/tools/testing/selftests/sched_ext/hotplug.c
index 0cfbb111a2d0..c1ff513b9579 100644
--- a/tools/testing/selftests/sched_ext/hotplug.c
+++ b/tools/testing/selftests/sched_ext/hotplug.c
@@ -43,7 +43,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status test_hotplug(bool onlining, bool cbs_defined)
{
struct hotplug *skel;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
long kind, code;
SCX_ASSERT(is_cpu_online());
@@ -90,7 +90,6 @@ static enum scx_test_status test_hotplug(bool onlining, bool cbs_defined)
if (!onlining)
toggle_online_status(1);
- bpf_link__destroy(link);
hotplug__destroy(skel);
return SCX_TEST_PASS;
@@ -99,7 +98,7 @@ static enum scx_test_status test_hotplug(bool onlining, bool cbs_defined)
static enum scx_test_status test_hotplug_attach(void)
{
struct hotplug *skel;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
enum scx_test_status status = SCX_TEST_PASS;
long kind, code;
@@ -130,7 +129,6 @@ static enum scx_test_status test_hotplug_attach(void)
SCX_EQ(skel->data->uei.kind, kind);
SCX_EQ(UEI_REPORT(skel, uei), code);
- bpf_link__destroy(link);
hotplug__destroy(skel);
return status;
diff --git a/tools/testing/selftests/sched_ext/numa.c b/tools/testing/selftests/sched_ext/numa.c
index b060c3b65c82..fe2dab1c73ae 100644
--- a/tools/testing/selftests/sched_ext/numa.c
+++ b/tools/testing/selftests/sched_ext/numa.c
@@ -28,7 +28,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct numa *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
link = bpf_map__attach_struct_ops(skel->maps.numa_ops);
SCX_FAIL_IF(!link, "Failed to attach scheduler");
@@ -37,7 +37,6 @@ static enum scx_test_status run(void *ctx)
sleep(1);
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_NONE));
- bpf_link__destroy(link);
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/peek_dsq.c b/tools/testing/selftests/sched_ext/peek_dsq.c
index a717384a3224..e7fd52ef15f6 100644
--- a/tools/testing/selftests/sched_ext/peek_dsq.c
+++ b/tools/testing/selftests/sched_ext/peek_dsq.c
@@ -84,7 +84,7 @@ static enum scx_test_status run(void *ctx)
/* Enable the scheduler to test DSQ operations */
printf("Enabling scheduler to test DSQ insert operations...\n");
- struct bpf_link *link =
+ struct bpf_link *link __autolink =
bpf_map__attach_struct_ops(skel->maps.peek_dsq_ops);
if (!link) {
@@ -102,7 +102,6 @@ static enum scx_test_status run(void *ctx)
workload_running = false;
for (int j = 0; j < i; j++)
pthread_join(workload_threads[j], NULL);
- bpf_link__destroy(link);
return SCX_TEST_FAIL;
}
}
@@ -120,7 +119,6 @@ static enum scx_test_status run(void *ctx)
workload_running = false;
for (int i = 0; i < NUM_WORKERS; i++)
pthread_join(workload_threads[i], NULL);
- bpf_link__destroy(link);
return SCX_TEST_FAIL;
}
}
@@ -130,7 +128,6 @@ static enum scx_test_status run(void *ctx)
err = pthread_join(workload_threads[i], NULL);
if (err) {
SCX_ERR("Failed to join workload thread %d: %s", i, strerror(err));
- bpf_link__destroy(link);
return SCX_TEST_FAIL;
}
}
@@ -138,9 +135,6 @@ static enum scx_test_status run(void *ctx)
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_NONE));
- /* Detach the scheduler */
- bpf_link__destroy(link);
-
printf("Enqueue/dispatch count over %d seconds: %d / %d\n", seconds,
skel->data->enqueue_count, skel->data->dispatch_count);
printf("Debug: ksym_exists=%d\n",
diff --git a/tools/testing/selftests/sched_ext/prog_run.c b/tools/testing/selftests/sched_ext/prog_run.c
index 05974820ca69..342cf000f514 100644
--- a/tools/testing/selftests/sched_ext/prog_run.c
+++ b/tools/testing/selftests/sched_ext/prog_run.c
@@ -28,7 +28,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct prog_run *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
int prog_fd, err = 0;
prog_fd = bpf_program__fd(skel->progs.prog_run_syscall);
@@ -56,7 +56,6 @@ static enum scx_test_status run(void *ctx)
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_UNREG_BPF));
SCX_EQ(skel->data->uei.exit_code, 0xdeadbeef);
close(prog_fd);
- bpf_link__destroy(link);
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/rt_stall.c b/tools/testing/selftests/sched_ext/rt_stall.c
index 81ea9b4883e5..20534abf3622 100644
--- a/tools/testing/selftests/sched_ext/rt_stall.c
+++ b/tools/testing/selftests/sched_ext/rt_stall.c
@@ -238,7 +238,6 @@ static bool sched_stress_test(bool is_ext)
static enum scx_test_status run(void *ctx)
{
struct rt_stall *skel = ctx;
- struct bpf_link *link = NULL;
bool res;
int i;
@@ -251,6 +250,7 @@ static enum scx_test_status run(void *ctx)
* - ext_server stop -> fair_server stop
*/
for (i = 0; i < 4; i++) {
+ struct bpf_link *link __autolink = NULL;
bool is_ext = i % 2;
if (is_ext) {
@@ -259,10 +259,8 @@ static enum scx_test_status run(void *ctx)
SCX_FAIL_IF(!link, "Failed to attach scheduler");
}
res = sched_stress_test(is_ext);
- if (is_ext) {
+ if (is_ext)
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_NONE));
- bpf_link__destroy(link);
- }
if (!res)
ksft_exit_fail();
diff --git a/tools/testing/selftests/sched_ext/scx_test.h b/tools/testing/selftests/sched_ext/scx_test.h
index 90b8d6915bb7..f75b5025c9f1 100644
--- a/tools/testing/selftests/sched_ext/scx_test.h
+++ b/tools/testing/selftests/sched_ext/scx_test.h
@@ -79,6 +79,14 @@ void scx_test_register(struct scx_test *test);
scx_test_register(__test); \
}
+static inline void autolink_destroy(struct bpf_link **linkp)
+{
+ if (*linkp)
+ bpf_link__destroy(*linkp);
+}
+
+#define __autolink __attribute__((cleanup(autolink_destroy)))
+
#define SCX_ERR(__fmt, ...) \
do { \
fprintf(stderr, "ERR: %s:%d\n", __FILE__, __LINE__); \
diff --git a/tools/testing/selftests/sched_ext/select_cpu_dfl.c b/tools/testing/selftests/sched_ext/select_cpu_dfl.c
index 5b6e045e1109..ced1a2ec5417 100644
--- a/tools/testing/selftests/sched_ext/select_cpu_dfl.c
+++ b/tools/testing/selftests/sched_ext/select_cpu_dfl.c
@@ -30,7 +30,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct select_cpu_dfl *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
pid_t pids[NUM_CHILDREN];
int i, status;
@@ -52,8 +52,6 @@ static enum scx_test_status run(void *ctx)
SCX_ASSERT(!skel->bss->saw_local);
- bpf_link__destroy(link);
-
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/select_cpu_dfl_nodispatch.c b/tools/testing/selftests/sched_ext/select_cpu_dfl_nodispatch.c
index 9b5d232efb7f..4014a812f85f 100644
--- a/tools/testing/selftests/sched_ext/select_cpu_dfl_nodispatch.c
+++ b/tools/testing/selftests/sched_ext/select_cpu_dfl_nodispatch.c
@@ -30,7 +30,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct select_cpu_dfl_nodispatch *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
pid_t pids[NUM_CHILDREN];
int i, status;
@@ -52,8 +52,6 @@ static enum scx_test_status run(void *ctx)
SCX_ASSERT(skel->bss->saw_local);
- bpf_link__destroy(link);
-
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/select_cpu_dispatch.c b/tools/testing/selftests/sched_ext/select_cpu_dispatch.c
index 80283dbc41b7..cecab356f915 100644
--- a/tools/testing/selftests/sched_ext/select_cpu_dispatch.c
+++ b/tools/testing/selftests/sched_ext/select_cpu_dispatch.c
@@ -30,7 +30,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct select_cpu_dispatch *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
pid_t pids[NUM_CHILDREN];
int i, status;
@@ -50,8 +50,6 @@ static enum scx_test_status run(void *ctx)
SCX_EQ(status, 0);
}
- bpf_link__destroy(link);
-
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/select_cpu_dispatch_bad_dsq.c b/tools/testing/selftests/sched_ext/select_cpu_dispatch_bad_dsq.c
index 5e72ebbc90a5..f4891e4293d2 100644
--- a/tools/testing/selftests/sched_ext/select_cpu_dispatch_bad_dsq.c
+++ b/tools/testing/selftests/sched_ext/select_cpu_dispatch_bad_dsq.c
@@ -28,7 +28,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct select_cpu_dispatch_bad_dsq *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
link = bpf_map__attach_struct_ops(skel->maps.select_cpu_dispatch_bad_dsq_ops);
SCX_FAIL_IF(!link, "Failed to attach scheduler");
@@ -36,7 +36,6 @@ static enum scx_test_status run(void *ctx)
sleep(1);
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_ERROR));
- bpf_link__destroy(link);
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/select_cpu_dispatch_dbl_dsp.c b/tools/testing/selftests/sched_ext/select_cpu_dispatch_dbl_dsp.c
index aa85949478bc..c13ccf26cfed 100644
--- a/tools/testing/selftests/sched_ext/select_cpu_dispatch_dbl_dsp.c
+++ b/tools/testing/selftests/sched_ext/select_cpu_dispatch_dbl_dsp.c
@@ -28,7 +28,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct select_cpu_dispatch_dbl_dsp *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
link = bpf_map__attach_struct_ops(skel->maps.select_cpu_dispatch_dbl_dsp_ops);
SCX_FAIL_IF(!link, "Failed to attach scheduler");
@@ -36,7 +36,6 @@ static enum scx_test_status run(void *ctx)
sleep(1);
SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_ERROR));
- bpf_link__destroy(link);
return SCX_TEST_PASS;
}
diff --git a/tools/testing/selftests/sched_ext/select_cpu_vtime.c b/tools/testing/selftests/sched_ext/select_cpu_vtime.c
index 1e9b5c9bfff1..f4edf2861502 100644
--- a/tools/testing/selftests/sched_ext/select_cpu_vtime.c
+++ b/tools/testing/selftests/sched_ext/select_cpu_vtime.c
@@ -28,7 +28,7 @@ static enum scx_test_status setup(void **ctx)
static enum scx_test_status run(void *ctx)
{
struct select_cpu_vtime *skel = ctx;
- struct bpf_link *link;
+ struct bpf_link *link __autolink = NULL;
SCX_ASSERT(!skel->bss->consumed);
@@ -39,8 +39,6 @@ static enum scx_test_status run(void *ctx)
SCX_ASSERT(skel->bss->consumed);
- bpf_link__destroy(link);
-
return SCX_TEST_PASS;
}
--
2.53.0
prev parent reply other threads:[~2026-03-17 18:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-17 17:44 [PATCH] sched_ext/selftests: Fix bpf_link leak on assertion failure David Carlier
2026-03-17 18:09 ` Tejun Heo
2026-03-17 18:28 ` David Carlier [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=20260317182807.51392-1-devnexen@gmail.com \
--to=devnexen@gmail.com \
--cc=arighi@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=tj@kernel.org \
--cc=void@manifault.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.