svn commit: r208589 - head/sys/mips/mips

Alan Cox alc at cs.rice.edu
Tue Jun 1 21:53:31 UTC 2010


On 5/27/2010 5:05 AM, Jayachandran C. wrote:
> Author: jchandra
> Date: Thu May 27 10:05:40 2010
> New Revision: 208589
> URL: http://svn.freebsd.org/changeset/base/208589
>
> Log:
>    Call VM_WAIT in pmap_ptpgzone_allocf() if  M_WAITOK is set.
>    Removed unused variable.
>
>    Approved by:	rrs (mentor)
>
>    

I'm afraid that this will work some of the time, but not all of the 
time.  Specifically, there is no guarantee that any of the available 
free (or cached) pages after the VM_WAIT will fall within the range of 
suitable physical addresses.  Moreover, and perhaps most worrisome, is 
that this function could do a lot of spinning.  Every time this function 
sleeps and a single page is freed (or cached) by someone else, this 
function will be reawakened.  With a little bad luck, you could spin 
indefinitely.

For essentially this reason, contigmalloc(), kmem_alloc_contig(), and 
kmem_alloc_attr() don't use VM_WAIT, but instead a function called 
vm_contig_grow_cache().

Regards,
Alan


> Modified:
>    head/sys/mips/mips/pmap.c
>
> Modified: head/sys/mips/mips/pmap.c
> ==============================================================================
> --- head/sys/mips/mips/pmap.c	Thu May 27 08:21:52 2010	(r208588)
> +++ head/sys/mips/mips/pmap.c	Thu May 27 10:05:40 2010	(r208589)
> @@ -969,10 +969,15 @@ pmap_ptpgzone_allocf(uma_zone_t zone, in
>   		("pmap_ptpgzone_allocf: invalid allocation size %d", bytes));
>
>   	*flags = UMA_SLAB_PRIV;
> -	m = vm_phys_alloc_contig(1, 0, MIPS_KSEG0_LARGEST_PHYS,
> -	     PAGE_SIZE, PAGE_SIZE);
> -	if (m == NULL)
> -		return (NULL);
> +	for (;;) {
> +		m = vm_phys_alloc_contig(1, 0, MIPS_KSEG0_LARGEST_PHYS,
> +		    PAGE_SIZE, PAGE_SIZE);
> +		if (m != NULL)
> +			break;
> +		if ((wait&  M_WAITOK) == 0)
> +			return (NULL);
> +		VM_WAIT;
> +	}
>
>   	paddr = VM_PAGE_TO_PHYS(m);
>   	return ((void *)MIPS_PHYS_TO_KSEG0(paddr));
> @@ -1039,8 +1044,10 @@ pmap_pinit(pmap_t pmap)
>   	 * allocate the page directory page
>   	 */
>   	ptdpg = pmap_alloc_pte_page(pmap, NUSERPGTBLS, M_WAITOK,&ptdva);
> -	pmap->pm_segtab = (pd_entry_t *)ptdva;
> +	if (ptdpg == NULL)
> +		return (0);
>
> +	pmap->pm_segtab = (pd_entry_t *)ptdva;
>   	pmap->pm_active = 0;
>   	pmap->pm_ptphint = NULL;
>   	for (i = 0; i<  MAXCPU; i++) {
> @@ -1062,13 +1069,11 @@ _pmap_allocpte(pmap_t pmap, unsigned pte
>   {
>   	vm_offset_t pteva;
>   	vm_page_t m;
> -	int req;
>
>   	KASSERT((flags&  (M_NOWAIT | M_WAITOK)) == M_NOWAIT ||
>   	    (flags&  (M_NOWAIT | M_WAITOK)) == M_WAITOK,
>   	    ("_pmap_allocpte: flags is neither M_NOWAIT nor M_WAITOK"));
>
> -	req = VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_NOOBJ;
>   	/*
>   	 * Find or fabricate a new pagetable page
>   	 */
>    



More information about the svn-src-all mailing list