linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Russell King - ARM Linux <linux@arm.linux.org.uk>
To: Minchan Kim <minchan.kim@gmail.com>
Cc: Nicolas Pitre <nico@cam.org>, lkml <linux-kernel@vger.kernel.org>,
	linux-mm@kvack.org
Subject: Re: [RFC] atomic highmem kmap page pinning
Date: Wed, 4 Mar 2009 23:46:33 +0000	[thread overview]
Message-ID: <20090304234633.GD14744@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <20090305080717.f7832c63.minchan.kim@barrios-desktop>

On Thu, Mar 05, 2009 at 08:07:17AM +0900, Minchan Kim wrote:
> On Wed, 04 Mar 2009 12:26:00 -0500 (EST)
> Nicolas Pitre <nico@cam.org> wrote:
> 
> > On Wed, 4 Mar 2009, Minchan Kim wrote:
> > 
> > > On Wed, 04 Mar 2009 00:58:13 -0500 (EST)
> > > Nicolas Pitre <nico@cam.org> wrote:
> > > 
> > > > I've implemented highmem for ARM.  Yes, some ARM machines do have lots 
> > > > of memory...
> > > > 
> > > > The problem is that most ARM machines have a non IO coherent cache, 
> > > > meaning that the dma_map_* set of functions must clean and/or invalidate 
> > > > the affected memory manually.  And because the majority of those 
> > > > machines have a VIVT cache, the cache maintenance operations must be 
> > > > performed using virtual addresses.
> > > > 
> > > > In dma_map_page(), an highmem pages could still be mapped and cached 
> > > > even after kunmap() was called on it.  As long as highmem pages are 
> > > > mapped, page_address(page) is non null and we can use that to 
> > > > synchronize the cache.
> > > > It is unlikely but still possible for kmap() to race and recycle the 
> > > > obtained virtual address above, and use it for another page though.  In 
> > > > that case, the new mapping could end up with dirty cache lines for 
> > > > another page, and the unsuspecting cache invalidation loop in 
> > > > dma_map_page() won't notice resulting in data loss.  Hence the need for 
> > > > some kind of kmap page pinning which can be used in any context, 
> > > > including IRQ context.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> > > > This is a RFC patch implementing the necessary part in the core code, as 
> > > > suggested by RMK. Please comment.
> > > 
> > > I am not sure if i understand your concern totally.
> > > I can understand it can be recycled. but Why is it racing ?
> > 
> > Suppose this sequence of events:
> > 
> > 	- dma_map_page(..., DMA_FROM_DEVICE) is called on a highmem page.
> > 
> > 	-->	- vaddr = page_address(page) is non null. In this case
> > 		  it is likely that the page has valid cache lines
> > 		  associated with vaddr. Remember that the cache is VIVT.
> > 
> > 		-->	- for (i = vaddr; i < vaddr + PAGE_SIZE; i += 32)
> > 				invalidate_cache_line(i);
> > 
> > 	*** preemption occurs in the middle of the loop above ***
> > 
> > 	- kmap_high() is called for a different page.
> > 
> > 	-->	- last_pkmap_nr wraps to zero and flush_all_zero_pkmaps()
> > 		  is called.  The pkmap_count value for the page passed
> > 		  to dma_map_page() above happens to be 1, so it is 
> > 		  unmapped.  But prior to that, flush_cache_kmaps() 
> > 		  cleared the cache for it.  So far so good.
> 
> Thanks for kind explanation.:)
> 
> I thought kmap and dma_map_page usage was following.
> 
> kmap(page);
> ...
> dma_map_page(...)
>   invalidate_cache_line
> 
> kunmap(page);

No, that's not the usage at all.  kmap() can't be called from the
contexts which dma_map_page() is called from (iow, IRQ contexts as
pointed out in the paragraph I underlined above.)

We're talking about dma_map_page() _internally_ calling kmap_get_page()
to _atomically_ and _safely_ check whether the page was kmapped.  If
it was kmapped, we need to pin the page and return its currently mapped
address for cache handling and then release that reference.

None of the existing kmap support comes anywhere near to providing a
mechanism for this because it can't be used in the contexts under which
dma_map_page() is called.

If we could do it with existing interfaces, we wouldn't need a new
interface would we?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2009-03-04 23:46 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-04  5:58 Nicolas Pitre
2009-03-04  7:39 ` Andrew Morton
2009-03-04  8:14 ` Minchan Kim
2009-03-04 17:26   ` Nicolas Pitre
2009-03-04 23:07     ` Minchan Kim
2009-03-04 23:46       ` Russell King - ARM Linux [this message]
2009-03-05  0:25         ` Minchan Kim
2009-03-05  0:30           ` Minchan Kim
2009-03-05  2:37       ` Nicolas Pitre
2009-03-05  4:20         ` Minchan Kim
2009-03-05  4:57           ` Nicolas Pitre
2009-03-05 22:23             ` Minchan Kim
2009-03-05 22:59               ` Russell King - ARM Linux
2009-03-05 23:14                 ` Minchan Kim
2009-03-07 22:28                   ` Nicolas Pitre

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090304234633.GD14744@n2100.arm.linux.org.uk \
    --to=linux@arm.linux.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=minchan.kim@gmail.com \
    --cc=nico@cam.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox