Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
On Thu, Jun 12, 2014 at 12:19:54PM +0200, Michal Nazarewicz wrote: > On Thu, Jun 12 2014, Joonsoo Kim wrote: > > ppc kvm's cma region management requires arbitrary bitmap granularity, > > since they want to reserve very large memory and manage this region > > with bitmap that one bit for several pages to reduce management overheads. > > So support arbitrary bitmap granularity for following generalization. > > > > Signed-off-by: Joonsoo Kim > > Acked-by: Michal Nazarewicz > > > diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c > > index bc4c171..9bc9340 100644 > > --- a/drivers/base/dma-contiguous.c > > +++ b/drivers/base/dma-contiguous.c > > @@ -38,6 +38,7 @@ struct cma { > > unsigned long base_pfn; > > unsigned long count; > > Have you considered replacing count with maxno? No, I haven't. I think that count is better than maxno, since it represent number of pages in this region. > > > unsigned long *bitmap; > > + int order_per_bit; /* Order of pages represented by one bit */ > > I'd make it unsigned. Will fix it. > > struct mutexlock; > > }; > > > > +static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int > > count) > > For consistency cma_clear_bitmap would make more sense I think. On the > other hand, you're just moving stuff around so perhaps renaming the > function at this point is not worth it any more. Will fix it. > > +{ > > + unsigned long bitmapno, nr_bits; > > + > > + bitmapno = (pfn - cma->base_pfn) >> cma->order_per_bit; > > + nr_bits = cma_bitmap_pages_to_bits(cma, count); > > + > > + mutex_lock(&cma->lock); > > + bitmap_clear(cma->bitmap, bitmapno, nr_bits); > > + mutex_unlock(&cma->lock); > > +} > > + > > static int __init cma_activate_area(struct cma *cma) > > { > > - int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); > > + int bitmap_maxno = cma_bitmap_maxno(cma); > > + int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long); > > unsigned long base_pfn = cma->base_pfn, pfn = base_pfn; > > unsigned i = cma->count >> pageblock_order; > > struct zone *zone; > > bitmap_maxno is never used again, perhaps: > > + int bitmap_size = BITS_TO_LONGS(cma_bitmap_maxno(cma)) * sizeof(long); > > instead? Up to you. Okay!! Thanks. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
Joonsoo Kim writes: > ppc kvm's cma region management requires arbitrary bitmap granularity, > since they want to reserve very large memory and manage this region > with bitmap that one bit for several pages to reduce management overheads. > So support arbitrary bitmap granularity for following generalization. > > Signed-off-by: Joonsoo Kim Reviewed-by: Aneesh Kumar K.V > > diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c > index bc4c171..9bc9340 100644 > --- a/drivers/base/dma-contiguous.c > +++ b/drivers/base/dma-contiguous.c > @@ -38,6 +38,7 @@ struct cma { > unsigned long base_pfn; > unsigned long count; > unsigned long *bitmap; > + int order_per_bit; /* Order of pages represented by one bit */ > struct mutexlock; > }; > > @@ -157,9 +158,38 @@ void __init dma_contiguous_reserve(phys_addr_t limit) > > static DEFINE_MUTEX(cma_mutex); > > +static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int > align_order) > +{ > + return (1 << (align_order >> cma->order_per_bit)) - 1; > +} > + > +static unsigned long cma_bitmap_maxno(struct cma *cma) > +{ > + return cma->count >> cma->order_per_bit; > +} > + > +static unsigned long cma_bitmap_pages_to_bits(struct cma *cma, > + unsigned long pages) > +{ > + return ALIGN(pages, 1 << cma->order_per_bit) >> cma->order_per_bit; > +} > + > +static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) > +{ > + unsigned long bitmapno, nr_bits; > + > + bitmapno = (pfn - cma->base_pfn) >> cma->order_per_bit; > + nr_bits = cma_bitmap_pages_to_bits(cma, count); > + > + mutex_lock(&cma->lock); > + bitmap_clear(cma->bitmap, bitmapno, nr_bits); > + mutex_unlock(&cma->lock); > +} > + > static int __init cma_activate_area(struct cma *cma) > { > - int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); > + int bitmap_maxno = cma_bitmap_maxno(cma); > + int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long); > unsigned long base_pfn = cma->base_pfn, pfn = base_pfn; > unsigned i = cma->count >> pageblock_order; > struct zone *zone; > @@ -221,6 +251,7 @@ core_initcall(cma_init_reserved_areas); > * @base: Base address of the reserved area optional, use 0 for any > * @limit: End address of the reserved memory (optional, 0 for any). > * @alignment: Alignment for the contiguous memory area, should be power of 2 > + * @order_per_bit: Order of pages represented by one bit on bitmap. > * @res_cma: Pointer to store the created cma region. > * @fixed: hint about where to place the reserved area > * > @@ -235,7 +266,7 @@ core_initcall(cma_init_reserved_areas); > */ > static int __init __dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, phys_addr_t limit, > - phys_addr_t alignment, > + phys_addr_t alignment, int order_per_bit, > struct cma **res_cma, bool fixed) > { > struct cma *cma = &cma_areas[cma_area_count]; > @@ -269,6 +300,8 @@ static int __init > __dma_contiguous_reserve_area(phys_addr_t size, > base = ALIGN(base, alignment); > size = ALIGN(size, alignment); > limit &= ~(alignment - 1); > + /* size should be aligned with order_per_bit */ > + BUG_ON(!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit)); > > /* Reserve memory */ > if (base && fixed) { > @@ -294,6 +327,7 @@ static int __init > __dma_contiguous_reserve_area(phys_addr_t size, >*/ > cma->base_pfn = PFN_DOWN(base); > cma->count = size >> PAGE_SHIFT; > + cma->order_per_bit = order_per_bit; > *res_cma = cma; > cma_area_count++; > > @@ -313,7 +347,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, > { > int ret; > > - ret = __dma_contiguous_reserve_area(size, base, limit, 0, > + ret = __dma_contiguous_reserve_area(size, base, limit, 0, 0, > res_cma, fixed); > if (ret) > return ret; > @@ -324,13 +358,6 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, > return 0; > } > > -static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) > -{ > - mutex_lock(&cma->lock); > - bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count); > - mutex_unlock(&cma->lock); > -} > - > /** > * dma_alloc_from_contiguous() - allocate pages from contiguous area > * @dev: Pointer to device for which the allocation is performed. > @@ -345,7 +372,8 @@ static void clear_cma_bitmap(struct cma *cma, unsigned > long pfn, int count) > static struct page *__dma_alloc_from_contiguous(struct cma *cma, int count, > unsigned int align) > { > - unsigned long mask, pfn, pageno, start = 0; > + unsigned long ma
Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
On Thu, Jun 12 2014, Joonsoo Kim wrote: > ppc kvm's cma region management requires arbitrary bitmap granularity, > since they want to reserve very large memory and manage this region > with bitmap that one bit for several pages to reduce management overheads. > So support arbitrary bitmap granularity for following generalization. > > Signed-off-by: Joonsoo Kim Acked-by: Michal Nazarewicz > diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c > index bc4c171..9bc9340 100644 > --- a/drivers/base/dma-contiguous.c > +++ b/drivers/base/dma-contiguous.c > @@ -38,6 +38,7 @@ struct cma { > unsigned long base_pfn; > unsigned long count; Have you considered replacing count with maxno? > unsigned long *bitmap; > + int order_per_bit; /* Order of pages represented by one bit */ I'd make it unsigned. > struct mutexlock; > }; > > +static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int > count) For consistency cma_clear_bitmap would make more sense I think. On the other hand, you're just moving stuff around so perhaps renaming the function at this point is not worth it any more. > +{ > + unsigned long bitmapno, nr_bits; > + > + bitmapno = (pfn - cma->base_pfn) >> cma->order_per_bit; > + nr_bits = cma_bitmap_pages_to_bits(cma, count); > + > + mutex_lock(&cma->lock); > + bitmap_clear(cma->bitmap, bitmapno, nr_bits); > + mutex_unlock(&cma->lock); > +} > + > static int __init cma_activate_area(struct cma *cma) > { > - int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); > + int bitmap_maxno = cma_bitmap_maxno(cma); > + int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long); > unsigned long base_pfn = cma->base_pfn, pfn = base_pfn; > unsigned i = cma->count >> pageblock_order; > struct zone *zone; bitmap_maxno is never used again, perhaps: + int bitmap_size = BITS_TO_LONGS(cma_bitmap_maxno(cma)) * sizeof(long); instead? Up to you. -- Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michał “mina86” Nazarewicz(o o) ooo +--ooO--(_)--Ooo-- -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
On 06/12/2014 11:21 AM, Joonsoo Kim wrote: > ppc kvm's cma region management requires arbitrary bitmap granularity, > since they want to reserve very large memory and manage this region > with bitmap that one bit for several pages to reduce management overheads. > So support arbitrary bitmap granularity for following generalization. > > Signed-off-by: Joonsoo Kim Acked-by: Zhang Yanfei > > diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c > index bc4c171..9bc9340 100644 > --- a/drivers/base/dma-contiguous.c > +++ b/drivers/base/dma-contiguous.c > @@ -38,6 +38,7 @@ struct cma { > unsigned long base_pfn; > unsigned long count; > unsigned long *bitmap; > + int order_per_bit; /* Order of pages represented by one bit */ > struct mutexlock; > }; > > @@ -157,9 +158,38 @@ void __init dma_contiguous_reserve(phys_addr_t limit) > > static DEFINE_MUTEX(cma_mutex); > > +static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int > align_order) > +{ > + return (1 << (align_order >> cma->order_per_bit)) - 1; > +} > + > +static unsigned long cma_bitmap_maxno(struct cma *cma) > +{ > + return cma->count >> cma->order_per_bit; > +} > + > +static unsigned long cma_bitmap_pages_to_bits(struct cma *cma, > + unsigned long pages) > +{ > + return ALIGN(pages, 1 << cma->order_per_bit) >> cma->order_per_bit; > +} > + > +static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) > +{ > + unsigned long bitmapno, nr_bits; > + > + bitmapno = (pfn - cma->base_pfn) >> cma->order_per_bit; > + nr_bits = cma_bitmap_pages_to_bits(cma, count); > + > + mutex_lock(&cma->lock); > + bitmap_clear(cma->bitmap, bitmapno, nr_bits); > + mutex_unlock(&cma->lock); > +} > + > static int __init cma_activate_area(struct cma *cma) > { > - int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); > + int bitmap_maxno = cma_bitmap_maxno(cma); > + int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long); > unsigned long base_pfn = cma->base_pfn, pfn = base_pfn; > unsigned i = cma->count >> pageblock_order; > struct zone *zone; > @@ -221,6 +251,7 @@ core_initcall(cma_init_reserved_areas); > * @base: Base address of the reserved area optional, use 0 for any > * @limit: End address of the reserved memory (optional, 0 for any). > * @alignment: Alignment for the contiguous memory area, should be power of 2 > + * @order_per_bit: Order of pages represented by one bit on bitmap. > * @res_cma: Pointer to store the created cma region. > * @fixed: hint about where to place the reserved area > * > @@ -235,7 +266,7 @@ core_initcall(cma_init_reserved_areas); > */ > static int __init __dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, phys_addr_t limit, > - phys_addr_t alignment, > + phys_addr_t alignment, int order_per_bit, > struct cma **res_cma, bool fixed) > { > struct cma *cma = &cma_areas[cma_area_count]; > @@ -269,6 +300,8 @@ static int __init > __dma_contiguous_reserve_area(phys_addr_t size, > base = ALIGN(base, alignment); > size = ALIGN(size, alignment); > limit &= ~(alignment - 1); > + /* size should be aligned with order_per_bit */ > + BUG_ON(!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit)); > > /* Reserve memory */ > if (base && fixed) { > @@ -294,6 +327,7 @@ static int __init > __dma_contiguous_reserve_area(phys_addr_t size, >*/ > cma->base_pfn = PFN_DOWN(base); > cma->count = size >> PAGE_SHIFT; > + cma->order_per_bit = order_per_bit; > *res_cma = cma; > cma_area_count++; > > @@ -313,7 +347,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, > { > int ret; > > - ret = __dma_contiguous_reserve_area(size, base, limit, 0, > + ret = __dma_contiguous_reserve_area(size, base, limit, 0, 0, > res_cma, fixed); > if (ret) > return ret; > @@ -324,13 +358,6 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, > return 0; > } > > -static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) > -{ > - mutex_lock(&cma->lock); > - bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count); > - mutex_unlock(&cma->lock); > -} > - > /** > * dma_alloc_from_contiguous() - allocate pages from contiguous area > * @dev: Pointer to device for which the allocation is performed. > @@ -345,7 +372,8 @@ static void clear_cma_bitmap(struct cma *cma, unsigned > long pfn, int count) > static struct page *__dma_alloc_from_contiguous(struct cma *cma, int count, > unsigned int align) > { > - unsigned long mask, pfn, pageno, start
Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
On Thu, Jun 12, 2014 at 04:08:11PM +0900, Minchan Kim wrote: > On Thu, Jun 12, 2014 at 12:21:42PM +0900, Joonsoo Kim wrote: > > ppc kvm's cma region management requires arbitrary bitmap granularity, > > since they want to reserve very large memory and manage this region > > with bitmap that one bit for several pages to reduce management overheads. > > So support arbitrary bitmap granularity for following generalization. > > > > Signed-off-by: Joonsoo Kim > Acked-by: Minchan Kim > Thanks. [snip...] > > /** > > * dma_alloc_from_contiguous() - allocate pages from contiguous area > > * @dev: Pointer to device for which the allocation is performed. > > @@ -345,7 +372,8 @@ static void clear_cma_bitmap(struct cma *cma, unsigned > > long pfn, int count) > > static struct page *__dma_alloc_from_contiguous(struct cma *cma, int count, > >unsigned int align) > > { > > - unsigned long mask, pfn, pageno, start = 0; > > + unsigned long mask, pfn, start = 0; > > + unsigned long bitmap_maxno, bitmapno, nr_bits; > > Just Nit: bitmap_maxno, bitmap_no or something consistent. > I know you love consistent when I read description in first patch > in this patchset. ;-) Yeah, I will fix it. :) Thanks. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
On 06/12/2014 03:08 PM, Minchan Kim wrote: > On Thu, Jun 12, 2014 at 12:21:42PM +0900, Joonsoo Kim wrote: >> ppc kvm's cma region management requires arbitrary bitmap granularity, >> since they want to reserve very large memory and manage this region >> with bitmap that one bit for several pages to reduce management overheads. >> So support arbitrary bitmap granularity for following generalization. >> >> Signed-off-by: Joonsoo Kim > Acked-by: Minchan Kim > > Just a nit below. > >> >> diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c >> index bc4c171..9bc9340 100644 >> --- a/drivers/base/dma-contiguous.c >> +++ b/drivers/base/dma-contiguous.c >> @@ -38,6 +38,7 @@ struct cma { >> unsigned long base_pfn; >> unsigned long count; >> unsigned long *bitmap; >> +int order_per_bit; /* Order of pages represented by one bit */ >> struct mutexlock; >> }; >> >> @@ -157,9 +158,38 @@ void __init dma_contiguous_reserve(phys_addr_t limit) >> >> static DEFINE_MUTEX(cma_mutex); >> >> +static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int >> align_order) >> +{ >> +return (1 << (align_order >> cma->order_per_bit)) - 1; >> +} >> + >> +static unsigned long cma_bitmap_maxno(struct cma *cma) >> +{ >> +return cma->count >> cma->order_per_bit; >> +} >> + >> +static unsigned long cma_bitmap_pages_to_bits(struct cma *cma, >> +unsigned long pages) >> +{ >> +return ALIGN(pages, 1 << cma->order_per_bit) >> cma->order_per_bit; >> +} >> + >> +static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) >> +{ >> +unsigned long bitmapno, nr_bits; >> + >> +bitmapno = (pfn - cma->base_pfn) >> cma->order_per_bit; >> +nr_bits = cma_bitmap_pages_to_bits(cma, count); >> + >> +mutex_lock(&cma->lock); >> +bitmap_clear(cma->bitmap, bitmapno, nr_bits); >> +mutex_unlock(&cma->lock); >> +} >> + >> static int __init cma_activate_area(struct cma *cma) >> { >> -int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); >> +int bitmap_maxno = cma_bitmap_maxno(cma); >> +int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long); >> unsigned long base_pfn = cma->base_pfn, pfn = base_pfn; >> unsigned i = cma->count >> pageblock_order; >> struct zone *zone; >> @@ -221,6 +251,7 @@ core_initcall(cma_init_reserved_areas); >> * @base: Base address of the reserved area optional, use 0 for any >> * @limit: End address of the reserved memory (optional, 0 for any). >> * @alignment: Alignment for the contiguous memory area, should be power of >> 2 >> + * @order_per_bit: Order of pages represented by one bit on bitmap. >> * @res_cma: Pointer to store the created cma region. >> * @fixed: hint about where to place the reserved area >> * >> @@ -235,7 +266,7 @@ core_initcall(cma_init_reserved_areas); >> */ >> static int __init __dma_contiguous_reserve_area(phys_addr_t size, >> phys_addr_t base, phys_addr_t limit, >> -phys_addr_t alignment, >> +phys_addr_t alignment, int order_per_bit, >> struct cma **res_cma, bool fixed) >> { >> struct cma *cma = &cma_areas[cma_area_count]; >> @@ -269,6 +300,8 @@ static int __init >> __dma_contiguous_reserve_area(phys_addr_t size, >> base = ALIGN(base, alignment); >> size = ALIGN(size, alignment); >> limit &= ~(alignment - 1); >> +/* size should be aligned with order_per_bit */ >> +BUG_ON(!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit)); >> >> /* Reserve memory */ >> if (base && fixed) { >> @@ -294,6 +327,7 @@ static int __init >> __dma_contiguous_reserve_area(phys_addr_t size, >> */ >> cma->base_pfn = PFN_DOWN(base); >> cma->count = size >> PAGE_SHIFT; >> +cma->order_per_bit = order_per_bit; >> *res_cma = cma; >> cma_area_count++; >> >> @@ -313,7 +347,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, >> phys_addr_t base, >> { >> int ret; >> >> -ret = __dma_contiguous_reserve_area(size, base, limit, 0, >> +ret = __dma_contiguous_reserve_area(size, base, limit, 0, 0, >> res_cma, fixed); >> if (ret) >> return ret; >> @@ -324,13 +358,6 @@ int __init dma_contiguous_reserve_area(phys_addr_t >> size, phys_addr_t base, >> return 0; >> } >> >> -static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) >> -{ >> -mutex_lock(&cma->lock); >> -bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count); >> -mutex_unlock(&cma->lock); >> -} >> - >> /** >> * dma_alloc_from_contiguous() - allocate pages from contiguous area >> * @dev: Pointer to device for which the allocation is performed. >> @@ -345,7 +372,8 @@ static void clear_cma_bitmap(struct cma *cma, unsigned >> long pfn, int count) >> static struct page *_
Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
On Thu, Jun 12, 2014 at 12:21:42PM +0900, Joonsoo Kim wrote: > ppc kvm's cma region management requires arbitrary bitmap granularity, > since they want to reserve very large memory and manage this region > with bitmap that one bit for several pages to reduce management overheads. > So support arbitrary bitmap granularity for following generalization. > > Signed-off-by: Joonsoo Kim Acked-by: Minchan Kim Just a nit below. > > diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c > index bc4c171..9bc9340 100644 > --- a/drivers/base/dma-contiguous.c > +++ b/drivers/base/dma-contiguous.c > @@ -38,6 +38,7 @@ struct cma { > unsigned long base_pfn; > unsigned long count; > unsigned long *bitmap; > + int order_per_bit; /* Order of pages represented by one bit */ > struct mutexlock; > }; > > @@ -157,9 +158,38 @@ void __init dma_contiguous_reserve(phys_addr_t limit) > > static DEFINE_MUTEX(cma_mutex); > > +static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int > align_order) > +{ > + return (1 << (align_order >> cma->order_per_bit)) - 1; > +} > + > +static unsigned long cma_bitmap_maxno(struct cma *cma) > +{ > + return cma->count >> cma->order_per_bit; > +} > + > +static unsigned long cma_bitmap_pages_to_bits(struct cma *cma, > + unsigned long pages) > +{ > + return ALIGN(pages, 1 << cma->order_per_bit) >> cma->order_per_bit; > +} > + > +static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) > +{ > + unsigned long bitmapno, nr_bits; > + > + bitmapno = (pfn - cma->base_pfn) >> cma->order_per_bit; > + nr_bits = cma_bitmap_pages_to_bits(cma, count); > + > + mutex_lock(&cma->lock); > + bitmap_clear(cma->bitmap, bitmapno, nr_bits); > + mutex_unlock(&cma->lock); > +} > + > static int __init cma_activate_area(struct cma *cma) > { > - int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); > + int bitmap_maxno = cma_bitmap_maxno(cma); > + int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long); > unsigned long base_pfn = cma->base_pfn, pfn = base_pfn; > unsigned i = cma->count >> pageblock_order; > struct zone *zone; > @@ -221,6 +251,7 @@ core_initcall(cma_init_reserved_areas); > * @base: Base address of the reserved area optional, use 0 for any > * @limit: End address of the reserved memory (optional, 0 for any). > * @alignment: Alignment for the contiguous memory area, should be power of 2 > + * @order_per_bit: Order of pages represented by one bit on bitmap. > * @res_cma: Pointer to store the created cma region. > * @fixed: hint about where to place the reserved area > * > @@ -235,7 +266,7 @@ core_initcall(cma_init_reserved_areas); > */ > static int __init __dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, phys_addr_t limit, > - phys_addr_t alignment, > + phys_addr_t alignment, int order_per_bit, > struct cma **res_cma, bool fixed) > { > struct cma *cma = &cma_areas[cma_area_count]; > @@ -269,6 +300,8 @@ static int __init > __dma_contiguous_reserve_area(phys_addr_t size, > base = ALIGN(base, alignment); > size = ALIGN(size, alignment); > limit &= ~(alignment - 1); > + /* size should be aligned with order_per_bit */ > + BUG_ON(!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit)); > > /* Reserve memory */ > if (base && fixed) { > @@ -294,6 +327,7 @@ static int __init > __dma_contiguous_reserve_area(phys_addr_t size, >*/ > cma->base_pfn = PFN_DOWN(base); > cma->count = size >> PAGE_SHIFT; > + cma->order_per_bit = order_per_bit; > *res_cma = cma; > cma_area_count++; > > @@ -313,7 +347,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, > { > int ret; > > - ret = __dma_contiguous_reserve_area(size, base, limit, 0, > + ret = __dma_contiguous_reserve_area(size, base, limit, 0, 0, > res_cma, fixed); > if (ret) > return ret; > @@ -324,13 +358,6 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, > return 0; > } > > -static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) > -{ > - mutex_lock(&cma->lock); > - bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count); > - mutex_unlock(&cma->lock); > -} > - > /** > * dma_alloc_from_contiguous() - allocate pages from contiguous area > * @dev: Pointer to device for which the allocation is performed. > @@ -345,7 +372,8 @@ static void clear_cma_bitmap(struct cma *cma, unsigned > long pfn, int count) > static struct page *__dma_alloc_from_contiguous(struct cma *cma, int count, > unsigned int align) > { > - uns
Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
On Thu, Jun 12, 2014 at 03:43:55PM +0900, Joonsoo Kim wrote: > On Thu, Jun 12, 2014 at 03:06:10PM +0900, Minchan Kim wrote: > > On Thu, Jun 12, 2014 at 12:21:42PM +0900, Joonsoo Kim wrote: > > > ppc kvm's cma region management requires arbitrary bitmap granularity, > > > since they want to reserve very large memory and manage this region > > > with bitmap that one bit for several pages to reduce management overheads. > > > So support arbitrary bitmap granularity for following generalization. > > > > > > Signed-off-by: Joonsoo Kim > > > > > > diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c > > > index bc4c171..9bc9340 100644 > > > --- a/drivers/base/dma-contiguous.c > > > +++ b/drivers/base/dma-contiguous.c > > > @@ -38,6 +38,7 @@ struct cma { > > > unsigned long base_pfn; > > > unsigned long count; > > > unsigned long *bitmap; > > > + int order_per_bit; /* Order of pages represented by one bit */ > > > > Hmm, I'm not sure it's good as *general* interface even though it covers > > existing usecases. > > > > It forces a cma area should be handled by same size unit. Right? > > It's really important point for this patchset's motivation so I will stop > > review and wait other opinions. > > If you pass 0 to order_per_bit, you can manage cma area in every > size(page unit) you want. If you pass certain number to order_per_bit, > you can allocate and release cma area in multiple of such page order. > > I think that this is more general implementation than previous versions. Fair enough. -- Kind regards, Minchan Kim -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
On Thu, Jun 12, 2014 at 03:06:10PM +0900, Minchan Kim wrote: > On Thu, Jun 12, 2014 at 12:21:42PM +0900, Joonsoo Kim wrote: > > ppc kvm's cma region management requires arbitrary bitmap granularity, > > since they want to reserve very large memory and manage this region > > with bitmap that one bit for several pages to reduce management overheads. > > So support arbitrary bitmap granularity for following generalization. > > > > Signed-off-by: Joonsoo Kim > > > > diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c > > index bc4c171..9bc9340 100644 > > --- a/drivers/base/dma-contiguous.c > > +++ b/drivers/base/dma-contiguous.c > > @@ -38,6 +38,7 @@ struct cma { > > unsigned long base_pfn; > > unsigned long count; > > unsigned long *bitmap; > > + int order_per_bit; /* Order of pages represented by one bit */ > > Hmm, I'm not sure it's good as *general* interface even though it covers > existing usecases. > > It forces a cma area should be handled by same size unit. Right? > It's really important point for this patchset's motivation so I will stop > review and wait other opinions. If you pass 0 to order_per_bit, you can manage cma area in every size(page unit) you want. If you pass certain number to order_per_bit, you can allocate and release cma area in multiple of such page order. I think that this is more general implementation than previous versions. Thanks. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 05/10] DMA, CMA: support arbitrary bitmap granularity
On Thu, Jun 12, 2014 at 12:21:42PM +0900, Joonsoo Kim wrote: > ppc kvm's cma region management requires arbitrary bitmap granularity, > since they want to reserve very large memory and manage this region > with bitmap that one bit for several pages to reduce management overheads. > So support arbitrary bitmap granularity for following generalization. > > Signed-off-by: Joonsoo Kim > > diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c > index bc4c171..9bc9340 100644 > --- a/drivers/base/dma-contiguous.c > +++ b/drivers/base/dma-contiguous.c > @@ -38,6 +38,7 @@ struct cma { > unsigned long base_pfn; > unsigned long count; > unsigned long *bitmap; > + int order_per_bit; /* Order of pages represented by one bit */ Hmm, I'm not sure it's good as *general* interface even though it covers existing usecases. It forces a cma area should be handled by same size unit. Right? It's really important point for this patchset's motivation so I will stop review and wait other opinions. > struct mutexlock; > }; > > @@ -157,9 +158,38 @@ void __init dma_contiguous_reserve(phys_addr_t limit) > > static DEFINE_MUTEX(cma_mutex); > > +static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int > align_order) > +{ > + return (1 << (align_order >> cma->order_per_bit)) - 1; > +} > + > +static unsigned long cma_bitmap_maxno(struct cma *cma) > +{ > + return cma->count >> cma->order_per_bit; > +} > + > +static unsigned long cma_bitmap_pages_to_bits(struct cma *cma, > + unsigned long pages) > +{ > + return ALIGN(pages, 1 << cma->order_per_bit) >> cma->order_per_bit; > +} > + > +static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) > +{ > + unsigned long bitmapno, nr_bits; > + > + bitmapno = (pfn - cma->base_pfn) >> cma->order_per_bit; > + nr_bits = cma_bitmap_pages_to_bits(cma, count); > + > + mutex_lock(&cma->lock); > + bitmap_clear(cma->bitmap, bitmapno, nr_bits); > + mutex_unlock(&cma->lock); > +} > + > static int __init cma_activate_area(struct cma *cma) > { > - int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long); > + int bitmap_maxno = cma_bitmap_maxno(cma); > + int bitmap_size = BITS_TO_LONGS(bitmap_maxno) * sizeof(long); > unsigned long base_pfn = cma->base_pfn, pfn = base_pfn; > unsigned i = cma->count >> pageblock_order; > struct zone *zone; > @@ -221,6 +251,7 @@ core_initcall(cma_init_reserved_areas); > * @base: Base address of the reserved area optional, use 0 for any > * @limit: End address of the reserved memory (optional, 0 for any). > * @alignment: Alignment for the contiguous memory area, should be power of 2 > + * @order_per_bit: Order of pages represented by one bit on bitmap. > * @res_cma: Pointer to store the created cma region. > * @fixed: hint about where to place the reserved area > * > @@ -235,7 +266,7 @@ core_initcall(cma_init_reserved_areas); > */ > static int __init __dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, phys_addr_t limit, > - phys_addr_t alignment, > + phys_addr_t alignment, int order_per_bit, > struct cma **res_cma, bool fixed) > { > struct cma *cma = &cma_areas[cma_area_count]; > @@ -269,6 +300,8 @@ static int __init > __dma_contiguous_reserve_area(phys_addr_t size, > base = ALIGN(base, alignment); > size = ALIGN(size, alignment); > limit &= ~(alignment - 1); > + /* size should be aligned with order_per_bit */ > + BUG_ON(!IS_ALIGNED(size >> PAGE_SHIFT, 1 << order_per_bit)); > > /* Reserve memory */ > if (base && fixed) { > @@ -294,6 +327,7 @@ static int __init > __dma_contiguous_reserve_area(phys_addr_t size, >*/ > cma->base_pfn = PFN_DOWN(base); > cma->count = size >> PAGE_SHIFT; > + cma->order_per_bit = order_per_bit; > *res_cma = cma; > cma_area_count++; > > @@ -313,7 +347,7 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, > { > int ret; > > - ret = __dma_contiguous_reserve_area(size, base, limit, 0, > + ret = __dma_contiguous_reserve_area(size, base, limit, 0, 0, > res_cma, fixed); > if (ret) > return ret; > @@ -324,13 +358,6 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, > phys_addr_t base, > return 0; > } > > -static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count) > -{ > - mutex_lock(&cma->lock); > - bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count); > - mutex_unlock(&cma->lock); > -} > - > /** > * dma_alloc_from_contiguous() - allocate pages from contiguous area > * @dev: Pointer to device for which the allocation is performed. > @@ -345,7 +372,8 @@ static voi