diff options
author | Tvrtko Ursulin <tvrtko.ursulin@intel.com> | 2017-08-03 05:13:51 -0400 |
---|---|---|
committer | Tvrtko Ursulin <tvrtko.ursulin@intel.com> | 2017-09-07 05:48:29 -0400 |
commit | 89d8589cd72c6f48b19c370517d16f3ee23909df (patch) | |
tree | 6b00e8b0121a55b72dc9098a412395cf99692575 /lib/scatterlist.c | |
parent | c125906b839b794c580a5de911de65bd2c63aaee (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.c | 66 |
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) | |||
370 | EXPORT_SYMBOL(sg_alloc_table); | 370 | EXPORT_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 | */ |
392 | int sg_alloc_table_from_pages(struct sg_table *sgt, | 393 | int __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 | } |
446 | EXPORT_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 | */ | ||
468 | int 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 | } | ||
443 | EXPORT_SYMBOL(sg_alloc_table_from_pages); | 475 | EXPORT_SYMBOL(sg_alloc_table_from_pages); |
444 | 476 | ||
445 | void __sg_page_iter_start(struct sg_page_iter *piter, | 477 | void __sg_page_iter_start(struct sg_page_iter *piter, |