* [PATCH v6 0/2] Generalize vmemmap_populate_hugepages to sparc @ 2026-02-01 6:35 chengkaitao 2026-02-01 6:35 ` [PATCH v6 1/2] sparc: Use vmemmap_populate_hugepages for vmemmap_populate chengkaitao 2026-02-01 6:35 ` [PATCH v6 2/2] mm: Convert vmemmap_p?d_populate() to static functions chengkaitao 0 siblings, 2 replies; 7+ messages in thread From: chengkaitao @ 2026-02-01 6:35 UTC (permalink / raw) To: davem, andreas, akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko Cc: kevin.brodsky, dave.hansen, ziy, chengkaitao, willy, zhengqi.arch, sparclinux, linux-kernel, linux-mm, chengkaitao Change sparc's implementation of vmemmap_populate() using vmemmap_populate_hugepages() to streamline the code. Another benefit is that it allows us to eliminate the external declarations of vmemmap_p?d_populate functions and convert them to static functions. Since vmemmap_populate_hugepages may fallback to vmemmap_populate- _basepages, which differs from sparc's original implementation. During the v1 discussion with Mike Rapoport, sparc uses base pages in the kernel page tables, so it should be able to use them in vmemmap as well. Consequently, no additional special handling is required. Changes in v6: - Ignore handling of altmap Changes in v5: - Remove [PATCH v4 3/3] sparc: Remove unnecessary whitespace Changes in v4: - Add commit message - Add verification that pmd actually maps a large page in the vmemmap_check_pmd function Changes in v3: - Allow sparc to fallback to vmemmap_populate_basepages - Convert vmemmap_p?d_populate() to static functions - Split the v1 patch Changes in v2: - Revert the whitespace deletions - Change vmemmap_false_pmd to vmemmap_pte_fallback_allowed Link to V5: https://lore.kernel.org/all/20260111074453.66728-1-pilgrimtao@gmail.com/ Link to V4: https://lore.kernel.org/all/20251219115812.65855-1-pilgrimtao@gmail.com/ Link to V3: https://lore.kernel.org/all/20251218174749.45965-1-pilgrimtao@gmail.com/ Link to V2: https://lore.kernel.org/all/20251218130957.36892-1-pilgrimtao@gmail.com/ Link to V1: https://lore.kernel.org/all/20251217120858.18713-1-pilgrimtao@gmail.com/ Chengkaitao (2): sparc: Use vmemmap_populate_hugepages for vmemmap_populate mm: Convert vmemmap_p?d_populate() to static functions arch/sparc/mm/init_64.c | 47 ++++++++++++++--------------------------- include/linux/mm.h | 7 ------ mm/sparse-vmemmap.c | 10 ++++----- 3 files changed, 21 insertions(+), 43 deletions(-) -- 2.50.1 (Apple Git-155) ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v6 1/2] sparc: Use vmemmap_populate_hugepages for vmemmap_populate 2026-02-01 6:35 [PATCH v6 0/2] Generalize vmemmap_populate_hugepages to sparc chengkaitao @ 2026-02-01 6:35 ` chengkaitao 2026-03-18 15:07 ` Andreas Larsson 2026-02-01 6:35 ` [PATCH v6 2/2] mm: Convert vmemmap_p?d_populate() to static functions chengkaitao 1 sibling, 1 reply; 7+ messages in thread From: chengkaitao @ 2026-02-01 6:35 UTC (permalink / raw) To: davem, andreas, akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko Cc: kevin.brodsky, dave.hansen, ziy, chengkaitao, willy, zhengqi.arch, sparclinux, linux-kernel, linux-mm From: Chengkaitao <chengkaitao@kylinos.cn> 1. In the SPARC architecture, reimplement vmemmap_populate using vmemmap_populate_hugepages. 2. Allow the SPARC arch to fallback to vmemmap_populate_basepages(), when vmemmap_alloc_block returns NULL. Signed-off-by: Chengkaitao <chengkaitao@kylinos.cn> --- arch/sparc/mm/init_64.c | 47 ++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index df9f7c444c39..f1981adc99ac 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -2581,8 +2581,8 @@ unsigned long _PAGE_CACHE __read_mostly; EXPORT_SYMBOL(_PAGE_CACHE); #ifdef CONFIG_SPARSEMEM_VMEMMAP -int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, - int node, struct vmem_altmap *altmap) +void __meminit vmemmap_set_pmd(pmd_t *pmd, void *p, int node, + unsigned long addr, unsigned long next) { unsigned long pte_base; @@ -2595,39 +2595,24 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, pte_base |= _PAGE_PMD_HUGE; - vstart = vstart & PMD_MASK; - vend = ALIGN(vend, PMD_SIZE); - for (; vstart < vend; vstart += PMD_SIZE) { - pgd_t *pgd = vmemmap_pgd_populate(vstart, node); - unsigned long pte; - p4d_t *p4d; - pud_t *pud; - pmd_t *pmd; - - if (!pgd) - return -ENOMEM; - - p4d = vmemmap_p4d_populate(pgd, vstart, node); - if (!p4d) - return -ENOMEM; - - pud = vmemmap_pud_populate(p4d, vstart, node); - if (!pud) - return -ENOMEM; + pmd_val(*pmd) = pte_base | __pa(p); +} - pmd = pmd_offset(pud, vstart); - pte = pmd_val(*pmd); - if (!(pte & _PAGE_VALID)) { - void *block = vmemmap_alloc_block(PMD_SIZE, node); +int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node, + unsigned long addr, unsigned long next) +{ + int large = pmd_leaf(*pmdp); - if (!block) - return -ENOMEM; + if (large) + vmemmap_verify((pte_t *)pmdp, node, addr, next); - pmd_val(*pmd) = pte_base | __pa(block); - } - } + return large; +} - return 0; +int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, + int node, struct vmem_altmap *altmap) +{ + return vmemmap_populate_hugepages(vstart, vend, node, NULL); } #endif /* CONFIG_SPARSEMEM_VMEMMAP */ -- 2.50.1 (Apple Git-155) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v6 1/2] sparc: Use vmemmap_populate_hugepages for vmemmap_populate 2026-02-01 6:35 ` [PATCH v6 1/2] sparc: Use vmemmap_populate_hugepages for vmemmap_populate chengkaitao @ 2026-03-18 15:07 ` Andreas Larsson 0 siblings, 0 replies; 7+ messages in thread From: Andreas Larsson @ 2026-03-18 15:07 UTC (permalink / raw) To: chengkaitao, davem, andreas, akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, Andrew Morton Cc: kevin.brodsky, dave.hansen, ziy, chengkaitao, willy, zhengqi.arch, sparclinux, linux-kernel, linux-mm On 2026-02-01 07:35, chengkaitao wrote: > From: Chengkaitao <chengkaitao@kylinos.cn> > > 1. In the SPARC architecture, reimplement vmemmap_populate using > vmemmap_populate_hugepages. > 2. Allow the SPARC arch to fallback to vmemmap_populate_basepages(), > when vmemmap_alloc_block returns NULL. > > Signed-off-by: Chengkaitao <chengkaitao@kylinos.cn> > --- > arch/sparc/mm/init_64.c | 47 ++++++++++++++--------------------------- > 1 file changed, 16 insertions(+), 31 deletions(-) > > diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c > index df9f7c444c39..f1981adc99ac 100644 > --- a/arch/sparc/mm/init_64.c > +++ b/arch/sparc/mm/init_64.c > @@ -2581,8 +2581,8 @@ unsigned long _PAGE_CACHE __read_mostly; > EXPORT_SYMBOL(_PAGE_CACHE); > > #ifdef CONFIG_SPARSEMEM_VMEMMAP > -int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, > - int node, struct vmem_altmap *altmap) > +void __meminit vmemmap_set_pmd(pmd_t *pmd, void *p, int node, > + unsigned long addr, unsigned long next) > { > unsigned long pte_base; > > @@ -2595,39 +2595,24 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, > > pte_base |= _PAGE_PMD_HUGE; > > - vstart = vstart & PMD_MASK; > - vend = ALIGN(vend, PMD_SIZE); > - for (; vstart < vend; vstart += PMD_SIZE) { > - pgd_t *pgd = vmemmap_pgd_populate(vstart, node); > - unsigned long pte; > - p4d_t *p4d; > - pud_t *pud; > - pmd_t *pmd; > - > - if (!pgd) > - return -ENOMEM; > - > - p4d = vmemmap_p4d_populate(pgd, vstart, node); > - if (!p4d) > - return -ENOMEM; > - > - pud = vmemmap_pud_populate(p4d, vstart, node); > - if (!pud) > - return -ENOMEM; > + pmd_val(*pmd) = pte_base | __pa(p); > +} > > - pmd = pmd_offset(pud, vstart); > - pte = pmd_val(*pmd); > - if (!(pte & _PAGE_VALID)) { > - void *block = vmemmap_alloc_block(PMD_SIZE, node); > +int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node, > + unsigned long addr, unsigned long next) > +{ > + int large = pmd_leaf(*pmdp); > > - if (!block) > - return -ENOMEM; > + if (large) > + vmemmap_verify((pte_t *)pmdp, node, addr, next); > > - pmd_val(*pmd) = pte_base | __pa(block); > - } > - } > + return large; > +} > > - return 0; > +int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, > + int node, struct vmem_altmap *altmap) > +{ > + return vmemmap_populate_hugepages(vstart, vend, node, NULL); > } > #endif /* CONFIG_SPARSEMEM_VMEMMAP */ > Tested-by: Andreas Larsson <andreas@gaisler.com> Acked-by: Andreas Larsson <andreas@gaisler.com> I assume this goes through the mm tree. Cheers, Andreas ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v6 2/2] mm: Convert vmemmap_p?d_populate() to static functions 2026-02-01 6:35 [PATCH v6 0/2] Generalize vmemmap_populate_hugepages to sparc chengkaitao 2026-02-01 6:35 ` [PATCH v6 1/2] sparc: Use vmemmap_populate_hugepages for vmemmap_populate chengkaitao @ 2026-02-01 6:35 ` chengkaitao 2026-02-02 9:09 ` David Hildenbrand (arm) 2026-03-31 3:16 ` Chengkaitao 1 sibling, 2 replies; 7+ messages in thread From: chengkaitao @ 2026-02-01 6:35 UTC (permalink / raw) To: davem, andreas, akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko Cc: kevin.brodsky, dave.hansen, ziy, chengkaitao, willy, zhengqi.arch, sparclinux, linux-kernel, linux-mm From: Chengkaitao <chengkaitao@kylinos.cn> Since the vmemmap_p?d_populate functions are unused outside the mm subsystem, we can remove their external declarations and convert them to static functions. Signed-off-by: Chengkaitao <chengkaitao@kylinos.cn> --- include/linux/mm.h | 7 ------- mm/sparse-vmemmap.c | 10 +++++----- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index f0d5be9dc736..10a0664b4ce2 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -4238,13 +4238,6 @@ unsigned long section_map_size(void); struct page * __populate_section_memmap(unsigned long pfn, unsigned long nr_pages, int nid, struct vmem_altmap *altmap, struct dev_pagemap *pgmap); -pgd_t *vmemmap_pgd_populate(unsigned long addr, int node); -p4d_t *vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node); -pud_t *vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node); -pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node); -pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, - struct vmem_altmap *altmap, unsigned long ptpfn, - unsigned long flags); void *vmemmap_alloc_block(unsigned long size, int node); struct vmem_altmap; void *vmemmap_alloc_block_buf(unsigned long size, int node, diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index 37522d6cb398..67f9a08c2376 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -151,7 +151,7 @@ void __meminit vmemmap_verify(pte_t *pte, int node, start, end - 1); } -pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, +static pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, struct vmem_altmap *altmap, unsigned long ptpfn, unsigned long flags) { @@ -195,7 +195,7 @@ static void * __meminit vmemmap_alloc_block_zero(unsigned long size, int node) return p; } -pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node) +static pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node) { pmd_t *pmd = pmd_offset(pud, addr); if (pmd_none(*pmd)) { @@ -208,7 +208,7 @@ pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node) return pmd; } -pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node) +static pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node) { pud_t *pud = pud_offset(p4d, addr); if (pud_none(*pud)) { @@ -221,7 +221,7 @@ pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node) return pud; } -p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node) +static p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node) { p4d_t *p4d = p4d_offset(pgd, addr); if (p4d_none(*p4d)) { @@ -234,7 +234,7 @@ p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node) return p4d; } -pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node) +static pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node) { pgd_t *pgd = pgd_offset_k(addr); if (pgd_none(*pgd)) { -- 2.50.1 (Apple Git-155) ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v6 2/2] mm: Convert vmemmap_p?d_populate() to static functions 2026-02-01 6:35 ` [PATCH v6 2/2] mm: Convert vmemmap_p?d_populate() to static functions chengkaitao @ 2026-02-02 9:09 ` David Hildenbrand (arm) 2026-03-31 3:16 ` Chengkaitao 1 sibling, 0 replies; 7+ messages in thread From: David Hildenbrand (arm) @ 2026-02-02 9:09 UTC (permalink / raw) To: chengkaitao, davem, andreas, akpm, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko Cc: kevin.brodsky, dave.hansen, ziy, chengkaitao, willy, zhengqi.arch, sparclinux, linux-kernel, linux-mm On 2/1/26 07:35, chengkaitao wrote: > From: Chengkaitao <chengkaitao@kylinos.cn> > > Since the vmemmap_p?d_populate functions are unused outside the mm > subsystem, we can remove their external declarations and convert > them to static functions. > > Signed-off-by: Chengkaitao <chengkaitao@kylinos.cn> > --- Acked-by: David Hildenbrand (arm) <david@kernel.org> -- Cheers David ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v6 2/2] mm: Convert vmemmap_p?d_populate() to static functions 2026-02-01 6:35 ` [PATCH v6 2/2] mm: Convert vmemmap_p?d_populate() to static functions chengkaitao 2026-02-02 9:09 ` David Hildenbrand (arm) @ 2026-03-31 3:16 ` Chengkaitao 2026-03-31 3:54 ` Andrew Morton 1 sibling, 1 reply; 7+ messages in thread From: Chengkaitao @ 2026-03-31 3:16 UTC (permalink / raw) To: akpm; +Cc: linux-mm, David Hildenbrand (Red Hat), llvm, oe-kbuild-all Hi Andrew Morton, I noticed this patch was dropped; the failure report is here: https://lore.kernel.org/all/202603251338.grra8xt7-lkp@intel.com/#R Could this be a false positive? The series has two patches: the first one already removed references to vmemmap_p?d_populate() on sparc; see: https://lore.kernel.org/all/20260201063532.44807-3-pilgrimtao@gmail.com/T/#mefaa36aeff173d08f0508cd44be46e830c067fe9 Might the build error be because only the second patch was applied, without the first? On Sun, Feb 1, 2026 at 2:35 PM chengkaitao <pilgrimtao@gmail.com> wrote: > > From: Chengkaitao <chengkaitao@kylinos.cn> > > Since the vmemmap_p?d_populate functions are unused outside the mm > subsystem, we can remove their external declarations and convert > them to static functions. > > Signed-off-by: Chengkaitao <chengkaitao@kylinos.cn> > --- > include/linux/mm.h | 7 ------- > mm/sparse-vmemmap.c | 10 +++++----- > 2 files changed, 5 insertions(+), 12 deletions(-) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index f0d5be9dc736..10a0664b4ce2 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -4238,13 +4238,6 @@ unsigned long section_map_size(void); > struct page * __populate_section_memmap(unsigned long pfn, > unsigned long nr_pages, int nid, struct vmem_altmap *altmap, > struct dev_pagemap *pgmap); > -pgd_t *vmemmap_pgd_populate(unsigned long addr, int node); > -p4d_t *vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node); > -pud_t *vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node); > -pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node); > -pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, > - struct vmem_altmap *altmap, unsigned long ptpfn, > - unsigned long flags); > void *vmemmap_alloc_block(unsigned long size, int node); > struct vmem_altmap; > void *vmemmap_alloc_block_buf(unsigned long size, int node, > diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c > index 37522d6cb398..67f9a08c2376 100644 > --- a/mm/sparse-vmemmap.c > +++ b/mm/sparse-vmemmap.c > @@ -151,7 +151,7 @@ void __meminit vmemmap_verify(pte_t *pte, int node, > start, end - 1); > } > > -pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, > +static pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node, > struct vmem_altmap *altmap, > unsigned long ptpfn, unsigned long flags) > { > @@ -195,7 +195,7 @@ static void * __meminit vmemmap_alloc_block_zero(unsigned long size, int node) > return p; > } > > -pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node) > +static pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node) > { > pmd_t *pmd = pmd_offset(pud, addr); > if (pmd_none(*pmd)) { > @@ -208,7 +208,7 @@ pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node) > return pmd; > } > > -pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node) > +static pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node) > { > pud_t *pud = pud_offset(p4d, addr); > if (pud_none(*pud)) { > @@ -221,7 +221,7 @@ pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node) > return pud; > } > > -p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node) > +static p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node) > { > p4d_t *p4d = p4d_offset(pgd, addr); > if (p4d_none(*p4d)) { > @@ -234,7 +234,7 @@ p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node) > return p4d; > } > > -pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node) > +static pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node) > { > pgd_t *pgd = pgd_offset_k(addr); > if (pgd_none(*pgd)) { > -- > 2.50.1 (Apple Git-155) > -- Yours, Chengkaitao ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v6 2/2] mm: Convert vmemmap_p?d_populate() to static functions 2026-03-31 3:16 ` Chengkaitao @ 2026-03-31 3:54 ` Andrew Morton 0 siblings, 0 replies; 7+ messages in thread From: Andrew Morton @ 2026-03-31 3:54 UTC (permalink / raw) To: Chengkaitao; +Cc: linux-mm, David Hildenbrand (Red Hat), llvm, oe-kbuild-all On Tue, 31 Mar 2026 11:16:33 +0800 Chengkaitao <pilgrimtao@gmail.com> wrote: > Hi Andrew Morton, > > I noticed this patch was dropped; the failure report is here: > https://lore.kernel.org/all/202603251338.grra8xt7-lkp@intel.com/#R > > Could this be a false positive? The series has two patches: the first > one already removed references to vmemmap_p?d_populate() on sparc; see: > https://lore.kernel.org/all/20260201063532.44807-3-pilgrimtao@gmail.com/T/#mefaa36aeff173d08f0508cd44be46e830c067fe9 > > Might the build error be because only the second patch was applied, > without the first? There was some confusion over a later patch which was there to fix an earlier patch, only the earlier patch was dropped! Sorry 'bout that. Can you please resend the patch after -rc1 and we'll try again. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-03-31 3:54 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-02-01 6:35 [PATCH v6 0/2] Generalize vmemmap_populate_hugepages to sparc chengkaitao 2026-02-01 6:35 ` [PATCH v6 1/2] sparc: Use vmemmap_populate_hugepages for vmemmap_populate chengkaitao 2026-03-18 15:07 ` Andreas Larsson 2026-02-01 6:35 ` [PATCH v6 2/2] mm: Convert vmemmap_p?d_populate() to static functions chengkaitao 2026-02-02 9:09 ` David Hildenbrand (arm) 2026-03-31 3:16 ` Chengkaitao 2026-03-31 3:54 ` Andrew Morton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox