From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Tomasz Stanislawski <t.stanislaws@samsung.com>
Cc: amwang@redhat.com, linux-kernel@vger.kernel.org,
dri-devel@lists.freedesktop.org,
"'???/Mobile S/W Platform Lab.(???)/E3(??)/????'"
<inki.dae@samsung.com>,
paul.gortmaker@windriver.com, '박경민' <kyungmin.park@samsung.com>,
"Dave Airlie" <airlied@redhat.com>, "Rob Clark" <rob@ti.com>,
"linux-media@vger.kernel.org" <linux-media@vger.kernel.org>,
prashanth.g@samsung.com,
"Marek Szyprowski" <m.szyprowski@samsung.com>
Subject: Re: [PATCH v3] scatterlist: add sg_alloc_table_from_pages function
Date: Tue, 08 May 2012 13:14:23 +0200 [thread overview]
Message-ID: <1976581.7lABks1hJQ@avalon> (raw)
In-Reply-To: <4FA8EC69.8010805@samsung.com>
Hi Tomasz,
Thank you for the patch.
On Tuesday 08 May 2012 11:50:33 Tomasz Stanislawski wrote:
> This patch adds a new constructor for an sg table. The table is constructed
> from an array of struct pages. All contiguous chunks of the pages are merged
> into a single sg nodes. A user may provide an offset and a size of a buffer
> if the buffer is not page-aligned.
>
> The function is dedicated for DMABUF exporters which often perform
> conversion from an page array to a scatterlist. Moreover the scatterlist
> should be squashed in order to save memory and to speed-up the process of
> DMA mapping using dma_map_sg.
>
> The code is based on the patch 'v4l: vb2-dma-contig: add support for
> scatterlist in userptr mode' and hints from Laurent Pinchart.
>
> Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> include/linux/scatterlist.h | 4 +++
> lib/scatterlist.c | 64
> +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68
> insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
> index ac9586d..7b600da 100644
> --- a/include/linux/scatterlist.h
> +++ b/include/linux/scatterlist.h
> @@ -214,6 +214,10 @@ void sg_free_table(struct sg_table *);
> int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t,
> sg_alloc_fn *);
> int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
> +int sg_alloc_table_from_pages(struct sg_table *sgt,
> + struct page **pages, unsigned int n_pages,
> + unsigned long offset, unsigned long size,
> + gfp_t gfp_mask);
>
> size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
> void *buf, size_t buflen);
> diff --git a/lib/scatterlist.c b/lib/scatterlist.c
> index 6096e89..85868a1 100644
> --- a/lib/scatterlist.c
> +++ b/lib/scatterlist.c
> @@ -319,6 +319,70 @@ int sg_alloc_table(struct sg_table *table, unsigned int
> nents, gfp_t gfp_mask) EXPORT_SYMBOL(sg_alloc_table);
>
> /**
> + * sg_alloc_table_from_pages - Allocate and initialize an sg table from
> + * an array of pages
> + * @sgt: The sg table header to use
> + * @pages: Pointer to an array of page pointers
> + * @n_pages: Number of pages in the pages array
> + * @offset: Offset from start of the first page to the start of a
> buffer + * @size: Number of valid bytes in the buffer (after offset)
> + * @gfp_mask: GFP allocation mask
> + *
> + * Description:
> + * Allocate and initialize an sg table from a list of pages. Continuous
> + * ranges of the pages are squashed into a single scatterlist node. A
> user + * may provide an offset at a start and a size of valid data in a
> buffer + * specified by the page array. The returned sg table is
> released by + * sg_free_table.
> + *
> + * Returns:
> + * 0 on success, negative error on failure
> + **/
> +int sg_alloc_table_from_pages(struct sg_table *sgt,
> + struct page **pages, unsigned int n_pages,
> + unsigned long offset, unsigned long size,
> + gfp_t gfp_mask)
> +{
> + unsigned int chunks;
> + unsigned int i;
> + unsigned int cur_page;
> + int ret;
> + struct scatterlist *s;
> +
> + /* compute number of contiguous chunks */
> + chunks = 1;
> + for (i = 1; i < n_pages; ++i)
> + if (page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1)
> + ++chunks;
> +
> + ret = sg_alloc_table(sgt, chunks, gfp_mask);
> + if (unlikely(ret))
> + return ret;
> +
> + /* merging chunks and putting them into the scatterlist */
> + cur_page = 0;
> + for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
> + unsigned long chunk_size;
> + unsigned int j;
> +
> + /* looking for the end of the current chunk */
> + for (j = cur_page + 1; j < n_pages; ++j)
> + if (page_to_pfn(pages[j]) !=
> + page_to_pfn(pages[j - 1]) + 1)
> + break;
> +
> + chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset;
> + sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
> + size -= chunk_size;
> + offset = 0;
> + cur_page = j;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(sg_alloc_table_from_pages);
> +
> +/**
> * sg_miter_start - start mapping iteration over a sg list
> * @miter: sg mapping iter to be started
> * @sgl: sg list to iterate over
--
Regards,
Laurent Pinchart
WARNING: multiple messages have this Message-ID (diff)
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Tomasz Stanislawski <t.stanislaws@samsung.com>
Cc: paul.gortmaker@windriver.com, '박경민' <kyungmin.park@samsung.com>,
amwang@redhat.com, dri-devel@lists.freedesktop.org,
"'???/Mobile S/W Platform Lab.(???)/E3(??)/????'"
<inki.dae@samsung.com>,
prashanth.g@samsung.com,
"Marek Szyprowski" <m.szyprowski@samsung.com>,
"linux-media@vger.kernel.org" <linux-media@vger.kernel.org>,
"Rob Clark" <rob@ti.com>, "Dave Airlie" <airlied@redhat.com>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3] scatterlist: add sg_alloc_table_from_pages function
Date: Tue, 08 May 2012 13:14:23 +0200 [thread overview]
Message-ID: <1976581.7lABks1hJQ@avalon> (raw)
In-Reply-To: <4FA8EC69.8010805@samsung.com>
Hi Tomasz,
Thank you for the patch.
On Tuesday 08 May 2012 11:50:33 Tomasz Stanislawski wrote:
> This patch adds a new constructor for an sg table. The table is constructed
> from an array of struct pages. All contiguous chunks of the pages are merged
> into a single sg nodes. A user may provide an offset and a size of a buffer
> if the buffer is not page-aligned.
>
> The function is dedicated for DMABUF exporters which often perform
> conversion from an page array to a scatterlist. Moreover the scatterlist
> should be squashed in order to save memory and to speed-up the process of
> DMA mapping using dma_map_sg.
>
> The code is based on the patch 'v4l: vb2-dma-contig: add support for
> scatterlist in userptr mode' and hints from Laurent Pinchart.
>
> Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> include/linux/scatterlist.h | 4 +++
> lib/scatterlist.c | 64
> +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68
> insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
> index ac9586d..7b600da 100644
> --- a/include/linux/scatterlist.h
> +++ b/include/linux/scatterlist.h
> @@ -214,6 +214,10 @@ void sg_free_table(struct sg_table *);
> int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t,
> sg_alloc_fn *);
> int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
> +int sg_alloc_table_from_pages(struct sg_table *sgt,
> + struct page **pages, unsigned int n_pages,
> + unsigned long offset, unsigned long size,
> + gfp_t gfp_mask);
>
> size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
> void *buf, size_t buflen);
> diff --git a/lib/scatterlist.c b/lib/scatterlist.c
> index 6096e89..85868a1 100644
> --- a/lib/scatterlist.c
> +++ b/lib/scatterlist.c
> @@ -319,6 +319,70 @@ int sg_alloc_table(struct sg_table *table, unsigned int
> nents, gfp_t gfp_mask) EXPORT_SYMBOL(sg_alloc_table);
>
> /**
> + * sg_alloc_table_from_pages - Allocate and initialize an sg table from
> + * an array of pages
> + * @sgt: The sg table header to use
> + * @pages: Pointer to an array of page pointers
> + * @n_pages: Number of pages in the pages array
> + * @offset: Offset from start of the first page to the start of a
> buffer + * @size: Number of valid bytes in the buffer (after offset)
> + * @gfp_mask: GFP allocation mask
> + *
> + * Description:
> + * Allocate and initialize an sg table from a list of pages. Continuous
> + * ranges of the pages are squashed into a single scatterlist node. A
> user + * may provide an offset at a start and a size of valid data in a
> buffer + * specified by the page array. The returned sg table is
> released by + * sg_free_table.
> + *
> + * Returns:
> + * 0 on success, negative error on failure
> + **/
> +int sg_alloc_table_from_pages(struct sg_table *sgt,
> + struct page **pages, unsigned int n_pages,
> + unsigned long offset, unsigned long size,
> + gfp_t gfp_mask)
> +{
> + unsigned int chunks;
> + unsigned int i;
> + unsigned int cur_page;
> + int ret;
> + struct scatterlist *s;
> +
> + /* compute number of contiguous chunks */
> + chunks = 1;
> + for (i = 1; i < n_pages; ++i)
> + if (page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1)
> + ++chunks;
> +
> + ret = sg_alloc_table(sgt, chunks, gfp_mask);
> + if (unlikely(ret))
> + return ret;
> +
> + /* merging chunks and putting them into the scatterlist */
> + cur_page = 0;
> + for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
> + unsigned long chunk_size;
> + unsigned int j;
> +
> + /* looking for the end of the current chunk */
> + for (j = cur_page + 1; j < n_pages; ++j)
> + if (page_to_pfn(pages[j]) !=
> + page_to_pfn(pages[j - 1]) + 1)
> + break;
> +
> + chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset;
> + sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
> + size -= chunk_size;
> + offset = 0;
> + cur_page = j;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(sg_alloc_table_from_pages);
> +
> +/**
> * sg_miter_start - start mapping iteration over a sg list
> * @miter: sg mapping iter to be started
> * @sgl: sg list to iterate over
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2012-05-08 11:14 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-08 9:50 [PATCH v3] scatterlist: add sg_alloc_table_from_pages function Tomasz Stanislawski
2012-05-08 9:50 ` Tomasz Stanislawski
2012-05-08 9:50 ` Tomasz Stanislawski
2012-05-08 10:02 ` Daniel Vetter
2012-05-08 11:14 ` Laurent Pinchart [this message]
2012-05-08 11:14 ` Laurent Pinchart
2012-05-17 23:56 ` Andrew Morton
2012-05-21 14:01 ` Tomasz Stanislawski
2012-05-21 14:01 ` Tomasz Stanislawski
2012-05-22 20:10 ` Andrew Morton
2012-05-22 20:10 ` Andrew Morton
2012-06-06 12:14 ` Tomasz Stanislawski
2012-06-06 12:14 ` Tomasz Stanislawski
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=1976581.7lABks1hJQ@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=airlied@redhat.com \
--cc=amwang@redhat.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=inki.dae@samsung.com \
--cc=kyungmin.park@samsung.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=m.szyprowski@samsung.com \
--cc=paul.gortmaker@windriver.com \
--cc=prashanth.g@samsung.com \
--cc=rob@ti.com \
--cc=t.stanislaws@samsung.com \
/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: link
Be 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.