From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from cantor2.suse.de ([195.135.220.15]:59489 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753312AbbEFH22 (ORCPT ); Wed, 6 May 2015 03:28:28 -0400 From: Jan Kara To: linux-mm@kvack.org Cc: linux-media@vger.kernel.org, Hans Verkuil , dri-devel@lists.freedesktop.org, Pawel Osciak , Mauro Carvalho Chehab , mgorman@suse.de, Marek Szyprowski , linux-samsung-soc@vger.kernel.org, Jan Kara Subject: [PATCH 7/9] media: vb2: Convert vb2_dc_get_userptr() to use frame vector Date: Wed, 6 May 2015 09:28:14 +0200 Message-Id: <1430897296-5469-8-git-send-email-jack@suse.cz> In-Reply-To: <1430897296-5469-1-git-send-email-jack@suse.cz> References: <1430897296-5469-1-git-send-email-jack@suse.cz> Sender: linux-media-owner@vger.kernel.org List-ID: Convert vb2_dc_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 Tested-by: Marek Szyprowski Signed-off-by: Jan Kara --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 214 ++++--------------------- 1 file changed, 34 insertions(+), 180 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 620c4aa78881..e6cea452302b 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -32,15 +32,13 @@ struct vb2_dc_buf { dma_addr_t dma_addr; enum dma_data_direction dma_dir; struct sg_table *dma_sgt; + struct frame_vector *vec; /* MMAP related */ struct vb2_vmarea_handler handler; atomic_t refcount; struct sg_table *sgt_base; - /* USERPTR related */ - struct vm_area_struct *vma; - /* DMABUF related */ struct dma_buf_attachment *db_attach; }; @@ -49,24 +47,6 @@ struct vb2_dc_buf { /* scatterlist table functions */ /*********************************************/ - -static void vb2_dc_sgt_foreach_page(struct sg_table *sgt, - void (*cb)(struct page *pg)) -{ - struct scatterlist *s; - unsigned int i; - - for_each_sg(sgt->sgl, s, sgt->orig_nents, i) { - struct page *page = sg_page(s); - unsigned int n_pages = PAGE_ALIGN(s->offset + s->length) - >> PAGE_SHIFT; - unsigned int j; - - for (j = 0; j < n_pages; ++j, ++page) - cb(page); - } -} - static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt) { struct scatterlist *s; @@ -429,92 +409,12 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags) /* callbacks for USERPTR buffers */ /*********************************************/ -static inline int vma_is_io(struct vm_area_struct *vma) -{ - return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); -} - -static int vb2_dc_get_user_pfn(unsigned long start, int n_pages, - struct vm_area_struct *vma, unsigned long *res) -{ - unsigned long pfn, start_pfn, prev_pfn; - unsigned int i; - int ret; - - if (!vma_is_io(vma)) - return -EFAULT; - - ret = follow_pfn(vma, start, &pfn); - if (ret) - return ret; - - start_pfn = pfn; - start += PAGE_SIZE; - - for (i = 1; i < n_pages; ++i, start += PAGE_SIZE) { - prev_pfn = pfn; - ret = follow_pfn(vma, start, &pfn); - - if (ret) { - pr_err("no page for address %lu\n", start); - return ret; - } - if (pfn != prev_pfn + 1) - return -EINVAL; - } - - *res = start_pfn; - return 0; -} - -static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, - int n_pages, struct vm_area_struct *vma, - enum dma_data_direction dma_dir) -{ - if (vma_is_io(vma)) { - unsigned int i; - - for (i = 0; i < n_pages; ++i, start += PAGE_SIZE) { - unsigned long pfn; - int ret = follow_pfn(vma, start, &pfn); - - if (!pfn_valid(pfn)) - return -EINVAL; - - if (ret) { - pr_err("no page for address %lu\n", start); - return ret; - } - pages[i] = pfn_to_page(pfn); - } - } else { - int n; - - n = get_user_pages(current, current->mm, start & PAGE_MASK, - n_pages, dma_dir == DMA_FROM_DEVICE, 1, pages, NULL); - /* negative error means that no page was pinned */ - n = max(n, 0); - if (n != n_pages) { - pr_err("got only %d of %d user pages\n", n, n_pages); - while (n) - put_page(pages[--n]); - return -EFAULT; - } - } - - return 0; -} - -static void vb2_dc_put_dirty_page(struct page *page) -{ - set_page_dirty_lock(page); - put_page(page); -} - static void vb2_dc_put_userptr(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; + int i; + struct page **pages; if (sgt) { DEFINE_DMA_ATTRS(attrs); @@ -526,15 +426,15 @@ static void vb2_dc_put_userptr(void *buf_priv) */ dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir, &attrs); - if (!vma_is_io(buf->vma)) - vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page); - + pages = frame_vector_pages(buf->vec); + /* sgt should exist only if vector contains pages... */ + BUG_ON(IS_ERR(pages)); + for (i = 0; i < frame_vector_count(buf->vec); i++) + set_page_dirty_lock(pages[i]); sg_free_table(sgt); kfree(sgt); } - down_read(¤t->mm->mmap_sem); - vb2_put_vma(buf->vma); - up_read(¤t->mm->mmap_sem); + vb2_destroy_framevec(buf->vec); kfree(buf); } @@ -574,13 +474,10 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, { struct vb2_dc_conf *conf = alloc_ctx; struct vb2_dc_buf *buf; - unsigned long start; - unsigned long end; + struct frame_vector *vec; unsigned long offset; - struct page **pages; - int n_pages; + int n_pages, i; int ret = 0; - struct vm_area_struct *vma; struct sg_table *sgt; unsigned long contig_size; unsigned long dma_align = dma_get_cache_alignment(); @@ -606,75 +503,43 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, buf->dev = conf->dev; buf->dma_dir = dma_dir; - start = vaddr & PAGE_MASK; offset = vaddr & ~PAGE_MASK; - end = PAGE_ALIGN(vaddr + size); - n_pages = (end - start) >> PAGE_SHIFT; - - pages = kmalloc(n_pages * sizeof(pages[0]), GFP_KERNEL); - if (!pages) { - ret = -ENOMEM; - pr_err("failed to allocate pages table\n"); + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); + if (IS_ERR(vec)) { + ret = PTR_ERR(vec); goto fail_buf; } + buf->vec = vec; + n_pages = frame_vector_count(vec); + ret = frame_vector_to_pages(vec); + if (ret < 0) { + unsigned long *nums = frame_vector_pfns(vec); - down_read(¤t->mm->mmap_sem); - /* current->mm->mmap_sem is taken by videobuf2 core */ - vma = find_vma(current->mm, vaddr); - if (!vma) { - pr_err("no vma for address %lu\n", vaddr); - ret = -EFAULT; - goto fail_pages; - } - - if (vma->vm_end < vaddr + size) { - pr_err("vma at %lu is too small for %lu bytes\n", vaddr, size); - ret = -EFAULT; - goto fail_pages; - } - - buf->vma = vb2_get_vma(vma); - if (!buf->vma) { - pr_err("failed to copy vma\n"); - ret = -ENOMEM; - goto fail_pages; - } - - /* extract page list from userspace mapping */ - ret = vb2_dc_get_user_pages(start, pages, n_pages, vma, dma_dir); - if (ret) { - unsigned long pfn; - if (vb2_dc_get_user_pfn(start, n_pages, vma, &pfn) == 0) { - up_read(¤t->mm->mmap_sem); - buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, pfn); - buf->size = size; - kfree(pages); - return buf; - } - - pr_err("failed to get user pages\n"); - goto fail_vma; + /* + * Failed to convert to pages... Check the memory is physically + * contiguous and use direct mapping + */ + for (i = 1; i < n_pages; i++) + if (nums[i-1] + 1 != nums[i]) + goto fail_pfnvec; + buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, nums[0]); + goto out; } - up_read(¤t->mm->mmap_sem); sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) { pr_err("failed to allocate sg table\n"); ret = -ENOMEM; - goto fail_get_user_pages; + goto fail_pfnvec; } - ret = sg_alloc_table_from_pages(sgt, pages, n_pages, + ret = sg_alloc_table_from_pages(sgt, frame_vector_pages(vec), n_pages, offset, size, GFP_KERNEL); if (ret) { pr_err("failed to initialize sg table\n"); goto fail_sgt; } - /* pages are no longer needed */ - kfree(pages); - pages = NULL; - /* * No need to sync to the device, this will happen later when the * prepare() memop is called. @@ -696,8 +561,9 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, } buf->dma_addr = sg_dma_address(sgt->sgl); - buf->size = size; buf->dma_sgt = sgt; +out: + buf->size = size; return buf; @@ -706,25 +572,13 @@ fail_map_sg: buf->dma_dir, &attrs); fail_sgt_init: - if (!vma_is_io(buf->vma)) - vb2_dc_sgt_foreach_page(sgt, put_page); sg_free_table(sgt); fail_sgt: kfree(sgt); -fail_get_user_pages: - if (pages && !vma_is_io(buf->vma)) - while (n_pages) - put_page(pages[--n_pages]); - - down_read(¤t->mm->mmap_sem); -fail_vma: - vb2_put_vma(buf->vma); - -fail_pages: - up_read(¤t->mm->mmap_sem); - kfree(pages); /* kfree is NULL-proof */ +fail_pfnvec: + vb2_destroy_framevec(vec); fail_buf: kfree(buf); -- 2.1.4 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kara Subject: [PATCH 7/9] media: vb2: Convert vb2_dc_get_userptr() to use frame vector Date: Wed, 6 May 2015 09:28:14 +0200 Message-ID: <1430897296-5469-8-git-send-email-jack@suse.cz> References: <1430897296-5469-1-git-send-email-jack@suse.cz> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1430897296-5469-1-git-send-email-jack@suse.cz> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: linux-mm@kvack.org Cc: linux-samsung-soc@vger.kernel.org, Jan Kara , Pawel Osciak , Mauro Carvalho Chehab , dri-devel@lists.freedesktop.org, mgorman@suse.de, Marek Szyprowski , linux-media@vger.kernel.org List-Id: linux-samsung-soc@vger.kernel.org Q29udmVydCB2YjJfZGNfZ2V0X3VzZXJwdHIoKSB0byB1c2UgZnJhbWUgdmVjdG9yIGluZnJhc3Ry dWN0dXJlLiBXaGVuIHdlCmFyZSBkb2luZyB0aGF0IHRoZXJlJ3Mgbm8gbmVlZCB0byBhbGxvY2F0 ZSBwYWdlIGFycmF5IGFuZCBzb21lIGNvZGUgY2FuCmJlIHNpbXBsaWZpZWQuCgpBY2tlZC1ieTog TWFyZWsgU3p5cHJvd3NraSA8bS5zenlwcm93c2tpQHNhbXN1bmcuY29tPgpUZXN0ZWQtYnk6IE1h cmVrIFN6eXByb3dza2kgPG0uc3p5cHJvd3NraUBzYW1zdW5nLmNvbT4KU2lnbmVkLW9mZi1ieTog SmFuIEthcmEgPGphY2tAc3VzZS5jej4KLS0tCiBkcml2ZXJzL21lZGlhL3Y0bDItY29yZS92aWRl b2J1ZjItZG1hLWNvbnRpZy5jIHwgMjE0ICsrKystLS0tLS0tLS0tLS0tLS0tLS0tLS0KIDEgZmls ZSBjaGFuZ2VkLCAzNCBpbnNlcnRpb25zKCspLCAxODAgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0 IGEvZHJpdmVycy9tZWRpYS92NGwyLWNvcmUvdmlkZW9idWYyLWRtYS1jb250aWcuYyBiL2RyaXZl cnMvbWVkaWEvdjRsMi1jb3JlL3ZpZGVvYnVmMi1kbWEtY29udGlnLmMKaW5kZXggNjIwYzRhYTc4 ODgxLi5lNmNlYTQ1MjMwMmIgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvbWVkaWEvdjRsMi1jb3JlL3Zp ZGVvYnVmMi1kbWEtY29udGlnLmMKKysrIGIvZHJpdmVycy9tZWRpYS92NGwyLWNvcmUvdmlkZW9i dWYyLWRtYS1jb250aWcuYwpAQCAtMzIsMTUgKzMyLDEzIEBAIHN0cnVjdCB2YjJfZGNfYnVmIHsK IAlkbWFfYWRkcl90CQkJZG1hX2FkZHI7CiAJZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24JCWRtYV9k aXI7CiAJc3RydWN0IHNnX3RhYmxlCQkJKmRtYV9zZ3Q7CisJc3RydWN0IGZyYW1lX3ZlY3RvcgkJ KnZlYzsKIAogCS8qIE1NQVAgcmVsYXRlZCAqLwogCXN0cnVjdCB2YjJfdm1hcmVhX2hhbmRsZXIJ aGFuZGxlcjsKIAlhdG9taWNfdAkJCXJlZmNvdW50OwogCXN0cnVjdCBzZ190YWJsZQkJCSpzZ3Rf YmFzZTsKIAotCS8qIFVTRVJQVFIgcmVsYXRlZCAqLwotCXN0cnVjdCB2bV9hcmVhX3N0cnVjdAkJ KnZtYTsKLQogCS8qIERNQUJVRiByZWxhdGVkICovCiAJc3RydWN0IGRtYV9idWZfYXR0YWNobWVu dAkqZGJfYXR0YWNoOwogfTsKQEAgLTQ5LDI0ICs0Nyw2IEBAIHN0cnVjdCB2YjJfZGNfYnVmIHsK IC8qICAgICAgICBzY2F0dGVybGlzdCB0YWJsZSBmdW5jdGlvbnMgICAgICAgICovCiAvKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogCi0KLXN0YXRpYyB2b2lk IHZiMl9kY19zZ3RfZm9yZWFjaF9wYWdlKHN0cnVjdCBzZ190YWJsZSAqc2d0LAotCXZvaWQgKCpj Yikoc3RydWN0IHBhZ2UgKnBnKSkKLXsKLQlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnM7Ci0JdW5zaWdu ZWQgaW50IGk7Ci0KLQlmb3JfZWFjaF9zZyhzZ3QtPnNnbCwgcywgc2d0LT5vcmlnX25lbnRzLCBp KSB7Ci0JCXN0cnVjdCBwYWdlICpwYWdlID0gc2dfcGFnZShzKTsKLQkJdW5zaWduZWQgaW50IG5f cGFnZXMgPSBQQUdFX0FMSUdOKHMtPm9mZnNldCArIHMtPmxlbmd0aCkKLQkJCT4+IFBBR0VfU0hJ RlQ7Ci0JCXVuc2lnbmVkIGludCBqOwotCi0JCWZvciAoaiA9IDA7IGogPCBuX3BhZ2VzOyArK2os ICsrcGFnZSkKLQkJCWNiKHBhZ2UpOwotCX0KLX0KLQogc3RhdGljIHVuc2lnbmVkIGxvbmcgdmIy X2RjX2dldF9jb250aWd1b3VzX3NpemUoc3RydWN0IHNnX3RhYmxlICpzZ3QpCiB7CiAJc3RydWN0 IHNjYXR0ZXJsaXN0ICpzOwpAQCAtNDI5LDkyICs0MDksMTIgQEAgc3RhdGljIHN0cnVjdCBkbWFf YnVmICp2YjJfZGNfZ2V0X2RtYWJ1Zih2b2lkICpidWZfcHJpdiwgdW5zaWduZWQgbG9uZyBmbGFn cykKIC8qICAgICAgIGNhbGxiYWNrcyBmb3IgVVNFUlBUUiBidWZmZXJzICAgICAgICovCiAvKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogCi1zdGF0aWMgaW5s aW5lIGludCB2bWFfaXNfaW8oc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCi17Ci0JcmV0dXJu ICEhKHZtYS0+dm1fZmxhZ3MgJiAoVk1fSU8gfCBWTV9QRk5NQVApKTsKLX0KLQotc3RhdGljIGlu dCB2YjJfZGNfZ2V0X3VzZXJfcGZuKHVuc2lnbmVkIGxvbmcgc3RhcnQsIGludCBuX3BhZ2VzLAot CXN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hLCB1bnNpZ25lZCBsb25nICpyZXMpCi17Ci0JdW5z aWduZWQgbG9uZyBwZm4sIHN0YXJ0X3BmbiwgcHJldl9wZm47Ci0JdW5zaWduZWQgaW50IGk7Ci0J aW50IHJldDsKLQotCWlmICghdm1hX2lzX2lvKHZtYSkpCi0JCXJldHVybiAtRUZBVUxUOwotCi0J cmV0ID0gZm9sbG93X3Bmbih2bWEsIHN0YXJ0LCAmcGZuKTsKLQlpZiAocmV0KQotCQlyZXR1cm4g cmV0OwotCi0Jc3RhcnRfcGZuID0gcGZuOwotCXN0YXJ0ICs9IFBBR0VfU0laRTsKLQotCWZvciAo aSA9IDE7IGkgPCBuX3BhZ2VzOyArK2ksIHN0YXJ0ICs9IFBBR0VfU0laRSkgewotCQlwcmV2X3Bm biA9IHBmbjsKLQkJcmV0ID0gZm9sbG93X3Bmbih2bWEsIHN0YXJ0LCAmcGZuKTsKLQotCQlpZiAo cmV0KSB7Ci0JCQlwcl9lcnIoIm5vIHBhZ2UgZm9yIGFkZHJlc3MgJWx1XG4iLCBzdGFydCk7Ci0J CQlyZXR1cm4gcmV0OwotCQl9Ci0JCWlmIChwZm4gIT0gcHJldl9wZm4gKyAxKQotCQkJcmV0dXJu IC1FSU5WQUw7Ci0JfQotCi0JKnJlcyA9IHN0YXJ0X3BmbjsKLQlyZXR1cm4gMDsKLX0KLQotc3Rh dGljIGludCB2YjJfZGNfZ2V0X3VzZXJfcGFnZXModW5zaWduZWQgbG9uZyBzdGFydCwgc3RydWN0 IHBhZ2UgKipwYWdlcywKLQlpbnQgbl9wYWdlcywgc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEs Ci0JZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZG1hX2RpcikKLXsKLQlpZiAodm1hX2lzX2lvKHZt YSkpIHsKLQkJdW5zaWduZWQgaW50IGk7Ci0KLQkJZm9yIChpID0gMDsgaSA8IG5fcGFnZXM7ICsr aSwgc3RhcnQgKz0gUEFHRV9TSVpFKSB7Ci0JCQl1bnNpZ25lZCBsb25nIHBmbjsKLQkJCWludCBy ZXQgPSBmb2xsb3dfcGZuKHZtYSwgc3RhcnQsICZwZm4pOwotCi0JCQlpZiAoIXBmbl92YWxpZChw Zm4pKQotCQkJCXJldHVybiAtRUlOVkFMOwotCi0JCQlpZiAocmV0KSB7Ci0JCQkJcHJfZXJyKCJu byBwYWdlIGZvciBhZGRyZXNzICVsdVxuIiwgc3RhcnQpOwotCQkJCXJldHVybiByZXQ7Ci0JCQl9 Ci0JCQlwYWdlc1tpXSA9IHBmbl90b19wYWdlKHBmbik7Ci0JCX0KLQl9IGVsc2UgewotCQlpbnQg bjsKLQotCQluID0gZ2V0X3VzZXJfcGFnZXMoY3VycmVudCwgY3VycmVudC0+bW0sIHN0YXJ0ICYg UEFHRV9NQVNLLAotCQkJbl9wYWdlcywgZG1hX2RpciA9PSBETUFfRlJPTV9ERVZJQ0UsIDEsIHBh Z2VzLCBOVUxMKTsKLQkJLyogbmVnYXRpdmUgZXJyb3IgbWVhbnMgdGhhdCBubyBwYWdlIHdhcyBw aW5uZWQgKi8KLQkJbiA9IG1heChuLCAwKTsKLQkJaWYgKG4gIT0gbl9wYWdlcykgewotCQkJcHJf ZXJyKCJnb3Qgb25seSAlZCBvZiAlZCB1c2VyIHBhZ2VzXG4iLCBuLCBuX3BhZ2VzKTsKLQkJCXdo aWxlIChuKQotCQkJCXB1dF9wYWdlKHBhZ2VzWy0tbl0pOwotCQkJcmV0dXJuIC1FRkFVTFQ7Ci0J CX0KLQl9Ci0KLQlyZXR1cm4gMDsKLX0KLQotc3RhdGljIHZvaWQgdmIyX2RjX3B1dF9kaXJ0eV9w YWdlKHN0cnVjdCBwYWdlICpwYWdlKQotewotCXNldF9wYWdlX2RpcnR5X2xvY2socGFnZSk7Ci0J cHV0X3BhZ2UocGFnZSk7Ci19Ci0KIHN0YXRpYyB2b2lkIHZiMl9kY19wdXRfdXNlcnB0cih2b2lk ICpidWZfcHJpdikKIHsKIAlzdHJ1Y3QgdmIyX2RjX2J1ZiAqYnVmID0gYnVmX3ByaXY7CiAJc3Ry dWN0IHNnX3RhYmxlICpzZ3QgPSBidWYtPmRtYV9zZ3Q7CisJaW50IGk7CisJc3RydWN0IHBhZ2Ug KipwYWdlczsKIAogCWlmIChzZ3QpIHsKIAkJREVGSU5FX0RNQV9BVFRSUyhhdHRycyk7CkBAIC01 MjYsMTUgKzQyNiwxNSBAQCBzdGF0aWMgdm9pZCB2YjJfZGNfcHV0X3VzZXJwdHIodm9pZCAqYnVm X3ByaXYpCiAJCSAqLwogCQlkbWFfdW5tYXBfc2dfYXR0cnMoYnVmLT5kZXYsIHNndC0+c2dsLCBz Z3QtPm9yaWdfbmVudHMsCiAJCQkJICAgYnVmLT5kbWFfZGlyLCAmYXR0cnMpOwotCQlpZiAoIXZt YV9pc19pbyhidWYtPnZtYSkpCi0JCQl2YjJfZGNfc2d0X2ZvcmVhY2hfcGFnZShzZ3QsIHZiMl9k Y19wdXRfZGlydHlfcGFnZSk7Ci0KKwkJcGFnZXMgPSBmcmFtZV92ZWN0b3JfcGFnZXMoYnVmLT52 ZWMpOworCQkvKiBzZ3Qgc2hvdWxkIGV4aXN0IG9ubHkgaWYgdmVjdG9yIGNvbnRhaW5zIHBhZ2Vz Li4uICovCisJCUJVR19PTihJU19FUlIocGFnZXMpKTsKKwkJZm9yIChpID0gMDsgaSA8IGZyYW1l X3ZlY3Rvcl9jb3VudChidWYtPnZlYyk7IGkrKykKKwkJCXNldF9wYWdlX2RpcnR5X2xvY2socGFn ZXNbaV0pOwogCQlzZ19mcmVlX3RhYmxlKHNndCk7CiAJCWtmcmVlKHNndCk7CiAJfQotCWRvd25f cmVhZCgmY3VycmVudC0+bW0tPm1tYXBfc2VtKTsKLQl2YjJfcHV0X3ZtYShidWYtPnZtYSk7Ci0J dXBfcmVhZCgmY3VycmVudC0+bW0tPm1tYXBfc2VtKTsKKwl2YjJfZGVzdHJveV9mcmFtZXZlYyhi dWYtPnZlYyk7CiAJa2ZyZWUoYnVmKTsKIH0KIApAQCAtNTc0LDEzICs0NzQsMTAgQEAgc3RhdGlj IHZvaWQgKnZiMl9kY19nZXRfdXNlcnB0cih2b2lkICphbGxvY19jdHgsIHVuc2lnbmVkIGxvbmcg dmFkZHIsCiB7CiAJc3RydWN0IHZiMl9kY19jb25mICpjb25mID0gYWxsb2NfY3R4OwogCXN0cnVj dCB2YjJfZGNfYnVmICpidWY7Ci0JdW5zaWduZWQgbG9uZyBzdGFydDsKLQl1bnNpZ25lZCBsb25n IGVuZDsKKwlzdHJ1Y3QgZnJhbWVfdmVjdG9yICp2ZWM7CiAJdW5zaWduZWQgbG9uZyBvZmZzZXQ7 Ci0Jc3RydWN0IHBhZ2UgKipwYWdlczsKLQlpbnQgbl9wYWdlczsKKwlpbnQgbl9wYWdlcywgaTsK IAlpbnQgcmV0ID0gMDsKLQlzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYTsKIAlzdHJ1Y3Qgc2df dGFibGUgKnNndDsKIAl1bnNpZ25lZCBsb25nIGNvbnRpZ19zaXplOwogCXVuc2lnbmVkIGxvbmcg ZG1hX2FsaWduID0gZG1hX2dldF9jYWNoZV9hbGlnbm1lbnQoKTsKQEAgLTYwNiw3NSArNTAzLDQz IEBAIHN0YXRpYyB2b2lkICp2YjJfZGNfZ2V0X3VzZXJwdHIodm9pZCAqYWxsb2NfY3R4LCB1bnNp Z25lZCBsb25nIHZhZGRyLAogCWJ1Zi0+ZGV2ID0gY29uZi0+ZGV2OwogCWJ1Zi0+ZG1hX2RpciA9 IGRtYV9kaXI7CiAKLQlzdGFydCA9IHZhZGRyICYgUEFHRV9NQVNLOwogCW9mZnNldCA9IHZhZGRy ICYgflBBR0VfTUFTSzsKLQllbmQgPSBQQUdFX0FMSUdOKHZhZGRyICsgc2l6ZSk7Ci0Jbl9wYWdl cyA9IChlbmQgLSBzdGFydCkgPj4gUEFHRV9TSElGVDsKLQotCXBhZ2VzID0ga21hbGxvYyhuX3Bh Z2VzICogc2l6ZW9mKHBhZ2VzWzBdKSwgR0ZQX0tFUk5FTCk7Ci0JaWYgKCFwYWdlcykgewotCQly ZXQgPSAtRU5PTUVNOwotCQlwcl9lcnIoImZhaWxlZCB0byBhbGxvY2F0ZSBwYWdlcyB0YWJsZVxu Iik7CisJdmVjID0gdmIyX2NyZWF0ZV9mcmFtZXZlYyh2YWRkciwgc2l6ZSwgZG1hX2RpciA9PSBE TUFfRlJPTV9ERVZJQ0UpOworCWlmIChJU19FUlIodmVjKSkgeworCQlyZXQgPSBQVFJfRVJSKHZl Yyk7CiAJCWdvdG8gZmFpbF9idWY7CiAJfQorCWJ1Zi0+dmVjID0gdmVjOworCW5fcGFnZXMgPSBm cmFtZV92ZWN0b3JfY291bnQodmVjKTsKKwlyZXQgPSBmcmFtZV92ZWN0b3JfdG9fcGFnZXModmVj KTsKKwlpZiAocmV0IDwgMCkgeworCQl1bnNpZ25lZCBsb25nICpudW1zID0gZnJhbWVfdmVjdG9y X3BmbnModmVjKTsKIAotCWRvd25fcmVhZCgmY3VycmVudC0+bW0tPm1tYXBfc2VtKTsKLQkvKiBj dXJyZW50LT5tbS0+bW1hcF9zZW0gaXMgdGFrZW4gYnkgdmlkZW9idWYyIGNvcmUgKi8KLQl2bWEg PSBmaW5kX3ZtYShjdXJyZW50LT5tbSwgdmFkZHIpOwotCWlmICghdm1hKSB7Ci0JCXByX2Vycigi bm8gdm1hIGZvciBhZGRyZXNzICVsdVxuIiwgdmFkZHIpOwotCQlyZXQgPSAtRUZBVUxUOwotCQln b3RvIGZhaWxfcGFnZXM7Ci0JfQotCi0JaWYgKHZtYS0+dm1fZW5kIDwgdmFkZHIgKyBzaXplKSB7 Ci0JCXByX2Vycigidm1hIGF0ICVsdSBpcyB0b28gc21hbGwgZm9yICVsdSBieXRlc1xuIiwgdmFk ZHIsIHNpemUpOwotCQlyZXQgPSAtRUZBVUxUOwotCQlnb3RvIGZhaWxfcGFnZXM7Ci0JfQotCi0J YnVmLT52bWEgPSB2YjJfZ2V0X3ZtYSh2bWEpOwotCWlmICghYnVmLT52bWEpIHsKLQkJcHJfZXJy KCJmYWlsZWQgdG8gY29weSB2bWFcbiIpOwotCQlyZXQgPSAtRU5PTUVNOwotCQlnb3RvIGZhaWxf cGFnZXM7Ci0JfQotCi0JLyogZXh0cmFjdCBwYWdlIGxpc3QgZnJvbSB1c2Vyc3BhY2UgbWFwcGlu ZyAqLwotCXJldCA9IHZiMl9kY19nZXRfdXNlcl9wYWdlcyhzdGFydCwgcGFnZXMsIG5fcGFnZXMs IHZtYSwgZG1hX2Rpcik7Ci0JaWYgKHJldCkgewotCQl1bnNpZ25lZCBsb25nIHBmbjsKLQkJaWYg KHZiMl9kY19nZXRfdXNlcl9wZm4oc3RhcnQsIG5fcGFnZXMsIHZtYSwgJnBmbikgPT0gMCkgewot CQkJdXBfcmVhZCgmY3VycmVudC0+bW0tPm1tYXBfc2VtKTsKLQkJCWJ1Zi0+ZG1hX2FkZHIgPSB2 YjJfZGNfcGZuX3RvX2RtYShidWYtPmRldiwgcGZuKTsKLQkJCWJ1Zi0+c2l6ZSA9IHNpemU7Ci0J CQlrZnJlZShwYWdlcyk7Ci0JCQlyZXR1cm4gYnVmOwotCQl9Ci0KLQkJcHJfZXJyKCJmYWlsZWQg dG8gZ2V0IHVzZXIgcGFnZXNcbiIpOwotCQlnb3RvIGZhaWxfdm1hOworCQkvKgorCQkgKiBGYWls ZWQgdG8gY29udmVydCB0byBwYWdlcy4uLiBDaGVjayB0aGUgbWVtb3J5IGlzIHBoeXNpY2FsbHkK KwkJICogY29udGlndW91cyBhbmQgdXNlIGRpcmVjdCBtYXBwaW5nCisJCSAqLworCQlmb3IgKGkg PSAxOyBpIDwgbl9wYWdlczsgaSsrKQorCQkJaWYgKG51bXNbaS0xXSArIDEgIT0gbnVtc1tpXSkK KwkJCQlnb3RvIGZhaWxfcGZudmVjOworCQlidWYtPmRtYV9hZGRyID0gdmIyX2RjX3Bmbl90b19k bWEoYnVmLT5kZXYsIG51bXNbMF0pOworCQlnb3RvIG91dDsKIAl9Ci0JdXBfcmVhZCgmY3VycmVu dC0+bW0tPm1tYXBfc2VtKTsKIAogCXNndCA9IGt6YWxsb2Moc2l6ZW9mKCpzZ3QpLCBHRlBfS0VS TkVMKTsKIAlpZiAoIXNndCkgewogCQlwcl9lcnIoImZhaWxlZCB0byBhbGxvY2F0ZSBzZyB0YWJs ZVxuIik7CiAJCXJldCA9IC1FTk9NRU07Ci0JCWdvdG8gZmFpbF9nZXRfdXNlcl9wYWdlczsKKwkJ Z290byBmYWlsX3BmbnZlYzsKIAl9CiAKLQlyZXQgPSBzZ19hbGxvY190YWJsZV9mcm9tX3BhZ2Vz KHNndCwgcGFnZXMsIG5fcGFnZXMsCisJcmV0ID0gc2dfYWxsb2NfdGFibGVfZnJvbV9wYWdlcyhz Z3QsIGZyYW1lX3ZlY3Rvcl9wYWdlcyh2ZWMpLCBuX3BhZ2VzLAogCQlvZmZzZXQsIHNpemUsIEdG UF9LRVJORUwpOwogCWlmIChyZXQpIHsKIAkJcHJfZXJyKCJmYWlsZWQgdG8gaW5pdGlhbGl6ZSBz ZyB0YWJsZVxuIik7CiAJCWdvdG8gZmFpbF9zZ3Q7CiAJfQogCi0JLyogcGFnZXMgYXJlIG5vIGxv bmdlciBuZWVkZWQgKi8KLQlrZnJlZShwYWdlcyk7Ci0JcGFnZXMgPSBOVUxMOwotCiAJLyoKIAkg KiBObyBuZWVkIHRvIHN5bmMgdG8gdGhlIGRldmljZSwgdGhpcyB3aWxsIGhhcHBlbiBsYXRlciB3 aGVuIHRoZQogCSAqIHByZXBhcmUoKSBtZW1vcCBpcyBjYWxsZWQuCkBAIC02OTYsOCArNTYxLDkg QEAgc3RhdGljIHZvaWQgKnZiMl9kY19nZXRfdXNlcnB0cih2b2lkICphbGxvY19jdHgsIHVuc2ln bmVkIGxvbmcgdmFkZHIsCiAJfQogCiAJYnVmLT5kbWFfYWRkciA9IHNnX2RtYV9hZGRyZXNzKHNn dC0+c2dsKTsKLQlidWYtPnNpemUgPSBzaXplOwogCWJ1Zi0+ZG1hX3NndCA9IHNndDsKK291dDoK KwlidWYtPnNpemUgPSBzaXplOwogCiAJcmV0dXJuIGJ1ZjsKIApAQCAtNzA2LDI1ICs1NzIsMTMg QEAgZmFpbF9tYXBfc2c6CiAJCQkgICBidWYtPmRtYV9kaXIsICZhdHRycyk7CiAKIGZhaWxfc2d0 X2luaXQ6Ci0JaWYgKCF2bWFfaXNfaW8oYnVmLT52bWEpKQotCQl2YjJfZGNfc2d0X2ZvcmVhY2hf cGFnZShzZ3QsIHB1dF9wYWdlKTsKIAlzZ19mcmVlX3RhYmxlKHNndCk7CiAKIGZhaWxfc2d0Ogog CWtmcmVlKHNndCk7CiAKLWZhaWxfZ2V0X3VzZXJfcGFnZXM6Ci0JaWYgKHBhZ2VzICYmICF2bWFf aXNfaW8oYnVmLT52bWEpKQotCQl3aGlsZSAobl9wYWdlcykKLQkJCXB1dF9wYWdlKHBhZ2VzWy0t bl9wYWdlc10pOwotCi0JZG93bl9yZWFkKCZjdXJyZW50LT5tbS0+bW1hcF9zZW0pOwotZmFpbF92 bWE6Ci0JdmIyX3B1dF92bWEoYnVmLT52bWEpOwotCi1mYWlsX3BhZ2VzOgotCXVwX3JlYWQoJmN1 cnJlbnQtPm1tLT5tbWFwX3NlbSk7Ci0Ja2ZyZWUocGFnZXMpOyAvKiBrZnJlZSBpcyBOVUxMLXBy b29mICovCitmYWlsX3BmbnZlYzoKKwl2YjJfZGVzdHJveV9mcmFtZXZlYyh2ZWMpOwogCiBmYWls X2J1ZjoKIAlrZnJlZShidWYpOwotLSAKMi4xLjQKCl9fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxp c3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4v bGlzdGluZm8vZHJpLWRldmVsCg== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wg0-f41.google.com (mail-wg0-f41.google.com [74.125.82.41]) by kanga.kvack.org (Postfix) with ESMTP id EE0156B007D for ; Wed, 6 May 2015 03:28:37 -0400 (EDT) Received: by wgin8 with SMTP id n8so1796843wgi.0 for ; Wed, 06 May 2015 00:28:37 -0700 (PDT) Received: from mx2.suse.de (cantor2.suse.de. [195.135.220.15]) by mx.google.com with ESMTPS id o1si766945wix.88.2015.05.06.00.28.26 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 06 May 2015 00:28:27 -0700 (PDT) From: Jan Kara Subject: [PATCH 7/9] media: vb2: Convert vb2_dc_get_userptr() to use frame vector Date: Wed, 6 May 2015 09:28:14 +0200 Message-Id: <1430897296-5469-8-git-send-email-jack@suse.cz> In-Reply-To: <1430897296-5469-1-git-send-email-jack@suse.cz> References: <1430897296-5469-1-git-send-email-jack@suse.cz> Sender: owner-linux-mm@kvack.org List-ID: To: linux-mm@kvack.org Cc: linux-media@vger.kernel.org, Hans Verkuil , dri-devel@lists.freedesktop.org, Pawel Osciak , Mauro Carvalho Chehab , mgorman@suse.de, Marek Szyprowski , linux-samsung-soc@vger.kernel.org, Jan Kara Convert vb2_dc_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 Tested-by: Marek Szyprowski Signed-off-by: Jan Kara --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 214 ++++--------------------- 1 file changed, 34 insertions(+), 180 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 620c4aa78881..e6cea452302b 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -32,15 +32,13 @@ struct vb2_dc_buf { dma_addr_t dma_addr; enum dma_data_direction dma_dir; struct sg_table *dma_sgt; + struct frame_vector *vec; /* MMAP related */ struct vb2_vmarea_handler handler; atomic_t refcount; struct sg_table *sgt_base; - /* USERPTR related */ - struct vm_area_struct *vma; - /* DMABUF related */ struct dma_buf_attachment *db_attach; }; @@ -49,24 +47,6 @@ struct vb2_dc_buf { /* scatterlist table functions */ /*********************************************/ - -static void vb2_dc_sgt_foreach_page(struct sg_table *sgt, - void (*cb)(struct page *pg)) -{ - struct scatterlist *s; - unsigned int i; - - for_each_sg(sgt->sgl, s, sgt->orig_nents, i) { - struct page *page = sg_page(s); - unsigned int n_pages = PAGE_ALIGN(s->offset + s->length) - >> PAGE_SHIFT; - unsigned int j; - - for (j = 0; j < n_pages; ++j, ++page) - cb(page); - } -} - static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt) { struct scatterlist *s; @@ -429,92 +409,12 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags) /* callbacks for USERPTR buffers */ /*********************************************/ -static inline int vma_is_io(struct vm_area_struct *vma) -{ - return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); -} - -static int vb2_dc_get_user_pfn(unsigned long start, int n_pages, - struct vm_area_struct *vma, unsigned long *res) -{ - unsigned long pfn, start_pfn, prev_pfn; - unsigned int i; - int ret; - - if (!vma_is_io(vma)) - return -EFAULT; - - ret = follow_pfn(vma, start, &pfn); - if (ret) - return ret; - - start_pfn = pfn; - start += PAGE_SIZE; - - for (i = 1; i < n_pages; ++i, start += PAGE_SIZE) { - prev_pfn = pfn; - ret = follow_pfn(vma, start, &pfn); - - if (ret) { - pr_err("no page for address %lu\n", start); - return ret; - } - if (pfn != prev_pfn + 1) - return -EINVAL; - } - - *res = start_pfn; - return 0; -} - -static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, - int n_pages, struct vm_area_struct *vma, - enum dma_data_direction dma_dir) -{ - if (vma_is_io(vma)) { - unsigned int i; - - for (i = 0; i < n_pages; ++i, start += PAGE_SIZE) { - unsigned long pfn; - int ret = follow_pfn(vma, start, &pfn); - - if (!pfn_valid(pfn)) - return -EINVAL; - - if (ret) { - pr_err("no page for address %lu\n", start); - return ret; - } - pages[i] = pfn_to_page(pfn); - } - } else { - int n; - - n = get_user_pages(current, current->mm, start & PAGE_MASK, - n_pages, dma_dir == DMA_FROM_DEVICE, 1, pages, NULL); - /* negative error means that no page was pinned */ - n = max(n, 0); - if (n != n_pages) { - pr_err("got only %d of %d user pages\n", n, n_pages); - while (n) - put_page(pages[--n]); - return -EFAULT; - } - } - - return 0; -} - -static void vb2_dc_put_dirty_page(struct page *page) -{ - set_page_dirty_lock(page); - put_page(page); -} - static void vb2_dc_put_userptr(void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; + int i; + struct page **pages; if (sgt) { DEFINE_DMA_ATTRS(attrs); @@ -526,15 +426,15 @@ static void vb2_dc_put_userptr(void *buf_priv) */ dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir, &attrs); - if (!vma_is_io(buf->vma)) - vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page); - + pages = frame_vector_pages(buf->vec); + /* sgt should exist only if vector contains pages... */ + BUG_ON(IS_ERR(pages)); + for (i = 0; i < frame_vector_count(buf->vec); i++) + set_page_dirty_lock(pages[i]); sg_free_table(sgt); kfree(sgt); } - down_read(¤t->mm->mmap_sem); - vb2_put_vma(buf->vma); - up_read(¤t->mm->mmap_sem); + vb2_destroy_framevec(buf->vec); kfree(buf); } @@ -574,13 +474,10 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, { struct vb2_dc_conf *conf = alloc_ctx; struct vb2_dc_buf *buf; - unsigned long start; - unsigned long end; + struct frame_vector *vec; unsigned long offset; - struct page **pages; - int n_pages; + int n_pages, i; int ret = 0; - struct vm_area_struct *vma; struct sg_table *sgt; unsigned long contig_size; unsigned long dma_align = dma_get_cache_alignment(); @@ -606,75 +503,43 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, buf->dev = conf->dev; buf->dma_dir = dma_dir; - start = vaddr & PAGE_MASK; offset = vaddr & ~PAGE_MASK; - end = PAGE_ALIGN(vaddr + size); - n_pages = (end - start) >> PAGE_SHIFT; - - pages = kmalloc(n_pages * sizeof(pages[0]), GFP_KERNEL); - if (!pages) { - ret = -ENOMEM; - pr_err("failed to allocate pages table\n"); + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); + if (IS_ERR(vec)) { + ret = PTR_ERR(vec); goto fail_buf; } + buf->vec = vec; + n_pages = frame_vector_count(vec); + ret = frame_vector_to_pages(vec); + if (ret < 0) { + unsigned long *nums = frame_vector_pfns(vec); - down_read(¤t->mm->mmap_sem); - /* current->mm->mmap_sem is taken by videobuf2 core */ - vma = find_vma(current->mm, vaddr); - if (!vma) { - pr_err("no vma for address %lu\n", vaddr); - ret = -EFAULT; - goto fail_pages; - } - - if (vma->vm_end < vaddr + size) { - pr_err("vma at %lu is too small for %lu bytes\n", vaddr, size); - ret = -EFAULT; - goto fail_pages; - } - - buf->vma = vb2_get_vma(vma); - if (!buf->vma) { - pr_err("failed to copy vma\n"); - ret = -ENOMEM; - goto fail_pages; - } - - /* extract page list from userspace mapping */ - ret = vb2_dc_get_user_pages(start, pages, n_pages, vma, dma_dir); - if (ret) { - unsigned long pfn; - if (vb2_dc_get_user_pfn(start, n_pages, vma, &pfn) == 0) { - up_read(¤t->mm->mmap_sem); - buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, pfn); - buf->size = size; - kfree(pages); - return buf; - } - - pr_err("failed to get user pages\n"); - goto fail_vma; + /* + * Failed to convert to pages... Check the memory is physically + * contiguous and use direct mapping + */ + for (i = 1; i < n_pages; i++) + if (nums[i-1] + 1 != nums[i]) + goto fail_pfnvec; + buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, nums[0]); + goto out; } - up_read(¤t->mm->mmap_sem); sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) { pr_err("failed to allocate sg table\n"); ret = -ENOMEM; - goto fail_get_user_pages; + goto fail_pfnvec; } - ret = sg_alloc_table_from_pages(sgt, pages, n_pages, + ret = sg_alloc_table_from_pages(sgt, frame_vector_pages(vec), n_pages, offset, size, GFP_KERNEL); if (ret) { pr_err("failed to initialize sg table\n"); goto fail_sgt; } - /* pages are no longer needed */ - kfree(pages); - pages = NULL; - /* * No need to sync to the device, this will happen later when the * prepare() memop is called. @@ -696,8 +561,9 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, } buf->dma_addr = sg_dma_address(sgt->sgl); - buf->size = size; buf->dma_sgt = sgt; +out: + buf->size = size; return buf; @@ -706,25 +572,13 @@ fail_map_sg: buf->dma_dir, &attrs); fail_sgt_init: - if (!vma_is_io(buf->vma)) - vb2_dc_sgt_foreach_page(sgt, put_page); sg_free_table(sgt); fail_sgt: kfree(sgt); -fail_get_user_pages: - if (pages && !vma_is_io(buf->vma)) - while (n_pages) - put_page(pages[--n_pages]); - - down_read(¤t->mm->mmap_sem); -fail_vma: - vb2_put_vma(buf->vma); - -fail_pages: - up_read(¤t->mm->mmap_sem); - kfree(pages); /* kfree is NULL-proof */ +fail_pfnvec: + vb2_destroy_framevec(vec); fail_buf: kfree(buf); -- 2.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: email@kvack.org