Abstraction fix; move physical address -> physical segment "reverse"

lookup code from uvm_page.h to uvm_page.c.

This code is used by some pmaps to lookup per-page state (PV) from
per-segment metadata (struct vm_physseg).  This is not needed if
UVM looks up physical segment once in fault handler, then directly
passes it to pmap.  This change helps transition to that model.

The only users of vm_physseg_find() are pmap_motorola.c and
powerpc/ibm4xx/pmap.c.

Tested By:	Compiling and running powerpc/ibm4xx/pmap.c
		(evbppc/conf/OPENBLOCKS266)
This commit is contained in:
uebayasi 2010-11-12 03:21:04 +00:00
parent 186b58eb54
commit aa803dbb9d
2 changed files with 110 additions and 110 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_page.c,v 1.161 2010/11/11 15:59:27 uebayasi Exp $ */
/* $NetBSD: uvm_page.c,v 1.162 2010/11/12 03:21:04 uebayasi Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.161 2010/11/11 15:59:27 uebayasi Exp $");
__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.162 2010/11/12 03:21:04 uebayasi Exp $");
#include "opt_ddb.h"
#include "opt_uvmhist.h"
@ -871,6 +871,112 @@ uvm_page_physload(paddr_t start, paddr_t end, paddr_t avail_start,
}
}
/*
* when VM_PHYSSEG_MAX is 1, we can simplify these functions
*/
#if VM_PHYSSEG_MAX == 1
static inline int vm_physseg_find_contig(struct vm_physseg *, int, paddr_t, int *);
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
static inline int vm_physseg_find_bsearch(struct vm_physseg *, int, paddr_t, int *);
#else
static inline int vm_physseg_find_linear(struct vm_physseg *, int, paddr_t, int *);
#endif
/*
* vm_physseg_find: find vm_physseg structure that belongs to a PA
*/
int
vm_physseg_find(paddr_t pframe, int *offp)
{
#if VM_PHYSSEG_MAX == 1
return vm_physseg_find_contig(vm_physmem, vm_nphysseg, pframe, offp);
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
return vm_physseg_find_bsearch(vm_physmem, vm_nphysseg, pframe, offp);
#else
return vm_physseg_find_linear(vm_physmem, vm_nphysseg, pframe, offp);
#endif
}
#if VM_PHYSSEG_MAX == 1
static inline int
vm_physseg_find_contig(struct vm_physseg *segs, int nsegs, paddr_t pframe, int *offp)
{
/* 'contig' case */
if (pframe >= segs[0].start && pframe < segs[0].end) {
if (offp)
*offp = pframe - segs[0].start;
return(0);
}
return(-1);
}
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
static inline int
vm_physseg_find_bsearch(struct vm_physseg *segs, int nsegs, paddr_t pframe, int *offp)
{
/* binary search for it */
u_int start, len, try;
/*
* if try is too large (thus target is less than try) we reduce
* the length to trunc(len/2) [i.e. everything smaller than "try"]
*
* if the try is too small (thus target is greater than try) then
* we set the new start to be (try + 1). this means we need to
* reduce the length to (round(len/2) - 1).
*
* note "adjust" below which takes advantage of the fact that
* (round(len/2) - 1) == trunc((len - 1) / 2)
* for any value of len we may have
*/
for (start = 0, len = nsegs ; len != 0 ; len = len / 2) {
try = start + (len / 2); /* try in the middle */
/* start past our try? */
if (pframe >= segs[try].start) {
/* was try correct? */
if (pframe < segs[try].end) {
if (offp)
*offp = pframe - segs[try].start;
return(try); /* got it */
}
start = try + 1; /* next time, start here */
len--; /* "adjust" */
} else {
/*
* pframe before try, just reduce length of
* region, done in "for" loop
*/
}
}
return(-1);
}
#else
static inline int
vm_physseg_find_linear(struct vm_physseg *segs, int nsegs, paddr_t pframe, int *offp)
{
/* linear search for it */
int lcv;
for (lcv = 0; lcv < nsegs; lcv++) {
if (pframe >= segs[lcv].start &&
pframe < segs[lcv].end) {
if (offp)
*offp = pframe - segs[lcv].start;
return(lcv); /* got it */
}
}
return(-1);
}
#endif
/*
* uvm_page_recolor: Recolor the pages if the new bucket count is
* larger than the old one.

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_page.h,v 1.63 2010/11/10 09:27:21 uebayasi Exp $ */
/* $NetBSD: uvm_page.h,v 1.64 2010/11/12 03:21:04 uebayasi Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@ -295,7 +295,7 @@ bool uvm_pageismanaged(paddr_t);
int uvm_page_lookup_freelist(struct vm_page *);
static struct vm_page *PHYS_TO_VM_PAGE(paddr_t);
static int vm_physseg_find(paddr_t, int *);
int vm_physseg_find(paddr_t, int *);
/*
* macros
@ -311,112 +311,6 @@ static int vm_physseg_find(paddr_t, int *);
#define VM_PGCOLOR_BUCKET(pg) \
(atop(VM_PAGE_TO_PHYS((pg))) & uvmexp.colormask)
/*
* when VM_PHYSSEG_MAX is 1, we can simplify these functions
*/
#if VM_PHYSSEG_MAX == 1
static inline int vm_physseg_find_contig(struct vm_physseg *, int, paddr_t, int *);
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
static inline int vm_physseg_find_bsearch(struct vm_physseg *, int, paddr_t, int *);
#else
static inline int vm_physseg_find_linear(struct vm_physseg *, int, paddr_t, int *);
#endif
/*
* vm_physseg_find: find vm_physseg structure that belongs to a PA
*/
static inline int
vm_physseg_find(paddr_t pframe, int *offp)
{
#if VM_PHYSSEG_MAX == 1
return vm_physseg_find_contig(vm_physmem, vm_nphysseg, pframe, offp);
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
return vm_physseg_find_bsearch(vm_physmem, vm_nphysseg, pframe, offp);
#else
return vm_physseg_find_linear(vm_physmem, vm_nphysseg, pframe, offp);
#endif
}
#if VM_PHYSSEG_MAX == 1
static inline int
vm_physseg_find_contig(struct vm_physseg *segs, int nsegs, paddr_t pframe, int *offp)
{
/* 'contig' case */
if (pframe >= segs[0].start && pframe < segs[0].end) {
if (offp)
*offp = pframe - segs[0].start;
return(0);
}
return(-1);
}
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
static inline int
vm_physseg_find_bsearch(struct vm_physseg *segs, int nsegs, paddr_t pframe, int *offp)
{
/* binary search for it */
u_int start, len, try;
/*
* if try is too large (thus target is less than try) we reduce
* the length to trunc(len/2) [i.e. everything smaller than "try"]
*
* if the try is too small (thus target is greater than try) then
* we set the new start to be (try + 1). this means we need to
* reduce the length to (round(len/2) - 1).
*
* note "adjust" below which takes advantage of the fact that
* (round(len/2) - 1) == trunc((len - 1) / 2)
* for any value of len we may have
*/
for (start = 0, len = nsegs ; len != 0 ; len = len / 2) {
try = start + (len / 2); /* try in the middle */
/* start past our try? */
if (pframe >= segs[try].start) {
/* was try correct? */
if (pframe < segs[try].end) {
if (offp)
*offp = pframe - segs[try].start;
return(try); /* got it */
}
start = try + 1; /* next time, start here */
len--; /* "adjust" */
} else {
/*
* pframe before try, just reduce length of
* region, done in "for" loop
*/
}
}
return(-1);
}
#else
static inline int
vm_physseg_find_linear(struct vm_physseg *segs, int nsegs, paddr_t pframe, int *offp)
{
/* linear search for it */
int lcv;
for (lcv = 0; lcv < nsegs; lcv++) {
if (pframe >= segs[lcv].start &&
pframe < segs[lcv].end) {
if (offp)
*offp = pframe - segs[lcv].start;
return(lcv); /* got it */
}
}
return(-1);
}
#endif
/*
* PHYS_TO_VM_PAGE: find vm_page for a PA. used by MI code to get vm_pages