2014-04-15 11:14:23

by Liu Hua

[permalink] [raw]
Subject: [PATCH v3 0/2] change ARM linux memory layout to support 32 CPUs

This patch series change fixmap mapping region to suppport 32 CPUs.
Because the "top_pmd" covers 0xfffe0000 - 0xffffffff(2M). And part
is used by vector table. So I move this region down to 0xffc00000
- 0xffdffff.


I have tested the patches on arma9(2 CPUs) and arma15(16 CPUs) platforms

Changes from v2:
---------------
- Removed two macros: FIX_KMAP_BEGIN and FIX_KMAP_END;
- Unchanged DMA mapping region related documentation;

Changes from v1:
---------------
- changed documentation for ARM linux memory layout.
- moved fixmap mapping region, not just extended.


Liu Hua (2):
ARM : fixmap : remove FIX_KMAP_BEGIN and FIX_KMAP_END
ARM : change fixmap mapping region to support 32 CPUs

Documentation/arm/memory.txt | 2 +-
arch/arm/include/asm/fixmap.h | 21 ++++-----------------
arch/arm/include/asm/highmem.h | 1 +
arch/arm/mm/highmem.c | 33 ++++++++++++++++++++++++---------
arch/arm/mm/mmu.c | 4 ++++
5 files changed, 34 insertions(+), 27 deletions(-)

--
1.9.0


2014-04-15 11:14:46

by Liu Hua

[permalink] [raw]
Subject: [PATCH v3 1/2] ARM : fixmap : remove FIX_KMAP_BEGIN and FIX_KMAP_END

It seems that these two macros are not used by non
architecture specific code. And on ARM FIX_KMAP_BEGIN
equals zero.

This patch removes these two macros. Instead, using
FIX_KMAP_NR_PTES to tell the pte number belonged to
fixmap mapping region. The code will become clearer
when I introduce a bugfix on fixmap mapping region.

Reviewed-by: Nicolas Pitre <[email protected]>
Signed-off-by: Liu Hua <[email protected]>
---
arch/arm/include/asm/fixmap.h | 5 ++---
arch/arm/mm/highmem.c | 6 +++---
2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index bbae919..be55ebc 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -17,8 +17,7 @@
#define FIXADDR_TOP 0xfffe0000UL
#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)

-#define FIX_KMAP_BEGIN 0
-#define FIX_KMAP_END (FIXADDR_SIZE >> PAGE_SHIFT)
+#define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT)

#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT))
#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT)
@@ -27,7 +26,7 @@ extern void __this_fixmap_does_not_exist(void);

