Benjamin Herrenschmidt wrote:
  
  
OK. It seems like mmap locks are needed even for
unmap_mapping_range().
    

Well, I came to the opposite conclusion :) unmap_mapping_range() uses
the truncate count mecanism to guard against a racing no_page().

The idea is that:

no_page() itself internally takes the per-obkect lock/mutex mostly as a
sycnhronisation point before looking for the struct page and releases it
before returning the struct page to do_no_page().

unmap_mapping_range() is called with that muetx/lock held (and the copy
is done with that held too).

That should work without taking the mmap_sem.
  
OK. i was reffering to another approach: Copying _to_ VRAM /AGP:

lock_mmap_sems()
unmap_mapping_range() (or similar)
copy() / flip()
foreach_affected_vma{
   io_remap_pfn_range() /* Map vram / AGP space */
}
unlock_mmap_sem()

This works like a charm in the drm memory manager but it requires the lock of the mmap sems from all affected processes, and the locking order must be the same all the time otherwise deadlocks will occur.

Now, of course, the real problem is that we don't have struct page for
vram.... There are two ways out of this:

 - Enforce use of sparsemem and create struct page for vram. That will
probably make a few people jump out of their seats in x86 land but
that's what we do for cell and SPUs for now.

 - There's a prooposal that I'm pusing to add a way for no_page() to
return a NOPAGE_RETRY error, which essentially causes it to go all the
way back to userland and re-do the access. I want that to be able to
handle signals while blocked inside no_page() but that could -also- be
used to have no_page() setup the PTE mappings itself and return
NOPAGE_RETRY, thus avoiding the need for a struct page. Now I do not
-ever- want to see drivers mucking around with PTEs directly, however,
we can provide something in mm/memory.c that a driver can call from
within no_page() to perform the set_pte() along with all the necessary
locking, flushes, etc... The base code for NOPAGE_RETRY should get in
2.6.19 soon (one of these days).

  
do_no_page() is smart enough to recheck the pte when it retakes the page table spinlock(), so if the pte has been populated by someone while in the driver nopage(), the returned struct page will simply be discarded.
io_remap_pfn_range() should do the job of setting up the new ptes, but it needs the mmap_sem, so if that one is held while blocked in nopage(), a deadlock will occur. Here, the NOPAGE_RETRY will obviously do the job. When io_remap_pfn_range() has finished setting up the ptes, one can simply return a bogus page to nopage() if it insists on retrying. Until NOPAGE_RETRY is implemented, I'm afraid I'm stuck with the approach outlined above.


/Thomas






   



Ben.

  

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to