On Tue, Nov 09, 2010 at 08:39:16AM -0800, Matt Thomas wrote: > > On Nov 8, 2010, at 11:25 PM, Masao Uebayashi wrote: > > > http://uebayasi.dyndns.org/~uebayasi/tmp/uebayasi-xip-20101109.txt > > Besides the churn (and there is a lot of it), I think my fundamental > problem with this incarnation of XIP is that it took a wrong approach. > It has tried to fit itself under uvm_vnodeops and I think that's a > fatal flaw by requiring invasive changes to contort to that decision. > > Instead, XIP should have its own pager ops uvm_xipops and vnodes should > be set to use that in vnalloc/insmntque which is easily done since you > can just check for MNT_XIP in the passed mount point. > > xipops would a pgo_fault routine to handle the entering the corresponding > PA for the faulting VA using similar logic to the genfs_getpages_xip in > your patch. > > This avoid the entire issue about vm_pages entirely since pgo_fault will > be calling pmap_enter directly with the correct paddr_t. We will need > to add a PMAP_CACHE flag as well. > > This leaves the issue of how to deal with copy-on-write (COW) page faults. > I think the best way to deal with is for pgo_fault to return a specific > error (EROFS seems appropriate) and let UVM deal with it. However UVM > doesn't know where the source data exists so we will need to add a > int (*pgo_copy_page)(struct uvm_object *uobj, voff_t offset, paddr_t pa) > op to pagerops which copy one page of data from uvm_object to the > specified pa. This would do what we would normally use pmap_copy_page > but we can't since we don't know the source pa and it's not a managed > page. > > I think with this approach most of churn goes away and there is minimal > changes to the rest of NetBSD.
I understand having a separate pager would work too. If you go that route, you have to give up COW. The two layered amap/uobj is the fundamental design of UVM. I'd also point out that pgo_fault() is prepaired only for *special* purposes. My plan is to rewrite those backends to use pgo_get(). Then use single pmap_enter(). Both of yours and mine are possible, and there're pros and cons.