lib/scatterlist: Introduce and export __sg_alloc_table_from_pages
Drivers like i915 benefit from being able to control the maxium size of the sg coalesced segment while building the scatter- gather list. Introduce and export the __sg_alloc_table_from_pages function which will allow it that control. v2: Reorder parameters. (Chris Wilson) v3: Fix incomplete reordering in v2. v4: max_segment needs to be page aligned. v5: Rebase. v6: Rebase. v7: Fix spelling in commit and mention max segment size in __sg_alloc_table_from_pages kerneldoc. (Andrew Morton) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> Cc: linux-kernel@vger.kernel.org Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Link: https://patchwork.freedesktop.org/patch/msgid/20170803091351.23594-1-tvrtko.ursulin@linux.intel.com
This commit is contained in:
parent
c125906b83
commit
89d8589cd7
|
@ -267,10 +267,13 @@ void sg_free_table(struct sg_table *);
|
||||||
int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int,
|
int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int,
|
||||||
struct scatterlist *, gfp_t, sg_alloc_fn *);
|
struct scatterlist *, gfp_t, sg_alloc_fn *);
|
||||||
int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
|
int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
|
||||||
int sg_alloc_table_from_pages(struct sg_table *sgt,
|
int __sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
|
||||||
struct page **pages, unsigned int n_pages,
|
unsigned int n_pages, unsigned int offset,
|
||||||
unsigned int offset, unsigned long size,
|
unsigned long size, unsigned int max_segment,
|
||||||
gfp_t gfp_mask);
|
gfp_t gfp_mask);
|
||||||
|
int sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
|
||||||
|
unsigned int n_pages, unsigned int offset,
|
||||||
|
unsigned long size, gfp_t gfp_mask);
|
||||||
|
|
||||||
size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf,
|
size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf,
|
||||||
size_t buflen, off_t skip, bool to_buffer);
|
size_t buflen, off_t skip, bool to_buffer);
|
||||||
|
|
|
@ -370,35 +370,38 @@ int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
|
||||||
EXPORT_SYMBOL(sg_alloc_table);
|
EXPORT_SYMBOL(sg_alloc_table);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sg_alloc_table_from_pages - Allocate and initialize an sg table from
|
* __sg_alloc_table_from_pages - Allocate and initialize an sg table from
|
||||||
* an array of pages
|
* an array of pages
|
||||||
* @sgt: The sg table header to use
|
* @sgt: The sg table header to use
|
||||||
* @pages: Pointer to an array of page pointers
|
* @pages: Pointer to an array of page pointers
|
||||||
* @n_pages: Number of pages in the pages array
|
* @n_pages: Number of pages in the pages array
|
||||||
* @offset: Offset from start of the first page to the start of a buffer
|
* @offset: Offset from start of the first page to the start of a buffer
|
||||||
* @size: Number of valid bytes in the buffer (after offset)
|
* @size: Number of valid bytes in the buffer (after offset)
|
||||||
* @gfp_mask: GFP allocation mask
|
* @max_segment: Maximum size of a scatterlist node in bytes (page aligned)
|
||||||
|
* @gfp_mask: GFP allocation mask
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate and initialize an sg table from a list of pages. Contiguous
|
* Allocate and initialize an sg table from a list of pages. Contiguous
|
||||||
* ranges of the pages are squashed into a single scatterlist node. A user
|
* ranges of the pages are squashed into a single scatterlist node up to the
|
||||||
* may provide an offset at a start and a size of valid data in a buffer
|
* maximum size specified in @max_segment. An user may provide an offset at a
|
||||||
* specified by the page array. The returned sg table is released by
|
* start and a size of valid data in a buffer specified by the page array.
|
||||||
* sg_free_table.
|
* The returned sg table is released by sg_free_table.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 on success, negative error on failure
|
* 0 on success, negative error on failure
|
||||||
*/
|
*/
|
||||||
int sg_alloc_table_from_pages(struct sg_table *sgt,
|
int __sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
|
||||||
struct page **pages, unsigned int n_pages,
|
unsigned int n_pages, unsigned int offset,
|
||||||
unsigned int offset, unsigned long size,
|
unsigned long size, unsigned int max_segment,
|
||||||
gfp_t gfp_mask)
|
gfp_t gfp_mask)
|
||||||
{
|
{
|
||||||
const unsigned int max_segment = SCATTERLIST_MAX_SEGMENT;
|
|
||||||
unsigned int chunks, cur_page, seg_len, i;
|
unsigned int chunks, cur_page, seg_len, i;
|
||||||
int ret;
|
int ret;
|
||||||
struct scatterlist *s;
|
struct scatterlist *s;
|
||||||
|
|
||||||
|
if (WARN_ON(!max_segment || offset_in_page(max_segment)))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* compute number of contiguous chunks */
|
/* compute number of contiguous chunks */
|
||||||
chunks = 1;
|
chunks = 1;
|
||||||
seg_len = 0;
|
seg_len = 0;
|
||||||
|
@ -440,6 +443,35 @@ int sg_alloc_table_from_pages(struct sg_table *sgt,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(__sg_alloc_table_from_pages);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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. Contiguous
|
||||||
|
* 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 int offset,
|
||||||
|
unsigned long size, gfp_t gfp_mask)
|
||||||
|
{
|
||||||
|
return __sg_alloc_table_from_pages(sgt, pages, n_pages, offset, size,
|
||||||
|
SCATTERLIST_MAX_SEGMENT, gfp_mask);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(sg_alloc_table_from_pages);
|
EXPORT_SYMBOL(sg_alloc_table_from_pages);
|
||||||
|
|
||||||
void __sg_page_iter_start(struct sg_page_iter *piter,
|
void __sg_page_iter_start(struct sg_page_iter *piter,
|
||||||
|
|
Loading…
Reference in New Issue