From: Dan Williams <dan.j.williams@intel.com>
To: Joao Martins <joao.m.martins@oracle.com>
Cc: Linux MM <linux-mm@kvack.org>,
Vishal Verma <vishal.l.verma@intel.com>,
Dave Jiang <dave.jiang@intel.com>,
Naoya Horiguchi <naoya.horiguchi@nec.com>,
Matthew Wilcox <willy@infradead.org>,
Jason Gunthorpe <jgg@ziepe.ca>,
John Hubbard <jhubbard@nvidia.com>,
Jane Chu <jane.chu@oracle.com>,
Muchun Song <songmuchun@bytedance.com>,
Mike Kravetz <mike.kravetz@oracle.com>,
Andrew Morton <akpm@linux-foundation.org>,
Jonathan Corbet <corbet@lwn.net>,
Linux NVDIMM <nvdimm@lists.linux.dev>,
Linux Doc Mailing List <linux-doc@vger.kernel.org>
Subject: Re: [PATCH v3 07/14] mm/hugetlb_vmemmap: move comment block to Documentation/vm
Date: Tue, 27 Jul 2021 23:09:09 -0700 [thread overview]
Message-ID: <CAPcyv4hMUY+wtB1P4SbzesOB45fo7bZzg14kdX86Hrnd4A-RBQ@mail.gmail.com> (raw)
In-Reply-To: <20210714193542.21857-8-joao.m.martins@oracle.com>
On Wed, Jul 14, 2021 at 12:36 PM Joao Martins <joao.m.martins@oracle.com> wrote:
>
> In preparation for device-dax for using hugetlbfs compound page tail
> deduplication technique, move the comment block explanation into a
> common place in Documentation/vm.
>
> Cc: Muchun Song <songmuchun@bytedance.com>
> Cc: Mike Kravetz <mike.kravetz@oracle.com>
> Suggested-by: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Looks good,
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
> ---
> Documentation/vm/index.rst | 1 +
> Documentation/vm/vmemmap_dedup.rst | 170 +++++++++++++++++++++++++++++
> mm/hugetlb_vmemmap.c | 162 +--------------------------
> 3 files changed, 172 insertions(+), 161 deletions(-)
> create mode 100644 Documentation/vm/vmemmap_dedup.rst
>
> diff --git a/Documentation/vm/index.rst b/Documentation/vm/index.rst
> index eff5fbd492d0..edd690afd890 100644
> --- a/Documentation/vm/index.rst
> +++ b/Documentation/vm/index.rst
> @@ -51,5 +51,6 @@ descriptions of data structures and algorithms.
> split_page_table_lock
> transhuge
> unevictable-lru
> + vmemmap_dedup
> z3fold
> zsmalloc
> diff --git a/Documentation/vm/vmemmap_dedup.rst b/Documentation/vm/vmemmap_dedup.rst
> new file mode 100644
> index 000000000000..215ae2ef3bce
> --- /dev/null
> +++ b/Documentation/vm/vmemmap_dedup.rst
> @@ -0,0 +1,170 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +.. _vmemmap_dedup:
> +
> +==================================
> +Free some vmemmap pages of HugeTLB
> +==================================
> +
> +The struct page structures (page structs) are used to describe a physical
> +page frame. By default, there is a one-to-one mapping from a page frame to
> +it's corresponding page struct.
> +
> +HugeTLB pages consist of multiple base page size pages and is supported by
> +many architectures. See hugetlbpage.rst in the Documentation directory for
> +more details. On the x86-64 architecture, HugeTLB pages of size 2MB and 1GB
> +are currently supported. Since the base page size on x86 is 4KB, a 2MB
> +HugeTLB page consists of 512 base pages and a 1GB HugeTLB page consists of
> +4096 base pages. For each base page, there is a corresponding page struct.
> +
> +Within the HugeTLB subsystem, only the first 4 page structs are used to
> +contain unique information about a HugeTLB page. __NR_USED_SUBPAGE provides
> +this upper limit. The only 'useful' information in the remaining page structs
> +is the compound_head field, and this field is the same for all tail pages.
> +
> +By removing redundant page structs for HugeTLB pages, memory can be returned
> +to the buddy allocator for other uses.
> +
> +Different architectures support different HugeTLB pages. For example, the
> +following table is the HugeTLB page size supported by x86 and arm64
> +architectures. Because arm64 supports 4k, 16k, and 64k base pages and
> +supports contiguous entries, so it supports many kinds of sizes of HugeTLB
> +page.
> +
> ++--------------+-----------+-----------------------------------------------+
> +| Architecture | Page Size | HugeTLB Page Size |
> ++--------------+-----------+-----------+-----------+-----------+-----------+
> +| x86-64 | 4KB | 2MB | 1GB | | |
> ++--------------+-----------+-----------+-----------+-----------+-----------+
> +| | 4KB | 64KB | 2MB | 32MB | 1GB |
> +| +-----------+-----------+-----------+-----------+-----------+
> +| arm64 | 16KB | 2MB | 32MB | 1GB | |
> +| +-----------+-----------+-----------+-----------+-----------+
> +| | 64KB | 2MB | 512MB | 16GB | |
> ++--------------+-----------+-----------+-----------+-----------+-----------+
> +
> +When the system boot up, every HugeTLB page has more than one struct page
> +structs which size is (unit: pages):
> +
> + struct_size = HugeTLB_Size / PAGE_SIZE * sizeof(struct page) / PAGE_SIZE
> +
> +Where HugeTLB_Size is the size of the HugeTLB page. We know that the size
> +of the HugeTLB page is always n times PAGE_SIZE. So we can get the following
> +relationship.
> +
> + HugeTLB_Size = n * PAGE_SIZE
> +
> +Then,
> +
> + struct_size = n * PAGE_SIZE / PAGE_SIZE * sizeof(struct page) / PAGE_SIZE
> + = n * sizeof(struct page) / PAGE_SIZE
> +
> +We can use huge mapping at the pud/pmd level for the HugeTLB page.
> +
> +For the HugeTLB page of the pmd level mapping, then
> +
> + struct_size = n * sizeof(struct page) / PAGE_SIZE
> + = PAGE_SIZE / sizeof(pte_t) * sizeof(struct page) / PAGE_SIZE
> + = sizeof(struct page) / sizeof(pte_t)
> + = 64 / 8
> + = 8 (pages)
> +
> +Where n is how many pte entries which one page can contains. So the value of
> +n is (PAGE_SIZE / sizeof(pte_t)).
> +
> +This optimization only supports 64-bit system, so the value of sizeof(pte_t)
> +is 8. And this optimization also applicable only when the size of struct page
> +is a power of two. In most cases, the size of struct page is 64 bytes (e.g.
> +x86-64 and arm64). So if we use pmd level mapping for a HugeTLB page, the
> +size of struct page structs of it is 8 page frames which size depends on the
> +size of the base page.
> +
> +For the HugeTLB page of the pud level mapping, then
> +
> + struct_size = PAGE_SIZE / sizeof(pmd_t) * struct_size(pmd)
> + = PAGE_SIZE / 8 * 8 (pages)
> + = PAGE_SIZE (pages)
> +
> +Where the struct_size(pmd) is the size of the struct page structs of a
> +HugeTLB page of the pmd level mapping.
> +
> +E.g.: A 2MB HugeTLB page on x86_64 consists in 8 page frames while 1GB
> +HugeTLB page consists in 4096.
> +
> +Next, we take the pmd level mapping of the HugeTLB page as an example to
> +show the internal implementation of this optimization. There are 8 pages
> +struct page structs associated with a HugeTLB page which is pmd mapped.
> +
> +Here is how things look before optimization.
> +
> + HugeTLB struct pages(8 pages) page frame(8 pages)
> + +-----------+ ---virt_to_page---> +-----------+ mapping to +-----------+
> + | | | 0 | -------------> | 0 |
> + | | +-----------+ +-----------+
> + | | | 1 | -------------> | 1 |
> + | | +-----------+ +-----------+
> + | | | 2 | -------------> | 2 |
> + | | +-----------+ +-----------+
> + | | | 3 | -------------> | 3 |
> + | | +-----------+ +-----------+
> + | | | 4 | -------------> | 4 |
> + | PMD | +-----------+ +-----------+
> + | level | | 5 | -------------> | 5 |
> + | mapping | +-----------+ +-----------+
> + | | | 6 | -------------> | 6 |
> + | | +-----------+ +-----------+
> + | | | 7 | -------------> | 7 |
> + | | +-----------+ +-----------+
> + | |
> + | |
> + | |
> + +-----------+
> +
> +The value of page->compound_head is the same for all tail pages. The first
> +page of page structs (page 0) associated with the HugeTLB page contains the 4
> +page structs necessary to describe the HugeTLB. The only use of the remaining
> +pages of page structs (page 1 to page 7) is to point to page->compound_head.
> +Therefore, we can remap pages 2 to 7 to page 1. Only 2 pages of page structs
> +will be used for each HugeTLB page. This will allow us to free the remaining
> +6 pages to the buddy allocator.
> +
> +Here is how things look after remapping.
> +
> + HugeTLB struct pages(8 pages) page frame(8 pages)
> + +-----------+ ---virt_to_page---> +-----------+ mapping to +-----------+
> + | | | 0 | -------------> | 0 |
> + | | +-----------+ +-----------+
> + | | | 1 | -------------> | 1 |
> + | | +-----------+ +-----------+
> + | | | 2 | ----------------^ ^ ^ ^ ^ ^
> + | | +-----------+ | | | | |
> + | | | 3 | ------------------+ | | | |
> + | | +-----------+ | | | |
> + | | | 4 | --------------------+ | | |
> + | PMD | +-----------+ | | |
> + | level | | 5 | ----------------------+ | |
> + | mapping | +-----------+ | |
> + | | | 6 | ------------------------+ |
> + | | +-----------+ |
> + | | | 7 | --------------------------+
> + | | +-----------+
> + | |
> + | |
> + | |
> + +-----------+
> +
> +When a HugeTLB is freed to the buddy system, we should allocate 6 pages for
> +vmemmap pages and restore the previous mapping relationship.
> +
> +For the HugeTLB page of the pud level mapping. It is similar to the former.
> +We also can use this approach to free (PAGE_SIZE - 2) vmemmap pages.
> +
> +Apart from the HugeTLB page of the pmd/pud level mapping, some architectures
> +(e.g. aarch64) provides a contiguous bit in the translation table entries
> +that hints to the MMU to indicate that it is one of a contiguous set of
> +entries that can be cached in a single TLB entry.
> +
> +The contiguous bit is used to increase the mapping size at the pmd and pte
> +(last) level. So this type of HugeTLB page can be optimized only when its
> +size of the struct page structs is greater than 2 pages.
> +
> diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
> index c540c21e26f5..e2994e50ddee 100644
> --- a/mm/hugetlb_vmemmap.c
> +++ b/mm/hugetlb_vmemmap.c
> @@ -6,167 +6,7 @@
> *
> * Author: Muchun Song <songmuchun@bytedance.com>
> *
> - * The struct page structures (page structs) are used to describe a physical
> - * page frame. By default, there is a one-to-one mapping from a page frame to
> - * it's corresponding page struct.
> - *
> - * HugeTLB pages consist of multiple base page size pages and is supported by
> - * many architectures. See hugetlbpage.rst in the Documentation directory for
> - * more details. On the x86-64 architecture, HugeTLB pages of size 2MB and 1GB
> - * are currently supported. Since the base page size on x86 is 4KB, a 2MB
> - * HugeTLB page consists of 512 base pages and a 1GB HugeTLB page consists of
> - * 4096 base pages. For each base page, there is a corresponding page struct.
> - *
> - * Within the HugeTLB subsystem, only the first 4 page structs are used to
> - * contain unique information about a HugeTLB page. __NR_USED_SUBPAGE provides
> - * this upper limit. The only 'useful' information in the remaining page structs
> - * is the compound_head field, and this field is the same for all tail pages.
> - *
> - * By removing redundant page structs for HugeTLB pages, memory can be returned
> - * to the buddy allocator for other uses.
> - *
> - * Different architectures support different HugeTLB pages. For example, the
> - * following table is the HugeTLB page size supported by x86 and arm64
> - * architectures. Because arm64 supports 4k, 16k, and 64k base pages and
> - * supports contiguous entries, so it supports many kinds of sizes of HugeTLB
> - * page.
> - *
> - * +--------------+-----------+-----------------------------------------------+
> - * | Architecture | Page Size | HugeTLB Page Size |
> - * +--------------+-----------+-----------+-----------+-----------+-----------+
> - * | x86-64 | 4KB | 2MB | 1GB | | |
> - * +--------------+-----------+-----------+-----------+-----------+-----------+
> - * | | 4KB | 64KB | 2MB | 32MB | 1GB |
> - * | +-----------+-----------+-----------+-----------+-----------+
> - * | arm64 | 16KB | 2MB | 32MB | 1GB | |
> - * | +-----------+-----------+-----------+-----------+-----------+
> - * | | 64KB | 2MB | 512MB | 16GB | |
> - * +--------------+-----------+-----------+-----------+-----------+-----------+
> - *
> - * When the system boot up, every HugeTLB page has more than one struct page
> - * structs which size is (unit: pages):
> - *
> - * struct_size = HugeTLB_Size / PAGE_SIZE * sizeof(struct page) / PAGE_SIZE
> - *
> - * Where HugeTLB_Size is the size of the HugeTLB page. We know that the size
> - * of the HugeTLB page is always n times PAGE_SIZE. So we can get the following
> - * relationship.
> - *
> - * HugeTLB_Size = n * PAGE_SIZE
> - *
> - * Then,
> - *
> - * struct_size = n * PAGE_SIZE / PAGE_SIZE * sizeof(struct page) / PAGE_SIZE
> - * = n * sizeof(struct page) / PAGE_SIZE
> - *
> - * We can use huge mapping at the pud/pmd level for the HugeTLB page.
> - *
> - * For the HugeTLB page of the pmd level mapping, then
> - *
> - * struct_size = n * sizeof(struct page) / PAGE_SIZE
> - * = PAGE_SIZE / sizeof(pte_t) * sizeof(struct page) / PAGE_SIZE
> - * = sizeof(struct page) / sizeof(pte_t)
> - * = 64 / 8
> - * = 8 (pages)
> - *
> - * Where n is how many pte entries which one page can contains. So the value of
> - * n is (PAGE_SIZE / sizeof(pte_t)).
> - *
> - * This optimization only supports 64-bit system, so the value of sizeof(pte_t)
> - * is 8. And this optimization also applicable only when the size of struct page
> - * is a power of two. In most cases, the size of struct page is 64 bytes (e.g.
> - * x86-64 and arm64). So if we use pmd level mapping for a HugeTLB page, the
> - * size of struct page structs of it is 8 page frames which size depends on the
> - * size of the base page.
> - *
> - * For the HugeTLB page of the pud level mapping, then
> - *
> - * struct_size = PAGE_SIZE / sizeof(pmd_t) * struct_size(pmd)
> - * = PAGE_SIZE / 8 * 8 (pages)
> - * = PAGE_SIZE (pages)
> - *
> - * Where the struct_size(pmd) is the size of the struct page structs of a
> - * HugeTLB page of the pmd level mapping.
> - *
> - * E.g.: A 2MB HugeTLB page on x86_64 consists in 8 page frames while 1GB
> - * HugeTLB page consists in 4096.
> - *
> - * Next, we take the pmd level mapping of the HugeTLB page as an example to
> - * show the internal implementation of this optimization. There are 8 pages
> - * struct page structs associated with a HugeTLB page which is pmd mapped.
> - *
> - * Here is how things look before optimization.
> - *
> - * HugeTLB struct pages(8 pages) page frame(8 pages)
> - * +-----------+ ---virt_to_page---> +-----------+ mapping to +-----------+
> - * | | | 0 | -------------> | 0 |
> - * | | +-----------+ +-----------+
> - * | | | 1 | -------------> | 1 |
> - * | | +-----------+ +-----------+
> - * | | | 2 | -------------> | 2 |
> - * | | +-----------+ +-----------+
> - * | | | 3 | -------------> | 3 |
> - * | | +-----------+ +-----------+
> - * | | | 4 | -------------> | 4 |
> - * | PMD | +-----------+ +-----------+
> - * | level | | 5 | -------------> | 5 |
> - * | mapping | +-----------+ +-----------+
> - * | | | 6 | -------------> | 6 |
> - * | | +-----------+ +-----------+
> - * | | | 7 | -------------> | 7 |
> - * | | +-----------+ +-----------+
> - * | |
> - * | |
> - * | |
> - * +-----------+
> - *
> - * The value of page->compound_head is the same for all tail pages. The first
> - * page of page structs (page 0) associated with the HugeTLB page contains the 4
> - * page structs necessary to describe the HugeTLB. The only use of the remaining
> - * pages of page structs (page 1 to page 7) is to point to page->compound_head.
> - * Therefore, we can remap pages 2 to 7 to page 1. Only 2 pages of page structs
> - * will be used for each HugeTLB page. This will allow us to free the remaining
> - * 6 pages to the buddy allocator.
> - *
> - * Here is how things look after remapping.
> - *
> - * HugeTLB struct pages(8 pages) page frame(8 pages)
> - * +-----------+ ---virt_to_page---> +-----------+ mapping to +-----------+
> - * | | | 0 | -------------> | 0 |
> - * | | +-----------+ +-----------+
> - * | | | 1 | -------------> | 1 |
> - * | | +-----------+ +-----------+
> - * | | | 2 | ----------------^ ^ ^ ^ ^ ^
> - * | | +-----------+ | | | | |
> - * | | | 3 | ------------------+ | | | |
> - * | | +-----------+ | | | |
> - * | | | 4 | --------------------+ | | |
> - * | PMD | +-----------+ | | |
> - * | level | | 5 | ----------------------+ | |
> - * | mapping | +-----------+ | |
> - * | | | 6 | ------------------------+ |
> - * | | +-----------+ |
> - * | | | 7 | --------------------------+
> - * | | +-----------+
> - * | |
> - * | |
> - * | |
> - * +-----------+
> - *
> - * When a HugeTLB is freed to the buddy system, we should allocate 6 pages for
> - * vmemmap pages and restore the previous mapping relationship.
> - *
> - * For the HugeTLB page of the pud level mapping. It is similar to the former.
> - * We also can use this approach to free (PAGE_SIZE - 2) vmemmap pages.
> - *
> - * Apart from the HugeTLB page of the pmd/pud level mapping, some architectures
> - * (e.g. aarch64) provides a contiguous bit in the translation table entries
> - * that hints to the MMU to indicate that it is one of a contiguous set of
> - * entries that can be cached in a single TLB entry.
> - *
> - * The contiguous bit is used to increase the mapping size at the pmd and pte
> - * (last) level. So this type of HugeTLB page can be optimized only when its
> - * size of the struct page structs is greater than 2 pages.
> + * See Documentation/vm/vmemmap_dedup.rst
> */
> #define pr_fmt(fmt) "HugeTLB: " fmt
>
> --
> 2.17.1
>
next prev parent reply other threads:[~2021-07-28 6:09 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-14 19:35 [PATCH v3 00/14] mm, sparse-vmemmap: Introduce compound pagemaps Joao Martins
2021-07-14 19:35 ` [PATCH v3 01/14] memory-failure: fetch compound_head after pgmap_pfn_valid() Joao Martins
2021-07-15 0:17 ` Dan Williams
2021-07-15 2:51 ` [External] " Muchun Song
2021-07-15 6:40 ` Christoph Hellwig
2021-07-15 9:19 ` Muchun Song
2021-07-15 13:17 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 02/14] mm/page_alloc: split prep_compound_page into head and tail subparts Joao Martins
2021-07-15 0:19 ` Dan Williams
2021-07-15 2:53 ` [External] " Muchun Song
2021-07-15 13:17 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 03/14] mm/page_alloc: refactor memmap_init_zone_device() page init Joao Martins
2021-07-15 0:20 ` Dan Williams
2021-07-14 19:35 ` [PATCH v3 04/14] mm/memremap: add ZONE_DEVICE support for compound pages Joao Martins
2021-07-15 1:08 ` Dan Williams
2021-07-15 12:52 ` Joao Martins
2021-07-15 13:06 ` Joao Martins
2021-07-15 19:48 ` Dan Williams
2021-07-30 16:13 ` Joao Martins
2021-07-22 0:38 ` Jane Chu
2021-07-22 10:56 ` Joao Martins
2021-07-15 12:59 ` Christoph Hellwig
2021-07-15 13:15 ` Joao Martins
2021-07-15 6:48 ` Christoph Hellwig
2021-07-15 13:15 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 05/14] mm/sparse-vmemmap: add a pgmap argument to section activation Joao Martins
2021-07-28 5:56 ` Dan Williams
2021-07-28 9:43 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 06/14] mm/sparse-vmemmap: refactor core of vmemmap_populate_basepages() to helper Joao Martins
2021-07-28 6:04 ` Dan Williams
2021-07-28 10:48 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 07/14] mm/hugetlb_vmemmap: move comment block to Documentation/vm Joao Martins
2021-07-15 2:47 ` [External] " Muchun Song
2021-07-15 13:16 ` Joao Martins
2021-07-28 6:09 ` Dan Williams [this message]
2021-07-14 19:35 ` [PATCH v3 08/14] mm/sparse-vmemmap: populate compound pagemaps Joao Martins
2021-07-28 6:55 ` Dan Williams
2021-07-28 15:35 ` Joao Martins
2021-07-28 18:03 ` Dan Williams
2021-07-28 18:54 ` Joao Martins
2021-07-28 20:04 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 09/14] mm/page_alloc: reuse tail struct pages for " Joao Martins
2021-07-28 7:28 ` Dan Williams
2021-07-28 15:56 ` Joao Martins
2021-07-28 16:08 ` Dan Williams
2021-07-28 16:12 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 10/14] device-dax: use ALIGN() for determining pgoff Joao Martins
2021-07-28 7:29 ` Dan Williams
2021-07-28 15:56 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 11/14] device-dax: ensure dev_dax->pgmap is valid for dynamic devices Joao Martins
2021-07-28 7:30 ` Dan Williams
2021-07-28 15:56 ` Joao Martins
2021-08-06 12:28 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 12/14] device-dax: compound pagemap support Joao Martins
2021-07-14 23:36 ` Dan Williams
2021-07-15 12:00 ` Joao Martins
2021-07-27 23:51 ` Dan Williams
2021-07-28 9:36 ` Joao Martins
2021-07-28 18:51 ` Dan Williams
2021-07-28 18:59 ` Joao Martins
2021-07-28 19:03 ` Dan Williams
2021-07-14 19:35 ` [PATCH v3 13/14] mm/gup: grab head page refcount once for group of subpages Joao Martins
2021-07-28 19:55 ` Dan Williams
2021-07-28 20:07 ` Joao Martins
2021-07-28 20:23 ` Dan Williams
2021-08-25 19:10 ` Joao Martins
2021-08-25 19:15 ` Matthew Wilcox
2021-08-25 19:26 ` Joao Martins
2021-07-14 19:35 ` [PATCH v3 14/14] mm/sparse-vmemmap: improve memory savings for compound pud geometry Joao Martins
2021-07-28 20:03 ` Dan Williams
2021-07-28 20:08 ` Joao Martins
2021-07-14 21:48 ` [PATCH v3 00/14] mm, sparse-vmemmap: Introduce compound pagemaps Andrew Morton
2021-07-14 23:47 ` Dan Williams
2021-07-22 2:24 ` Matthew Wilcox
2021-07-22 10:53 ` Joao Martins
2021-07-27 23:23 ` Dan Williams
2021-08-02 10:40 ` Joao Martins
2021-08-02 14:06 ` Dan Williams
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=CAPcyv4hMUY+wtB1P4SbzesOB45fo7bZzg14kdX86Hrnd4A-RBQ@mail.gmail.com \
--to=dan.j.williams@intel.com \
--cc=akpm@linux-foundation.org \
--cc=corbet@lwn.net \
--cc=dave.jiang@intel.com \
--cc=jane.chu@oracle.com \
--cc=jgg@ziepe.ca \
--cc=jhubbard@nvidia.com \
--cc=joao.m.martins@oracle.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mike.kravetz@oracle.com \
--cc=naoya.horiguchi@nec.com \
--cc=nvdimm@lists.linux.dev \
--cc=songmuchun@bytedance.com \
--cc=vishal.l.verma@intel.com \
--cc=willy@infradead.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).