diff mbox

arm64: Use and error-check DMA_ERROR_CODE

Message ID 1412108121-19262-1-git-send-email-seanpaul@chromium.org (mailing list archive)
State New, archived
Headers show

Commit Message

Sean Paul Sept. 30, 2014, 8:15 p.m. UTC
This patch replaces the static assignment of ~0 to dma_handle with
DMA_ERROR_CODE to be consistent with other platforms.

In addition to that, it also adds a check for DMA_ERROR_CODE before
calling __dma_free_coherent with an invalid dma_handle.

Signed-off-by: Sean Paul <seanpaul@chromium.org>
---
 arch/arm64/mm/dma-mapping.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Will Deacon Oct. 1, 2014, 10:13 a.m. UTC | #1
Hi Sean,

On Tue, Sep 30, 2014 at 09:15:21PM +0100, Sean Paul wrote:
> This patch replaces the static assignment of ~0 to dma_handle with
> DMA_ERROR_CODE to be consistent with other platforms.
> 
> In addition to that, it also adds a check for DMA_ERROR_CODE before
> calling __dma_free_coherent with an invalid dma_handle.
> 
> Signed-off-by: Sean Paul <seanpaul@chromium.org>
> ---
>  arch/arm64/mm/dma-mapping.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index 4164c5a..69fd2c4 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -125,7 +125,7 @@ static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
>  no_map:
>  	__dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
>  no_mem:
> -	*dma_handle = ~0;
> +	*dma_handle = DMA_ERROR_CODE;
>  	return NULL;
>  }
>  
> @@ -136,7 +136,9 @@ static void __dma_free_noncoherent(struct device *dev, size_t size,
>  	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
>  
>  	vunmap(vaddr);
> -	__dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
> +
> +	if (dma_handle != DMA_ERROR_CODE)
> +		__dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);

Is it legal to try and free a DMA buffer after a failed allocation? If so, I
think we need something similar for arch/arm/.

Will
Catalin Marinas Oct. 1, 2014, 10:56 a.m. UTC | #2
On Wed, Oct 01, 2014 at 11:13:23AM +0100, Will Deacon wrote:
> On Tue, Sep 30, 2014 at 09:15:21PM +0100, Sean Paul wrote:
> > This patch replaces the static assignment of ~0 to dma_handle with
> > DMA_ERROR_CODE to be consistent with other platforms.
> > 
> > In addition to that, it also adds a check for DMA_ERROR_CODE before
> > calling __dma_free_coherent with an invalid dma_handle.
> > 
> > Signed-off-by: Sean Paul <seanpaul@chromium.org>
> > ---
> >  arch/arm64/mm/dma-mapping.c | 6 ++++--
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> > index 4164c5a..69fd2c4 100644
> > --- a/arch/arm64/mm/dma-mapping.c
> > +++ b/arch/arm64/mm/dma-mapping.c
> > @@ -125,7 +125,7 @@ static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
> >  no_map:
> >  	__dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
> >  no_mem:
> > -	*dma_handle = ~0;
> > +	*dma_handle = DMA_ERROR_CODE;
> >  	return NULL;
> >  }
> >  
> > @@ -136,7 +136,9 @@ static void __dma_free_noncoherent(struct device *dev, size_t size,
> >  	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
> >  
> >  	vunmap(vaddr);
> > -	__dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
> > +
> > +	if (dma_handle != DMA_ERROR_CODE)
> > +		__dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
> 
> Is it legal to try and free a DMA buffer after a failed allocation? If so, I
> think we need something similar for arch/arm/.

If the allocation failed, we don't even have a vaddr to unmap, so I
don't see the reason for the additional check.
Russell King - ARM Linux Oct. 1, 2014, 1:52 p.m. UTC | #3
On Wed, Oct 01, 2014 at 11:13:23AM +0100, Will Deacon wrote:
> Hi Sean,
> 
> On Tue, Sep 30, 2014 at 09:15:21PM +0100, Sean Paul wrote:
> > +
> > +	if (dma_handle != DMA_ERROR_CODE)
> > +		__dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
> 
> Is it legal to try and free a DMA buffer after a failed allocation? If so, I
> think we need something similar for arch/arm/.

No.

	void
	dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
	                           dma_addr_t dma_handle)

	Free a region of consistent memory you previously allocated.  dev,
	                                       ^^^^^^^^^^^^^^^^^^^^^
This implies that the allocation was successful.

	size and dma_handle must all be the same as those passed into
	dma_alloc_coherent().  cpu_addr must be the virtual address returned by
	                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you want this behaviour, the proper way to do it would be to check
for a NULL cpu_addr, just like kfree() etc.

	the dma_alloc_coherent().
diff mbox

Patch

diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 4164c5a..69fd2c4 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -125,7 +125,7 @@  static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
 no_map:
 	__dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
 no_mem:
-	*dma_handle = ~0;
+	*dma_handle = DMA_ERROR_CODE;
 	return NULL;
 }
 
@@ -136,7 +136,9 @@  static void __dma_free_noncoherent(struct device *dev, size_t size,
 	void *swiotlb_addr = phys_to_virt(dma_to_phys(dev, dma_handle));
 
 	vunmap(vaddr);
-	__dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
+
+	if (dma_handle != DMA_ERROR_CODE)
+		__dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
 }
 
 static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,