prefaulting MAP_ANONYMOUS pages

Matthew Dillon dillon at apollo.backplane.com
Sun Dec 30 16:22:31 PST 2007


:1) Lots of page faults, which drop performance by a factor of 10 
:compared to the case where everything is faulted in.
:
:...
:Is there a way to achieve this that I am overlooking?  If not can 
:someone give me some advice about what is needed?
:
:Kris

    The main problem here is that the backing pages do not exist anywhere.
    No backing store is assigned and the pages themselves aren't even
    allocated until the user touches the memory.

    You might be able to work magic with the default pager.  The default
    pager handles all UNBACKED anonymous mappings.  Default pager objects
    are quietly converted to swap pager objects when the kernel tries to
    page them out.  In otherwords, the 'backing' store for the default
    pager is always zero-fill.

    default_pager_haspage() returns FALSE which basically causes the VM
    layer to fall through to zero-fill fault code.  It optimizes the fault
    by allocating out of the zero'd page pool in order to avoid having to
    bzero the page.  Because default_pager_haspage() returns FALSE,
    default_pager_getpages() is never called.

    You could theoretically have default_pager_haspage() return TRUE and
    also load up the before and after variables, and then manually zero-fill
    the pages in default_pager_getpages().  This is probably the simplest
    solution, but not necessarily optimal since you will not necessarily
    be provided with pre-zero'd pages.

    Another possibility would be to have the VM code which handles a FALSE
    return from *_pager_haspage() to check additional adjacent pages and
    zero-fill a larger block instead of just one page.  This would be more
    work but would also be a more optimal solution.

    A third possibility would be to add an additional argument to
    *_pager_haspage() that allows it to tell the caller how many pages
    do not have backing store, so the kernel doesn't have to poll for
    each page and can zero-fill several at once.  This is more complex
    but probably the most optimal solution.

    --

    Note that these sorts of optimizations could create non-optimal
    operation for unrelated programs which rely on sparse allocations.  I
    am not sure if FreeBSD has a heuristic for VM faults... I think it does.
    That heuristic could be used to determine how much fault-ahead to actually
    do.  It may already exist, I haven't checked, and simply need to be
    applied to whatever code you cook up for the zero-fill fault.

    Also note that OBJT_DEFAULT and OBJT_SWAP (default and swap pagers)
    are special cased all over the code base.  There might be unexpected
    side effects if you mess with the default_pager*() functions.

					-Matt
					Matthew Dillon 
					<dillon at backplane.com>


More information about the freebsd-hackers mailing list