[PATCH 6/9] media: vb2: Convert vb2_vmalloc_get_userptr() to use frame vector
From: Jan Kara j...@suse.cz Convert vb2_vmalloc_get_userptr() to use frame vector infrastructure. When we are doing that there's no need to allocate page array and some code can be simplified. Acked-by: Marek Szyprowski m.szyprow...@samsung.com Tested-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Jan Kara j...@suse.cz --- drivers/media/v4l2-core/videobuf2-vmalloc.c | 92 +++-- 1 file changed, 36 insertions(+), 56 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 63bef959623e..ecb8f0c7f025 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -23,11 +23,9 @@ struct vb2_vmalloc_buf { void*vaddr; - struct page **pages; - struct vm_area_struct *vma; + struct frame_vector *vec; enum dma_data_direction dma_dir; unsigned long size; - unsigned intn_pages; atomic_trefcount; struct vb2_vmarea_handler handler; struct dma_buf *dbuf; @@ -76,10 +74,8 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, enum dma_data_direction dma_dir) { struct vb2_vmalloc_buf *buf; - unsigned long first, last; - int n_pages, offset; - struct vm_area_struct *vma; - dma_addr_t physp; + struct frame_vector *vec; + int n_pages, offset, i; buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (!buf) @@ -88,53 +84,36 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, buf-dma_dir = dma_dir; offset = vaddr ~PAGE_MASK; buf-size = size; - - down_read(current-mm-mmap_sem); - vma = find_vma(current-mm, vaddr); - if (vma (vma-vm_flags VM_PFNMAP) (vma-vm_pgoff)) { - if (vb2_get_contig_userptr(vaddr, size, vma, physp)) - goto fail_pages_array_alloc; - buf-vma = vma; - buf-vaddr = (__force void *)ioremap_nocache(physp, size); - if (!buf-vaddr) - goto fail_pages_array_alloc; + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); + if (IS_ERR(vec)) + goto fail_pfnvec_create; + buf-vec = vec; + n_pages = frame_vector_count(vec); + if (frame_vector_to_pages(vec) 0) { + unsigned long *nums = frame_vector_pfns(vec); + + /* +* We cannot get page pointers for these pfns. Check memory is +* physically contiguous and use direct mapping. +*/ + for (i = 1; i n_pages; i++) + if (nums[i-1] + 1 != nums[i]) + goto fail_map; + buf-vaddr = (__force void *) + ioremap_nocache(nums[0] PAGE_SHIFT, size); } else { - first = vaddr PAGE_SHIFT; - last = (vaddr + size - 1) PAGE_SHIFT; - buf-n_pages = last - first + 1; - buf-pages = kzalloc(buf-n_pages * sizeof(struct page *), -GFP_KERNEL); - if (!buf-pages) - goto fail_pages_array_alloc; - - /* current-mm-mmap_sem is taken by videobuf2 core */ - n_pages = get_user_pages(current, current-mm, -vaddr PAGE_MASK, buf-n_pages, -dma_dir == DMA_FROM_DEVICE, -1, /* force */ -buf-pages, NULL); - if (n_pages != buf-n_pages) - goto fail_get_user_pages; - - buf-vaddr = vm_map_ram(buf-pages, buf-n_pages, -1, + buf-vaddr = vm_map_ram(frame_vector_pages(vec), n_pages, -1, PAGE_KERNEL); - if (!buf-vaddr) - goto fail_get_user_pages; } - up_read(current-mm-mmap_sem); + if (!buf-vaddr) + goto fail_map; buf-vaddr += offset; return buf; -fail_get_user_pages: - pr_debug(get_user_pages requested/got: %d/%d]\n, n_pages, -buf-n_pages); - while (--n_pages = 0) - put_page(buf-pages[n_pages]); - kfree(buf-pages); - -fail_pages_array_alloc: - up_read(current-mm-mmap_sem); +fail_map: + vb2_destroy_framevec(vec); +fail_pfnvec_create: kfree(buf); return NULL; @@ -145,20 +124,21 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) struct vb2_vmalloc_buf *buf = buf_priv; unsigned long vaddr = (unsigned long)buf-vaddr
[PATCH 6/9] media: vb2: Convert vb2_vmalloc_get_userptr() to use frame vector
Convert vb2_vmalloc_get_userptr() to use frame vector infrastructure. When we are doing that there's no need to allocate page array and some code can be simplified. Acked-by: Marek Szyprowski m.szyprow...@samsung.com Tested-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Jan Kara j...@suse.cz --- drivers/media/v4l2-core/videobuf2-vmalloc.c | 94 +++-- 1 file changed, 36 insertions(+), 58 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 0ba40be21ebd..d2ce81fa2cdf 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -23,11 +23,9 @@ struct vb2_vmalloc_buf { void*vaddr; - struct page **pages; - struct vm_area_struct *vma; + struct frame_vector *vec; enum dma_data_direction dma_dir; unsigned long size; - unsigned intn_pages; atomic_trefcount; struct vb2_vmarea_handler handler; struct dma_buf *dbuf; @@ -76,10 +74,8 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, enum dma_data_direction dma_dir) { struct vb2_vmalloc_buf *buf; - unsigned long first, last; - int n_pages, offset; - struct vm_area_struct *vma; - dma_addr_t physp; + struct frame_vector *vec; + int n_pages, offset, i; buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (!buf) @@ -88,53 +84,36 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, buf-dma_dir = dma_dir; offset = vaddr ~PAGE_MASK; buf-size = size; - - down_read(current-mm-mmap_sem); - vma = find_vma(current-mm, vaddr); - if (vma (vma-vm_flags VM_PFNMAP) (vma-vm_pgoff)) { - if (vb2_get_contig_userptr(vaddr, size, vma, physp)) - goto fail_pages_array_alloc; - buf-vma = vma; - buf-vaddr = (__force void *)ioremap_nocache(physp, size); - if (!buf-vaddr) - goto fail_pages_array_alloc; + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); + if (IS_ERR(vec)) + goto fail_pfnvec_create; + buf-vec = vec; + n_pages = frame_vector_count(vec); + if (frame_vector_to_pages(vec) 0) { + unsigned long *nums = frame_vector_pfns(vec); + + /* +* We cannot get page pointers for these pfns. Check memory is +* physically contiguous and use direct mapping. +*/ + for (i = 1; i n_pages; i++) + if (nums[i-1] + 1 != nums[i]) + goto fail_map; + buf-vaddr = (__force void *) + ioremap_nocache(nums[0] PAGE_SHIFT, size); } else { - first = vaddr PAGE_SHIFT; - last = (vaddr + size - 1) PAGE_SHIFT; - buf-n_pages = last - first + 1; - buf-pages = kzalloc(buf-n_pages * sizeof(struct page *), -GFP_KERNEL); - if (!buf-pages) - goto fail_pages_array_alloc; - - /* current-mm-mmap_sem is taken by videobuf2 core */ - n_pages = get_user_pages(current, current-mm, -vaddr PAGE_MASK, buf-n_pages, -dma_dir == DMA_FROM_DEVICE, -1, /* force */ -buf-pages, NULL); - if (n_pages != buf-n_pages) - goto fail_get_user_pages; - - buf-vaddr = vm_map_ram(buf-pages, buf-n_pages, -1, + buf-vaddr = vm_map_ram(frame_vector_pages(vec), n_pages, -1, PAGE_KERNEL); - if (!buf-vaddr) - goto fail_get_user_pages; } - up_read(current-mm-mmap_sem); + if (!buf-vaddr) + goto fail_map; buf-vaddr += offset; return buf; -fail_get_user_pages: - pr_debug(get_user_pages requested/got: %d/%d]\n, n_pages, -buf-n_pages); - while (--n_pages = 0) - put_page(buf-pages[n_pages]); - kfree(buf-pages); - -fail_pages_array_alloc: - up_read(current-mm-mmap_sem); +fail_map: + vb2_destroy_framevec(vec); +fail_pfnvec_create: kfree(buf); return NULL; @@ -145,22 +124,21 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) struct vb2_vmalloc_buf *buf = buf_priv; unsigned long vaddr = (unsigned long)buf-vaddr PAGE_MASK; unsigned int i; +
[PATCH 6/9] media: vb2: Convert vb2_vmalloc_get_userptr() to use frame vector
Convert vb2_vmalloc_get_userptr() to use frame vector infrastructure. When we are doing that there's no need to allocate page array and some code can be simplified. Acked-by: Marek Szyprowski m.szyprow...@samsung.com Tested-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Jan Kara j...@suse.cz --- drivers/media/v4l2-core/videobuf2-vmalloc.c | 94 +++-- 1 file changed, 36 insertions(+), 58 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 0ba40be21ebd..d2ce81fa2cdf 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -23,11 +23,9 @@ struct vb2_vmalloc_buf { void*vaddr; - struct page **pages; - struct vm_area_struct *vma; + struct frame_vector *vec; enum dma_data_direction dma_dir; unsigned long size; - unsigned intn_pages; atomic_trefcount; struct vb2_vmarea_handler handler; struct dma_buf *dbuf; @@ -76,10 +74,8 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, enum dma_data_direction dma_dir) { struct vb2_vmalloc_buf *buf; - unsigned long first, last; - int n_pages, offset; - struct vm_area_struct *vma; - dma_addr_t physp; + struct frame_vector *vec; + int n_pages, offset, i; buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (!buf) @@ -88,53 +84,36 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, buf-dma_dir = dma_dir; offset = vaddr ~PAGE_MASK; buf-size = size; - - down_read(current-mm-mmap_sem); - vma = find_vma(current-mm, vaddr); - if (vma (vma-vm_flags VM_PFNMAP) (vma-vm_pgoff)) { - if (vb2_get_contig_userptr(vaddr, size, vma, physp)) - goto fail_pages_array_alloc; - buf-vma = vma; - buf-vaddr = (__force void *)ioremap_nocache(physp, size); - if (!buf-vaddr) - goto fail_pages_array_alloc; + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); + if (IS_ERR(vec)) + goto fail_pfnvec_create; + buf-vec = vec; + n_pages = frame_vector_count(vec); + if (frame_vector_to_pages(vec) 0) { + unsigned long *nums = frame_vector_pfns(vec); + + /* +* We cannot get page pointers for these pfns. Check memory is +* physically contiguous and use direct mapping. +*/ + for (i = 1; i n_pages; i++) + if (nums[i-1] + 1 != nums[i]) + goto fail_map; + buf-vaddr = (__force void *) + ioremap_nocache(nums[0] PAGE_SHIFT, size); } else { - first = vaddr PAGE_SHIFT; - last = (vaddr + size - 1) PAGE_SHIFT; - buf-n_pages = last - first + 1; - buf-pages = kzalloc(buf-n_pages * sizeof(struct page *), -GFP_KERNEL); - if (!buf-pages) - goto fail_pages_array_alloc; - - /* current-mm-mmap_sem is taken by videobuf2 core */ - n_pages = get_user_pages(current, current-mm, -vaddr PAGE_MASK, buf-n_pages, -dma_dir == DMA_FROM_DEVICE, -1, /* force */ -buf-pages, NULL); - if (n_pages != buf-n_pages) - goto fail_get_user_pages; - - buf-vaddr = vm_map_ram(buf-pages, buf-n_pages, -1, + buf-vaddr = vm_map_ram(frame_vector_pages(vec), n_pages, -1, PAGE_KERNEL); - if (!buf-vaddr) - goto fail_get_user_pages; } - up_read(current-mm-mmap_sem); + if (!buf-vaddr) + goto fail_map; buf-vaddr += offset; return buf; -fail_get_user_pages: - pr_debug(get_user_pages requested/got: %d/%d]\n, n_pages, -buf-n_pages); - while (--n_pages = 0) - put_page(buf-pages[n_pages]); - kfree(buf-pages); - -fail_pages_array_alloc: - up_read(current-mm-mmap_sem); +fail_map: + vb2_destroy_framevec(vec); +fail_pfnvec_create: kfree(buf); return NULL; @@ -145,22 +124,21 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) struct vb2_vmalloc_buf *buf = buf_priv; unsigned long vaddr = (unsigned long)buf-vaddr PAGE_MASK; unsigned int i; +
[PATCH 6/9] media: vb2: Convert vb2_vmalloc_get_userptr() to use frame vector
Convert vb2_vmalloc_get_userptr() to use frame vector infrastructure. When we are doing that there's no need to allocate page array and some code can be simplified. Acked-by: Marek Szyprowski m.szyprow...@samsung.com Tested-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Jan Kara j...@suse.cz --- drivers/media/v4l2-core/videobuf2-vmalloc.c | 94 +++-- 1 file changed, 36 insertions(+), 58 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index 0ba40be21ebd..d2ce81fa2cdf 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -23,11 +23,9 @@ struct vb2_vmalloc_buf { void*vaddr; - struct page **pages; - struct vm_area_struct *vma; + struct frame_vector *vec; enum dma_data_direction dma_dir; unsigned long size; - unsigned intn_pages; atomic_trefcount; struct vb2_vmarea_handler handler; struct dma_buf *dbuf; @@ -76,10 +74,8 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, enum dma_data_direction dma_dir) { struct vb2_vmalloc_buf *buf; - unsigned long first, last; - int n_pages, offset; - struct vm_area_struct *vma; - dma_addr_t physp; + struct frame_vector *vec; + int n_pages, offset, i; buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (!buf) @@ -88,53 +84,36 @@ static void *vb2_vmalloc_get_userptr(void *alloc_ctx, unsigned long vaddr, buf-dma_dir = dma_dir; offset = vaddr ~PAGE_MASK; buf-size = size; - - down_read(current-mm-mmap_sem); - vma = find_vma(current-mm, vaddr); - if (vma (vma-vm_flags VM_PFNMAP) (vma-vm_pgoff)) { - if (vb2_get_contig_userptr(vaddr, size, vma, physp)) - goto fail_pages_array_alloc; - buf-vma = vma; - buf-vaddr = (__force void *)ioremap_nocache(physp, size); - if (!buf-vaddr) - goto fail_pages_array_alloc; + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); + if (IS_ERR(vec)) + goto fail_pfnvec_create; + buf-vec = vec; + n_pages = frame_vector_count(vec); + if (frame_vector_to_pages(vec) 0) { + unsigned long *nums = frame_vector_pfns(vec); + + /* +* We cannot get page pointers for these pfns. Check memory is +* physically contiguous and use direct mapping. +*/ + for (i = 1; i n_pages; i++) + if (nums[i-1] + 1 != nums[i]) + goto fail_map; + buf-vaddr = (__force void *) + ioremap_nocache(nums[0] PAGE_SHIFT, size); } else { - first = vaddr PAGE_SHIFT; - last = (vaddr + size - 1) PAGE_SHIFT; - buf-n_pages = last - first + 1; - buf-pages = kzalloc(buf-n_pages * sizeof(struct page *), -GFP_KERNEL); - if (!buf-pages) - goto fail_pages_array_alloc; - - /* current-mm-mmap_sem is taken by videobuf2 core */ - n_pages = get_user_pages(current, current-mm, -vaddr PAGE_MASK, buf-n_pages, -dma_dir == DMA_FROM_DEVICE, -1, /* force */ -buf-pages, NULL); - if (n_pages != buf-n_pages) - goto fail_get_user_pages; - - buf-vaddr = vm_map_ram(buf-pages, buf-n_pages, -1, + buf-vaddr = vm_map_ram(frame_vector_pages(vec), n_pages, -1, PAGE_KERNEL); - if (!buf-vaddr) - goto fail_get_user_pages; } - up_read(current-mm-mmap_sem); + if (!buf-vaddr) + goto fail_map; buf-vaddr += offset; return buf; -fail_get_user_pages: - pr_debug(get_user_pages requested/got: %d/%d]\n, n_pages, -buf-n_pages); - while (--n_pages = 0) - put_page(buf-pages[n_pages]); - kfree(buf-pages); - -fail_pages_array_alloc: - up_read(current-mm-mmap_sem); +fail_map: + vb2_destroy_framevec(vec); +fail_pfnvec_create: kfree(buf); return NULL; @@ -145,22 +124,21 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) struct vb2_vmalloc_buf *buf = buf_priv; unsigned long vaddr = (unsigned long)buf-vaddr PAGE_MASK; unsigned int i; +