static inline unsigned long fix_to_virt(const unsigned int idx)
{
- if (idx >= FIX_KMAP_END)
+ if (idx >= FIX_KMAP_NR_PTES)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 21b9e1b..e05e8ad 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -63,7 +63,7 @@ void *kmap_atomic(struct page *page)
type = kmap_atomic_idx_push();

idx = type + KM_TYPE_NR * smp_processor_id();
- vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ vaddr = __fix_to_virt(idx);
#ifdef CONFIG_DEBUG_HIGHMEM
/*
* With debugging enabled, kunmap_atomic forces that entry to 0.
@@ -94,7 +94,7 @@ void __kunmap_atomic(void *kvaddr)
if (cache_is_vivt())
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
#ifdef CONFIG_DEBUG_HIGHMEM
- BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+ BUG_ON(vaddr != __fix_to_virt(idx));
set_top_pte(vaddr, __pte(0));
#else
(void) idx; /* to kill a warning */
@@ -117,7 +117,7 @@ void *kmap_atomic_pfn(unsigned long pfn)

type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR * smp_processor_id();
- vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ vaddr = __fix_to_virt(idx);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(!pte_none(get_top_pte(vaddr)));
#endif
--
1.9.0

2014-04-15 11:14:44

by Liu Hua

[permalink] [raw]
Subject: [PATCH v3 2/2] ARM : change fixmap mapping region to support 32 CPUs

In 32-bit ARM systems, the fixmap mapping region can support
no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
configure NR_CPUS up to 32. So there is a mismatch.

This patch moves fixmapping region downwards to region
0xffc00000-0xffe00000. Then the fixmap mapping region can
support up to 32 CPUs

Signed-off-by: Liu Hua <[email protected]>
---
Documentation/arm/memory.txt | 2 +-
arch/arm/include/asm/fixmap.h | 16 ++--------------
arch/arm/include/asm/highmem.h | 1 +
arch/arm/mm/highmem.c | 27 +++++++++++++++++++++------
arch/arm/mm/mmu.c | 4 ++++
5 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index 4bfb9ff..a9fc59b 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -41,7 +41,7 @@ fffe8000 fffeffff DTCM mapping area for platforms with
fffe0000 fffe7fff ITCM mapping area for platforms with
ITCM mounted inside the CPU.

-fff00000 fffdffff Fixmap mapping region. Addresses provided
+fffc0000 ffdfffff Fixmap mapping region. Addresses provided
by fix_to_virt() will be located here.

ffc00000 ffefffff DMA memory mapping region. Memory returned
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index be55ebc..74124b0 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -1,20 +1,8 @@
#ifndef _ASM_FIXMAP_H
#define _ASM_FIXMAP_H

-/*
- * Nothing too fancy for now.
- *
- * On ARM we already have well known fixed virtual addresses imposed by
- * the architecture such as the vector page which is located at 0xffff0000,
- * therefore a second level page table is already allocated covering
- * 0xfff00000 upwards.
- *
- * The cache flushing code in proc-xscale.S uses the virtual area between
- * 0xfffe0000 and 0xfffeffff.
- */
-
-#define FIXADDR_START 0xfff00000UL
-#define FIXADDR_TOP 0xfffe0000UL
+#define FIXADDR_START 0xffc00000UL
+#define FIXADDR_TOP 0xffe00000UL
#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)

#define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT)
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 91b99ab..5355795 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -18,6 +18,7 @@
} while (0)

extern pte_t *pkmap_page_table;
+extern pte_t *fixmap_page_table;

extern void *kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index e05e8ad..45aeaac 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -18,6 +18,21 @@
#include <asm/tlbflush.h>
#include "mm.h"

+pte_t *fixmap_page_table;
+
+static inline void set_fixmap_pte(int idx, pte_t pte)
+{
+ unsigned long vaddr = __fix_to_virt(idx);
+ set_pte_ext(fixmap_page_table + idx, pte, 0);
+ local_flush_tlb_kernel_page(vaddr);
+}
+
+static inline pte_t get_fixmap_pte(unsigned long vaddr)
+{
+ unsigned long idx = __virt_to_fix(vaddr);
+ return *(fixmap_page_table + idx);
+}
+
void *kmap(struct page *page)
{
might_sleep();
@@ -69,14 +84,14 @@ void *kmap_atomic(struct page *page)
* With debugging enabled, kunmap_atomic forces that entry to 0.
* Make sure it was indeed properly unmapped.
*/
- BUG_ON(!pte_none(get_top_pte(vaddr)));
+ BUG_ON(!pte_none(*(fixmap_page_table + idx)));
#endif
/*
* When debugging is off, kunmap_atomic leaves the previous mapping
* in place, so the contained TLB flush ensures the TLB is updated
* with the new mapping.
*/
- set_top_pte(vaddr, mk_pte(page, kmap_prot));
+ set_fixmap_pte(idx, mk_pte(page, kmap_prot));

return (void *)vaddr;
}
@@ -95,7 +110,7 @@ void __kunmap_atomic(void *kvaddr)
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(vaddr != __fix_to_virt(idx));
- set_top_pte(vaddr, __pte(0));
+ set_fixmap_pte(idx, __pte(0));
#else
(void) idx; /* to kill a warning */
#endif
@@ -119,9 +134,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
idx = type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(idx);
#ifdef CONFIG_DEBUG_HIGHMEM
- BUG_ON(!pte_none(get_top_pte(vaddr)));
+ BUG_ON(!pte_none(*(fixmap_page_table + idx)));
#endif
- set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
+ set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));

