Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Sep 2010 11:04:17 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        Neel Natu <neelnatu@gmail.com>
Subject:   Re: PATCH: fix bogus error message "bus_dmamem_alloc failed to align memory properly"
Message-ID:  <201009271104.17478.jhb@freebsd.org>
In-Reply-To: <AANLkTik3gtndjQWh22fzq8vr_QTRAUwPRoca-wkVEYY=@mail.gmail.com>
References:  <AANLkTik3gtndjQWh22fzq8vr_QTRAUwPRoca-wkVEYY=@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Friday, September 24, 2010 9:00:44 pm Neel Natu wrote:
> Hi,
> 
> This patch fixes the bogus error message from bus_dmamem_alloc() about
> the buffer not being aligned properly.
> 
> The problem is that the check is against a virtual address as opposed
> to the physical address. contigmalloc() makes guarantees about
> the alignment of physical addresses but not the virtual address
> mapping it.
> 
> Any objections if I commit this patch?

Hmmm, I guess you are doing super-page alignment rather than sub-page 
alignment?  In general I thought the busdma code only handled sub-page 
alignment and doesn't fully handle requests for super-page alignment.

For example, since it insists on walking individual pages at a time, if you 
had an alignment setting of 4 pages and passed in a single, aligned 4-page 
buffer, bus_dma would actually bounce the last 3 pages so that each individual 
page is 4-page aligned.  At least, I think that is what would happen.

For sub-page alignment, the virtual and physical address alignments should be 
the same.

> best
> Neel
> 
> Index: sys/powerpc/powerpc/busdma_machdep.c
> ===================================================================
> --- sys/powerpc/powerpc/busdma_machdep.c	(revision 213113)
> +++ sys/powerpc/powerpc/busdma_machdep.c	(working copy)
> @@ -529,7 +529,7 @@
>  		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
>  		    __func__, dmat, dmat->flags, ENOMEM);
>  		return (ENOMEM);
> -	} else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) {
> +	} else if (vtophys(*vaddr) & (dmat->alignment - 1)) {
>  		printf("bus_dmamem_alloc failed to align memory properly.\n");
>  	}
>  #ifdef NOTYET
> Index: sys/sparc64/sparc64/bus_machdep.c
> ===================================================================
> --- sys/sparc64/sparc64/bus_machdep.c	(revision 213113)
> +++ sys/sparc64/sparc64/bus_machdep.c	(working copy)
> @@ -652,7 +652,7 @@
>  	}
>  	if (*vaddr == NULL)
>  		return (ENOMEM);
> -	if ((uintptr_t)*vaddr % dmat->dt_alignment)
> +	if (vtophys(*vaddr) % dmat->dt_alignment)
>  		printf("%s: failed to align memory properly.\n", __func__);
>  	return (0);
>  }
> Index: sys/ia64/ia64/busdma_machdep.c
> ===================================================================
> --- sys/ia64/ia64/busdma_machdep.c	(revision 213113)
> +++ sys/ia64/ia64/busdma_machdep.c	(working copy)
> @@ -455,7 +455,7 @@
>  	}
>  	if (*vaddr == NULL)
>  		return (ENOMEM);
> -	else if ((uintptr_t)*vaddr & (dmat->alignment - 1))
> +	else if (vtophys(*vaddr) & (dmat->alignment - 1))
>  		printf("bus_dmamem_alloc failed to align memory properly.\n");
>  	return (0);
>  }
> Index: sys/i386/i386/busdma_machdep.c
> ===================================================================
> --- sys/i386/i386/busdma_machdep.c	(revision 213113)
> +++ sys/i386/i386/busdma_machdep.c	(working copy)
> @@ -540,7 +540,7 @@
>  		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
>  		    __func__, dmat, dmat->flags, ENOMEM);
>  		return (ENOMEM);
> -	} else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) {
> +	} else if (vtophys(*vaddr) & (dmat->alignment - 1)) {
>  		printf("bus_dmamem_alloc failed to align memory properly.\n");
>  	}
>  	if (flags & BUS_DMA_NOCACHE)
> Index: sys/amd64/amd64/busdma_machdep.c
> ===================================================================
> --- sys/amd64/amd64/busdma_machdep.c	(revision 213113)
> +++ sys/amd64/amd64/busdma_machdep.c	(working copy)
> @@ -526,7 +526,7 @@
>  		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
>  		    __func__, dmat, dmat->flags, ENOMEM);
>  		return (ENOMEM);
> -	} else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) {
> +	} else if (vtophys(*vaddr) & (dmat->alignment - 1)) {
>  		printf("bus_dmamem_alloc failed to align memory properly.\n");
>  	}
>  	if (flags & BUS_DMA_NOCACHE)
> _______________________________________________
> freebsd-hackers@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
> 

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009271104.17478.jhb>