aboutsummaryrefslogtreecommitdiffstats
path: root/lib/scatterlist.c
diff options
context:
space:
mode:
authorTvrtko Ursulin <tvrtko.ursulin@intel.com>2017-08-03 05:13:51 -0400
committerTvrtko Ursulin <tvrtko.ursulin@intel.com>2017-09-07 05:48:29 -0400
commit89d8589cd72c6f48b19c370517d16f3ee23909df (patch)
tree6b00e8b0121a55b72dc9098a412395cf99692575 /lib/scatterlist.c
parentc125906b839b794c580a5de911de65bd2c63aaee (diff)
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
Diffstat (limited to 'lib/scatterlist.c')
-rw-r--r--lib/scatterlist.c66
1 files changed, 49 insertions, 17 deletions
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 7b2e74da2c44..7c1c55f7daaa 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -370,35 +370,38 @@ int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
370EXPORT_SYMBOL(sg_alloc_table); 370EXPORT_SYMBOL(sg_alloc_table);
371 371
372/** 372/**
373 * sg_alloc_table_from_pages - Allocate and initialize an sg table from 373 * __sg_alloc_table_from_pages - Allocate and initialize an sg table from
374 * an array of pages 374 * an array of pages
375 * @sgt: The sg table header to use 375 * @sgt: The sg table header to use
376 * @pages: Pointer to an array of page pointers 376 * @pages: Pointer to an array of page pointers
377 * @n_pages: Number of pages in the pages array 377 * @n_pages: Number of pages in the pages array
378 * @offset: Offset from start of the first page to the start of a buffer 378 * @offset: Offset from start of the first page to the start of a buffer
379 * @size: Number of valid bytes in the buffer (after offset) 379 * @size: Number of valid bytes in the buffer (after offset)
380 * @gfp_mask: GFP allocation mask 380 * @max_segment: Maximum size of a scatterlist node in bytes (page aligned)
381 * @gfp_mask: GFP allocation mask
381 * 382 *
382 * Description: 383 * Description:
383 * Allocate and initialize an sg table from a list of pages. Contiguous 384 * Allocate and initialize an sg table from a list of pages. Contiguous
384 * ranges of the pages are squashed into a single scatterlist node. A user 385 * ranges of the pages are squashed into a single scatterlist node up to the
385 * may provide an offset at a start and a size of valid data in a buffer 386 * maximum size specified in @max_segment. An user may provide an offset at a
386 * specified by the page array. The returned sg table is released by 387 * start and a size of valid data in a buffer specified by the page array.
387 * sg_free_table. 388 * The returned sg table is released by sg_free_table.
388 * 389 *
389 * Returns: 390 * Returns:
390 * 0 on success, negative error on failure 391 * 0 on success, negative error on failure
391 */ 392 */
392int sg_alloc_table_from_pages(struct sg_table *sgt, 393int __sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
393 struct page **pages, unsigned int n_pages, 394 unsigned int n_pages, unsigned int offset,
394 unsigned int offset, unsigned long size, 395 unsigned long size, unsigned int max_segment,
395 gfp_t gfp_mask) 396 gfp_t gfp_mask)
396{ 397{
397 const unsigned int max_segment = SCATTERLIST_MAX_SEGMENT;
398 unsigned int chunks, cur_page, seg_len, i; 398 unsigned int chunks, cur_page, seg_len, i;
399 int ret; 399 int ret;
400 struct scatterlist *s; 400 struct scatterlist *s;
401 401
402 if (WARN_ON(!max_segment || offset_in_page(max_segment)))
403 return -EINVAL;
404
402 /* compute number of contiguous chunks */ 405 /* compute number of contiguous chunks */
403 chunks = 1; 406 chunks = 1;
404 seg_len = 0; 407 seg_len = 0;
@@ -440,6 +443,35 @@ int sg_alloc_table_from_pages(struct sg_table *sgt,
440 443
441 return 0; 444 return 0;
442} 445}
446EXPORT_SYMBOL(__sg_alloc_table_from_pages);
447
448/**
449 * sg_alloc_table_from_pages - Allocate and initialize an sg table from
450 * an array of pages
451 * @sgt: The sg table header to use
452 * @pages: Pointer to an array of page pointers
453 * @n_pages: Number of pages in the pages array
454 * @offset: Offset from start of the first page to the start of a buffer
455 * @size: Number of valid bytes in the buffer (after offset)
456 * @gfp_mask: GFP allocation mask
457 *
458 * Description:
459 * Allocate and initialize an sg table from a list of pages. Contiguous
460 * ranges of the pages are squashed into a single scatterlist node. A user
461 * may provide an offset at a start and a size of valid data in a buffer
462 * specified by the page array. The returned sg table is released by
463 * sg_free_table.
464 *
465 * Returns:
466 * 0 on success, negative error on failure
467 */
468int sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
469 unsigned int n_pages, unsigned int offset,
470 unsigned long size, gfp_t gfp_mask)
471{
472 return __sg_alloc_table_from_pages(sgt, pages, n_pages, offset, size,
473 SCATTERLIST_MAX_SEGMENT, gfp_mask);
474}
443EXPORT_SYMBOL(sg_alloc_table_from_pages); 475EXPORT_SYMBOL(sg_alloc_table_from_pages);
444 476
445void __sg_page_iter_start(struct sg_page_iter *piter, 477void __sg_page_iter_start(struct sg_page_iter *piter,