return (void *)vaddr;
}
@@ -133,5 +148,5 @@ struct page *kmap_atomic_to_page(const void *ptr)
if (vaddr < FIXADDR_START)
return virt_to_page(ptr);

- return pte_page(get_top_pte(vaddr));
+ return pte_page(get_fixmap_pte(vaddr));
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b68c6b2..09c0a16 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -35,6 +35,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
+#include <asm/fixmap.h>

#include "mm.h"
#include "tcm.h"
@@ -1359,6 +1360,9 @@ static void __init kmap_init(void)
#ifdef CONFIG_HIGHMEM
pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
PKMAP_BASE, _PAGE_KERNEL_TABLE);
+
+ fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START),
+ FIXADDR_START, _PAGE_KERNEL_TABLE);
#endif
}

--
1.9.0

2014-04-15 15:06:35

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] ARM : change fixmap mapping region to support 32 CPUs

On Tue, 15 Apr 2014, Liu Hua wrote:

> In 32-bit ARM systems, the fixmap mapping region can support
> no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
> configure NR_CPUS up to 32. So there is a mismatch.
>
> This patch moves fixmapping region downwards to region
> 0xffc00000-0xffe00000. Then the fixmap mapping region can
> support up to 32 CPUs
>
> Signed-off-by: Liu Hua <[email protected]>

Reviewed-by: Nicolas Pitre <[email protected]>

