public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
	akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
	Mel Gorman <mel@csn.ul.ie>,
	Christoph Lameter <cl@linux-foundation.org>,
	KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
	Wu Fengguang <fengguang.wu@intel.com>
Subject: [patch 100/108] vmscan: properly account for the number of page cache pages zone_reclaim() can reclaim
Date: Tue, 30 Jun 2009 17:24:29 -0700	[thread overview]
Message-ID: <20090701002443.184726273@mini.kroah.org> (raw)
In-Reply-To: <20090701002838.GA7100@kroah.com>

[-- Attachment #1: vmscan-properly-account-for-the-number-of-page-cache-pages-zone_reclaim-can-reclaim.patch --]
[-- Type: text/plain, Size: 7924 bytes --]

2.6.30-stable review patch.  If anyone has any objections, please let us know.

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

From: Mel Gorman <mel@csn.ul.ie>

commit 90afa5de6f3fa89a733861e843377302479fcf7e upstream.

A bug was brought to my attention against a distro kernel but it affects
mainline and I believe problems like this have been reported in various
guises on the mailing lists although I don't have specific examples at the
moment.

The reported problem was that malloc() stalled for a long time (minutes in
some cases) if a large tmpfs mount was occupying a large percentage of
memory overall.  The pages did not get cleaned or reclaimed by
zone_reclaim() because the zone_reclaim_mode was unsuitable, but the lists
are uselessly scanned frequencly making the CPU spin at near 100%.

This patchset intends to address that bug and bring the behaviour of
zone_reclaim() more in line with expectations which were noticed during
investigation.  It is based on top of mmotm and takes advantage of
Kosaki's work with respect to zone_reclaim().

Patch 1 fixes the heuristics that zone_reclaim() uses to determine if the
	scan should go ahead. The broken heuristic is what was causing the
	malloc() stall as it uselessly scanned the LRU constantly. Currently,
	zone_reclaim is assuming zone_reclaim_mode is 1 and historically it
	could not deal with tmpfs pages at all. This fixes up the heuristic so
	that an unnecessary scan is more likely to be correctly avoided.

Patch 2 notes that zone_reclaim() returning a failure automatically means
	the zone is marked full. This is not always true. It could have
	failed because the GFP mask or zone_reclaim_mode were unsuitable.

Patch 3 introduces a counter zreclaim_failed that will increment each
	time the zone_reclaim scan-avoidance heuristics fail. If that
	counter is rapidly increasing, then zone_reclaim_mode should be
	set to 0 as a temporarily resolution and a bug reported because
	the scan-avoidance heuristic is still broken.

This patch:

On NUMA machines, the administrator can configure zone_reclaim_mode that
is a more targetted form of direct reclaim.  On machines with large NUMA
distances for example, a zone_reclaim_mode defaults to 1 meaning that
clean unmapped pages will be reclaimed if the zone watermarks are not
being met.

There is a heuristic that determines if the scan is worthwhile but the
problem is that the heuristic is not being properly applied and is
basically assuming zone_reclaim_mode is 1 if it is enabled.  The lack of
proper detection can manfiest as high CPU usage as the LRU list is scanned
uselessly.

Historically, once enabled it was depending on NR_FILE_PAGES which may
include swapcache pages that the reclaim_mode cannot deal with.  Patch
vmscan-change-the-number-of-the-unmapped-files-in-zone-reclaim.patch by
Kosaki Motohiro noted that zone_page_state(zone, NR_FILE_PAGES) included
pages that were not file-backed such as swapcache and made a calculation
based on the inactive, active and mapped files.  This is far superior when
zone_reclaim==1 but if RECLAIM_SWAP is set, then NR_FILE_PAGES is a
reasonable starting figure.

This patch alters how zone_reclaim() works out how many pages it might be
able to reclaim given the current reclaim_mode.  If RECLAIM_SWAP is set in
the reclaim_mode it will either consider NR_FILE_PAGES as potential
candidates or else use NR_{IN}ACTIVE}_PAGES-NR_FILE_MAPPED to discount
swapcache and other non-file-backed pages.  If RECLAIM_WRITE is not set,
then NR_FILE_DIRTY number of pages are not candidates.  If RECLAIM_SWAP is
not set, then NR_FILE_MAPPED are not.

