stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Michal Hocko <mhocko@suse.com>,
	Mel Gorman <mgorman@suse.de>,
	Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 4.4 80/90] mm: consider memblock reservations for deferred memory initialization sizing
Date: Mon, 12 Jun 2017 17:26:26 +0200	[thread overview]
Message-ID: <20170612152601.880958587@linuxfoundation.org> (raw)
In-Reply-To: <20170612152556.133240249@linuxfoundation.org>

4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Michal Hocko <mhocko@suse.com>

commit 864b9a393dcb5aed09b8fd31b9bbda0fdda99374 upstream.

We have seen an early OOM killer invocation on ppc64 systems with
crashkernel=4096M:

	kthreadd invoked oom-killer: gfp_mask=0x16040c0(GFP_KERNEL|__GFP_COMP|__GFP_NOTRACK), nodemask=7, order=0, oom_score_adj=0
	kthreadd cpuset=/ mems_allowed=7
	CPU: 0 PID: 2 Comm: kthreadd Not tainted 4.4.68-1.gd7fe927-default #1
	Call Trace:
	  dump_stack+0xb0/0xf0 (unreliable)
	  dump_header+0xb0/0x258
	  out_of_memory+0x5f0/0x640
	  __alloc_pages_nodemask+0xa8c/0xc80
	  kmem_getpages+0x84/0x1a0
	  fallback_alloc+0x2a4/0x320
	  kmem_cache_alloc_node+0xc0/0x2e0
	  copy_process.isra.25+0x260/0x1b30
	  _do_fork+0x94/0x470
	  kernel_thread+0x48/0x60
	  kthreadd+0x264/0x330
	  ret_from_kernel_thread+0x5c/0xa4

	Mem-Info:
	active_anon:0 inactive_anon:0 isolated_anon:0
	 active_file:0 inactive_file:0 isolated_file:0
	 unevictable:0 dirty:0 writeback:0 unstable:0
	 slab_reclaimable:5 slab_unreclaimable:73
	 mapped:0 shmem:0 pagetables:0 bounce:0
	 free:0 free_pcp:0 free_cma:0
	Node 7 DMA free:0kB min:0kB low:0kB high:0kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:52428800kB managed:110016kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:320kB slab_unreclaimable:4672kB kernel_stack:1152kB pagetables:0kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
	lowmem_reserve[]: 0 0 0 0
	Node 7 DMA: 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 0kB
	0 total pagecache pages
	0 pages in swap cache
	Swap cache stats: add 0, delete 0, find 0/0
	Free swap  = 0kB
	Total swap = 0kB
	819200 pages RAM
	0 pages HighMem/MovableOnly
	817481 pages reserved
	0 pages cma reserved
	0 pages hwpoisoned

the reason is that the managed memory is too low (only 110MB) while the
rest of the the 50GB is still waiting for the deferred intialization to
be done.  update_defer_init estimates the initial memoty to initialize
to 2GB at least but it doesn't consider any memory allocated in that
range.  In this particular case we've had

	Reserving 4096MB of memory at 128MB for crashkernel (System RAM: 51200MB)

so the low 2GB is mostly depleted.

Fix this by considering memblock allocations in the initial static
initialization estimation.  Move the max_initialise to
reset_deferred_meminit and implement a simple memblock_reserved_memory
helper which iterates all reserved blocks and sums the size of all that
start below the given address.  The cumulative size is than added on top
of the initial estimation.  This is still not ideal because
reset_deferred_meminit doesn't consider holes and so reservation might
be above the initial estimation whihch we ignore but let's make the
logic simpler until we really need to handle more complicated cases.

Fixes: 3a80a7fa7989 ("mm: meminit: initialise a subset of struct pages if CONFIG_DEFERRED_STRUCT_PAGE_INIT is set")
Link: http://lkml.kernel.org/r/20170531104010.GI27783@dhcp22.suse.cz
Signed-off-by: Michal Hocko <mhocko@suse.com>
Acked-by: Mel Gorman <mgorman@suse.de>
Tested-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


