From: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
To: Yu Zhao <yuzhao@google.com>,
Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>
Cc: "Andi Kleen" <ak@linux.intel.com>,
"Catalin Marinas" <catalin.marinas@arm.com>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
"Hillf Danton" <hdanton@sina.com>, "Jens Axboe" <axboe@kernel.dk>,
"Jesse Barnes" <jsbarnes@google.com>,
"Johannes Weiner" <hannes@cmpxchg.org>,
"Jonathan Corbet" <corbet@lwn.net>,
"Matthew Wilcox" <willy@infradead.org>,
"Mel Gorman" <mgorman@suse.de>,
"Michael Larabel" <Michael@michaellarabel.com>,
"Michal Hocko" <mhocko@kernel.org>,
"Mike Rapoport" <rppt@kernel.org>,
"Rik van Riel" <riel@surriel.com>,
"Vlastimil Babka" <vbabka@suse.cz>,
"Will Deacon" <will@kernel.org>,
"Ying Huang" <ying.huang@intel.com>,
linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
page-reclaim@google.com, x86@kernel.org,
"Yu Zhao" <yuzhao@google.com>,
"Brian Geffon" <bgeffon@google.com>,
"Jan Alexander Steffens" <heftig@archlinux.org>,
"Oleksandr Natalenko" <oleksandr@natalenko.name>,
"Steven Barrett" <steven@liquorix.net>,
"Suleiman Souhlal" <suleiman@google.com>,
"Daniel Byrne" <djbyrne@mtu.edu>,
"Donald Carr" <d@chaos-reins.com>,
"Holger Hoffstätte" <holger@applied-asynchrony.com>,
"Konstantin Kharlamov" <Hi-Angel@yandex.ru>,
"Shuang Zhai" <szhai2@cs.rochester.edu>,
"Sofia Trinh" <sofia.trinh@edi.works>,
"Vaibhav Jain" <vaibhav@linux.ibm.com>
Subject: Re: [PATCH v9 06/14] mm: multi-gen LRU: minimal implementation
Date: Tue, 22 Mar 2022 10:56:50 +0530 [thread overview]
Message-ID: <877d8m7e1x.fsf@linux.ibm.com> (raw)
In-Reply-To: <20220309021230.721028-7-yuzhao@google.com>
Yu Zhao <yuzhao@google.com> writes:
+
> +static void inc_min_seq(struct lruvec *lruvec)
> +{
> + int type;
> + struct lru_gen_struct *lrugen = &lruvec->lrugen;
> +
> + VM_BUG_ON(!seq_is_valid(lruvec));
> +
> + for (type = 0; type < ANON_AND_FILE; type++) {
> + if (get_nr_gens(lruvec, type) != MAX_NR_GENS)
> + continue;
> +
> + reset_ctrl_pos(lruvec, type, true);
> + WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1);
> + }
> +}
> +
> +static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
> +{
> + int gen, type, zone;
> + bool success = false;
> + struct lru_gen_struct *lrugen = &lruvec->lrugen;
> + DEFINE_MIN_SEQ(lruvec);
> +
> + VM_BUG_ON(!seq_is_valid(lruvec));
> +
> + for (type = !can_swap; type < ANON_AND_FILE; type++) {
> + while (min_seq[type] + MIN_NR_GENS <= lrugen->max_seq) {
> + gen = lru_gen_from_seq(min_seq[type]);
> +
> + for (zone = 0; zone < MAX_NR_ZONES; zone++) {
> + if (!list_empty(&lrugen->lists[gen][type][zone]))
> + goto next;
> + }
> +
> + min_seq[type]++;
> + }
> +next:
> + ;
> + }
> +
> + /* see the comment on lru_gen_struct */
> + if (can_swap) {
> + min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]);
> + min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]);
> + }
> +
> + for (type = !can_swap; type < ANON_AND_FILE; type++) {
> + if (min_seq[type] == lrugen->min_seq[type])
> + continue;
> +
> + reset_ctrl_pos(lruvec, type, true);
> + WRITE_ONCE(lrugen->min_seq[type], min_seq[type]);
> + success = true;
> + }
> +
> + return success;
> +}
> +
> +static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq)
> +{
> + int prev, next;
> + int type, zone;
> + struct lru_gen_struct *lrugen = &lruvec->lrugen;
> +
> + spin_lock_irq(&lruvec->lru_lock);
> +
> + VM_BUG_ON(!seq_is_valid(lruvec));
> +
> + if (max_seq != lrugen->max_seq)
> + goto unlock;
> +
> + inc_min_seq(lruvec);
Can this min seq update result in pages considered oldest become young.
ie, if we had seq value of 0 - 3 and we need ageing, the new min seq and
max_seq value will now become 1 - 4. What happens to pages in the
generation value 0 which was oldest generation earlier and is youngest
now.
> +
> + /* update the active/inactive LRU sizes for compatibility */
> + prev = lru_gen_from_seq(lrugen->max_seq - 1);
> + next = lru_gen_from_seq(lrugen->max_seq + 1);
> +
> + for (type = 0; type < ANON_AND_FILE; type++) {
> + for (zone = 0; zone < MAX_NR_ZONES; zone++) {
> + enum lru_list lru = type * LRU_INACTIVE_FILE;
> + long delta = lrugen->nr_pages[prev][type][zone] -
> + lrugen->nr_pages[next][type][zone];
> +
> + if (!delta)
> + continue;
> +
> + __update_lru_size(lruvec, lru, zone, delta);
> + __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, -delta);
> + }
> + }
> +
> + for (type = 0; type < ANON_AND_FILE; type++)
> + reset_ctrl_pos(lruvec, type, false);
> +
> + /* make sure preceding modifications appear */
> + smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1);
> +unlock:
> + spin_unlock_irq(&lruvec->lru_lock);
> +}
> +
....
+
> +static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness)
> +{
> + int type;
> + int scanned;
> + int reclaimed;
> + LIST_HEAD(list);
> + struct folio *folio;
> + enum vm_event_item item;
> + struct reclaim_stat stat;
> + struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> + struct pglist_data *pgdat = lruvec_pgdat(lruvec);
> +
> + spin_lock_irq(&lruvec->lru_lock);
> +
> + scanned = isolate_folios(lruvec, sc, swappiness, &type, &list);
> +
> + if (try_to_inc_min_seq(lruvec, swappiness))
> + scanned++;
we are doing this before we shrink the page list. Any reason to do this before?
> +
> + if (get_nr_gens(lruvec, LRU_GEN_FILE) == MIN_NR_GENS)
> + scanned = 0;
WARNING: multiple messages have this Message-ID (diff)
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
To: Yu Zhao <yuzhao@google.com>,
Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>
Cc: "Andi Kleen" <ak@linux.intel.com>,
"Catalin Marinas" <catalin.marinas@arm.com>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
"Hillf Danton" <hdanton@sina.com>, "Jens Axboe" <axboe@kernel.dk>,
"Jesse Barnes" <jsbarnes@google.com>,
"Johannes Weiner" <hannes@cmpxchg.org>,
"Jonathan Corbet" <corbet@lwn.net>,
"Matthew Wilcox" <willy@infradead.org>,
"Mel Gorman" <mgorman@suse.de>,
"Michael Larabel" <Michael@michaellarabel.com>,
"Michal Hocko" <mhocko@kernel.org>,
"Mike Rapoport" <rppt@kernel.org>,
"Rik van Riel" <riel@surriel.com>,
"Vlastimil Babka" <vbabka@suse.cz>,
"Will Deacon" <will@kernel.org>,
"Ying Huang" <ying.huang@intel.com>,
linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
page-reclaim@google.com, x86@kernel.org,
"Yu Zhao" <yuzhao@google.com>,
"Brian Geffon" <bgeffon@google.com>,
"Jan Alexander Steffens" <heftig@archlinux.org>,
"Oleksandr Natalenko" <oleksandr@natalenko.name>,
"Steven Barrett" <steven@liquorix.net>,
"Suleiman Souhlal" <suleiman@google.com>,
"Daniel Byrne" <djbyrne@mtu.edu>,
"Donald Carr" <d@chaos-reins.com>,
"Holger Hoffstätte" <holger@applied-asynchrony.com>,
"Konstantin Kharlamov" <Hi-Angel@yandex.ru>,
"Shuang Zhai" <szhai2@cs.rochester.edu>,
"Sofia Trinh" <sofia.trinh@edi.works>,
"Vaibhav Jain" <vaibhav@linux.ibm.com>
Subject: Re: [PATCH v9 06/14] mm: multi-gen LRU: minimal implementation
Date: Tue, 22 Mar 2022 10:56:50 +0530 [thread overview]
Message-ID: <877d8m7e1x.fsf@linux.ibm.com> (raw)
In-Reply-To: <20220309021230.721028-7-yuzhao@google.com>
Yu Zhao <yuzhao@google.com> writes:
+
> +static void inc_min_seq(struct lruvec *lruvec)
> +{
> + int type;
> + struct lru_gen_struct *lrugen = &lruvec->lrugen;
> +
> + VM_BUG_ON(!seq_is_valid(lruvec));
> +
> + for (type = 0; type < ANON_AND_FILE; type++) {
> + if (get_nr_gens(lruvec, type) != MAX_NR_GENS)
> + continue;
> +
> + reset_ctrl_pos(lruvec, type, true);
> + WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1);
> + }
> +}
> +
> +static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
> +{
> + int gen, type, zone;
> + bool success = false;
> + struct lru_gen_struct *lrugen = &lruvec->lrugen;
> + DEFINE_MIN_SEQ(lruvec);
> +
> + VM_BUG_ON(!seq_is_valid(lruvec));
> +
> + for (type = !can_swap; type < ANON_AND_FILE; type++) {
> + while (min_seq[type] + MIN_NR_GENS <= lrugen->max_seq) {
> + gen = lru_gen_from_seq(min_seq[type]);
> +
> + for (zone = 0; zone < MAX_NR_ZONES; zone++) {
> + if (!list_empty(&lrugen->lists[gen][type][zone]))
> + goto next;
> + }
> +
> + min_seq[type]++;
> + }
> +next:
> + ;
> + }
> +
> + /* see the comment on lru_gen_struct */
> + if (can_swap) {
> + min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]);
> + min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]);
> + }
> +
> + for (type = !can_swap; type < ANON_AND_FILE; type++) {
> + if (min_seq[type] == lrugen->min_seq[type])
> + continue;
> +
> + reset_ctrl_pos(lruvec, type, true);
> + WRITE_ONCE(lrugen->min_seq[type], min_seq[type]);
> + success = true;
> + }
> +
> + return success;
> +}
> +
> +static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq)
> +{
> + int prev, next;
> + int type, zone;
> + struct lru_gen_struct *lrugen = &lruvec->lrugen;
> +
> + spin_lock_irq(&lruvec->lru_lock);
> +
> + VM_BUG_ON(!seq_is_valid(lruvec));
> +
> + if (max_seq != lrugen->max_seq)
> + goto unlock;
> +
> + inc_min_seq(lruvec);
Can this min seq update result in pages considered oldest become young.
ie, if we had seq value of 0 - 3 and we need ageing, the new min seq and
max_seq value will now become 1 - 4. What happens to pages in the
generation value 0 which was oldest generation earlier and is youngest
now.
> +
> + /* update the active/inactive LRU sizes for compatibility */
> + prev = lru_gen_from_seq(lrugen->max_seq - 1);
> + next = lru_gen_from_seq(lrugen->max_seq + 1);
> +
> + for (type = 0; type < ANON_AND_FILE; type++) {
> + for (zone = 0; zone < MAX_NR_ZONES; zone++) {
> + enum lru_list lru = type * LRU_INACTIVE_FILE;
> + long delta = lrugen->nr_pages[prev][type][zone] -
> + lrugen->nr_pages[next][type][zone];
> +
> + if (!delta)
> + continue;
> +
> + __update_lru_size(lruvec, lru, zone, delta);
> + __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, -delta);
> + }
> + }
> +
> + for (type = 0; type < ANON_AND_FILE; type++)
> + reset_ctrl_pos(lruvec, type, false);
> +
> + /* make sure preceding modifications appear */
> + smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1);
> +unlock:
> + spin_unlock_irq(&lruvec->lru_lock);
> +}
> +
....
+
> +static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness)
> +{
> + int type;
> + int scanned;
> + int reclaimed;
> + LIST_HEAD(list);
> + struct folio *folio;
> + enum vm_event_item item;
> + struct reclaim_stat stat;
> + struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> + struct pglist_data *pgdat = lruvec_pgdat(lruvec);
> +
> + spin_lock_irq(&lruvec->lru_lock);
> +
> + scanned = isolate_folios(lruvec, sc, swappiness, &type, &list);
> +
> + if (try_to_inc_min_seq(lruvec, swappiness))
> + scanned++;
we are doing this before we shrink the page list. Any reason to do this before?
> +
> + if (get_nr_gens(lruvec, LRU_GEN_FILE) == MIN_NR_GENS)
> + scanned = 0;
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2022-03-22 5:28 UTC|newest]
Thread overview: 120+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-09 2:12 [PATCH v9 00/14] Multi-Gen LRU Framework Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 01/14] mm: x86, arm64: add arch_has_hw_pte_young() Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-11 10:55 ` Barry Song
2022-03-11 10:55 ` Barry Song
2022-03-11 22:57 ` Yu Zhao
2022-03-11 22:57 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 02/14] mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-16 22:15 ` Barry Song
2022-03-16 22:15 ` Barry Song
2022-03-09 2:12 ` [PATCH v9 03/14] mm/vmscan.c: refactor shrink_node() Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-18 1:15 ` Barry Song
2022-03-18 1:15 ` Barry Song
2022-03-09 2:12 ` [PATCH v9 04/14] Revert "include/linux/mm_inline.h: fold __update_lru_size() into its sole caller" Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 05/14] mm: multi-gen LRU: groundwork Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-14 8:08 ` Huang, Ying
2022-03-14 8:08 ` Huang, Ying
2022-03-14 9:30 ` Yu Zhao
2022-03-14 9:30 ` Yu Zhao
2022-03-15 0:34 ` Huang, Ying
2022-03-15 0:34 ` Huang, Ying
2022-03-15 0:50 ` Yu Zhao
2022-03-15 0:50 ` Yu Zhao
2022-03-21 18:58 ` Justin Forbes
2022-03-21 18:58 ` Justin Forbes
2022-03-21 19:17 ` Prarit Bhargava
2022-03-21 19:17 ` Prarit Bhargava
2022-03-22 4:52 ` Yu Zhao
2022-03-22 4:52 ` Yu Zhao
2022-03-16 23:25 ` Barry Song
2022-03-16 23:25 ` Barry Song
2022-03-21 9:04 ` Yu Zhao
2022-03-21 9:04 ` Yu Zhao
2022-03-21 11:47 ` Barry Song
2022-03-21 11:47 ` Barry Song
2022-03-09 2:12 ` [PATCH v9 06/14] mm: multi-gen LRU: minimal implementation Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-16 5:55 ` Huang, Ying
2022-03-16 5:55 ` Huang, Ying
2022-03-16 7:54 ` Yu Zhao
2022-03-16 7:54 ` Yu Zhao
2022-03-19 3:01 ` Barry Song
2022-03-19 3:01 ` Barry Song
2022-03-19 3:11 ` Yu Zhao
2022-03-19 3:11 ` Yu Zhao
2022-03-23 7:47 ` Barry Song
2022-03-23 7:47 ` Barry Song
2022-03-24 6:24 ` Yu Zhao
2022-03-24 6:24 ` Yu Zhao
2022-03-24 8:13 ` Barry Song
2022-03-24 8:13 ` Barry Song
2022-03-19 10:14 ` Barry Song
2022-03-19 10:14 ` Barry Song
2022-03-21 23:51 ` Yu Zhao
2022-03-21 23:51 ` Yu Zhao
2022-03-19 11:15 ` Barry Song
2022-03-19 11:15 ` Barry Song
2022-03-22 0:30 ` Yu Zhao
2022-03-22 0:30 ` Yu Zhao
2022-03-21 12:51 ` Aneesh Kumar K.V
2022-03-21 12:51 ` Aneesh Kumar K.V
2022-03-22 4:02 ` Yu Zhao
2022-03-22 4:02 ` Yu Zhao
2022-03-21 13:01 ` Aneesh Kumar K.V
2022-03-21 13:01 ` Aneesh Kumar K.V
2022-03-22 4:39 ` Yu Zhao
2022-03-22 4:39 ` Yu Zhao
2022-03-22 5:26 ` Aneesh Kumar K.V [this message]
2022-03-22 5:26 ` Aneesh Kumar K.V
2022-03-22 5:55 ` Yu Zhao
2022-03-22 5:55 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 07/14] mm: multi-gen LRU: exploit locality in rmap Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-04-07 2:29 ` Barry Song
2022-04-07 2:29 ` Barry Song
2022-04-07 3:04 ` Yu Zhao
2022-04-07 3:04 ` Yu Zhao
2022-04-07 3:46 ` Barry Song
2022-04-07 3:46 ` Barry Song
2022-04-07 23:51 ` Yu Zhao
2022-04-07 23:51 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 08/14] mm: multi-gen LRU: support page table walks Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 09/14] mm: multi-gen LRU: optimize multiple memcgs Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 10/14] mm: multi-gen LRU: kill switch Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-22 7:47 ` Barry Song
2022-03-22 7:47 ` Barry Song
2022-03-22 8:20 ` Yu Zhao
2022-03-22 8:20 ` Yu Zhao
2022-03-22 8:45 ` Barry Song
2022-03-22 8:45 ` Barry Song
2022-03-22 9:00 ` Yu Zhao
2022-03-22 9:00 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 11/14] mm: multi-gen LRU: thrashing prevention Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-22 7:22 ` Barry Song
2022-03-22 7:22 ` Barry Song
2022-03-22 8:14 ` Yu Zhao
2022-03-22 8:14 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 12/14] mm: multi-gen LRU: debugfs interface Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 13/14] mm: multi-gen LRU: admin guide Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-10 12:29 ` Mike Rapoport
2022-03-10 12:29 ` Mike Rapoport
2022-03-11 0:37 ` Yu Zhao
2022-03-11 0:37 ` Yu Zhao
2022-03-09 2:12 ` [PATCH v9 14/14] mm: multi-gen LRU: design doc Yu Zhao
2022-03-09 2:12 ` Yu Zhao
2022-03-11 8:22 ` Mike Rapoport
2022-03-11 8:22 ` Mike Rapoport
2022-03-11 9:38 ` Yu Zhao
2022-03-11 9:38 ` Yu Zhao
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=877d8m7e1x.fsf@linux.ibm.com \
--to=aneesh.kumar@linux.ibm.com \
--cc=Hi-Angel@yandex.ru \
--cc=Michael@michaellarabel.com \
--cc=ak@linux.intel.com \
--cc=akpm@linux-foundation.org \
--cc=axboe@kernel.dk \
--cc=bgeffon@google.com \
--cc=catalin.marinas@arm.com \
--cc=corbet@lwn.net \
--cc=d@chaos-reins.com \
--cc=dave.hansen@linux.intel.com \
--cc=djbyrne@mtu.edu \
--cc=hannes@cmpxchg.org \
--cc=hdanton@sina.com \
--cc=heftig@archlinux.org \
--cc=holger@applied-asynchrony.com \
--cc=jsbarnes@google.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mgorman@suse.de \
--cc=mhocko@kernel.org \
--cc=oleksandr@natalenko.name \
--cc=page-reclaim@google.com \
--cc=riel@surriel.com \
--cc=rppt@kernel.org \
--cc=sofia.trinh@edi.works \
--cc=steven@liquorix.net \
--cc=suleiman@google.com \
--cc=szhai2@cs.rochester.edu \
--cc=torvalds@linux-foundation.org \
--cc=vaibhav@linux.ibm.com \
--cc=vbabka@suse.cz \
--cc=will@kernel.org \
--cc=willy@infradead.org \
--cc=x86@kernel.org \
--cc=ying.huang@intel.com \
--cc=yuzhao@google.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.