[kosaki.motohiro@jp.fujitsu.com: Estimate unmapped pages minus tmpfs pages]
[fengguang.wu@intel.com: Fix underflow problem in Kosaki's estimate]
Signed-off-by: Mel Gorman <mel@csn.ul.ie>
Reviewed-by: Rik van Riel <riel@redhat.com>
Acked-by: Christoph Lameter <cl@linux-foundation.org>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Wu Fengguang <fengguang.wu@intel.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@suse.de>

---
 Documentation/sysctl/vm.txt |   12 ++++++----
 mm/vmscan.c                 |   52 ++++++++++++++++++++++++++++++++++++++------
 2 files changed, 53 insertions(+), 11 deletions(-)

--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -314,10 +314,14 @@ min_unmapped_ratio:
 
 This is available only on NUMA kernels.
 
-A percentage of the total pages in each zone.  Zone reclaim will only
-occur if more than this percentage of pages are file backed and unmapped.
-This is to insure that a minimal amount of local pages is still available for
-file I/O even if the node is overallocated.
+This is a percentage of the total pages in each zone. Zone reclaim will
+only occur if more than this percentage of pages are in a state that
+zone_reclaim_mode allows to be reclaimed.
+
+If zone_reclaim_mode has the value 4 OR'd, then the percentage is compared
+against all file-backed unmapped pages including swapcache pages and tmpfs
+files. Otherwise, only unmapped pages backed by normal files but not tmpfs
+files and similar are considered.
 
 The default is 1 percent.
 
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2290,6 +2290,48 @@ int sysctl_min_unmapped_ratio = 1;
  */
 int sysctl_min_slab_ratio = 5;
 
+static inline unsigned long zone_unmapped_file_pages(struct zone *zone)
+{
+	unsigned long file_mapped = zone_page_state(zone, NR_FILE_MAPPED);
+	unsigned long file_lru = zone_page_state(zone, NR_INACTIVE_FILE) +
+		zone_page_state(zone, NR_ACTIVE_FILE);
+
+	/*
+	 * It's possible for there to be more file mapped pages than
+	 * accounted for by the pages on the file LRU lists because
+	 * tmpfs pages accounted for as ANON can also be FILE_MAPPED
+	 */
+	return (file_lru > file_mapped) ? (file_lru - file_mapped) : 0;
+}
+
+/* Work out how many page cache pages we can reclaim in this reclaim_mode */
+static long zone_pagecache_reclaimable(struct zone *zone)
+{
+	long nr_pagecache_reclaimable;
+	long delta = 0;
+
+	/*
+	 * If RECLAIM_SWAP is set, then all file pages are considered
+	 * potentially reclaimable. Otherwise, we have to worry about
+	 * pages like swapcache and zone_unmapped_file_pages() provides
+	 * a better estimate
+	 */
+	if (zone_reclaim_mode & RECLAIM_SWAP)
+		nr_pagecache_reclaimable = zone_page_state(zone, NR_FILE_PAGES);
+	else
+		nr_pagecache_reclaimable = zone_unmapped_file_pages(zone);
+
+	/* If we can't clean pages, remove dirty pages from consideration */
+	if (!(zone_reclaim_mode & RECLAIM_WRITE))
+		delta += zone_page_state(zone, NR_FILE_DIRTY);
+
+	/* Watch for any possible underflows due to delta */
+	if (unlikely(delta > nr_pagecache_reclaimable))
+		delta = nr_pagecache_reclaimable;
+
+	return nr_pagecache_reclaimable - delta;
+}
+
 /*
  * Try to free up some pages from this zone through reclaim.
  */
@@ -2324,9 +2366,7 @@ static int __zone_reclaim(struct zone *z
 	reclaim_state.reclaimed_slab = 0;
 	p->reclaim_state = &reclaim_state;
 
-	if (zone_page_state(zone, NR_FILE_PAGES) -
-		zone_page_state(zone, NR_FILE_MAPPED) >
-		zone->min_unmapped_pages) {
+	if (zone_pagecache_reclaimable(zone) > zone->min_unmapped_pages) {
 		/*
 		 * Free memory by calling shrink zone with increasing
 		 * priorities until we have enough memory freed.
@@ -2384,10 +2424,8 @@ int zone_reclaim(struct zone *zone, gfp_
 	 * if less than a specified percentage of the zone is used by
 	 * unmapped file backed pages.
 	 */
-	if (zone_page_state(zone, NR_FILE_PAGES) -
-	    zone_page_state(zone, NR_FILE_MAPPED) <= zone->min_unmapped_pages
-	    && zone_page_state(zone, NR_SLAB_RECLAIMABLE)
-			<= zone->min_slab_pages)
+	if (zone_pagecache_reclaimable(zone) <= zone->min_unmapped_pages &&
+	    zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages)
 		return 0;
 
 	if (zone_is_all_unreclaimable(zone))



  parent reply	other threads:[~2009-07-01  1:16 UTC|newest]

Thread overview: 124+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20090701002249.937782934@mini.kroah.org>
2009-07-01  0:28 ` [patch 000/108] 2.6.30-stable review Greg KH
2009-07-01  0:22   ` [patch 001/108] firmware_map: fix hang with x86/32bit Greg KH
2009-07-01  0:22   ` [patch 002/108] fs: remove incorrect I_NEW warnings Greg KH
2009-07-01  0:22   ` [patch 003/108] PCI: disable ASPM on VIA root-port-under-bridge configurations Greg KH
2009-07-01  0:22   ` [patch 004/108] KVM: VMX: Fix handling of a fault during NMI unblocked due to IRET Greg KH
2009-07-01  0:22   ` [patch 005/108] KVM: Move "exit due to NMI" handling into vmx_complete_interrupts() Greg KH
2009-07-01  0:22   ` [patch 006/108] KVM: Add VT-x machine check support Greg KH
2009-07-01  0:22   ` [patch 007/108] KVM: Disable large pages on misaligned memory slots Greg KH
2009-07-01  0:22   ` [patch 008/108] KVM: Prevent overflow in largepages calculation Greg KH
2009-07-01  0:22   ` [patch 009/108] KVM: x86: check for cr3 validity in ioctl_set_sregs Greg KH
2009-07-01  0:22   ` [patch 010/108] KVM: VMX: Handle vmx instruction vmexits Greg KH
2009-07-01  0:23   ` [patch 011/108] KVM: protect concurrent make_all_cpus_request Greg KH
2009-07-01  0:23   ` [patch 012/108] KVM: Fix dirty bit tracking for slots with large pages Greg KH
2009-07-01  0:23   ` [patch 013/108] IMA: use current_cred() instead of current->cred Greg KH
2009-07-01  0:23   ` [patch 014/108] IMA: Handle dentry_open failures Greg KH
2009-07-01  0:23   ` [patch 015/108] IMA: open all files O_LARGEFILE Greg KH
2009-07-01  0:23   ` [patch 016/108] e1000e: stop unnecessary polling when using msi-x Greg KH
2009-07-01  0:23   ` [patch 017/108] pegasus usb-net: Fix endianness bugs Greg KH
2009-07-01  0:23   ` [patch 018/108] ipv4: fix NULL pointer + success return in route lookup path Greg KH
2009-07-01  0:23   ` [patch 019/108] ipv4 routing: Ensure that route cache entries are usable and reclaimable with caching is off Greg KH
2009-07-01  0:23   ` [patch 020/108] sky2: dont look for VPD size Greg KH
2009-07-01  0:23   ` [patch 021/108] tun: Fix unregister race Greg KH
2009-07-01  0:23   ` [patch 022/108] via-velocity: Fix velocity driver unmapping incorrect size Greg KH
2009-07-01  0:23   ` [patch 023/108] x25: Fix sleep from timer on socket destroy Greg KH
2009-07-01  0:23   ` [patch 024/108] bonding: fix multiple module load problem Greg KH
2009-07-01  0:23   ` [patch 025/108] dma-debug: change hash_bucket_find from first-fit to best-fit Greg KH
2009-07-01  0:23   ` [patch 026/108] char: moxa, prevent opening unavailable ports Greg KH
2009-07-01  0:23   ` [patch 027/108] serial: refactor ASYNC_ flags Greg KH
2009-07-01  0:23   ` [patch 028/108] rocket: fix test_bit parameters Greg KH
2009-07-01  0:23   ` [patch 029/108] epca: " Greg KH
2009-07-01  0:23   ` [patch 030/108] x86: Detect use of extended APIC ID for AMD CPUs Greg KH
2009-07-01  0:23   ` [patch 031/108] USB: usbtmc: fix switch statment Greg KH
2009-07-01  0:23   ` [patch 032/108] DVB: lgdt3305: fix 64bit division in function lgdt3305_set_if Greg KH
2009-07-01  0:23   ` [patch 033/108] V4L: ivtv/cx18: fix regression: class controls are no longer seen Greg KH
2009-07-01  0:23   ` [patch 034/108] V4L: pvrusb2: Fix hardware scaling when used with cx25840 Greg KH
2009-07-01  0:23   ` [patch 035/108] V4L: pvrusb2: Re-fix hardware scaling on video standard change Greg KH
2009-07-01  0:23   ` [patch 036/108] V4L: i2c modules must be linked before the v4l2 drivers Greg KH
2009-07-01  0:23   ` [patch 037/108] sym53c8xx: ratelimit parity errors Greg KH
2009-07-01  0:23   ` [patch 038/108] ISDN: Fix DMA alloc for hfcpci Greg KH
2009-07-01  0:23   ` [patch 039/108] jfs: fix regression preventing coalescing of extents Greg KH
2009-07-01  0:23   ` [patch 040/108] spi: takes size of a pointer to determine the size of the pointed-to type Greg KH
2009-07-01  0:23   ` [patch 041/108] serial: bfin_5xx: add missing spin_lock init Greg KH
2009-07-01  0:23   ` [patch 042/108] x86: memtest: remove 64-bit division Greg KH
2009-07-01  0:23   ` [patch 043/108] x86: Fix UV BAU activation descriptor init Greg KH
2009-07-01  0:23   ` [patch 044/108] x86, UV: Fix macros for multiple coherency domains Greg KH
2009-07-01  0:23   ` [patch 045/108] x86: enable GART-IOMMU only after setting up protection methods Greg KH
2009-07-01  0:23   ` [patch 046/108] x86: move rdtsc_barrier() into the TSC vread method Greg KH
2009-07-01  0:23   ` [patch 047/108] x86: Fix uv bau sending buffer initialization Greg KH
2009-07-01  0:23   ` [patch 048/108] x86: Add quirk for reboot stalls on a Dell Optiplex 360 Greg KH
2009-07-01  0:23   ` [patch 049/108] x86: handle initrd that extends into unusable memory Greg KH
2009-07-01  0:23   ` [patch 050/108] ALSA: ca0106 - Add missing registrations of vmaster controls Greg KH
2009-07-01  0:23   ` [patch 051/108] ALSA: intel8x0 - Fix PCM position craziness Greg KH
2009-07-01  0:23   ` [patch 052/108] ALSA: hda - Get back Input Source for ALC262 toshiba-s06 model Greg KH
2009-07-01  0:23   ` [patch 053/108] ALSA: hda - Add quirk for Sony VAIO Z21MN Greg KH
2009-07-01  0:23   ` [patch 054/108] ALSA: cmi8330: fix MPU-401 PnP init copy&paste bug Greg KH
2009-07-01  0:23   ` [patch 055/108] x86: hpet: Mark per cpu interrupts IRQF_TIMER to prevent resume failure Greg KH
2009-07-01  0:23   ` [patch 056/108] ARM: 5545/2: add flush_kernel_dcache_page() for ARM Greg KH
2009-07-01  0:23   ` [patch 057/108] IB/mlx4: Add strong ordering to local inval and fast reg work requests Greg KH
2009-07-01  0:23   ` [patch 058/108] epoll: fix nested calls support Greg KH
2009-07-01  0:23   ` [patch 059/108] lockdep: Select frame pointers on x86 Greg KH
2009-07-01  0:23   ` [patch 060/108] ASoC: Remove odd bit clock ratios for WM8903 Greg KH
2009-07-01  0:23   ` [patch 061/108] ramfs: ignore unknown mount options Greg KH
2009-07-01  0:23   ` [patch 062/108] mac80211: fix minstrel single-rate memory corruption Greg KH
2009-07-01  0:23   ` [patch 063/108] cfg80211: fix for duplicate userspace replies Greg KH
2009-07-01  0:23   ` [patch 064/108] cfg80211: cleanup return calls on nl80211_set_reg() Greg KH
2009-07-01  0:23   ` [patch 065/108] cfg80211: return immediately if num reg rules > NL80211_MAX_SUPP_REG_RULES Greg KH
2009-07-01  0:23   ` [patch 066/108] cfg80211: fix in nl80211_set_reg() Greg KH
2009-07-01  0:23   ` [patch 067/108] ath9k: Fix bug when using a card with a busted EEPROM Greg KH
2009-07-01  0:23   ` [patch 068/108] ath9k: Fix bug in calibration initialization Greg KH
2009-07-01  0:23   ` [patch 069/108] ath9k: Fix bug in determining calibration support Greg KH
2009-07-01  0:23   ` [patch 070/108] ath9k: Fix bug in checking HT flag Greg KH
2009-07-01  0:24   ` [patch 071/108] ath9k: Fix bug in scan termination Greg KH
2009-07-01  0:24   ` [patch 072/108] ath9k: Fix memleak on TX DMA failure Greg KH
2009-07-01  0:24   ` [patch 073/108] ath9k: Initialize ANI timers Greg KH
2009-07-01  0:24   ` [patch 074/108] ath9k: Fix PCI FATAL interrupts by restoring RETRY_TIMEOUT disabling Greg KH
2009-07-01  0:24   ` [patch 075/108] crypto: aes-ni - Fix cbc mode IV saving Greg KH
2009-07-01  0:24   ` [patch 076/108] md/raid5: add missing call to schedule() after prepare_to_wait() Greg KH
2009-07-01  0:24   ` [patch 077/108] tracing/urgent: fix unbalanced ftrace_start_up Greg KH
2009-07-01  0:24   ` [patch 078/108] cifs: fix fh_mutex locking in cifs_reopen_file Greg KH
2009-07-01  0:24   ` [patch 079/108] vt_ioctl: fix lock imbalance Greg KH
2009-07-01  0:24   ` [patch 080/108] x86: Fix non-lazy GS handling in sys_vm86() Greg KH
2009-07-01  0:24   ` [patch 081/108] x86: Set cpu_llc_id on AMD CPUs Greg KH
2009-07-01  0:24   ` [patch 082/108] usb-serial: replace shutdown with disconnect, release Greg KH
2009-07-01  0:24   ` [patch 083/108] pcmcia/cm4000: fix lock imbalance Greg KH
2009-07-01  0:24   ` [patch 084/108] n_r3964: " Greg KH
2009-07-01  0:24   ` [patch 085/108] parport_pc: set properly the dma_mask for parport_pc device Greg KH
2009-07-01  0:24   ` [patch 086/108] parport_pc: after superio probing restore original register values Greg KH
2009-07-01  0:24   ` [patch 087/108] mv643xx_eth: fix unicast filter programming in promiscuous mode Greg KH
2009-07-01  0:24   ` [patch 088/108] ath5k: avoid PCI FATAL interrupts by restoring RETRY_TIMEOUT disabling Greg KH
2009-07-01  0:24   ` [patch 089/108] sound: seq_midi_event: fix decoding of (N)RPN events Greg KH
2009-07-01  0:24   ` [patch 090/108] PCI PM: Fix handling of devices without PM support by pci_target_state() Greg KH
2009-07-01  0:24   ` [patch 091/108] PCI PM: Follow PCI_PM_CTRL_NO_SOFT_RESET during transitions from D3 Greg KH
2009-07-01  0:24   ` [patch 092/108] qla2xxx: Correct (again) overflow during dump-processing on large-memory ISP23xx parts Greg KH
2009-07-01  0:24   ` [patch 093/108] mm: fix handling of pagesets for downed cpus Greg KH
2009-07-01  0:24   ` [patch 094/108] dm mpath: validate hw_handler argument count Greg KH
2009-07-01  0:24   ` [patch 095/108] dm mpath: validate table " Greg KH
2009-07-01  0:24   ` [patch 096/108] dm: sysfs skip output when device is being destroyed Greg KH
2009-07-01  0:24   ` [patch 097/108] dm mpath: flush keventd queue in destructor Greg KH
2009-07-01  0:24   ` [patch 098/108] dm exception store: fix exstore lookup to be case insensitive Greg KH
2009-07-01  7:11     ` Milan Broz
2009-07-01 17:26       ` [Stable-review] " Greg KH
2009-07-01  0:24   ` [patch 099/108] dm: use i_size_read Greg KH
2009-07-01  0:24   ` Greg KH [this message]
2009-07-01  0:24   ` [patch 101/108] vmscan: count the number of times zone_reclaim() scans and fails Greg KH
2009-07-01  0:24   ` [patch 102/108] lib/genalloc.c: remove unmatched write_lock() in gen_pool_destroy Greg KH
2009-07-01  0:24   ` [patch 103/108] CONFIG_FILE_LOCKING should not depend on CONFIG_BLOCK Greg KH
2009-07-01  0:24   ` [patch 104/108] serial: bfin_5xx: fix building as module when early printk is enabled Greg KH
2009-07-01  0:24   ` [patch 105/108] ocfs2: Fix ocfs2_osb_dump() Greg KH
2009-07-01  0:24   ` [patch 106/108] ide-cd: prevent null pointer deref via cdrom_newpc_intr Greg KH
2009-07-01  0:24   ` [patch 107/108] drm/i915: correct suspend/resume ordering Greg KH
2009-07-01  0:24   ` [patch 108/108] KVM: x86: silence preempt warning on kvm_write_guest_time Greg KH
2009-07-01 11:22   ` [patch 000/108] 2.6.30-stable review Julien BLACHE
2009-07-01 15:02     ` Stefan Richter
2009-07-01 15:41       ` Julien BLACHE
2009-07-01 16:22         ` [Stable-review] " Luis R. Rodriguez
2009-07-01 16:27           ` Julien BLACHE
2009-07-01 16:43             ` Stefan Richter
2009-07-01 17:21     ` Greg KH
2009-07-01 18:10   ` Greg KH
2009-07-01 18:12     ` [patch 109/108] bsdacct: fix access to invalid filp in acct_on() Greg KH
2009-07-01 18:13     ` [patch 110/108] dm exception store: really fix type lookup Greg KH
2009-07-01 18:14     ` [patch 111/108] xfs: fix freeing memory in xfs_getbmap() Greg KH
2009-07-01 18:33     ` [patch 000/108] 2.6.30-stable review Greg KH
2009-07-01 18:24   ` [Stable-review] " Luis R. Rodriguez

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=20090701002443.184726273@mini.kroah.org \
    --to=gregkh@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=cl@linux-foundation.org \
    --cc=fengguang.wu@intel.com \
    --cc=kosaki.motohiro@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mel@csn.ul.ie \
    --cc=stable-review@kernel.org \
    --cc=stable@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