From: "Michael S. Tsirkin" <mst@redhat.com> To: Michal Hocko <mhocko@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org>, Vlastimil Babka <vbabka@suse.cz>, David Rientjes <rientjes@google.com>, Mel Gorman <mgorman@suse.de>, Johannes Weiner <hannes@cmpxchg.org>, Al Viro <viro@zeniv.linux.org.uk>, linux-mm@kvack.org, LKML <linux-kernel@vger.kernel.org>, Michal Hocko <mhocko@suse.com> Subject: Re: [PATCH 2/6] mm: support __GFP_REPEAT in kvmalloc_node for >=64kB Date: Tue, 24 Jan 2017 17:40:38 +0200 [thread overview] Message-ID: <20170124173956-mutt-send-email-mst@kernel.org> (raw) In-Reply-To: <20170112153717.28943-3-mhocko@kernel.org> On Thu, Jan 12, 2017 at 04:37:13PM +0100, Michal Hocko wrote: > From: Michal Hocko <mhocko@suse.com> > > vhost code uses __GFP_REPEAT when allocating vhost_virtqueue resp. > vhost_vsock because it would really like to prefer kmalloc to the > vmalloc fallback - see 23cc5a991c7a ("vhost-net: extend device > allocation to vmalloc") for more context. Michael Tsirkin has also > noted: > " > __GFP_REPEAT overhead is during allocation time. Using vmalloc means all > accesses are slowed down. Allocation is not on data path, accesses are. > " > > The similar applies to other vhost_kvzalloc users. > > Let's teach kvmalloc_node to handle __GFP_REPEAT properly. There are two > things to be careful about. First we should prevent from the OOM killer > and so have to involve __GFP_NORETRY by default and secondly override > __GFP_REPEAT for !costly order requests as the __GFP_REPEAT is ignored > for !costly orders. > > Supporting __GFP_REPEAT like semantic for !costly request is possible > it would require changes in the page allocator. This is out of scope of > this patch. > > This patch shouldn't introduce any functional change. > > Cc: "Michael S. Tsirkin" <mst@redhat.com> > Acked-by: Vlastimil Babka <vbabka@suse.cz> > Signed-off-by: Michal Hocko <mhocko@suse.com> Assuming the new APIs are upstream I see no reason not to use them in vhost. For vhost bits: Acked-by: Michael S. Tsirkin <mst@redhat.com> > --- > drivers/vhost/net.c | 9 +++------ > drivers/vhost/vhost.c | 15 +++------------ > drivers/vhost/vsock.c | 9 +++------ > mm/util.c | 17 ++++++++++++++--- > 4 files changed, 23 insertions(+), 27 deletions(-) > > diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c > index 5dc34653274a..105cd04c7414 100644 > --- a/drivers/vhost/net.c > +++ b/drivers/vhost/net.c > @@ -797,12 +797,9 @@ static int vhost_net_open(struct inode *inode, struct file *f) > struct vhost_virtqueue **vqs; > int i; > > - n = kmalloc(sizeof *n, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); > - if (!n) { > - n = vmalloc(sizeof *n); > - if (!n) > - return -ENOMEM; > - } > + n = kvmalloc(sizeof *n, GFP_KERNEL | __GFP_REPEAT); > + if (!n) > + return -ENOMEM; > vqs = kmalloc(VHOST_NET_VQ_MAX * sizeof(*vqs), GFP_KERNEL); > if (!vqs) { > kvfree(n); > diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c > index d6432603880c..d2bf8a41f55e 100644 > --- a/drivers/vhost/vhost.c > +++ b/drivers/vhost/vhost.c > @@ -515,18 +515,9 @@ long vhost_dev_set_owner(struct vhost_dev *dev) > } > EXPORT_SYMBOL_GPL(vhost_dev_set_owner); > > -static void *vhost_kvzalloc(unsigned long size) > -{ > - void *n = kzalloc(size, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); > - > - if (!n) > - n = vzalloc(size); > - return n; > -} > - > struct vhost_umem *vhost_dev_reset_owner_prepare(void) > { > - return vhost_kvzalloc(sizeof(struct vhost_umem)); > + return kvzalloc(sizeof(struct vhost_umem), GFP_KERNEL); > } > EXPORT_SYMBOL_GPL(vhost_dev_reset_owner_prepare); > > @@ -1190,7 +1181,7 @@ EXPORT_SYMBOL_GPL(vhost_vq_access_ok); > > static struct vhost_umem *vhost_umem_alloc(void) > { > - struct vhost_umem *umem = vhost_kvzalloc(sizeof(*umem)); > + struct vhost_umem *umem = kvzalloc(sizeof(*umem), GFP_KERNEL); > > if (!umem) > return NULL; > @@ -1216,7 +1207,7 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) > return -EOPNOTSUPP; > if (mem.nregions > max_mem_regions) > return -E2BIG; > - newmem = vhost_kvzalloc(size + mem.nregions * sizeof(*m->regions)); > + newmem = kvzalloc(size + mem.nregions * sizeof(*m->regions), GFP_KERNEL); > if (!newmem) > return -ENOMEM; > > diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c > index bbbf588540ed..7e0159867553 100644 > --- a/drivers/vhost/vsock.c > +++ b/drivers/vhost/vsock.c > @@ -455,12 +455,9 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) > /* This struct is large and allocation could fail, fall back to vmalloc > * if there is no other way. > */ > - vsock = kzalloc(sizeof(*vsock), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); > - if (!vsock) { > - vsock = vmalloc(sizeof(*vsock)); > - if (!vsock) > - return -ENOMEM; > - } > + vsock = kvmalloc(sizeof(*vsock), GFP_KERNEL | __GFP_REPEAT); > + if (!vsock) > + return -ENOMEM; > > vqs = kmalloc_array(ARRAY_SIZE(vsock->vqs), sizeof(*vqs), GFP_KERNEL); > if (!vqs) { > diff --git a/mm/util.c b/mm/util.c > index 7e0c240b5760..9306244b9f41 100644 > --- a/mm/util.c > +++ b/mm/util.c > @@ -333,7 +333,8 @@ EXPORT_SYMBOL(vm_mmap); > * Uses kmalloc to get the memory but if the allocation fails then falls back > * to the vmalloc allocator. Use kvfree for freeing the memory. > * > - * Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported > + * Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT > + * is supported only for large (>64kB) allocations > */ > void *kvmalloc_node(size_t size, gfp_t flags, int node) > { > @@ -350,8 +351,18 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node) > * Make sure that larger requests are not too disruptive - no OOM > * killer and no allocation failure warnings as we have a fallback > */ > - if (size > PAGE_SIZE) > - kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; > + if (size > PAGE_SIZE) { > + kmalloc_flags |= __GFP_NOWARN; > + > + /* > + * We have to override __GFP_REPEAT by __GFP_NORETRY for !costly > + * requests because there is no other way to tell the allocator > + * that we want to fail rather than retry endlessly. > + */ > + if (!(kmalloc_flags & __GFP_REPEAT) || > + (size <= PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) > + kmalloc_flags |= __GFP_NORETRY; > + } > > ret = kmalloc_node(size, kmalloc_flags, node); > > -- > 2.11.0
WARNING: multiple messages have this Message-ID (diff)
From: "Michael S. Tsirkin" <mst@redhat.com> To: Michal Hocko <mhocko@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org>, Vlastimil Babka <vbabka@suse.cz>, David Rientjes <rientjes@google.com>, Mel Gorman <mgorman@suse.de>, Johannes Weiner <hannes@cmpxchg.org>, Al Viro <viro@zeniv.linux.org.uk>, linux-mm@kvack.org, LKML <linux-kernel@vger.kernel.org>, Michal Hocko <mhocko@suse.com> Subject: Re: [PATCH 2/6] mm: support __GFP_REPEAT in kvmalloc_node for >=64kB Date: Tue, 24 Jan 2017 17:40:38 +0200 [thread overview] Message-ID: <20170124173956-mutt-send-email-mst@kernel.org> (raw) In-Reply-To: <20170112153717.28943-3-mhocko@kernel.org> On Thu, Jan 12, 2017 at 04:37:13PM +0100, Michal Hocko wrote: > From: Michal Hocko <mhocko@suse.com> > > vhost code uses __GFP_REPEAT when allocating vhost_virtqueue resp. > vhost_vsock because it would really like to prefer kmalloc to the > vmalloc fallback - see 23cc5a991c7a ("vhost-net: extend device > allocation to vmalloc") for more context. Michael Tsirkin has also > noted: > " > __GFP_REPEAT overhead is during allocation time. Using vmalloc means all > accesses are slowed down. Allocation is not on data path, accesses are. > " > > The similar applies to other vhost_kvzalloc users. > > Let's teach kvmalloc_node to handle __GFP_REPEAT properly. There are two > things to be careful about. First we should prevent from the OOM killer > and so have to involve __GFP_NORETRY by default and secondly override > __GFP_REPEAT for !costly order requests as the __GFP_REPEAT is ignored > for !costly orders. > > Supporting __GFP_REPEAT like semantic for !costly request is possible > it would require changes in the page allocator. This is out of scope of > this patch. > > This patch shouldn't introduce any functional change. > > Cc: "Michael S. Tsirkin" <mst@redhat.com> > Acked-by: Vlastimil Babka <vbabka@suse.cz> > Signed-off-by: Michal Hocko <mhocko@suse.com> Assuming the new APIs are upstream I see no reason not to use them in vhost. For vhost bits: Acked-by: Michael S. Tsirkin <mst@redhat.com> > --- > drivers/vhost/net.c | 9 +++------ > drivers/vhost/vhost.c | 15 +++------------ > drivers/vhost/vsock.c | 9 +++------ > mm/util.c | 17 ++++++++++++++--- > 4 files changed, 23 insertions(+), 27 deletions(-) > > diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c > index 5dc34653274a..105cd04c7414 100644 > --- a/drivers/vhost/net.c > +++ b/drivers/vhost/net.c > @@ -797,12 +797,9 @@ static int vhost_net_open(struct inode *inode, struct file *f) > struct vhost_virtqueue **vqs; > int i; > > - n = kmalloc(sizeof *n, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); > - if (!n) { > - n = vmalloc(sizeof *n); > - if (!n) > - return -ENOMEM; > - } > + n = kvmalloc(sizeof *n, GFP_KERNEL | __GFP_REPEAT); > + if (!n) > + return -ENOMEM; > vqs = kmalloc(VHOST_NET_VQ_MAX * sizeof(*vqs), GFP_KERNEL); > if (!vqs) { > kvfree(n); > diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c > index d6432603880c..d2bf8a41f55e 100644 > --- a/drivers/vhost/vhost.c > +++ b/drivers/vhost/vhost.c > @@ -515,18 +515,9 @@ long vhost_dev_set_owner(struct vhost_dev *dev) > } > EXPORT_SYMBOL_GPL(vhost_dev_set_owner); > > -static void *vhost_kvzalloc(unsigned long size) > -{ > - void *n = kzalloc(size, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); > - > - if (!n) > - n = vzalloc(size); > - return n; > -} > - > struct vhost_umem *vhost_dev_reset_owner_prepare(void) > { > - return vhost_kvzalloc(sizeof(struct vhost_umem)); > + return kvzalloc(sizeof(struct vhost_umem), GFP_KERNEL); > } > EXPORT_SYMBOL_GPL(vhost_dev_reset_owner_prepare); > > @@ -1190,7 +1181,7 @@ EXPORT_SYMBOL_GPL(vhost_vq_access_ok); > > static struct vhost_umem *vhost_umem_alloc(void) > { > - struct vhost_umem *umem = vhost_kvzalloc(sizeof(*umem)); > + struct vhost_umem *umem = kvzalloc(sizeof(*umem), GFP_KERNEL); > > if (!umem) > return NULL; > @@ -1216,7 +1207,7 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) > return -EOPNOTSUPP; > if (mem.nregions > max_mem_regions) > return -E2BIG; > - newmem = vhost_kvzalloc(size + mem.nregions * sizeof(*m->regions)); > + newmem = kvzalloc(size + mem.nregions * sizeof(*m->regions), GFP_KERNEL); > if (!newmem) > return -ENOMEM; > > diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c > index bbbf588540ed..7e0159867553 100644 > --- a/drivers/vhost/vsock.c > +++ b/drivers/vhost/vsock.c > @@ -455,12 +455,9 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) > /* This struct is large and allocation could fail, fall back to vmalloc > * if there is no other way. > */ > - vsock = kzalloc(sizeof(*vsock), GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); > - if (!vsock) { > - vsock = vmalloc(sizeof(*vsock)); > - if (!vsock) > - return -ENOMEM; > - } > + vsock = kvmalloc(sizeof(*vsock), GFP_KERNEL | __GFP_REPEAT); > + if (!vsock) > + return -ENOMEM; > > vqs = kmalloc_array(ARRAY_SIZE(vsock->vqs), sizeof(*vqs), GFP_KERNEL); > if (!vqs) { > diff --git a/mm/util.c b/mm/util.c > index 7e0c240b5760..9306244b9f41 100644 > --- a/mm/util.c > +++ b/mm/util.c > @@ -333,7 +333,8 @@ EXPORT_SYMBOL(vm_mmap); > * Uses kmalloc to get the memory but if the allocation fails then falls back > * to the vmalloc allocator. Use kvfree for freeing the memory. > * > - * Reclaim modifiers - __GFP_NORETRY, __GFP_REPEAT and __GFP_NOFAIL are not supported > + * Reclaim modifiers - __GFP_NORETRY and __GFP_NOFAIL are not supported. __GFP_REPEAT > + * is supported only for large (>64kB) allocations > */ > void *kvmalloc_node(size_t size, gfp_t flags, int node) > { > @@ -350,8 +351,18 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node) > * Make sure that larger requests are not too disruptive - no OOM > * killer and no allocation failure warnings as we have a fallback > */ > - if (size > PAGE_SIZE) > - kmalloc_flags |= __GFP_NORETRY | __GFP_NOWARN; > + if (size > PAGE_SIZE) { > + kmalloc_flags |= __GFP_NOWARN; > + > + /* > + * We have to override __GFP_REPEAT by __GFP_NORETRY for !costly > + * requests because there is no other way to tell the allocator > + * that we want to fail rather than retry endlessly. > + */ > + if (!(kmalloc_flags & __GFP_REPEAT) || > + (size <= PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) > + kmalloc_flags |= __GFP_NORETRY; > + } > > ret = kmalloc_node(size, kmalloc_flags, node); > > -- > 2.11.0 -- 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:[~2017-01-24 15:40 UTC|newest] Thread overview: 129+ messages / expand[flat|nested] mbox.gz Atom feed top 2017-01-12 15:37 [PATCH 0/6 v3] kvmalloc Michal Hocko 2017-01-12 15:37 ` Michal Hocko 2017-01-12 15:37 ` [PATCH 1/6] mm: introduce kv[mz]alloc helpers Michal Hocko 2017-01-12 15:37 ` Michal Hocko 2017-01-16 4:34 ` John Hubbard 2017-01-16 4:34 ` John Hubbard 2017-01-16 8:47 ` Michal Hocko 2017-01-16 8:47 ` Michal Hocko 2017-01-16 19:09 ` John Hubbard 2017-01-16 19:09 ` John Hubbard 2017-01-16 19:40 ` Michal Hocko 2017-01-16 19:40 ` Michal Hocko 2017-01-16 21:15 ` John Hubbard 2017-01-16 21:15 ` John Hubbard 2017-01-16 21:48 ` Michal Hocko 2017-01-16 21:48 ` Michal Hocko 2017-01-16 21:57 ` John Hubbard 2017-01-16 21:57 ` John Hubbard 2017-01-17 7:51 ` Michal Hocko 2017-01-17 7:51 ` Michal Hocko 2017-01-18 5:59 ` John Hubbard 2017-01-18 5:59 ` John Hubbard 2017-01-18 8:21 ` Michal Hocko 2017-01-18 8:21 ` Michal Hocko 2017-01-19 8:37 ` John Hubbard 2017-01-19 8:37 ` John Hubbard 2017-01-19 8:45 ` Michal Hocko 2017-01-19 8:45 ` Michal Hocko 2017-01-19 9:09 ` John Hubbard 2017-01-19 9:09 ` John Hubbard 2017-01-19 9:56 ` Michal Hocko 2017-01-19 9:56 ` Michal Hocko 2017-01-19 21:28 ` John Hubbard 2017-01-19 21:28 ` John Hubbard 2017-01-26 12:09 ` Michal Hocko 2017-01-26 12:09 ` Michal Hocko 2017-01-30 8:42 ` Vlastimil Babka 2017-01-30 8:42 ` Vlastimil Babka 2017-01-12 15:37 ` [PATCH 2/6] mm: support __GFP_REPEAT in kvmalloc_node for >=64kB Michal Hocko 2017-01-12 15:37 ` Michal Hocko 2017-01-12 16:12 ` Michael S. Tsirkin 2017-01-12 16:12 ` Michael S. Tsirkin 2017-01-14 2:42 ` Tetsuo Handa 2017-01-14 2:42 ` Tetsuo Handa 2017-01-14 8:45 ` Michal Hocko 2017-01-14 8:45 ` Michal Hocko 2017-01-24 15:40 ` Michael S. Tsirkin [this message] 2017-01-24 15:40 ` Michael S. Tsirkin 2017-01-12 15:37 ` [PATCH 3/6] rhashtable: simplify a strange allocation pattern Michal Hocko 2017-01-12 15:37 ` Michal Hocko 2017-01-12 15:37 ` [PATCH 4/6] ila: " Michal Hocko 2017-01-12 15:37 ` Michal Hocko 2017-01-12 15:37 ` [PATCH 5/6] treewide: use kv[mz]alloc* rather than opencoded variants Michal Hocko 2017-01-12 15:37 ` Michal Hocko 2017-01-12 15:37 ` Michal Hocko 2017-01-12 15:57 ` David Sterba 2017-01-12 15:57 ` David Sterba 2017-01-12 15:57 ` David Sterba 2017-01-12 16:05 ` Christian Borntraeger 2017-01-12 16:05 ` Christian Borntraeger 2017-01-12 16:05 ` Christian Borntraeger 2017-01-12 16:54 ` Ilya Dryomov 2017-01-12 16:54 ` Ilya Dryomov 2017-01-12 16:54 ` Ilya Dryomov 2017-01-12 17:18 ` Michal Hocko 2017-01-12 17:18 ` Michal Hocko 2017-01-12 17:18 ` Michal Hocko 2017-01-12 17:00 ` Dan Williams 2017-01-12 17:00 ` Dan Williams 2017-01-12 17:00 ` Dan Williams 2017-01-12 17:26 ` Kees Cook 2017-01-12 17:26 ` Kees Cook 2017-01-12 17:26 ` Kees Cook 2017-01-12 17:37 ` Michal Hocko 2017-01-12 17:37 ` Michal Hocko 2017-01-12 17:37 ` Michal Hocko 2017-01-20 13:41 ` Vlastimil Babka 2017-01-20 13:41 ` Vlastimil Babka 2017-01-20 13:41 ` Vlastimil Babka 2017-01-24 15:00 ` Michal Hocko 2017-01-24 15:00 ` Michal Hocko 2017-01-24 15:00 ` Michal Hocko 2017-01-25 11:15 ` Vlastimil Babka 2017-01-25 11:15 ` Vlastimil Babka 2017-01-25 11:15 ` Vlastimil Babka 2017-01-25 13:09 ` Michal Hocko 2017-01-25 13:09 ` Michal Hocko 2017-01-25 13:09 ` Michal Hocko 2017-01-25 13:40 ` Ilya Dryomov 2017-01-25 13:40 ` Ilya Dryomov 2017-01-25 13:40 ` Ilya Dryomov 2017-01-12 17:29 ` Michal Hocko 2017-01-12 17:29 ` Michal Hocko 2017-01-12 17:29 ` Michal Hocko 2017-01-14 3:01 ` Tetsuo Handa 2017-01-14 3:01 ` Tetsuo Handa 2017-01-14 8:49 ` Michal Hocko 2017-01-14 8:49 ` Michal Hocko 2017-01-12 20:14 ` Boris Ostrovsky 2017-01-12 20:14 ` Boris Ostrovsky 2017-01-12 20:14 ` Boris Ostrovsky 2017-01-13 1:11 ` Dilger, Andreas 2017-01-13 1:11 ` Dilger, Andreas 2017-01-13 1:11 ` Dilger, Andreas 2017-01-14 10:56 ` Leon Romanovsky 2017-01-14 10:56 ` Leon Romanovsky 2017-01-16 7:33 ` Michal Hocko 2017-01-16 7:33 ` Michal Hocko 2017-01-16 7:33 ` Michal Hocko 2017-01-16 8:28 ` Leon Romanovsky 2017-01-16 8:28 ` Leon Romanovsky 2017-01-16 8:18 ` Tariq Toukan 2017-01-16 8:18 ` Tariq Toukan 2017-01-16 8:18 ` Tariq Toukan 2017-01-12 15:37 ` [RFC PATCH 6/6] net: use kvmalloc with __GFP_REPEAT rather than open coded variant Michal Hocko 2017-01-12 15:37 ` Michal Hocko 2017-01-12 15:37 ` Michal Hocko 2017-01-24 15:17 ` [PATCH 0/6 v3] kvmalloc Michal Hocko 2017-01-24 15:17 ` Michal Hocko 2017-01-24 16:00 ` Eric Dumazet 2017-01-24 16:00 ` Eric Dumazet 2017-01-25 13:10 ` Michal Hocko 2017-01-25 13:10 ` Michal Hocko 2017-01-24 19:17 ` Alexei Starovoitov 2017-01-24 19:17 ` Alexei Starovoitov 2017-01-25 13:10 ` Michal Hocko 2017-01-25 13:10 ` Michal Hocko 2017-01-25 13:21 ` Michal Hocko 2017-01-25 13:21 ` Michal Hocko
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=20170124173956-mutt-send-email-mst@kernel.org \ --to=mst@redhat.com \ --cc=akpm@linux-foundation.org \ --cc=hannes@cmpxchg.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=mgorman@suse.de \ --cc=mhocko@kernel.org \ --cc=mhocko@suse.com \ --cc=rientjes@google.com \ --cc=vbabka@suse.cz \ --cc=viro@zeniv.linux.org.uk \ /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: linkBe 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.