> ---
> Documentation/arm/memory.txt | 2 +-
> arch/arm/include/asm/fixmap.h | 16 ++--------------
> arch/arm/include/asm/highmem.h | 1 +
> arch/arm/mm/highmem.c | 27 +++++++++++++++++++++------
> arch/arm/mm/mmu.c | 4 ++++
> 5 files changed, 29 insertions(+), 21 deletions(-)
>
> diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
> index 4bfb9ff..a9fc59b 100644
> --- a/Documentation/arm/memory.txt
> +++ b/Documentation/arm/memory.txt
> @@ -41,7 +41,7 @@ fffe8000 fffeffff DTCM mapping area for platforms with
> fffe0000 fffe7fff ITCM mapping area for platforms with
> ITCM mounted inside the CPU.
>
> -fff00000 fffdffff Fixmap mapping region. Addresses provided
> +fffc0000 ffdfffff Fixmap mapping region. Addresses provided
> by fix_to_virt() will be located here.
>
> ffc00000 ffefffff DMA memory mapping region. Memory returned
> diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
> index be55ebc..74124b0 100644
> --- a/arch/arm/include/asm/fixmap.h
> +++ b/arch/arm/include/asm/fixmap.h
> @@ -1,20 +1,8 @@
> #ifndef _ASM_FIXMAP_H
> #define _ASM_FIXMAP_H
>
> -/*
> - * Nothing too fancy for now.
> - *
> - * On ARM we already have well known fixed virtual addresses imposed by
> - * the architecture such as the vector page which is located at 0xffff0000,
> - * therefore a second level page table is already allocated covering
> - * 0xfff00000 upwards.
> - *
> - * The cache flushing code in proc-xscale.S uses the virtual area between
> - * 0xfffe0000 and 0xfffeffff.
> - */
> -
> -#define FIXADDR_START 0xfff00000UL
> -#define FIXADDR_TOP 0xfffe0000UL
> +#define FIXADDR_START 0xffc00000UL
> +#define FIXADDR_TOP 0xffe00000UL
> #define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
>
> #define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT)
> diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
> index 91b99ab..5355795 100644
> --- a/arch/arm/include/asm/highmem.h
> +++ b/arch/arm/include/asm/highmem.h
> @@ -18,6 +18,7 @@
> } while (0)
>
> extern pte_t *pkmap_page_table;
> +extern pte_t *fixmap_page_table;
>
> extern void *kmap_high(struct page *page);
> extern void kunmap_high(struct page *page);
> diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
> index e05e8ad..45aeaac 100644
> --- a/arch/arm/mm/highmem.c
> +++ b/arch/arm/mm/highmem.c
> @@ -18,6 +18,21 @@
> #include <asm/tlbflush.h>
> #include "mm.h"
>
> +pte_t *fixmap_page_table;
> +
> +static inline void set_fixmap_pte(int idx, pte_t pte)
> +{
> + unsigned long vaddr = __fix_to_virt(idx);
> + set_pte_ext(fixmap_page_table + idx, pte, 0);
> + local_flush_tlb_kernel_page(vaddr);
> +}
> +
> +static inline pte_t get_fixmap_pte(unsigned long vaddr)
> +{
> + unsigned long idx = __virt_to_fix(vaddr);
> + return *(fixmap_page_table + idx);
> +}
> +
> void *kmap(struct page *page)
> {
> might_sleep();
> @@ -69,14 +84,14 @@ void *kmap_atomic(struct page *page)
> * With debugging enabled, kunmap_atomic forces that entry to 0.
> * Make sure it was indeed properly unmapped.
> */
> - BUG_ON(!pte_none(get_top_pte(vaddr)));
> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
> #endif
> /*
> * When debugging is off, kunmap_atomic leaves the previous mapping
> * in place, so the contained TLB flush ensures the TLB is updated
> * with the new mapping.
> */
> - set_top_pte(vaddr, mk_pte(page, kmap_prot));
> + set_fixmap_pte(idx, mk_pte(page, kmap_prot));
>
> return (void *)vaddr;
> }
> @@ -95,7 +110,7 @@ void __kunmap_atomic(void *kvaddr)
> __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
> #ifdef CONFIG_DEBUG_HIGHMEM
> BUG_ON(vaddr != __fix_to_virt(idx));
> - set_top_pte(vaddr, __pte(0));
> + set_fixmap_pte(idx, __pte(0));
> #else
> (void) idx; /* to kill a warning */
> #endif
> @@ -119,9 +134,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
> idx = type + KM_TYPE_NR * smp_processor_id();
> vaddr = __fix_to_virt(idx);
> #ifdef CONFIG_DEBUG_HIGHMEM
> - BUG_ON(!pte_none(get_top_pte(vaddr)));
> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
> #endif
> - set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
> + set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
>
> return (void *)vaddr;
> }
> @@ -133,5 +148,5 @@ struct page *kmap_atomic_to_page(const void *ptr)
> if (vaddr < FIXADDR_START)
> return virt_to_page(ptr);
>
> - return pte_page(get_top_pte(vaddr));
> + return pte_page(get_fixmap_pte(vaddr));
> }
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index b68c6b2..09c0a16 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -35,6 +35,7 @@
> #include <asm/mach/arch.h>
> #include <asm/mach/map.h>
> #include <asm/mach/pci.h>
> +#include <asm/fixmap.h>
>
> #include "mm.h"
> #include "tcm.h"
> @@ -1359,6 +1360,9 @@ static void __init kmap_init(void)
> #ifdef CONFIG_HIGHMEM
> pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
> PKMAP_BASE, _PAGE_KERNEL_TABLE);
> +
> + fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START),
> + FIXADDR_START, _PAGE_KERNEL_TABLE);
> #endif
> }
>
> --
> 1.9.0
>

2014-04-22 21:32:13

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [PATCH v3 0/2] change ARM linux memory layout to support 32 CPUs

On Tue, Apr 15, 2014 at 07:06:05PM +0800, Liu Hua wrote:
> This patch series change fixmap mapping region to suppport 32 CPUs.
> Because the "top_pmd" covers 0xfffe0000 - 0xffffffff(2M). And part
> is used by vector table. So I move this region down to 0xffc00000
> - 0xffdffff.

