[PATCH 6/7] arm64: Mark kernel page ranges contiguous

Catalin Marinas catalin.marinas at arm.com
Tue Oct 6 04:15:42 PDT 2015


On Fri, Oct 02, 2015 at 03:47:44PM -0500, Jeremy Linton wrote:
>  static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
> -				  unsigned long end, unsigned long pfn,
> +				  unsigned long end, phys_addr_t phys,
>  				  pgprot_t prot,
>  				  void *(*alloc)(unsigned long size))
>  {
>  	pte_t *pte;
> +	unsigned long next;
>  
>  	if (pmd_none(*pmd) || pmd_sect(*pmd)) {
>  		pte = alloc(PTRS_PER_PTE * sizeof(pte_t));
> @@ -104,10 +145,31 @@ static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
>  	BUG_ON(pmd_bad(*pmd));
>  
>  	pte = pte_offset_kernel(pmd, addr);
> -	do {
> -		set_pte(pte, pfn_pte(pfn, prot));
> -		pfn++;
> -	} while (pte++, addr += PAGE_SIZE, addr != end);
> +	if (!cont_linear_ptes)
> +		__populate_init_pte(pte, addr, end, phys, prot);
> +	else
> +	    do {
> +		next = min(end, (addr + CONT_SIZE) & CONT_MASK);
> +		if (((addr | next | phys) & CONT_RANGE_MASK) == 0) {

~CONT_MASK directly here? We don't expect addr/next/phys to not be page
aligned (and if they are, the condition fails anyway).

> +			/* a block of CONT_RANGE_SIZE PTEs */

We don't have a CONT_RANGE_SIZE macro, I guess that's CONT_RANGE (or
CONT_PTES if you rename it).

> +			__populate_init_pte(pte, addr, next, phys,
> +					    prot | __pgprot(PTE_CONT));
> +		} else {
> +			/*
> +			 * If the range being split is already inside of a
> +			 * contiguous range but this PTE isn't going to be
> +			 * contiguous, then we want to unmark the adjacent
> +			 * ranges, then update the portion of the range we
> +			 * are interrested in.
> +			 */
> +			 clear_cont_pte_range(pte, addr);
> +			 __populate_init_pte(pte, addr, next, phys, prot);
> +		}
> +
> +		pte += (next - addr) >> PAGE_SHIFT;
> +		phys += next - addr;
> +		addr = next;
> +	} while (addr != end);
>  }

-- 
Catalin



More information about the linux-arm-kernel mailing list