From: Johannes Weiner <hannes@cmpxchg.org> To: Andrew Morton <akpm@linux-foundation.org> Cc: Michal Hocko <mhocko@suse.cz>, David Rientjes <rientjes@google.com>, KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>, azurIt <azurit@pobox.sk>, KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>, linux-mm@kvack.org, cgroups@vger.kernel.org, x86@kernel.org, linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [patch 2/7] arch: mm: do not invoke OOM killer on kernel fault OOM Date: Sat, 3 Aug 2013 12:59:55 -0400 [thread overview] Message-ID: <1375549200-19110-3-git-send-email-hannes@cmpxchg.org> (raw) In-Reply-To: <1375549200-19110-1-git-send-email-hannes@cmpxchg.org> Kernel faults are expected to handle OOM conditions gracefully (gup, uaccess etc.), so they should never invoke the OOM killer. Reserve this for faults triggered in user context when it is the only option. Most architectures already do this, fix up the remaining few. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Michal Hocko <mhocko@suse.cz> Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> --- arch/arm/mm/fault.c | 14 +++++++------- arch/arm64/mm/fault.c | 14 +++++++------- arch/avr32/mm/fault.c | 2 +- arch/mips/mm/fault.c | 2 ++ arch/um/kernel/trap.c | 2 ++ arch/unicore32/mm/fault.c | 14 +++++++------- 6 files changed, 26 insertions(+), 22 deletions(-) diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index c97f794..217bcbf 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -349,6 +349,13 @@ retry: if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) return 0; + /* + * If we are in kernel mode at this point, we + * have no context to handle this fault with. + */ + if (!user_mode(regs)) + goto no_context; + if (fault & VM_FAULT_OOM) { /* * We ran out of memory, call the OOM killer, and return to @@ -359,13 +366,6 @@ retry: return 0; } - /* - * If we are in kernel mode at this point, we - * have no context to handle this fault with. - */ - if (!user_mode(regs)) - goto no_context; - if (fault & VM_FAULT_SIGBUS) { /* * We had some memory, but were unable to diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 0ecac89..dab1cfd 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -294,6 +294,13 @@ retry: VM_FAULT_BADACCESS)))) return 0; + /* + * If we are in kernel mode at this point, we have no context to + * handle this fault with. + */ + if (!user_mode(regs)) + goto no_context; + if (fault & VM_FAULT_OOM) { /* * We ran out of memory, call the OOM killer, and return to @@ -304,13 +311,6 @@ retry: return 0; } - /* - * If we are in kernel mode at this point, we have no context to - * handle this fault with. - */ - if (!user_mode(regs)) - goto no_context; - if (fault & VM_FAULT_SIGBUS) { /* * We had some memory, but were unable to successfully fix up diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index b2f2d2d..2ca27b0 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -228,9 +228,9 @@ no_context: */ out_of_memory: up_read(&mm->mmap_sem); - pagefault_out_of_memory(); if (!user_mode(regs)) goto no_context; + pagefault_out_of_memory(); return; do_sigbus: diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 85df1cd..94d3a31 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -241,6 +241,8 @@ out_of_memory: * (which will retry the fault, or kill us if we got oom-killed). */ up_read(&mm->mmap_sem); + if (!user_mode(regs)) + goto no_context; pagefault_out_of_memory(); return; diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 089f398..b2f5adf 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -124,6 +124,8 @@ out_of_memory: * (which will retry the fault, or kill us if we got oom-killed). */ up_read(&mm->mmap_sem); + if (!is_user) + goto out_nosemaphore; pagefault_out_of_memory(); return 0; } diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index f9b5c10..8ed3c45 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c @@ -278,6 +278,13 @@ retry: (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) return 0; + /* + * If we are in kernel mode at this point, we + * have no context to handle this fault with. + */ + if (!user_mode(regs)) + goto no_context; + if (fault & VM_FAULT_OOM) { /* * We ran out of memory, call the OOM killer, and return to @@ -288,13 +295,6 @@ retry: return 0; } - /* - * If we are in kernel mode at this point, we - * have no context to handle this fault with. - */ - if (!user_mode(regs)) - goto no_context; - if (fault & VM_FAULT_SIGBUS) { /* * We had some memory, but were unable to -- 1.8.3.2
WARNING: multiple messages have this Message-ID (diff)
From: Johannes Weiner <hannes@cmpxchg.org> To: Andrew Morton <akpm@linux-foundation.org> Cc: Michal Hocko <mhocko@suse.cz>, David Rientjes <rientjes@google.com>, KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>, azurIt <azurit@pobox.sk>, KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>, linux-mm@kvack.org, cgroups@vger.kernel.org, x86@kernel.org, linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [patch 2/7] arch: mm: do not invoke OOM killer on kernel fault OOM Date: Sat, 3 Aug 2013 12:59:55 -0400 [thread overview] Message-ID: <1375549200-19110-3-git-send-email-hannes@cmpxchg.org> (raw) In-Reply-To: <1375549200-19110-1-git-send-email-hannes@cmpxchg.org> Kernel faults are expected to handle OOM conditions gracefully (gup, uaccess etc.), so they should never invoke the OOM killer. Reserve this for faults triggered in user context when it is the only option. Most architectures already do this, fix up the remaining few. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Michal Hocko <mhocko@suse.cz> Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> --- arch/arm/mm/fault.c | 14 +++++++------- arch/arm64/mm/fault.c | 14 +++++++------- arch/avr32/mm/fault.c | 2 +- arch/mips/mm/fault.c | 2 ++ arch/um/kernel/trap.c | 2 ++ arch/unicore32/mm/fault.c | 14 +++++++------- 6 files changed, 26 insertions(+), 22 deletions(-) diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index c97f794..217bcbf 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -349,6 +349,13 @@ retry: if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) return 0; + /* + * If we are in kernel mode at this point, we + * have no context to handle this fault with. + */ + if (!user_mode(regs)) + goto no_context; + if (fault & VM_FAULT_OOM) { /* * We ran out of memory, call the OOM killer, and return to @@ -359,13 +366,6 @@ retry: return 0; } - /* - * If we are in kernel mode at this point, we - * have no context to handle this fault with. - */ - if (!user_mode(regs)) - goto no_context; - if (fault & VM_FAULT_SIGBUS) { /* * We had some memory, but were unable to diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 0ecac89..dab1cfd 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -294,6 +294,13 @@ retry: VM_FAULT_BADACCESS)))) return 0; + /* + * If we are in kernel mode at this point, we have no context to + * handle this fault with. + */ + if (!user_mode(regs)) + goto no_context; + if (fault & VM_FAULT_OOM) { /* * We ran out of memory, call the OOM killer, and return to @@ -304,13 +311,6 @@ retry: return 0; } - /* - * If we are in kernel mode at this point, we have no context to - * handle this fault with. - */ - if (!user_mode(regs)) - goto no_context; - if (fault & VM_FAULT_SIGBUS) { /* * We had some memory, but were unable to successfully fix up diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index b2f2d2d..2ca27b0 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -228,9 +228,9 @@ no_context: */ out_of_memory: up_read(&mm->mmap_sem); - pagefault_out_of_memory(); if (!user_mode(regs)) goto no_context; + pagefault_out_of_memory(); return; do_sigbus: diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 85df1cd..94d3a31 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -241,6 +241,8 @@ out_of_memory: * (which will retry the fault, or kill us if we got oom-killed). */ up_read(&mm->mmap_sem); + if (!user_mode(regs)) + goto no_context; pagefault_out_of_memory(); return; diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 089f398..b2f5adf 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -124,6 +124,8 @@ out_of_memory: * (which will retry the fault, or kill us if we got oom-killed). */ up_read(&mm->mmap_sem); + if (!is_user) + goto out_nosemaphore; pagefault_out_of_memory(); return 0; } diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index f9b5c10..8ed3c45 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c @@ -278,6 +278,13 @@ retry: (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) return 0; + /* + * If we are in kernel mode at this point, we + * have no context to handle this fault with. + */ + if (!user_mode(regs)) + goto no_context; + if (fault & VM_FAULT_OOM) { /* * We ran out of memory, call the OOM killer, and return to @@ -288,13 +295,6 @@ retry: return 0; } - /* - * If we are in kernel mode at this point, we - * have no context to handle this fault with. - */ - if (!user_mode(regs)) - goto no_context; - if (fault & VM_FAULT_SIGBUS) { /* * We had some memory, but were unable to -- 1.8.3.2 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2013-08-03 17:00 UTC|newest] Thread overview: 227+ messages / expand[flat|nested] mbox.gz Atom feed top 2013-08-03 16:59 [patch 0/7] improve memcg oom killer robustness v2 Johannes Weiner 2013-08-03 16:59 ` Johannes Weiner 2013-08-03 16:59 ` [patch 1/7] arch: mm: remove obsolete init OOM protection Johannes Weiner 2013-08-03 16:59 ` Johannes Weiner 2013-08-06 6:34 ` Vineet Gupta 2013-08-06 6:34 ` Vineet Gupta 2013-08-06 6:34 ` Vineet Gupta 2013-08-03 16:59 ` Johannes Weiner [this message] 2013-08-03 16:59 ` [patch 2/7] arch: mm: do not invoke OOM killer on kernel fault OOM Johannes Weiner 2013-08-03 16:59 ` [patch 3/7] arch: mm: pass userspace fault flag to generic fault handler Johannes Weiner 2013-08-03 16:59 ` Johannes Weiner 2013-08-05 22:06 ` Andrew Morton 2013-08-05 22:06 ` Andrew Morton 2013-08-05 22:25 ` Johannes Weiner 2013-08-05 22:25 ` Johannes Weiner 2013-08-03 16:59 ` [patch 4/7] x86: finish user fault error path with fatal signal Johannes Weiner 2013-08-03 16:59 ` Johannes Weiner 2013-08-03 16:59 ` [patch 5/7] mm: memcg: enable memcg OOM killer only for user faults Johannes Weiner 2013-08-03 16:59 ` Johannes Weiner 2013-08-05 9:18 ` Michal Hocko 2013-08-05 9:18 ` Michal Hocko 2013-08-03 16:59 ` [patch 6/7] mm: memcg: rework and document OOM waiting and wakeup Johannes Weiner 2013-08-03 16:59 ` Johannes Weiner 2013-08-03 17:00 ` [patch 7/7] mm: memcg: do not trap chargers with full callstack on OOM Johannes Weiner 2013-08-03 17:00 ` Johannes Weiner 2013-08-05 9:54 ` Michal Hocko 2013-08-05 9:54 ` Michal Hocko 2013-08-05 9:54 ` Michal Hocko 2013-08-05 20:56 ` Johannes Weiner 2013-08-05 20:56 ` Johannes Weiner 2013-08-03 17:08 ` [patch 0/7] improve memcg oom killer robustness v2 Johannes Weiner 2013-08-03 17:08 ` Johannes Weiner 2013-08-09 9:06 ` azurIt 2013-08-09 9:06 ` azurIt 2013-08-09 9:06 ` azurIt 2013-08-30 19:58 ` azurIt 2013-08-30 19:58 ` azurIt 2013-09-02 10:38 ` azurIt 2013-09-02 10:38 ` azurIt 2013-09-03 20:48 ` Johannes Weiner 2013-09-03 20:48 ` Johannes Weiner 2013-09-04 7:53 ` azurIt 2013-09-04 7:53 ` azurIt 2013-09-04 7:53 ` azurIt 2013-09-04 7:53 ` azurIt 2013-09-04 8:18 ` azurIt 2013-09-04 8:18 ` azurIt 2013-09-05 11:54 ` Johannes Weiner 2013-09-05 11:54 ` Johannes Weiner 2013-09-05 12:43 ` Michal Hocko 2013-09-05 12:43 ` Michal Hocko 2013-09-05 16:18 ` Johannes Weiner 2013-09-05 16:18 ` Johannes Weiner 2013-09-09 12:36 ` Michal Hocko 2013-09-09 12:36 ` Michal Hocko 2013-09-09 12:56 ` Michal Hocko 2013-09-09 12:56 ` Michal Hocko 2013-09-12 12:59 ` Johannes Weiner 2013-09-12 12:59 ` Johannes Weiner 2013-09-16 14:03 ` Michal Hocko 2013-09-16 14:03 ` Michal Hocko 2013-09-16 14:03 ` Michal Hocko 2013-09-05 13:24 ` Michal Hocko 2013-09-05 13:24 ` Michal Hocko 2013-09-09 13:10 ` azurIt 2013-09-09 13:10 ` azurIt 2013-09-09 17:28 ` Johannes Weiner 2013-09-09 17:28 ` Johannes Weiner 2013-09-09 19:59 ` azurIt 2013-09-09 19:59 ` azurIt 2013-09-09 20:12 ` Johannes Weiner 2013-09-09 20:12 ` Johannes Weiner 2013-09-09 20:18 ` azurIt 2013-09-09 20:18 ` azurIt 2013-09-09 21:08 ` azurIt 2013-09-09 21:08 ` azurIt 2013-09-10 18:13 ` azurIt 2013-09-10 18:13 ` azurIt 2013-09-10 18:37 ` Johannes Weiner 2013-09-10 18:37 ` Johannes Weiner 2013-09-10 19:32 ` azurIt 2013-09-10 19:32 ` azurIt 2013-09-10 20:12 ` Johannes Weiner 2013-09-10 20:12 ` Johannes Weiner 2013-09-10 21:08 ` azurIt 2013-09-10 21:08 ` azurIt 2013-09-10 21:08 ` azurIt 2013-09-10 21:18 ` Johannes Weiner 2013-09-10 21:18 ` Johannes Weiner 2013-09-10 21:32 ` azurIt 2013-09-10 21:32 ` azurIt 2013-09-10 22:03 ` Johannes Weiner 2013-09-10 22:03 ` Johannes Weiner 2013-09-11 12:33 ` azurIt 2013-09-11 12:33 ` azurIt 2013-09-11 18:03 ` Johannes Weiner 2013-09-11 18:03 ` Johannes Weiner 2013-09-11 18:03 ` Johannes Weiner 2013-09-11 18:54 ` azurIt 2013-09-11 18:54 ` azurIt 2013-09-11 19:11 ` Johannes Weiner 2013-09-11 19:11 ` Johannes Weiner 2013-09-11 19:41 ` azurIt 2013-09-11 19:41 ` azurIt 2013-09-11 20:04 ` Johannes Weiner 2013-09-11 20:04 ` Johannes Weiner 2013-09-14 10:48 ` azurIt 2013-09-14 10:48 ` azurIt 2013-09-16 13:40 ` Michal Hocko 2013-09-16 13:40 ` Michal Hocko 2013-09-16 14:01 ` azurIt 2013-09-16 14:01 ` azurIt 2013-09-16 14:06 ` Michal Hocko 2013-09-16 14:06 ` Michal Hocko 2013-09-16 14:13 ` azurIt 2013-09-16 14:13 ` azurIt 2013-09-16 14:13 ` azurIt 2013-09-16 14:57 ` Michal Hocko 2013-09-16 14:57 ` Michal Hocko 2013-09-16 15:05 ` azurIt 2013-09-16 15:05 ` azurIt 2013-09-16 15:17 ` Johannes Weiner 2013-09-16 15:17 ` Johannes Weiner 2013-09-16 15:17 ` Johannes Weiner 2013-09-16 15:24 ` azurIt 2013-09-16 15:24 ` azurIt 2013-09-16 15:25 ` Michal Hocko 2013-09-16 15:25 ` Michal Hocko 2013-09-16 15:40 ` azurIt 2013-09-16 15:40 ` azurIt 2013-09-16 20:52 ` azurIt 2013-09-16 20:52 ` azurIt 2013-09-17 0:02 ` Johannes Weiner 2013-09-17 0:02 ` Johannes Weiner 2013-09-17 11:15 ` azurIt 2013-09-17 11:15 ` azurIt 2013-09-17 11:15 ` azurIt 2013-09-17 14:10 ` Michal Hocko 2013-09-17 14:10 ` Michal Hocko 2013-09-18 14:03 ` azurIt 2013-09-18 14:03 ` azurIt 2013-09-18 14:03 ` azurIt 2013-09-18 14:24 ` Michal Hocko 2013-09-18 14:24 ` Michal Hocko 2013-09-18 14:33 ` azurIt 2013-09-18 14:33 ` azurIt 2013-09-18 14:42 ` Michal Hocko 2013-09-18 14:42 ` Michal Hocko 2013-09-18 14:42 ` Michal Hocko 2013-09-18 18:02 ` azurIt 2013-09-18 18:02 ` azurIt 2013-09-18 18:36 ` Michal Hocko 2013-09-18 18:36 ` Michal Hocko 2013-09-18 18:36 ` Michal Hocko 2013-09-18 18:04 ` Johannes Weiner 2013-09-18 18:04 ` Johannes Weiner 2013-09-18 18:19 ` Johannes Weiner 2013-09-18 18:19 ` Johannes Weiner 2013-09-18 19:55 ` Johannes Weiner 2013-09-18 19:55 ` Johannes Weiner 2013-09-18 19:55 ` Johannes Weiner 2013-09-18 20:52 ` azurIt 2013-09-18 20:52 ` azurIt 2013-09-18 20:52 ` azurIt 2013-09-25 7:26 ` azurIt 2013-09-25 7:26 ` azurIt 2013-09-25 7:26 ` azurIt 2013-09-26 16:54 ` azurIt 2013-09-26 16:54 ` azurIt 2013-09-26 16:54 ` azurIt 2013-09-26 19:27 ` Johannes Weiner 2013-09-26 19:27 ` Johannes Weiner 2013-09-27 2:04 ` azurIt 2013-09-27 2:04 ` azurIt 2013-09-27 2:04 ` azurIt 2013-09-27 2:04 ` azurIt 2013-10-07 11:01 ` azurIt 2013-10-07 11:01 ` azurIt 2013-10-07 11:01 ` azurIt 2013-10-07 11:01 ` azurIt 2013-10-07 19:23 ` Johannes Weiner 2013-10-07 19:23 ` Johannes Weiner 2013-10-09 18:44 ` azurIt 2013-10-09 18:44 ` azurIt 2013-10-09 18:44 ` azurIt 2013-10-10 0:14 ` Johannes Weiner 2013-10-10 0:14 ` Johannes Weiner 2013-10-10 0:14 ` Johannes Weiner 2013-10-10 22:59 ` azurIt 2013-10-10 22:59 ` azurIt 2013-10-10 22:59 ` azurIt 2013-09-17 11:20 ` azurIt 2013-09-17 11:20 ` azurIt 2013-09-16 10:22 ` azurIt 2013-09-16 10:22 ` azurIt 2013-09-04 9:45 ` azurIt 2013-09-04 9:45 ` azurIt 2013-09-04 11:57 ` Michal Hocko 2013-09-04 11:57 ` Michal Hocko 2013-09-04 12:10 ` azurIt 2013-09-04 12:10 ` azurIt 2013-09-04 12:10 ` azurIt 2013-09-04 12:26 ` Michal Hocko 2013-09-04 12:26 ` Michal Hocko 2013-09-04 12:26 ` Michal Hocko 2013-09-04 12:39 ` azurIt 2013-09-04 12:39 ` azurIt 2013-09-05 9:14 ` azurIt 2013-09-05 9:14 ` azurIt 2013-09-05 9:53 ` Michal Hocko 2013-09-05 9:53 ` Michal Hocko 2013-09-05 10:17 ` azurIt 2013-09-05 10:17 ` azurIt 2013-09-05 11:17 ` Michal Hocko 2013-09-05 11:17 ` Michal Hocko 2013-09-05 11:17 ` Michal Hocko 2013-09-05 11:47 ` azurIt 2013-09-05 11:47 ` azurIt 2013-09-05 12:03 ` Michal Hocko 2013-09-05 12:03 ` Michal Hocko 2013-09-05 12:33 ` azurIt 2013-09-05 12:33 ` azurIt 2013-09-05 12:33 ` azurIt 2013-09-05 12:45 ` Michal Hocko 2013-09-05 12:45 ` Michal Hocko 2013-09-05 13:00 ` azurIt 2013-09-05 13:00 ` azurIt
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=1375549200-19110-3-git-send-email-hannes@cmpxchg.org \ --to=hannes@cmpxchg.org \ --cc=akpm@linux-foundation.org \ --cc=azurit@pobox.sk \ --cc=cgroups@vger.kernel.org \ --cc=kamezawa.hiroyu@jp.fujitsu.com \ --cc=kosaki.motohiro@jp.fujitsu.com \ --cc=linux-arch@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=mhocko@suse.cz \ --cc=rientjes@google.com \ --cc=x86@kernel.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: linkBe 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.