Can you explain why you have submitted these patches to my patch tracker
with a copy to [email protected] ?

What makes these qualify for stable tree inclusion? What regression are
they fixing?

We don't put patches into the stable tree for things that /never/ worked
in the past. We've never supported 32 CPUs so I don't think these
qualify.

--
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

2014-04-22 23:50:53

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [PATCH v3 0/2] change ARM linux memory layout to support 32 CPUs

On Tue, 22 Apr 2014, Russell King - ARM Linux wrote:

> On Tue, Apr 15, 2014 at 07:06:05PM +0800, Liu Hua wrote:
> > This patch series change fixmap mapping region to suppport 32 CPUs.
> > Because the "top_pmd" covers 0xfffe0000 - 0xffffffff(2M). And part
> > is used by vector table. So I move this region down to 0xffc00000
> > - 0xffdffff.
>
> Can you explain why you have submitted these patches to my patch tracker
> with a copy to [email protected] ?
>
> What makes these qualify for stable tree inclusion? What regression are
> they fixing?
>
> We don't put patches into the stable tree for things that /never/ worked
> in the past. We've never supported 32 CPUs so I don't think these
> qualify.

Indeed. The stable qualifier should be dropped.


Nicolas

2014-06-10 06:54:38

by Liu Hua

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] ARM : change fixmap mapping region to support 32 CPUs

On 2014/5/31 3:25, Nicolas Pitre Wrote:
> On Fri, 30 May 2014, Rob Herring wrote:
>
>> There's work in flight to support early_ioremap, early console, and RO
>> text patching which all use the fixmap region.
>>
>> There's a couple of options to solve this:
>>
>> - Only support up to 16 cpus. It could be anywhere between 17-31, but
>> that seems somewhat unlikely. Are we really ever going to see 32-bit
>> 32 core systems?
>
> I wouldn't rule that out. I've seen 16-core ARM chips in 2008 (although
> they didn't go into production). Silly limitations like that always
> come back to bite you. And we have better alternatives.New

Now our team is woring on arma15 with 16 CPUs.
>
>> - Reduce KM_TYPE_NR from 16 to 15. Based on the comment for it, we
>> probably don't want to do that. Is increasing it to the default of 20
>> worthwhile? Some of the options here would allow doing that.
>> - Add 0xffe00000-0xfff00000 to the fixmap region. This would make
>> fixmap span 2 PMDs with the top PMD having a mixture of uses like we
>> had before.
>
> That would be my preferred approach. Note here it could be
> 0xffe00000-0xfffe0000 to include the whole of the previous fixmap area
> curently unused.
>
>> - push the PCI i/o space down to 0xfec00000 and make fixmap 4MB. This
>> is a cleaner solution as the 2 PMDs are only used for fixmap. This may
>> require some static mapping adjustments on some platforms.
>
> No need. With the latest changes, the fixmap area is between 0xffc00000
> and 0xffe00000 (there is apparently a mistake in
> Documentation/arm/memory.txt). So currently 0xff000000-0xffc00000 is
> free, which makes the fixmap area far away from the PCI i/o area with
> plenti of space in between.
>
>> - Same as previous option, but convert the PCI i/o space to fixmap
>> entries. We don't really need all 2MB for PCI.
>
> See above.
>
>> Also, there is an error in the documentation below:
>>
>>>
>>> Signed-off-by: Liu Hua <[email protected]>
>>> ---
>>> Documentation/arm/memory.txt | 2 +-
>
> Yep, good that you spotted it as well. I failed to catch it during my
> review so I'll send a patch.
>

Very sorry for the mistake and ignoreing this mail. Maybe I should imporve
my email client!

Thanks again for Nicolas.

Thanks,
Liu Hua
>
> Nicolas
>
> .
>