* [PATCH 0/2] dma-contiguous: two bug fixes for dma_{alloc,free}_contiguous() @ 2019-07-25 23:39 Nicolin Chen 2019-07-25 23:39 ` [PATCH 1/2] dma-contiguous: do not overwrite align in dma_alloc_contiguous() Nicolin Chen 2019-07-25 23:39 ` [PATCH 2/2] dma-contiguous: page-align the size in dma_free_contiguous() Nicolin Chen 0 siblings, 2 replies; 6+ messages in thread From: Nicolin Chen @ 2019-07-25 23:39 UTC (permalink / raw) To: dafna.hirschfeld, hch, m.szyprowski, robin.murphy; +Cc: iommu, linux-kernel There are two obvious bugs in these two functions. So having two patches to fix them. Nicolin Chen (2): dma-contiguous: do not overwrite align in dma_alloc_contiguous() dma-contiguous: page-align the size in dma_free_contiguous() kernel/dma/contiguous.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) -- 2.17.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] dma-contiguous: do not overwrite align in dma_alloc_contiguous() 2019-07-25 23:39 [PATCH 0/2] dma-contiguous: two bug fixes for dma_{alloc,free}_contiguous() Nicolin Chen @ 2019-07-25 23:39 ` Nicolin Chen 2019-07-26 6:28 ` Christoph Hellwig 2019-07-25 23:39 ` [PATCH 2/2] dma-contiguous: page-align the size in dma_free_contiguous() Nicolin Chen 1 sibling, 1 reply; 6+ messages in thread From: Nicolin Chen @ 2019-07-25 23:39 UTC (permalink / raw) To: dafna.hirschfeld, hch, m.szyprowski, robin.murphy; +Cc: iommu, linux-kernel The dma_alloc_contiguous() limits align at CONFIG_CMA_ALIGNMENT for cma_alloc() however it does not restore it for the fallback routine. This will result in a size mismatch between the allocation and free when running in the fallback routines, if the align is larger than CONFIG_CMA_ALIGNMENT. This patch adds a cma_align to take care of cma_alloc() and prevent the align from being overwritten. Fixes: fdaeec198ada ("dma-contiguous: add dma_{alloc,free}_contiguous() helpers") Reported-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com> --- kernel/dma/contiguous.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c index bfc0c17f2a3d..fa8cd0f0512e 100644 --- a/kernel/dma/contiguous.c +++ b/kernel/dma/contiguous.c @@ -233,6 +233,7 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp) int node = dev ? dev_to_node(dev) : NUMA_NO_NODE; size_t count = PAGE_ALIGN(size) >> PAGE_SHIFT; size_t align = get_order(PAGE_ALIGN(size)); + size_t cma_align = CONFIG_CMA_ALIGNMENT; struct page *page = NULL; struct cma *cma = NULL; @@ -241,11 +242,11 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp) else if (count > 1) cma = dma_contiguous_default_area; + cma_align = min_t(size_t, align, cma_align); + /* CMA can be used only in the context which permits sleeping */ - if (cma && gfpflags_allow_blocking(gfp)) { - align = min_t(size_t, align, CONFIG_CMA_ALIGNMENT); - page = cma_alloc(cma, count, align, gfp & __GFP_NOWARN); - } + if (cma && gfpflags_allow_blocking(gfp)) + page = cma_alloc(cma, count, cma_align, gfp & __GFP_NOWARN); /* Fallback allocation of normal pages */ if (!page) -- 2.17.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] dma-contiguous: do not overwrite align in dma_alloc_contiguous() 2019-07-25 23:39 ` [PATCH 1/2] dma-contiguous: do not overwrite align in dma_alloc_contiguous() Nicolin Chen @ 2019-07-26 6:28 ` Christoph Hellwig 2019-07-26 19:22 ` Nicolin Chen 0 siblings, 1 reply; 6+ messages in thread From: Christoph Hellwig @ 2019-07-26 6:28 UTC (permalink / raw) To: Nicolin Chen Cc: dafna.hirschfeld, hch, m.szyprowski, robin.murphy, iommu, linux-kernel On Thu, Jul 25, 2019 at 04:39:58PM -0700, Nicolin Chen wrote: > The dma_alloc_contiguous() limits align at CONFIG_CMA_ALIGNMENT for > cma_alloc() however it does not restore it for the fallback routine. > This will result in a size mismatch between the allocation and free > when running in the fallback routines, if the align is larger than > CONFIG_CMA_ALIGNMENT. > > This patch adds a cma_align to take care of cma_alloc() and prevent > the align from being overwritten. > > Fixes: fdaeec198ada ("dma-contiguous: add dma_{alloc,free}_contiguous() helpers") > Reported-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com> > Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com> > --- > kernel/dma/contiguous.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c > index bfc0c17f2a3d..fa8cd0f0512e 100644 > --- a/kernel/dma/contiguous.c > +++ b/kernel/dma/contiguous.c > @@ -233,6 +233,7 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp) > int node = dev ? dev_to_node(dev) : NUMA_NO_NODE; > size_t count = PAGE_ALIGN(size) >> PAGE_SHIFT; > size_t align = get_order(PAGE_ALIGN(size)); > + size_t cma_align = CONFIG_CMA_ALIGNMENT; > struct page *page = NULL; > struct cma *cma = NULL; > > @@ -241,11 +242,11 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp) > else if (count > 1) > cma = dma_contiguous_default_area; > > + cma_align = min_t(size_t, align, cma_align); > + > /* CMA can be used only in the context which permits sleeping */ > - if (cma && gfpflags_allow_blocking(gfp)) { > - align = min_t(size_t, align, CONFIG_CMA_ALIGNMENT); > - page = cma_alloc(cma, count, align, gfp & __GFP_NOWARN); > - } > + if (cma && gfpflags_allow_blocking(gfp)) > + page = cma_alloc(cma, count, cma_align, gfp & __GFP_NOWARN); Shouldn't cma_align be confined to the block guarded by "if (cma && gfpflags_allow_blocking(gfp))" so that we can optimize it away for configurations that do not support CMA? ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] dma-contiguous: do not overwrite align in dma_alloc_contiguous() 2019-07-26 6:28 ` Christoph Hellwig @ 2019-07-26 19:22 ` Nicolin Chen 0 siblings, 0 replies; 6+ messages in thread From: Nicolin Chen @ 2019-07-26 19:22 UTC (permalink / raw) To: Christoph Hellwig Cc: dafna.hirschfeld, m.szyprowski, robin.murphy, iommu, linux-kernel On Fri, Jul 26, 2019 at 08:28:49AM +0200, Christoph Hellwig wrote: > On Thu, Jul 25, 2019 at 04:39:58PM -0700, Nicolin Chen wrote: > > The dma_alloc_contiguous() limits align at CONFIG_CMA_ALIGNMENT for > > cma_alloc() however it does not restore it for the fallback routine. > > This will result in a size mismatch between the allocation and free > > when running in the fallback routines, if the align is larger than > > CONFIG_CMA_ALIGNMENT. > > > > This patch adds a cma_align to take care of cma_alloc() and prevent > > the align from being overwritten. > > > > Fixes: fdaeec198ada ("dma-contiguous: add dma_{alloc,free}_contiguous() helpers") > > Reported-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com> > > Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com> > > --- > > kernel/dma/contiguous.c | 9 +++++---- > > 1 file changed, 5 insertions(+), 4 deletions(-) > > > > diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c > > index bfc0c17f2a3d..fa8cd0f0512e 100644 > > --- a/kernel/dma/contiguous.c > > +++ b/kernel/dma/contiguous.c > > @@ -233,6 +233,7 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp) > > int node = dev ? dev_to_node(dev) : NUMA_NO_NODE; > > size_t count = PAGE_ALIGN(size) >> PAGE_SHIFT; > > size_t align = get_order(PAGE_ALIGN(size)); > > + size_t cma_align = CONFIG_CMA_ALIGNMENT; > > struct page *page = NULL; > > struct cma *cma = NULL; > > > > @@ -241,11 +242,11 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp) > > else if (count > 1) > > cma = dma_contiguous_default_area; > > > > + cma_align = min_t(size_t, align, cma_align); > > + > > /* CMA can be used only in the context which permits sleeping */ > > - if (cma && gfpflags_allow_blocking(gfp)) { > > - align = min_t(size_t, align, CONFIG_CMA_ALIGNMENT); > > - page = cma_alloc(cma, count, align, gfp & __GFP_NOWARN); > > - } > > + if (cma && gfpflags_allow_blocking(gfp)) > > + page = cma_alloc(cma, count, cma_align, gfp & __GFP_NOWARN); > > Shouldn't cma_align be confined to the block guarded by > "if (cma && gfpflags_allow_blocking(gfp))" so that we can optimize it > away for configurations that do not support CMA? Had my local 1st version doing just like that but then wanted to simplify the statement within that if-condition so redid in this way. Will change it back as you suggested. Thanks ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] dma-contiguous: page-align the size in dma_free_contiguous() 2019-07-25 23:39 [PATCH 0/2] dma-contiguous: two bug fixes for dma_{alloc,free}_contiguous() Nicolin Chen 2019-07-25 23:39 ` [PATCH 1/2] dma-contiguous: do not overwrite align in dma_alloc_contiguous() Nicolin Chen @ 2019-07-25 23:39 ` Nicolin Chen 2019-07-26 6:30 ` Christoph Hellwig 1 sibling, 1 reply; 6+ messages in thread From: Nicolin Chen @ 2019-07-25 23:39 UTC (permalink / raw) To: dafna.hirschfeld, hch, m.szyprowski, robin.murphy; +Cc: iommu, linux-kernel According to the original dma_direct_alloc_pages() code: { unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; if (!dma_release_from_contiguous(dev, page, count)) __free_pages(page, get_order(size)); } The count parameter for dma_release_from_contiguous() was page aligned before the right-shifting operation, while the new API dma_free_contiguous() forgets to have PAGE_ALIGN() at the size. So this patch simply adds it to prevent any corner case. Fixes: fdaeec198ada ("dma-contiguous: add dma_{alloc,free}_contiguous() helpers") Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com> --- kernel/dma/contiguous.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c index fa8cd0f0512e..5735a9166866 100644 --- a/kernel/dma/contiguous.c +++ b/kernel/dma/contiguous.c @@ -267,7 +267,8 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp) */ void dma_free_contiguous(struct device *dev, struct page *page, size_t size) { - if (!cma_release(dev_get_cma_area(dev), page, size >> PAGE_SHIFT)) + if (!cma_release(dev_get_cma_area(dev), page, + PAGE_ALIGN(size) >> PAGE_SHIFT)) __free_pages(page, get_order(size)); } -- 2.17.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] dma-contiguous: page-align the size in dma_free_contiguous() 2019-07-25 23:39 ` [PATCH 2/2] dma-contiguous: page-align the size in dma_free_contiguous() Nicolin Chen @ 2019-07-26 6:30 ` Christoph Hellwig 0 siblings, 0 replies; 6+ messages in thread From: Christoph Hellwig @ 2019-07-26 6:30 UTC (permalink / raw) To: Nicolin Chen Cc: dafna.hirschfeld, hch, m.szyprowski, robin.murphy, iommu, linux-kernel On Thu, Jul 25, 2019 at 04:39:59PM -0700, Nicolin Chen wrote: > According to the original dma_direct_alloc_pages() code: > { > unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; > > if (!dma_release_from_contiguous(dev, page, count)) > __free_pages(page, get_order(size)); > } > > The count parameter for dma_release_from_contiguous() was page > aligned before the right-shifting operation, while the new API > dma_free_contiguous() forgets to have PAGE_ALIGN() at the size. > > So this patch simply adds it to prevent any corner case. > > Fixes: fdaeec198ada ("dma-contiguous: add dma_{alloc,free}_contiguous() helpers") > Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com> Looks good, Reviewed-by: Christoph Hellwig <hch@lst.de> ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-07-26 19:21 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-07-25 23:39 [PATCH 0/2] dma-contiguous: two bug fixes for dma_{alloc,free}_contiguous() Nicolin Chen 2019-07-25 23:39 ` [PATCH 1/2] dma-contiguous: do not overwrite align in dma_alloc_contiguous() Nicolin Chen 2019-07-26 6:28 ` Christoph Hellwig 2019-07-26 19:22 ` Nicolin Chen 2019-07-25 23:39 ` [PATCH 2/2] dma-contiguous: page-align the size in dma_free_contiguous() Nicolin Chen 2019-07-26 6:30 ` Christoph Hellwig
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).