aboutsummaryrefslogtreecommitdiffstats
path: root/lib/scatterlist.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2013-02-27 20:02:57 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-27 22:10:10 -0500
commit4225fc8555a992c7f91d174ef424384d6781e144 (patch)
tree46f73428afef93acc729fd36842e463b503bab58 /lib/scatterlist.c
parenta321e91b6d73ed011ffceed384c40d2785cf723b (diff)
lib/scatterlist: use page iterator in the mapping iterator
For better code reuse use the newly added page iterator to iterate through the pages. The offset, length within the page is still calculated by the mapping iterator as well as the actual mapping. Idea from Tejun Heo. Signed-off-by: Imre Deak <imre.deak@intel.com> Cc: Maxim Levitsky <maximlevitsky@gmail.com> Cc: Tejun Heo <tj@kernel.org> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: James Hogan <james.hogan@imgtec.com> Cc: Stephen Warren <swarren@wwwdotorg.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/scatterlist.c')
-rw-r--r--lib/scatterlist.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index a1d15647d7db..b83c144d731f 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -449,9 +449,7 @@ void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
449{ 449{
450 memset(miter, 0, sizeof(struct sg_mapping_iter)); 450 memset(miter, 0, sizeof(struct sg_mapping_iter));
451 451
452 miter->__sg = sgl; 452 __sg_page_iter_start(&miter->piter, sgl, nents, 0);
453 miter->__nents = nents;
454 miter->__offset = 0;
455 WARN_ON(!(flags & (SG_MITER_TO_SG | SG_MITER_FROM_SG))); 453 WARN_ON(!(flags & (SG_MITER_TO_SG | SG_MITER_FROM_SG)));
456 miter->__flags = flags; 454 miter->__flags = flags;
457} 455}
@@ -476,36 +474,35 @@ EXPORT_SYMBOL(sg_miter_start);
476 */ 474 */
477bool sg_miter_next(struct sg_mapping_iter *miter) 475bool sg_miter_next(struct sg_mapping_iter *miter)
478{ 476{
479 unsigned int off, len;
480
481 /* check for end and drop resources from the last iteration */
482 if (!miter->__nents)
483 return false;
484
485 sg_miter_stop(miter); 477 sg_miter_stop(miter);
486 478
487 /* get to the next sg if necessary. __offset is adjusted by stop */ 479 /*
488 while (miter->__offset == miter->__sg->length) { 480 * Get to the next page if necessary.
489 if (--miter->__nents) { 481 * __remaining, __offset is adjusted by sg_miter_stop
490 miter->__sg = sg_next(miter->__sg); 482 */
491 miter->__offset = 0; 483 if (!miter->__remaining) {
492 } else 484 struct scatterlist *sg;
485 unsigned long pgoffset;
486
487 if (!__sg_page_iter_next(&miter->piter))
493 return false; 488 return false;
494 }
495 489
496 /* map the next page */ 490 sg = miter->piter.sg;
497 off = miter->__sg->offset + miter->__offset; 491 pgoffset = miter->piter.sg_pgoffset;
498 len = miter->__sg->length - miter->__offset;
499 492
500 miter->page = nth_page(sg_page(miter->__sg), off >> PAGE_SHIFT); 493 miter->__offset = pgoffset ? 0 : sg->offset;
501 off &= ~PAGE_MASK; 494 miter->__remaining = sg->offset + sg->length -
502 miter->length = min_t(unsigned int, len, PAGE_SIZE - off); 495 (pgoffset << PAGE_SHIFT) - miter->__offset;
503 miter->consumed = miter->length; 496 miter->__remaining = min_t(unsigned long, miter->__remaining,
497 PAGE_SIZE - miter->__offset);
498 }
499 miter->page = miter->piter.page;
500 miter->consumed = miter->length = miter->__remaining;
504 501
505 if (miter->__flags & SG_MITER_ATOMIC) 502 if (miter->__flags & SG_MITER_ATOMIC)
506 miter->addr = kmap_atomic(miter->page) + off; 503 miter->addr = kmap_atomic(miter->page) + miter->__offset;
507 else 504 else
508 miter->addr = kmap(miter->page) + off; 505 miter->addr = kmap(miter->page) + miter->__offset;
509 506
510 return true; 507 return true;
511} 508}
@@ -532,6 +529,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter)
532 /* drop resources from the last iteration */ 529 /* drop resources from the last iteration */
533 if (miter->addr) { 530 if (miter->addr) {
534 miter->__offset += miter->consumed; 531 miter->__offset += miter->consumed;
532 miter->__remaining -= miter->consumed;
535 533
536 if (miter->__flags & SG_MITER_TO_SG) 534 if (miter->__flags & SG_MITER_TO_SG)
537 flush_kernel_dcache_page(miter->page); 535 flush_kernel_dcache_page(miter->page);