---
 include/linux/memblock.h |    8 ++++++++
 include/linux/mmzone.h   |    1 +
 mm/memblock.c            |   24 ++++++++++++++++++++++++
 mm/page_alloc.c          |   25 ++++++++++++++++++++++---
 4 files changed, 55 insertions(+), 3 deletions(-)

--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -408,11 +408,19 @@ static inline void early_memtest(phys_ad
 }
 #endif
 
+extern unsigned long memblock_reserved_memory_within(phys_addr_t start_addr,
+		phys_addr_t end_addr);
 #else
 static inline phys_addr_t memblock_alloc(phys_addr_t size, phys_addr_t align)
 {
 	return 0;
 }
+
+static inline unsigned long memblock_reserved_memory_within(phys_addr_t start_addr,
+		phys_addr_t end_addr)
+{
+	return 0;
+}
 
 #endif /* CONFIG_HAVE_MEMBLOCK */
 
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -688,6 +688,7 @@ typedef struct pglist_data {
 	 * is the first PFN that needs to be initialised.
 	 */
 	unsigned long first_deferred_pfn;
+	unsigned long static_init_size;
 #endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */
 } pg_data_t;
 
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1634,6 +1634,30 @@ static void __init_memblock memblock_dum
 	}
 }
 
+extern unsigned long __init_memblock
+memblock_reserved_memory_within(phys_addr_t start_addr, phys_addr_t end_addr)
+{
+	struct memblock_type *type = &memblock.reserved;
+	unsigned long size = 0;
+	int idx;
+
+	for (idx = 0; idx < type->cnt; idx++) {
+		struct memblock_region *rgn = &type->regions[idx];
+		phys_addr_t start, end;
+
+		if (rgn->base + rgn->size < start_addr)
+			continue;
+		if (rgn->base > end_addr)
+			continue;
+
+		start = rgn->base;
+		end = start + rgn->size;
+		size += end - start;
+	}
+
+	return size;
+}
+
 void __init_memblock __memblock_dump_all(void)
 {
 	pr_info("MEMBLOCK configuration:\n");
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -269,6 +269,26 @@ int page_group_by_mobility_disabled __re
 #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
 static inline void reset_deferred_meminit(pg_data_t *pgdat)
 {
+	unsigned long max_initialise;
+	unsigned long reserved_lowmem;
+
+	/*
+	 * Initialise at least 2G of a node but also take into account that
+	 * two large system hashes that can take up 1GB for 0.25TB/node.
+	 */
+	max_initialise = max(2UL << (30 - PAGE_SHIFT),
+		(pgdat->node_spanned_pages >> 8));
+
+	/*
+	 * Compensate the all the memblock reservations (e.g. crash kernel)
+	 * from the initial estimation to make sure we will initialize enough
+	 * memory to boot.
+	 */
+	reserved_lowmem = memblock_reserved_memory_within(pgdat->node_start_pfn,
+			pgdat->node_start_pfn + max_initialise);
+	max_initialise += reserved_lowmem;
+
+	pgdat->static_init_size = min(max_initialise, pgdat->node_spanned_pages);
 	pgdat->first_deferred_pfn = ULONG_MAX;
 }
 
@@ -302,10 +322,9 @@ static inline bool update_defer_init(pg_
 	/* Always populate low zones for address-contrained allocations */
 	if (zone_end < pgdat_end_pfn(pgdat))
 		return true;
-
 	/* Initialise at least 2G of the highest zone */
 	(*nr_initialised)++;
-	if (*nr_initialised > (2UL << (30 - PAGE_SHIFT)) &&
+	if ((*nr_initialised > pgdat->static_init_size) &&
 	    (pfn & (PAGES_PER_SECTION - 1)) == 0) {
 		pgdat->first_deferred_pfn = pfn;
 		return false;
@@ -5343,7 +5362,6 @@ void __paginginit free_area_init_node(in
 	/* pg_data_t should be reset to zero when it's allocated */
 	WARN_ON(pgdat->nr_zones || pgdat->classzone_idx);
 
-	reset_deferred_meminit(pgdat);
 	pgdat->node_id = nid;
 	pgdat->node_start_pfn = node_start_pfn;
 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
@@ -5362,6 +5380,7 @@ void __paginginit free_area_init_node(in
 		(unsigned long)pgdat->node_mem_map);
 #endif
 
+	reset_deferred_meminit(pgdat);
 	free_area_init_core(pgdat);
 }
 

  parent reply	other threads:[~2017-06-12 15:40 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-12 15:25 [PATCH 4.4 00/90] 4.4.72-stable review Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 01/90] bnx2x: Fix Multi-Cos Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 02/90] ipv6: xfrm: Handle errors reported by xfrm6_find_1stfragopt() Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 03/90] cxgb4: avoid enabling napi twice to the same queue Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 04/90] tcp: disallow cwnd undo when switching congestion control Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 05/90] vxlan: fix use-after-free on deletion Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 06/90] ipv6: Fix leak in ipv6_gso_segment() Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 07/90] net: ping: do not abuse udp_poll() Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 08/90] net: ethoc: enable NAPI before poll may be scheduled Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 09/90] net: bridge: start hello timer only if device is up Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 10/90] sparc64: mm: fix copy_tsb to correctly copy huge page TSBs Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 11/90] sparc: Machine description indices can vary Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 12/90] sparc64: reset mm cpumask after wrap Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 13/90] sparc64: combine activate_mm and switch_mm Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 14/90] sparc64: redefine first version Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 15/90] sparc64: add per-cpu mm of secondary contexts Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 16/90] sparc64: new context wrap Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 17/90] sparc64: delete old wrap code Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 18/90] arch/sparc: support NR_CPUS = 4096 Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 19/90] serial: ifx6x60: fix use-after-free on module unload Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 20/90] ptrace: Properly initialize ptracer_cred on fork Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 21/90] KEYS: fix dereferencing NULL payload with nonzero length Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 22/90] KEYS: fix freeing uninitialized memory in key_update() Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 23/90] crypto: gcm - wait for crypto op not signal safe Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 25/90] nfsd4: fix null dereference on replay Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 26/90] nfsd: Fix up the "supattr_exclcreat" attributes Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 29/90] arm: KVM: Allow unaligned accesses at HYP Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 31/90] dmaengine: usb-dmac: Fix DMAOR AE bit definition Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 32/90] dmaengine: ep93xx: Always start from BASE0 Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 33/90] xen/privcmd: Support correctly 64KB page granularity when mapping memory Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 34/90] xen-netfront: do not cast grant table reference to signed short Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 35/90] xen-netfront: cast grant table reference first to type int Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 36/90] ext4: fix SEEK_HOLE Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 37/90] ext4: keep existing extra fields when inode expands Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 38/90] ext4: fix fdatasync(2) after extent manipulation operations Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 39/90] usb: gadget: f_mass_storage: Serialize wake and sleep execution Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 40/90] usb: chipidea: udc: fix NULL pointer dereference if udc_start failed Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 41/90] usb: chipidea: debug: check before accessing ci_role Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 42/90] staging/lustre/lov: remove set_fs() call from lov_getstripe() Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 43/90] iio: light: ltr501 Fix interchanged als/ps register field Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 44/90] iio: proximity: as3935: fix AS3935_INT mask Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 45/90] drivers: char: random: add get_random_long() Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 46/90] random: properly align get_random_int_hash Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 47/90] stackprotector: Increase the per-task stack canarys random range from 32 bits to 64 bits on 64-bit platforms Greg Kroah-Hartman
