tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Device page



> > recording physical adderess in each vm_page wastes space given that vm_page
> > is allocated as an array.
> > ie. if we have a way to find the corresponding physseg from a vm_page,
> > its corresponding physical address can be calculated.
> > so i hesitate to propagate the assumption of fast VM_PAGE_TO_PHYS.
> 
> I'd also like to see UVM/pmap use a pfn_t (physical/page frame number)
> instead of paddr_t.  That would allow most ports to return to using 32bit
> for that type.  (for a 4K page, a 32 bit PFN would be usable for up to 16TB
> of physical address space - more than enough for now).

That's fine with me.  What I wanted to say was, I "pack" a pfn_t in struct
vm_page *.  This is enough for now for now.

        (struct vm_page *)(intptr_t)((pfn_t << 2) | MAGIC);

*

In the long run, we should re-consider how vm_page's physical address is
used.  Actually the physical address can be known by looking up vm_physseg
Given a struct vm_page *, look up the vm_physseg it's contained, then offset.

    232 struct vm_physseg {
    233         paddr_t start;
    234         paddr_t end;
        :
    238         struct  vm_page *pgs;
    239         struct  vm_page *lastpg;

I think the reason why we have phys_addr in vm_page is that we have
no way to convey any data from the fault handler to callees, and back.
We pass down only "struct vm_page *" and some hint int flags.  If we allocate
a little more space on the fault handler's stack.  Something like:

        struct vm_fault_page_state {
                struct vm_page *flt_pg;
                /* assume all pages in one phys seg */
                pfn_t flt_pfn;
                int flags;
                :
        };

        uvm_fault()
        {
        #if 0
                struct vm_page *pages[16];
        #else
                struct vm_fault_page_info pages[16];
        #endif

                :
                uvn_get(pages);
                :
        }

        uvn_get(pages)
        {
                VOP_GETPAGES(pages);
        }

        genfs_getpages(pages)
        {
                :
        }

Note that this new struct's life-time is one function activation.  It's put
on stack, and it's per-CPU.  We can keep state there and do some operations
later.  We can concentrate expensive operations or defer less important ones.
I guess touching global vm_page *[] one by one is suboptimal in performance POV
in some cases.

Masao

-- 
Masao Uebayashi / Tombi Inc. / Tel: +81-90-9141-4635


Home | Main Index | Thread Index | Old Index