powerpc: use mm zones more sensibly
Powerpc has somewhat odd usage where ZONE_DMA is used for all memory on common 64-bit configfs, and ZONE_DMA32 is used for 31-bit schemes. Move to a scheme closer to what other architectures use (and I dare to say the intent of the system): - ZONE_DMA: optionally for memory < 31-bit (64-bit embedded only) - ZONE_NORMAL: everything addressable by the kernel - ZONE_HIGHMEM: memory > 32-bit for 32-bit kernels Also provide information on how ZONE_DMA is used by defining ARCH_ZONE_DMA_BITS. Contains various fixes from Benjamin Herrenschmidt. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
f3e5a8579c
commit
25078dc1f7
@ -375,9 +375,9 @@ config PPC_ADV_DEBUG_DAC_RANGE
|
||||
depends on PPC_ADV_DEBUG_REGS && 44x
|
||||
default y
|
||||
|
||||
config ZONE_DMA32
|
||||
config ZONE_DMA
|
||||
bool
|
||||
default y if PPC64
|
||||
default y if PPC_BOOK3E_64
|
||||
|
||||
config PGTABLE_LEVELS
|
||||
int
|
||||
@ -870,10 +870,6 @@ config ISA
|
||||
have an IBM RS/6000 or pSeries machine, say Y. If you have an
|
||||
embedded board, consult your board documentation.
|
||||
|
||||
config ZONE_DMA
|
||||
bool
|
||||
default y
|
||||
|
||||
config GENERIC_ISA_DMA
|
||||
bool
|
||||
depends on ISA_DMA_API
|
||||
|
@ -340,4 +340,6 @@ struct vm_area_struct;
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#include <asm/slice.h>
|
||||
|
||||
#define ARCH_ZONE_DMA_BITS 31
|
||||
|
||||
#endif /* _ASM_POWERPC_PAGE_H */
|
||||
|
@ -66,7 +66,6 @@ extern unsigned long empty_zero_page[];
|
||||
|
||||
extern pgd_t swapper_pg_dir[];
|
||||
|
||||
void limit_zone_pfn(enum zone_type zone, unsigned long max_pfn);
|
||||
int dma_pfn_limit_to_zone(u64 pfn_limit);
|
||||
extern void paging_init(void);
|
||||
|
||||
|
@ -108,12 +108,8 @@ int __init swiotlb_setup_bus_notifier(void)
|
||||
|
||||
void __init swiotlb_detect_4g(void)
|
||||
{
|
||||
if ((memblock_end_of_DRAM() - 1) > 0xffffffff) {
|
||||
if ((memblock_end_of_DRAM() - 1) > 0xffffffff)
|
||||
ppc_swiotlb_enable = 1;
|
||||
#ifdef CONFIG_ZONE_DMA32
|
||||
limit_zone_pfn(ZONE_DMA32, (1ULL << 32) >> PAGE_SHIFT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int __init check_swiotlb_enabled(void)
|
||||
|
@ -50,7 +50,8 @@ static int dma_nommu_dma_supported(struct device *dev, u64 mask)
|
||||
return 1;
|
||||
|
||||
#ifdef CONFIG_FSL_SOC
|
||||
/* Freescale gets another chance via ZONE_DMA/ZONE_DMA32, however
|
||||
/*
|
||||
* Freescale gets another chance via ZONE_DMA, however
|
||||
* that will have to be refined if/when they support iommus
|
||||
*/
|
||||
return 1;
|
||||
@ -88,13 +89,10 @@ void *__dma_nommu_alloc_coherent(struct device *dev, size_t size,
|
||||
}
|
||||
|
||||
switch (zone) {
|
||||
#ifdef CONFIG_ZONE_DMA
|
||||
case ZONE_DMA:
|
||||
flag |= GFP_DMA;
|
||||
break;
|
||||
#ifdef CONFIG_ZONE_DMA32
|
||||
case ZONE_DMA32:
|
||||
flag |= GFP_DMA32;
|
||||
break;
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_FSL_SOC */
|
||||
|
@ -246,35 +246,19 @@ static int __init mark_nonram_nosave(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool zone_limits_final;
|
||||
|
||||
/*
|
||||
* The memory zones past TOP_ZONE are managed by generic mm code.
|
||||
* These should be set to zero since that's what every other
|
||||
* architecture does.
|
||||
* Zones usage:
|
||||
*
|
||||
* We setup ZONE_DMA to be 31-bits on all platforms and ZONE_NORMAL to be
|
||||
* everything else. GFP_DMA32 page allocations automatically fall back to
|
||||
* ZONE_DMA.
|
||||
*
|
||||
* By using 31-bit unconditionally, we can exploit ARCH_ZONE_DMA_BITS to
|
||||
* inform the generic DMA mapping code. 32-bit only devices (if not handled
|
||||
* by an IOMMU anyway) will take a first dip into ZONE_NORMAL and get
|
||||
* otherwise served by ZONE_DMA.
|
||||
*/
|
||||
static unsigned long max_zone_pfns[MAX_NR_ZONES] = {
|
||||
[0 ... TOP_ZONE ] = ~0UL,
|
||||
[TOP_ZONE + 1 ... MAX_NR_ZONES - 1] = 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Restrict the specified zone and all more restrictive zones
|
||||
* to be below the specified pfn. May not be called after
|
||||
* paging_init().
|
||||
*/
|
||||
void __init limit_zone_pfn(enum zone_type zone, unsigned long pfn_limit)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (WARN_ON(zone_limits_final))
|
||||
return;
|
||||
|
||||
for (i = zone; i >= 0; i--) {
|
||||
if (max_zone_pfns[i] > pfn_limit)
|
||||
max_zone_pfns[i] = pfn_limit;
|
||||
}
|
||||
}
|
||||
static unsigned long max_zone_pfns[MAX_NR_ZONES];
|
||||
|
||||
/*
|
||||
* Find the least restrictive zone that is entirely below the
|
||||
@ -324,11 +308,14 @@ void __init paging_init(void)
|
||||
printk(KERN_DEBUG "Memory hole size: %ldMB\n",
|
||||
(long int)((top_of_ram - total_ram) >> 20));
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
limit_zone_pfn(ZONE_NORMAL, lowmem_end_addr >> PAGE_SHIFT);
|
||||
#ifdef CONFIG_ZONE_DMA
|
||||
max_zone_pfns[ZONE_DMA] = min(max_low_pfn, 0x7fffffffUL >> PAGE_SHIFT);
|
||||
#endif
|
||||
limit_zone_pfn(TOP_ZONE, top_of_ram >> PAGE_SHIFT);
|
||||
zone_limits_final = true;
|
||||
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
max_zone_pfns[ZONE_HIGHMEM] = max_pfn;
|
||||
#endif
|
||||
|
||||
free_area_init_nodes(max_zone_pfns);
|
||||
|
||||
mark_nonram_nosave();
|
||||
|
@ -68,16 +68,6 @@ void __init corenet_gen_setup_arch(void)
|
||||
|
||||
swiotlb_detect_4g();
|
||||
|
||||
#if defined(CONFIG_FSL_PCI) && defined(CONFIG_ZONE_DMA32)
|
||||
/*
|
||||
* Inbound windows don't cover the full lower 4 GiB
|
||||
* due to conflicts with PCICSRBAR and outbound windows,
|
||||
* so limit the DMA32 zone to 2 GiB, to allow consistent
|
||||
* allocations to succeed.
|
||||
*/
|
||||
limit_zone_pfn(ZONE_DMA32, 1UL << (31 - PAGE_SHIFT));
|
||||
#endif
|
||||
|
||||
pr_info("%s board\n", ppc_md.name);
|
||||
|
||||
mpc85xx_qe_init();
|
||||
|
@ -45,15 +45,6 @@ static void __init qemu_e500_setup_arch(void)
|
||||
|
||||
fsl_pci_assign_primary();
|
||||
swiotlb_detect_4g();
|
||||
#if defined(CONFIG_FSL_PCI) && defined(CONFIG_ZONE_DMA32)
|
||||
/*
|
||||
* Inbound windows don't cover the full lower 4 GiB
|
||||
* due to conflicts with PCICSRBAR and outbound windows,
|
||||
* so limit the DMA32 zone to 2 GiB, to allow consistent
|
||||
* allocations to succeed.
|
||||
*/
|
||||
limit_zone_pfn(ZONE_DMA32, 1UL << (31 - PAGE_SHIFT));
|
||||
#endif
|
||||
mpc85xx_smp_init();
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ enum zone_type {
|
||||
* Architecture Limit
|
||||
* ---------------------------
|
||||
* parisc, ia64, sparc <4G
|
||||
* s390 <2G
|
||||
* s390, powerpc <2G
|
||||
* arm Various
|
||||
* alpha Unlimited or 0-16MB.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user