From: Christoph Lameter <clameter@sgi.com>
To: akpm@linux-foundation.org
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [08/18] GFP_VFALLBACK: Allow fallback of compound pages to virtual mappings
Date: Wed, 03 Oct 2007 20:59:43 -0700 [thread overview]
Message-ID: <20071004040003.556122828@sgi.com> (raw)
In-Reply-To: 20071004035935.042951211@sgi.com
[-- Attachment #1: vcompound_core --]
[-- Type: text/plain, Size: 7133 bytes --]
Add a new gfp flag
__GFP_VFALLBACK
If specified during a higher order allocation then the system will fall
back to vmap if no physically contiguous pages can be found. This will
create a virtually contiguous area instead of a physically contiguous area.
In many cases the virtually contiguous area can stand in for the physically
contiguous area (with some loss of performance).
Signed-off-by: Christoph Lameter <clameter@sgi.com>
---
include/linux/gfp.h | 5 +
mm/page_alloc.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 139 insertions(+), 5 deletions(-)
Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c 2007-10-03 19:44:07.000000000 -0700
+++ linux-2.6/mm/page_alloc.c 2007-10-03 19:44:08.000000000 -0700
@@ -60,6 +60,9 @@ long nr_swap_pages;
int percpu_pagelist_fraction;
static void __free_pages_ok(struct page *page, unsigned int order);
+static struct page *alloc_vcompound(gfp_t, int,
+ struct zonelist *, unsigned long);
+static void destroy_compound_page(struct page *page, unsigned long order);
/*
* results with 256, 32 in the lowmem_reserve sysctl:
@@ -260,9 +263,51 @@ static void bad_page(struct page *page)
* This usage means that zero-order pages may not be compound.
*/
+static void __free_vcompound(void *addr)
+{
+ struct page **pages;
+ int i;
+ struct page *page = vmalloc_to_page(addr);
+ int order = compound_order(page);
+ int nr_pages = 1 << order;
+
+ if (!PageVcompound(page) || !PageHead(page)) {
+ bad_page(page);
+ return;
+ }
+ destroy_compound_page(page, order);
+ pages = vunmap(addr);
+ /*
+ * First page will have zero refcount since it maintains state
+ * for the compound and was decremented before we got here.
+ */
+ set_page_address(page, NULL);
+ __ClearPageVcompound(page);
+ free_hot_page(page);
+
+ for (i = 1; i < nr_pages; i++) {
+ page = pages[i];
+ set_page_address(page, NULL);
+ __ClearPageVcompound(page);
+ __free_page(page);
+ }
+ kfree(pages);
+}
+
+
+static void free_vcompound(void *addr)
+{
+ __free_vcompound(addr);
+}
+
static void free_compound_page(struct page *page)
{
- __free_pages_ok(page, compound_order(page));
+ if (PageVcompound(page))
+ free_vcompound(page_address(page));
+ else {
+ destroy_compound_page(page, compound_order(page));
+ __free_pages_ok(page, compound_order(page));
+ }
}
static void prep_compound_page(struct page *page, unsigned long order)
@@ -1259,6 +1304,67 @@ try_next_zone:
}
/*
+ * Virtual Compound Page support.
+ *
+ * Virtual Compound Pages are used to fall back to order 0 allocations if large
+ * linear mappings are not available and __GFP_VFALLBACK is set. They are
+ * formatted according to compound page conventions. I.e. following
+ * page->first_page if PageTail(page) is set can be used to determine the
+ * head page.
+ */
+static noinline struct page *alloc_vcompound(gfp_t gfp_mask, int order,
+ struct zonelist *zonelist, unsigned long alloc_flags)
+{
+ struct page *page;
+ int i;
+ struct vm_struct *vm;
+ int nr_pages = 1 << order;
+ struct page **pages = kmalloc(nr_pages * sizeof(struct page *),
+ gfp_mask & GFP_LEVEL_MASK);
+ struct page **pages2;
+
+ if (!pages)
+ return NULL;
+
+ gfp_mask &= ~(__GFP_COMP | __GFP_VFALLBACK);
+ for (i = 0; i < nr_pages; i++) {
+ page = get_page_from_freelist(gfp_mask, 0, zonelist,
+ alloc_flags);
+ if (!page)
+ goto abort;
+
+ /* Sets PageCompound which makes PageHead(page) true */
+ __SetPageVcompound(page);
+ pages[i] = page;
+ }
+
+ vm = get_vm_area_node(nr_pages << PAGE_SHIFT, VM_MAP,
+ zone_to_nid(zonelist->zones[0]), gfp_mask);
+ pages2 = pages;
+ if (map_vm_area(vm, PAGE_KERNEL, &pages2))
+ goto abort;
+
+ prep_compound_page(pages[0], order);
+
+ for (i = 0; i < nr_pages; i++)
+ set_page_address(pages[0], vm->addr + (i << PAGE_SHIFT));
+
+ return pages[0];
+
+abort:
+ while (i-- > 0) {
+ page = pages[i];
+ if (!page)
+ continue;
+ set_page_address(page, NULL);
+ __ClearPageVcompound(page);
+ __free_page(page);
+ }
+ kfree(pages);
+ return NULL;
+}
+
+/*
* This is the 'heart' of the zoned buddy allocator.
*/
struct page * fastcall
@@ -1353,12 +1459,12 @@ nofail_alloc:
goto nofail_alloc;
}
}
- goto nopage;
+ goto try_vcompound;
}
/* Atomic allocations - we can't balance anything */
if (!wait)
- goto nopage;
+ goto try_vcompound;
cond_resched();
@@ -1389,6 +1495,11 @@ nofail_alloc:
*/
page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET);
+
+ if (!page && order && (gfp_mask & __GFP_VFALLBACK))
+ page = alloc_vcompound(gfp_mask, order,
+ zonelist, alloc_flags);
+
if (page)
goto got_pg;
@@ -1420,6 +1531,14 @@ nofail_alloc:
goto rebalance;
}
+try_vcompound:
+ /* Last chance before failing the allocation */
+ if (order && (gfp_mask & __GFP_VFALLBACK)) {
+ page = alloc_vcompound(gfp_mask, order,
+ zonelist, alloc_flags);
+ if (page)
+ goto got_pg;
+ }
nopage:
if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit()) {
printk(KERN_WARNING "%s: page allocation failure."
@@ -1480,6 +1599,9 @@ fastcall void __free_pages(struct page *
if (order == 0)
free_hot_page(page);
else
+ if (unlikely(PageHead(page)))
+ free_compound_page(page);
+ else
__free_pages_ok(page, order);
}
}
@@ -1489,8 +1611,15 @@ EXPORT_SYMBOL(__free_pages);
fastcall void free_pages(unsigned long addr, unsigned int order)
{
if (addr != 0) {
- VM_BUG_ON(!virt_addr_valid((void *)addr));
- __free_pages(virt_to_page((void *)addr), order);
+ struct page *page;
+
+ if (unlikely(addr >= VMALLOC_START && addr < VMALLOC_END))
+ page = vmalloc_to_page((void *)addr);
+ else {
+ VM_BUG_ON(!virt_addr_valid(addr));
+ page = virt_to_page(addr);
+ };
+ __free_pages(page, order);
}
}
Index: linux-2.6/include/linux/gfp.h
===================================================================
--- linux-2.6.orig/include/linux/gfp.h 2007-10-03 19:44:07.000000000 -0700
+++ linux-2.6/include/linux/gfp.h 2007-10-03 19:44:08.000000000 -0700
@@ -43,6 +43,7 @@ struct vm_area_struct;
#define __GFP_REPEAT ((__force gfp_t)0x400u) /* Retry the allocation. Might fail */
#define __GFP_NOFAIL ((__force gfp_t)0x800u) /* Retry for ever. Cannot fail */
#define __GFP_NORETRY ((__force gfp_t)0x1000u)/* Do not retry. Might fail */
+#define __GFP_VFALLBACK ((__force gfp_t)0x2000u)/* Permit fallback to vmalloc */
#define __GFP_COMP ((__force gfp_t)0x4000u)/* Add compound page metadata */
#define __GFP_ZERO ((__force gfp_t)0x8000u)/* Return zeroed page on success */
#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
@@ -86,6 +87,10 @@ struct vm_area_struct;
#define GFP_THISNODE ((__force gfp_t)0)
#endif
+/*
+ * Allocate large page but allow fallback to a virtually mapped page
+ */
+#define GFP_VFALLBACK (GFP_KERNEL | __GFP_VFALLBACK)
/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some
platforms, used as appropriate on others */
--
WARNING: multiple messages have this Message-ID (diff)
From: Christoph Lameter <clameter@sgi.com>
To: akpm@linux-foundation.org
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [08/18] GFP_VFALLBACK: Allow fallback of compound pages to virtual mappings
Date: Wed, 03 Oct 2007 20:59:43 -0700 [thread overview]
Message-ID: <20071004040003.556122828@sgi.com> (raw)
In-Reply-To: 20071004035935.042951211@sgi.com
[-- Attachment #1: vcompound_core --]
[-- Type: text/plain, Size: 7359 bytes --]
Add a new gfp flag
__GFP_VFALLBACK
If specified during a higher order allocation then the system will fall
back to vmap if no physically contiguous pages can be found. This will
create a virtually contiguous area instead of a physically contiguous area.
In many cases the virtually contiguous area can stand in for the physically
contiguous area (with some loss of performance).
Signed-off-by: Christoph Lameter <clameter@sgi.com>
---
include/linux/gfp.h | 5 +
mm/page_alloc.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 139 insertions(+), 5 deletions(-)
Index: linux-2.6/mm/page_alloc.c
===================================================================
--- linux-2.6.orig/mm/page_alloc.c 2007-10-03 19:44:07.000000000 -0700
+++ linux-2.6/mm/page_alloc.c 2007-10-03 19:44:08.000000000 -0700
@@ -60,6 +60,9 @@ long nr_swap_pages;
int percpu_pagelist_fraction;
static void __free_pages_ok(struct page *page, unsigned int order);
+static struct page *alloc_vcompound(gfp_t, int,
+ struct zonelist *, unsigned long);
+static void destroy_compound_page(struct page *page, unsigned long order);
/*
* results with 256, 32 in the lowmem_reserve sysctl:
@@ -260,9 +263,51 @@ static void bad_page(struct page *page)
* This usage means that zero-order pages may not be compound.
*/
+static void __free_vcompound(void *addr)
+{
+ struct page **pages;
+ int i;
+ struct page *page = vmalloc_to_page(addr);
+ int order = compound_order(page);
+ int nr_pages = 1 << order;
+
+ if (!PageVcompound(page) || !PageHead(page)) {
+ bad_page(page);
+ return;
+ }
+ destroy_compound_page(page, order);
+ pages = vunmap(addr);
+ /*
+ * First page will have zero refcount since it maintains state
+ * for the compound and was decremented before we got here.
+ */
+ set_page_address(page, NULL);
+ __ClearPageVcompound(page);
+ free_hot_page(page);
+
+ for (i = 1; i < nr_pages; i++) {
+ page = pages[i];
+ set_page_address(page, NULL);
+ __ClearPageVcompound(page);
+ __free_page(page);
+ }
+ kfree(pages);
+}
+
+
+static void free_vcompound(void *addr)
+{
+ __free_vcompound(addr);
+}
+
static void free_compound_page(struct page *page)
{
- __free_pages_ok(page, compound_order(page));
+ if (PageVcompound(page))
+ free_vcompound(page_address(page));
+ else {
+ destroy_compound_page(page, compound_order(page));
+ __free_pages_ok(page, compound_order(page));
+ }
}
static void prep_compound_page(struct page *page, unsigned long order)
@@ -1259,6 +1304,67 @@ try_next_zone:
}
/*
+ * Virtual Compound Page support.
+ *
+ * Virtual Compound Pages are used to fall back to order 0 allocations if large
+ * linear mappings are not available and __GFP_VFALLBACK is set. They are
+ * formatted according to compound page conventions. I.e. following
+ * page->first_page if PageTail(page) is set can be used to determine the
+ * head page.
+ */
+static noinline struct page *alloc_vcompound(gfp_t gfp_mask, int order,
+ struct zonelist *zonelist, unsigned long alloc_flags)
+{
+ struct page *page;
+ int i;
+ struct vm_struct *vm;
+ int nr_pages = 1 << order;
+ struct page **pages = kmalloc(nr_pages * sizeof(struct page *),
+ gfp_mask & GFP_LEVEL_MASK);
+ struct page **pages2;
+
+ if (!pages)
+ return NULL;
+
+ gfp_mask &= ~(__GFP_COMP | __GFP_VFALLBACK);
+ for (i = 0; i < nr_pages; i++) {
+ page = get_page_from_freelist(gfp_mask, 0, zonelist,
+ alloc_flags);
+ if (!page)
+ goto abort;
+
+ /* Sets PageCompound which makes PageHead(page) true */
+ __SetPageVcompound(page);
+ pages[i] = page;
+ }
+
+ vm = get_vm_area_node(nr_pages << PAGE_SHIFT, VM_MAP,
+ zone_to_nid(zonelist->zones[0]), gfp_mask);
+ pages2 = pages;
+ if (map_vm_area(vm, PAGE_KERNEL, &pages2))
+ goto abort;
+
+ prep_compound_page(pages[0], order);
+
+ for (i = 0; i < nr_pages; i++)
+ set_page_address(pages[0], vm->addr + (i << PAGE_SHIFT));
+
+ return pages[0];
+
+abort:
+ while (i-- > 0) {
+ page = pages[i];
+ if (!page)
+ continue;
+ set_page_address(page, NULL);
+ __ClearPageVcompound(page);
+ __free_page(page);
+ }
+ kfree(pages);
+ return NULL;
+}
+
+/*
* This is the 'heart' of the zoned buddy allocator.
*/
struct page * fastcall
@@ -1353,12 +1459,12 @@ nofail_alloc:
goto nofail_alloc;
}
}
- goto nopage;
+ goto try_vcompound;
}
/* Atomic allocations - we can't balance anything */
if (!wait)
- goto nopage;
+ goto try_vcompound;
cond_resched();
@@ -1389,6 +1495,11 @@ nofail_alloc:
*/
page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET);
+
+ if (!page && order && (gfp_mask & __GFP_VFALLBACK))
+ page = alloc_vcompound(gfp_mask, order,
+ zonelist, alloc_flags);
+
if (page)
goto got_pg;
@@ -1420,6 +1531,14 @@ nofail_alloc:
goto rebalance;
}
+try_vcompound:
+ /* Last chance before failing the allocation */
+ if (order && (gfp_mask & __GFP_VFALLBACK)) {
+ page = alloc_vcompound(gfp_mask, order,
+ zonelist, alloc_flags);
+ if (page)
+ goto got_pg;
+ }
nopage:
if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit()) {
printk(KERN_WARNING "%s: page allocation failure."
@@ -1480,6 +1599,9 @@ fastcall void __free_pages(struct page *
if (order == 0)
free_hot_page(page);
else
+ if (unlikely(PageHead(page)))
+ free_compound_page(page);
+ else
__free_pages_ok(page, order);
}
}
@@ -1489,8 +1611,15 @@ EXPORT_SYMBOL(__free_pages);
fastcall void free_pages(unsigned long addr, unsigned int order)
{
if (addr != 0) {
- VM_BUG_ON(!virt_addr_valid((void *)addr));
- __free_pages(virt_to_page((void *)addr), order);
+ struct page *page;
+
+ if (unlikely(addr >= VMALLOC_START && addr < VMALLOC_END))
+ page = vmalloc_to_page((void *)addr);
+ else {
+ VM_BUG_ON(!virt_addr_valid(addr));
+ page = virt_to_page(addr);
+ };
+ __free_pages(page, order);
}
}
Index: linux-2.6/include/linux/gfp.h
===================================================================
--- linux-2.6.orig/include/linux/gfp.h 2007-10-03 19:44:07.000000000 -0700
+++ linux-2.6/include/linux/gfp.h 2007-10-03 19:44:08.000000000 -0700
@@ -43,6 +43,7 @@ struct vm_area_struct;
#define __GFP_REPEAT ((__force gfp_t)0x400u) /* Retry the allocation. Might fail */
#define __GFP_NOFAIL ((__force gfp_t)0x800u) /* Retry for ever. Cannot fail */
#define __GFP_NORETRY ((__force gfp_t)0x1000u)/* Do not retry. Might fail */
+#define __GFP_VFALLBACK ((__force gfp_t)0x2000u)/* Permit fallback to vmalloc */
#define __GFP_COMP ((__force gfp_t)0x4000u)/* Add compound page metadata */
#define __GFP_ZERO ((__force gfp_t)0x8000u)/* Return zeroed page on success */
#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
@@ -86,6 +87,10 @@ struct vm_area_struct;
#define GFP_THISNODE ((__force gfp_t)0)
#endif
+/*
+ * Allocate large page but allow fallback to a virtually mapped page
+ */
+#define GFP_VFALLBACK (GFP_KERNEL | __GFP_VFALLBACK)
/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some
platforms, used as appropriate on others */
--
--
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:[~2007-10-04 4:02 UTC|newest]
Thread overview: 85+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-04 3:59 [00/18] Virtual Compound Page Support V2 Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [01/18] vmalloc: clean up page array indexing Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [02/18] vunmap: return page array passed on vmap() Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [03/18] vmalloc_address(): Determine vmalloc address from page struct Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [04/18] Vcompound: Smart up virt_to_head_page() Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [05/18] Page flags: Add PageVcompound() Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [06/18] Vcompound: Update page address determination Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [07/18] Vcompound: Add compound_nth_page() to determine nth base page Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-13 16:46 ` Compiling kernel 2.6.23.1 HELP animesh saxena
2007-10-13 17:12 ` Willy Tarreau
2007-10-14 2:35 ` Kristoffer Ericson
2007-10-04 3:59 ` Christoph Lameter [this message]
2007-10-04 3:59 ` [08/18] GFP_VFALLBACK: Allow fallback of compound pages to virtual mappings Christoph Lameter
2007-10-04 3:59 ` [09/18] Vcompound: GFP_VFALLBACK debugging aid Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [10/18] Sparsemem: Use fallback for the memmap Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [11/18] Page allocator: Use a higher order allocation for the zone wait table Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [12/18] Wait: Allow bit_waitqueue to wait on a bit in a virtual compound page Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [13/18] x86_64: Allow fallback for the stack Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 11:56 ` Andi Kleen
2007-10-04 11:56 ` Andi Kleen
2007-10-04 12:08 ` Peter Zijlstra
2007-10-04 12:08 ` Peter Zijlstra
2007-10-04 12:25 ` Andi Kleen
2007-10-04 12:25 ` Andi Kleen
2007-10-04 12:30 ` Peter Zijlstra
2007-10-04 12:30 ` Peter Zijlstra
2007-10-04 17:40 ` Christoph Lameter
2007-10-04 17:40 ` Christoph Lameter
2007-10-04 19:20 ` Christoph Lameter
2007-10-04 19:20 ` Christoph Lameter
2007-10-04 19:39 ` Rik van Riel
2007-10-04 19:39 ` Rik van Riel
2007-10-04 21:20 ` Christoph Lameter
2007-10-04 21:20 ` Christoph Lameter
2007-10-07 7:35 ` Nick Piggin
2007-10-07 7:35 ` Nick Piggin
2007-10-08 17:36 ` Christoph Lameter
2007-10-08 17:36 ` Christoph Lameter
2007-10-08 12:55 ` Nick Piggin
2007-10-08 12:55 ` Nick Piggin
2007-10-09 18:39 ` Christoph Lameter
2007-10-09 18:39 ` Christoph Lameter
2007-10-09 8:46 ` Nick Piggin
2007-10-09 8:46 ` Nick Piggin
2007-10-10 1:26 ` Christoph Lameter
2007-10-10 1:26 ` Christoph Lameter
2007-10-09 9:56 ` Nick Piggin
2007-10-09 9:56 ` Nick Piggin
2007-10-10 3:36 ` where to get ZONE_MOVABLE pathces? Jacky(GuangXiang Lee)
2007-10-10 10:32 ` Mel Gorman
2007-10-06 18:53 ` [13/18] x86_64: Allow fallback for the stack Bill Davidsen
2007-10-06 18:53 ` Bill Davidsen
2007-10-04 3:59 ` [14/18] Configure stack size Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 4:36 ` Arjan van de Ven
2007-10-04 4:36 ` Arjan van de Ven
2007-10-04 4:43 ` David Miller
2007-10-04 4:43 ` David Miller, Arjan van de Ven
2007-10-04 19:34 ` Christoph Lameter
2007-10-04 19:34 ` Christoph Lameter
2007-10-04 9:11 ` Andi Kleen
2007-10-04 9:11 ` Andi Kleen
2007-10-04 19:26 ` Christoph Lameter
2007-10-04 19:26 ` Christoph Lameter
2007-10-04 3:59 ` [15/18] Fallback for temporary order 2 allocation Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [16/18] Virtual Compound page allocation from interrupt context Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [17/18] Virtual compound page freeing in " Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
2007-10-04 3:59 ` [18/18] SLUB: Use fallback for table of callers/freers of a slab cache Christoph Lameter
2007-10-04 3:59 ` Christoph Lameter
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=20071004040003.556122828@sgi.com \
--to=clameter@sgi.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.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 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.