From: Jan Kara <jack@suse.cz> To: linux-mm@kvack.org Cc: linux-media@vger.kernel.org, Jan Kara <jack@suse.cz> Subject: [PATCH 4/9] media: vb2: Convert vb2_dma_sg_get_userptr() to use pinned pfns Date: Mon, 17 Mar 2014 20:49:31 +0100 [thread overview] Message-ID: <1395085776-8626-5-git-send-email-jack@suse.cz> (raw) In-Reply-To: <1395085776-8626-1-git-send-email-jack@suse.cz> Signed-off-by: Jan Kara <jack@suse.cz> --- drivers/media/v4l2-core/videobuf2-dma-sg.c | 85 ++++++------------------------ 1 file changed, 15 insertions(+), 70 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index ef0b3f765d8e..a37ee0fa84d3 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -33,6 +33,7 @@ module_param(debug, int, 0644); struct vb2_dma_sg_buf { void *vaddr; struct page **pages; + struct pinned_pfns *pfns; int write; int offset; struct sg_table sg_table; @@ -166,9 +167,10 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, struct pinned_pfns **ppfn, int write) { struct vb2_dma_sg_buf *buf; - unsigned long first, last; - int num_pages_from_user; - struct vm_area_struct *vma; + struct pinned_pfns *pfns = *ppfn; + + if (pfns_vector_to_pages(pfns)) + return NULL; buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) @@ -178,75 +180,20 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, struct pinned_pfns **ppfn, buf->write = write; buf->offset = vaddr & ~PAGE_MASK; buf->size = size; - - first = (vaddr & PAGE_MASK) >> PAGE_SHIFT; - last = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT; - buf->num_pages = last - first + 1; - - buf->pages = kzalloc(buf->num_pages * sizeof(struct page *), - GFP_KERNEL); - if (!buf->pages) - goto userptr_fail_alloc_pages; - - vma = find_vma(current->mm, vaddr); - if (!vma) { - dprintk(1, "no vma for address %lu\n", vaddr); - goto userptr_fail_find_vma; - } - - if (vma->vm_end < vaddr + size) { - dprintk(1, "vma at %lu is too small for %lu bytes\n", - vaddr, size); - goto userptr_fail_find_vma; - } - - buf->vma = vb2_get_vma(vma); - if (!buf->vma) { - dprintk(1, "failed to copy vma\n"); - goto userptr_fail_find_vma; - } - - if (vma_is_io(buf->vma)) { - for (num_pages_from_user = 0; - num_pages_from_user < buf->num_pages; - ++num_pages_from_user, vaddr += PAGE_SIZE) { - unsigned long pfn; - - if (follow_pfn(buf->vma, vaddr, &pfn)) { - dprintk(1, "no page for address %lu\n", vaddr); - break; - } - buf->pages[num_pages_from_user] = pfn_to_page(pfn); - } - } else - num_pages_from_user = get_user_pages(current, current->mm, - vaddr & PAGE_MASK, - buf->num_pages, - write, - 1, /* force */ - buf->pages, - NULL); - - if (num_pages_from_user != buf->num_pages) - goto userptr_fail_get_user_pages; + buf->pages = pfns_vector_pages(pfns); + buf->num_pages = pfns_vector_count(pfns); if (sg_alloc_table_from_pages(&buf->sg_table, buf->pages, buf->num_pages, buf->offset, size, 0)) - goto userptr_fail_alloc_table_from_pages; + goto fail; + + buf->pfns = pfns; + /* Clear *ppfn so that the caller doesn't free the vector */ + *ppfn = NULL; return buf; -userptr_fail_alloc_table_from_pages: -userptr_fail_get_user_pages: - dprintk(1, "get_user_pages requested/got: %d/%d]\n", - buf->num_pages, num_pages_from_user); - if (!vma_is_io(buf->vma)) - while (--num_pages_from_user >= 0) - put_page(buf->pages[num_pages_from_user]); - vb2_put_vma(buf->vma); -userptr_fail_find_vma: - kfree(buf->pages); -userptr_fail_alloc_pages: +fail: kfree(buf); return NULL; } @@ -268,11 +215,9 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) while (--i >= 0) { if (buf->write) set_page_dirty_lock(buf->pages[i]); - if (!vma_is_io(buf->vma)) - put_page(buf->pages[i]); } - kfree(buf->pages); - vb2_put_vma(buf->vma); + put_vaddr_pfns(buf->pfns); + pfns_vector_destroy(buf->pfns); kfree(buf); } -- 1.8.1.4
WARNING: multiple messages have this Message-ID (diff)
From: Jan Kara <jack@suse.cz> To: linux-mm@kvack.org Cc: linux-media@vger.kernel.org, Jan Kara <jack@suse.cz> Subject: [PATCH 4/9] media: vb2: Convert vb2_dma_sg_get_userptr() to use pinned pfns Date: Mon, 17 Mar 2014 20:49:31 +0100 [thread overview] Message-ID: <1395085776-8626-5-git-send-email-jack@suse.cz> (raw) In-Reply-To: <1395085776-8626-1-git-send-email-jack@suse.cz> Signed-off-by: Jan Kara <jack@suse.cz> --- drivers/media/v4l2-core/videobuf2-dma-sg.c | 85 ++++++------------------------ 1 file changed, 15 insertions(+), 70 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index ef0b3f765d8e..a37ee0fa84d3 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -33,6 +33,7 @@ module_param(debug, int, 0644); struct vb2_dma_sg_buf { void *vaddr; struct page **pages; + struct pinned_pfns *pfns; int write; int offset; struct sg_table sg_table; @@ -166,9 +167,10 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, struct pinned_pfns **ppfn, int write) { struct vb2_dma_sg_buf *buf; - unsigned long first, last; - int num_pages_from_user; - struct vm_area_struct *vma; + struct pinned_pfns *pfns = *ppfn; + + if (pfns_vector_to_pages(pfns)) + return NULL; buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) @@ -178,75 +180,20 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, struct pinned_pfns **ppfn, buf->write = write; buf->offset = vaddr & ~PAGE_MASK; buf->size = size; - - first = (vaddr & PAGE_MASK) >> PAGE_SHIFT; - last = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT; - buf->num_pages = last - first + 1; - - buf->pages = kzalloc(buf->num_pages * sizeof(struct page *), - GFP_KERNEL); - if (!buf->pages) - goto userptr_fail_alloc_pages; - - vma = find_vma(current->mm, vaddr); - if (!vma) { - dprintk(1, "no vma for address %lu\n", vaddr); - goto userptr_fail_find_vma; - } - - if (vma->vm_end < vaddr + size) { - dprintk(1, "vma at %lu is too small for %lu bytes\n", - vaddr, size); - goto userptr_fail_find_vma; - } - - buf->vma = vb2_get_vma(vma); - if (!buf->vma) { - dprintk(1, "failed to copy vma\n"); - goto userptr_fail_find_vma; - } - - if (vma_is_io(buf->vma)) { - for (num_pages_from_user = 0; - num_pages_from_user < buf->num_pages; - ++num_pages_from_user, vaddr += PAGE_SIZE) { - unsigned long pfn; - - if (follow_pfn(buf->vma, vaddr, &pfn)) { - dprintk(1, "no page for address %lu\n", vaddr); - break; - } - buf->pages[num_pages_from_user] = pfn_to_page(pfn); - } - } else - num_pages_from_user = get_user_pages(current, current->mm, - vaddr & PAGE_MASK, - buf->num_pages, - write, - 1, /* force */ - buf->pages, - NULL); - - if (num_pages_from_user != buf->num_pages) - goto userptr_fail_get_user_pages; + buf->pages = pfns_vector_pages(pfns); + buf->num_pages = pfns_vector_count(pfns); if (sg_alloc_table_from_pages(&buf->sg_table, buf->pages, buf->num_pages, buf->offset, size, 0)) - goto userptr_fail_alloc_table_from_pages; + goto fail; + + buf->pfns = pfns; + /* Clear *ppfn so that the caller doesn't free the vector */ + *ppfn = NULL; return buf; -userptr_fail_alloc_table_from_pages: -userptr_fail_get_user_pages: - dprintk(1, "get_user_pages requested/got: %d/%d]\n", - buf->num_pages, num_pages_from_user); - if (!vma_is_io(buf->vma)) - while (--num_pages_from_user >= 0) - put_page(buf->pages[num_pages_from_user]); - vb2_put_vma(buf->vma); -userptr_fail_find_vma: - kfree(buf->pages); -userptr_fail_alloc_pages: +fail: kfree(buf); return NULL; } @@ -268,11 +215,9 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) while (--i >= 0) { if (buf->write) set_page_dirty_lock(buf->pages[i]); - if (!vma_is_io(buf->vma)) - put_page(buf->pages[i]); } - kfree(buf->pages); - vb2_put_vma(buf->vma); + put_vaddr_pfns(buf->pfns); + pfns_vector_destroy(buf->pfns); kfree(buf); } -- 1.8.1.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2014-03-17 19:49 UTC|newest] Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-03-17 19:49 [RFC] Helper to abstract vma handling in media layer Jan Kara 2014-03-17 19:49 ` Jan Kara 2014-03-17 19:49 ` [PATCH 1/9] mm: Provide new get_vaddr_pfns() helper Jan Kara 2014-03-17 19:49 ` Jan Kara 2014-03-17 20:53 ` Dave Hansen 2014-03-17 20:53 ` Dave Hansen 2014-03-18 10:25 ` Jan Kara 2014-03-18 10:25 ` Jan Kara 2015-04-24 16:21 ` Jan Kara 2015-04-24 16:21 ` Jan Kara 2014-03-17 19:49 ` [PATCH 2/9] media: omap_vout: Convert omap_vout_uservirt_to_phys() to use get_vaddr_pfns() Jan Kara 2014-03-17 19:49 ` Jan Kara 2014-03-17 19:49 ` [PATCH 3/9] media: vb2: Teach vb2_queue_or_prepare_buf() to get pfns for user buffers Jan Kara 2014-03-17 19:49 ` Jan Kara 2014-03-17 19:49 ` Jan Kara [this message] 2014-03-17 19:49 ` [PATCH 4/9] media: vb2: Convert vb2_dma_sg_get_userptr() to use pinned pfns Jan Kara 2014-03-17 19:49 ` [PATCH 5/9] media: vb2: Convert vb2_vmalloc_get_userptr() to use pfns vector Jan Kara 2014-03-17 19:49 ` Jan Kara 2014-03-17 19:49 ` [PATCH 6/9] media: vb2: Convert vb2_dc_get_userptr() " Jan Kara 2014-03-17 19:49 ` Jan Kara 2014-03-17 19:49 ` [PATCH 7/9] media: vb2: Remove unused functions Jan Kara 2014-03-17 19:49 ` Jan Kara 2014-03-17 19:49 ` [PATCH 8/9] drm/exynos: Convert g2d_userptr_get_dma_addr() to use get_vaddr_pfn() Jan Kara 2014-03-17 19:49 ` Jan Kara 2014-03-17 19:49 ` [PATCH 9/9] staging: tidspbridge: Convert to get_vaddr_pfns() Jan Kara 2014-03-17 19:49 ` Jan Kara 2014-04-10 10:02 ` [RFC] Helper to abstract vma handling in media layer Marek Szyprowski 2014-04-10 10:02 ` Marek Szyprowski 2014-04-10 10:32 ` Jan Kara 2014-04-10 10:32 ` Jan Kara 2014-04-10 11:07 ` Hans Verkuil 2014-04-10 11:07 ` Hans Verkuil 2014-04-10 12:15 ` Jan Kara 2014-04-10 12:15 ` Jan Kara 2014-04-10 12:22 ` Hans Verkuil 2014-04-10 12:22 ` Hans Verkuil 2014-04-10 21:57 ` Jan Kara 2014-04-10 21:57 ` Jan Kara 2014-04-10 22:18 ` Jan Kara 2014-04-10 22:18 ` Jan Kara 2014-04-11 6:58 ` Hans Verkuil 2014-04-11 6:58 ` Hans Verkuil 2014-04-14 21:19 ` Jan Kara 2014-04-14 21:19 ` Jan Kara
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1395085776-8626-5-git-send-email-jack@suse.cz \ --to=jack@suse.cz \ --cc=linux-media@vger.kernel.org \ --cc=linux-mm@kvack.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.