2017-06-12 15:41   ` [kernel-hardening] " Jann Horn
2017-06-12 15:45     ` Jann Horn
2017-06-12 15:25 ` [PATCH 4.4 48/90] cpufreq: cpufreq_register_driver() should return -ENODEV if init fails Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 49/90] target: Re-add check to reject control WRITEs with overflow data Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 50/90] drm/msm: Expose our reservation object when exporting a dmabuf Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 51/90] Input: elantech - add Fujitsu Lifebook E546/E557 to force crc_enabled Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 52/90] cpuset: consider dying css as offline Greg Kroah-Hartman
2017-06-12 15:25 ` [PATCH 4.4 53/90] fs: add i_blocksize() Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 54/90] ufs: restore proper tail allocation Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 55/90] fix ufs_isblockset() Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 56/90] ufs: restore maintaining ->i_blocks Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 57/90] ufs: set correct ->s_maxsize Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 58/90] ufs_extend_tail(): fix the braino in calling conventions of ufs_new_fragments() Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 59/90] ufs_getfrag_block(): we only grab ->truncate_mutex on block creation path Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 60/90] cxl: Fix error path on bad ioctl Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 61/90] btrfs: use correct types for page indices in btrfs_page_exists_in_range Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 62/90] btrfs: fix memory leak in update_space_info failure path Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 63/90] KVM: arm/arm64: Handle possible NULL stage2 pud when ageing pages Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 64/90] scsi: qla2xxx: dont disable a not previously enabled PCI device Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 65/90] powerpc/eeh: Avoid use after free in eeh_handle_special_event() Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 66/90] powerpc/numa: Fix percpu allocations to be NUMA aware Greg Kroah-Hartman
2017-07-28 13:53   ` Michal Hocko
2017-07-28 22:41     ` Greg Kroah-Hartman
2017-07-31  6:41       ` Michal Hocko
2017-08-03 19:29         ` Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 67/90] powerpc/hotplug-mem: Fix missing endian conversion of aa_index Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 68/90] perf/core: Drop kernel samples even though :u is specified Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 69/90] drm/vmwgfx: Handle vmalloc() failure in vmw_local_fifo_reserve() Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 70/90] drm/vmwgfx: limit the number of mip levels in vmw_gb_surface_define_ioctl() Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 71/90] drm/vmwgfx: Make sure backup_handle is always valid Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 72/90] drm/nouveau/tmr: fully separate alarm execution/pending lists Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 73/90] ALSA: timer: Fix race between read and ioctl Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 74/90] ALSA: timer: Fix missing queue indices reset at SNDRV_TIMER_IOCTL_SELECT Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 75/90] ASoC: Fix use-after-free at card unregistration Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 76/90] drivers: char: mem: Fix wraparound check to allow mappings up to the end Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 77/90] tty: Drop krefs for interrupted tty lock Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 78/90] serial: sh-sci: Fix panic when serial console and DMA are enabled Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 79/90] net: better skb->sender_cpu and skb->napi_id cohabitation Greg Kroah-Hartman
2017-06-12 15:26 ` Greg Kroah-Hartman [this message]
2017-06-12 15:26 ` [PATCH 4.4 81/90] NFS: Ensure we revalidate attributes before using execute_ok() Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 82/90] NFSv4: Dont perform cached access checks before weve OPENed the file Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 83/90] Make __xfs_xattr_put_listen preperly report errors Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 84/90] arm64: hw_breakpoint: fix watchpoint matching for tagged pointers Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 85/90] arm64: entry: improve data abort handling of " Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 86/90] RDMA/qib,hfi1: Fix MR reference count leak on write with immediate Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 87/90] tracing: Use strlcpy() instead of strcpy() in __trace_find_cmdline() Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 88/90] usercopy: Adjust tests to deal with SMAP/PAN Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 89/90] arm64: armv8_deprecated: ensure extension of addr Greg Kroah-Hartman
2017-06-12 15:26 ` [PATCH 4.4 90/90] arm64: ensure extension of smp_store_release value Greg Kroah-Hartman
2017-06-12 21:53 ` [PATCH 4.4 00/90] 4.4.72-stable review Guenter Roeck
2017-06-13  0:45 ` Shuah Khan

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=20170612152601.880958587@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=mhocko@suse.com \
    --cc=srikar@linux.vnet.ibm.com \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.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).