* [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
* [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 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 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
* 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
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).