Skip to content

Commit

Permalink
lib/scatterlist: add a flags to signalize mapping direction
Browse files Browse the repository at this point in the history
sg_miter_start() is currently unaware of the direction of the copy
process (to or from the scatter list). It is important to know the
direction because the page has to be flushed in case the data written
is seen on a different mapping in user land on cache incoherent
architectures.

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Acked-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Pierre Ossman <pierre@ossman.eu>
  • Loading branch information
Sebastian Andrzej Siewior authored and Pierre Ossman committed Jul 31, 2009
1 parent b592972 commit 6de7e35
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 4 deletions.
2 changes: 2 additions & 0 deletions include/linux/scatterlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,
*/

#define SG_MITER_ATOMIC (1 << 0) /* use kmap_atomic */
#define SG_MITER_TO_SG (1 << 1) /* flush back to phys on unmap */
#define SG_MITER_FROM_SG (1 << 2) /* nop */

struct sg_mapping_iter {
/* the following three fields can be accessed directly */
Expand Down
16 changes: 12 additions & 4 deletions lib/scatterlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
miter->__sg = sgl;
miter->__nents = nents;
miter->__offset = 0;
WARN_ON(!(flags & (SG_MITER_TO_SG | SG_MITER_FROM_SG)));
miter->__flags = flags;
}
EXPORT_SYMBOL(sg_miter_start);
Expand Down Expand Up @@ -394,6 +395,9 @@ void sg_miter_stop(struct sg_mapping_iter *miter)
if (miter->addr) {
miter->__offset += miter->consumed;

if (miter->__flags & SG_MITER_TO_SG)
flush_kernel_dcache_page(miter->page);

if (miter->__flags & SG_MITER_ATOMIC) {
WARN_ON(!irqs_disabled());
kunmap_atomic(miter->addr, KM_BIO_SRC_IRQ);
Expand Down Expand Up @@ -426,8 +430,14 @@ static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
unsigned int offset = 0;
struct sg_mapping_iter miter;
unsigned long flags;
unsigned int sg_flags = SG_MITER_ATOMIC;

if (to_buffer)
sg_flags |= SG_MITER_FROM_SG;
else
sg_flags |= SG_MITER_TO_SG;

sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC);
sg_miter_start(&miter, sgl, nents, sg_flags);

local_irq_save(flags);

Expand All @@ -438,10 +448,8 @@ static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,

if (to_buffer)
memcpy(buf + offset, miter.addr, len);
else {
else
memcpy(miter.addr, buf + offset, len);
flush_kernel_dcache_page(miter.page);
}

offset += len;
}
Expand Down

0 comments on commit 6de7e35

Please sign in to comment.