Module Name: src
Committed By: uebayasi
Date: Thu Nov 25 04:45:30 UTC 2010
Modified Files:
src/sys/uvm: uvm_page.c uvm_page.h uvm_pglist.c
Log Message:
Revert vm_physseg allocation changes. A report says that it causes
panics when used with mplayer in heavy load.
To generate a diff of this commit:
cvs rdiff -u -r1.166 -r1.167 src/sys/uvm/uvm_page.c
cvs rdiff -u -r1.67 -r1.68 src/sys/uvm/uvm_page.h
cvs rdiff -u -r1.50 -r1.51 src/sys/uvm/uvm_pglist.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/uvm/uvm_page.c
diff -u src/sys/uvm/uvm_page.c:1.166 src/sys/uvm/uvm_page.c:1.167
--- src/sys/uvm/uvm_page.c:1.166 Sun Nov 14 15:18:07 2010
+++ src/sys/uvm/uvm_page.c Thu Nov 25 04:45:30 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_page.c,v 1.166 2010/11/14 15:18:07 uebayasi Exp $ */
+/* $NetBSD: uvm_page.c,v 1.167 2010/11/25 04:45:30 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.166 2010/11/14 15:18:07 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.167 2010/11/25 04:45:30 uebayasi Exp $");
#include "opt_ddb.h"
#include "opt_uvmhist.h"
@@ -125,13 +125,9 @@
* physical memory config is stored in vm_physmem.
*/
-SIMPLEQ_HEAD(vm_physseg_freelist, vm_physseg);
-
-struct vm_physseg *vm_physmem_ptrs[VM_PHYSSEG_MAX];
-int vm_nphysmem = 0;
-static struct vm_physseg vm_physmem_store[VM_PHYSSEG_MAX];
-static struct vm_physseg_freelist vm_physmem_freelist =
- SIMPLEQ_HEAD_INITIALIZER(vm_physmem_freelist);
+struct vm_physseg vm_physmem[VM_PHYSSEG_MAX]; /* XXXCDC: uvm.physmem */
+int vm_nphysseg = 0; /* XXXCDC: uvm.nphysseg */
+#define vm_nphysmem vm_nphysseg
/*
* Some supported CPUs in a given architecture don't support all
@@ -185,19 +181,6 @@
static void uvm_pageinsert(struct uvm_object *, struct vm_page *);
static void uvm_pageremove(struct uvm_object *, struct vm_page *);
-static struct vm_physseg *uvm_physseg_alloc(
- struct vm_physseg_freelist * const, struct vm_physseg **, int,
- const paddr_t, const paddr_t);
-#if 0
-static void uvm_physseg_free(struct vm_physseg_freelist *,
- struct vm_physseg **, struct vm_physseg *);
-#endif
-static void uvm_physseg_init(void);
-static void uvm_physseg_insert(struct vm_physseg *,
- struct vm_physseg **, int);
-#if 0
-static void uvm_physseg_remove(struct vm_physseg **, struct vm_physseg *);
-#endif
/*
* per-object tree of pages
@@ -701,6 +684,7 @@
panic("uvm_page_physget: out of memory!");
vm_nphysmem--;
for (x = lcv ; x < vm_nphysmem ; x++)
+ /* structure copy */
VM_PHYSMEM_PTR_SWAP(x, x + 1);
}
return (true);
@@ -718,6 +702,7 @@
panic("uvm_page_physget: out of memory!");
vm_nphysmem--;
for (x = lcv ; x < vm_nphysmem ; x++)
+ /* structure copy */
VM_PHYSMEM_PTR_SWAP(x, x + 1);
}
return (true);
@@ -748,6 +733,7 @@
panic("uvm_page_physget: out of memory!");
vm_nphysmem--;
for (x = lcv ; x < vm_nphysmem ; x++)
+ /* structure copy */
VM_PHYSMEM_PTR_SWAP(x, x + 1);
}
return (true);
@@ -782,18 +768,31 @@
uvm_page_physload(paddr_t start, paddr_t end, paddr_t avail_start,
paddr_t avail_end, int free_list)
{
- struct vm_physseg *seg;
- int lcv;
+ int preload, lcv;
+ psize_t npages;
+ struct vm_page *pgs;
+ struct vm_physseg *ps;
+ if (uvmexp.pagesize == 0)
+ panic("uvm_page_physload: page size not set!");
if (free_list >= VM_NFREELIST || free_list < VM_FREELIST_DEFAULT)
panic("uvm_page_physload: bad free list %d", free_list);
+ if (start >= end)
+ panic("uvm_page_physload: start >= end");
- seg = uvm_physseg_alloc(&vm_physmem_freelist, vm_physmem_ptrs,
- vm_nphysmem, start, end);
- KASSERT(seg != NULL);
+ /*
+ * do we have room?
+ */
+
+ if (vm_nphysmem == VM_PHYSSEG_MAX) {
+ printf("uvm_page_physload: unable to load physical memory "
+ "segment\n");
+ printf("\t%d segments allocated, ignoring 0x%llx -> 0x%llx\n",
+ VM_PHYSSEG_MAX, (long long)start, (long long)end);
+ printf("\tincrease VM_PHYSSEG_MAX\n");
+ return;
+ }
- seg->avail_start = avail_start;
- seg->avail_end = avail_end;
/*
* check to see if this is a "preload" (i.e. uvm_page_init hasn't been
* called yet, so malloc is not available).
@@ -803,188 +802,112 @@
if (VM_PHYSMEM_PTR(lcv)->pgs)
break;
}
- if (lcv == vm_nphysmem) {
- seg->pgs = NULL;
- seg->lastpg = NULL;
- seg->free_list = free_list;
- } else {
- panic("uvm_page_physload: "
- "tried to add RAM after uvm_page_init");
- }
- vm_nphysmem++;
-}
-
-#if 0
-void
-uvm_page_physunload(void *cookie)
-{
- struct vm_physseg *seg = cookie;
-
- panic("memory unload is not supported yet");
-
- uvm_physseg_free(&vm_physmem_freelist, vm_physmem_ptrs, seg);
- vm_nphysmem--;
-}
-#endif
-
-int uvm_physseg_inited;
-
-static struct vm_physseg *
-uvm_physseg_alloc(struct vm_physseg_freelist *freelist,
- struct vm_physseg **segs, int nsegs,
- const paddr_t start, const paddr_t end)
-{
- struct vm_physseg *ps;
-
- if (uvmexp.pagesize == 0)
- panic("uvm_page_physload: page size not set!");
- if (start >= end)
- panic("uvm_page_physload: start >= end");
- if (nsegs == VM_PHYSSEG_MAX)
- panic("uvm_page_physload: unable to load physical memory "
- "segment\n"
- "\t%d segments allocated, ignoring 0x%llx -> 0x%llx\n"
- "\tincrease VM_PHYSSEG_MAX\n",
- VM_PHYSSEG_MAX, (long long)start, (long long)end);
-
- if (uvm_physseg_inited == 0) {
- uvm_physseg_inited = 1;
- uvm_physseg_init();
- }
-
- ps = SIMPLEQ_FIRST(freelist);
- KASSERT(ps != NULL);
- SIMPLEQ_REMOVE_HEAD(freelist, list);
-
- ps->start = start;
- ps->end = end;
- uvm_physseg_insert(ps, segs, nsegs);
- return ps;
-}
-
-#if 0
-void
-uvm_physseg_free(struct vm_physseg_freelist *freelist,
- struct vm_physseg **segs, struct vm_physseg *seg)
-{
-
- uvm_physseg_remove(segs, seg);
- SIMPLEQ_INSERT_TAIL(freelist, seg, list);
-}
-#endif
+ preload = (lcv == vm_nphysmem);
-static void
-uvm_physseg_init(void)
-{
- int lcv;
+ /*
+ * if VM is already running, attempt to malloc() vm_page structures
+ */
- for (lcv = 0; lcv < VM_PHYSSEG_MAX; lcv++) {
- SIMPLEQ_INSERT_TAIL(&vm_physmem_freelist,
- &vm_physmem_store[lcv], list);
+ if (!preload) {
+ panic("uvm_page_physload: tried to add RAM after vm_mem_init");
+ } else {
+ pgs = NULL;
+ npages = 0;
}
-}
-static void
-uvm_physseg_insert(struct vm_physseg *ps,
- struct vm_physseg **segs, int nsegs)
-{
+ /*
+ * now insert us in the proper place in vm_physmem[]
+ */
#if (VM_PHYSSEG_STRAT == VM_PSTRAT_RANDOM)
/* random: put it at the end (easy!) */
- segs[nsegs] = ps;
+ ps = VM_PHYSMEM_PTR(vm_nphysmem);
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
{
- int lcv;
int x;
/* sort by address for binary search */
- for (lcv = 0 ; lcv < nsegs ; lcv++)
- if (ps->start < segs[lcv]->start)
+ for (lcv = 0 ; lcv < vm_nphysmem ; lcv++)
+ if (start < VM_PHYSMEM_PTR(lcv)->start)
break;
+ ps = VM_PHYSMEM_PTR(lcv);
/* move back other entries, if necessary ... */
- for (x = nsegs ; x > lcv ; x--)
- segs[x] = segs[x - 1];
- segs[lcv] = ps;
+ for (x = vm_nphysmem ; x > lcv ; x--)
+ /* structure copy */
+ VM_PHYSMEM_PTR_SWAP(x, x - 1);
}
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BIGFIRST)
{
- int lcv;
int x;
/* sort by largest segment first */
- for (lcv = 0 ; lcv < nsegs ; lcv++)
- if ((ps->end - ps->start) >
- (segs[lcv]->end - segs[lcv]->start))
+ for (lcv = 0 ; lcv < vm_nphysmem ; lcv++)
+ if ((end - start) >
+ (VM_PHYSMEM_PTR(lcv)->end - VM_PHYSMEM_PTR(lcv)->start))
break;
+ ps = VM_PHYSMEM_PTR(lcv);
/* move back other entries, if necessary ... */
- for (x = nsegs ; x > lcv ; x--)
- segs[x] = segs[x - 1];
- segs[lcv] = ps;
+ for (x = vm_nphysmem ; x > lcv ; x--)
+ /* structure copy */
+ VM_PHYSMEM_PTR_SWAP(x, x - 1);
}
#else
panic("uvm_page_physload: unknown physseg strategy selected!");
#endif
-}
-#if 0
-static void
-uvm_physseg_remove(struct vm_physseg **segs, struct vm_physseg *seg)
-{
- struct vm_physseg **segp;
+ ps->start = start;
+ ps->end = end;
+ ps->avail_start = avail_start;
+ ps->avail_end = avail_end;
+ if (preload) {
+ ps->pgs = NULL;
+ } else {
+ ps->pgs = pgs;
+ ps->lastpg = pgs + npages;
+ }
+ ps->free_list = free_list;
+ vm_nphysmem++;
- for (segp = segs; segp < segs + VM_PHYSSEG_MAX; segp++)
- if (*segp == seg)
- break;
- if (segp == segs + VM_PHYSSEG_MAX)
- panic("unknown segment: %p", seg);
- while (segp + 1 < segs + VM_PHYSSEG_MAX) {
- *segp = *(segp + 1);
- segp++;
+ if (!preload) {
+ uvmpdpol_reinit();
}
- *segp = NULL;
}
-#endif
/*
- * vm_physseg_find: find vm_physseg structure that belongs to a PA
+ * when VM_PHYSSEG_MAX is 1, we can simplify these functions
*/
-#define VM_PHYSSEG_OP_PF 1
-#define VM_PHYSSEG_OP_PG 2
-
#if VM_PHYSSEG_MAX == 1
-#define VM_PHYSSEG_FIND vm_physseg_find_contig
+static inline int vm_physseg_find_contig(struct vm_physseg *, int, paddr_t, int *);
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
-#define VM_PHYSSEG_FIND vm_physseg_find_bsearch
+static inline int vm_physseg_find_bsearch(struct vm_physseg *, int, paddr_t, int *);
#else
-#define VM_PHYSSEG_FIND vm_physseg_find_linear
+static inline int vm_physseg_find_linear(struct vm_physseg *, int, paddr_t, int *);
#endif
-static inline int VM_PHYSSEG_FIND(struct vm_physseg **, int, int,
- paddr_t, const struct vm_page *, int *);
-static inline bool vm_physseg_within_p(struct vm_physseg *, int, paddr_t,
- const struct vm_page *, int *);
-static inline bool vm_physseg_ge_p(struct vm_physseg *, int, paddr_t,
- const struct vm_page *, int *);
-static inline bool vm_physseg_lt_p(struct vm_physseg *, int, paddr_t,
- const struct vm_page *, int *);
-
+/*
+ * vm_physseg_find: find vm_physseg structure that belongs to a PA
+ */
int
vm_physseg_find(paddr_t pframe, int *offp)
{
- return VM_PHYSSEG_FIND(vm_physmem_ptrs, vm_nphysmem, VM_PHYSSEG_OP_PF,
- pframe, NULL, 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, int op,
- paddr_t pframe, const struct vm_page *pg, int *offp)
+vm_physseg_find_contig(struct vm_physseg *segs, int nsegs, paddr_t pframe, int *offp)
{
/* 'contig' case */
- if (nsegs == 0)
- return(-1);
- if (vm_physseg_within_p(segs[0], op, pframe, pg, offp)) {
+ if (pframe >= segs[0].start && pframe < segs[0].end) {
+ if (offp)
+ *offp = pframe - segs[0].start;
return(0);
}
return(-1);
@@ -993,8 +916,7 @@
#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
static inline int
-vm_physseg_find_bsearch(struct vm_physseg **segs, int nsegs, int op,
- paddr_t pframe, const struct vm_page *pg, int *offp)
+vm_physseg_find_bsearch(struct vm_physseg *segs, int nsegs, paddr_t pframe, int *offp)
{
/* binary search for it */
u_int start, len, try;
@@ -1016,9 +938,11 @@
try = start + (len / 2); /* try in the middle */
/* start past our try? */
- if (vm_physseg_ge_p(segs[try], op, pframe, pg, offp)) {
+ if (pframe >= segs[try].start) {
/* was try correct? */
- if (vm_physseg_lt_p(segs[try], op, pframe, pg, offp)) {
+ if (pframe < segs[try].end) {
+ if (offp)
+ *offp = pframe - segs[try].start;
return(try); /* got it */
}
start = try + 1; /* next time, start here */
@@ -1036,14 +960,16 @@
#else
static inline int
-vm_physseg_find_linear(struct vm_physseg **segs, int nsegs, int op,
- paddr_t pframe, const struct vm_page *pg, int *offp)
+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 (vm_physseg_within_p(segs[lcv], op, pframe, pg, offp)) {
+ if (pframe >= segs[lcv].start &&
+ pframe < segs[lcv].end) {
+ if (offp)
+ *offp = pframe - segs[lcv].start;
return(lcv); /* got it */
}
}
@@ -1051,49 +977,6 @@
}
#endif
-static inline bool
-vm_physseg_within_p(struct vm_physseg *seg, int op, paddr_t pframe,
- const struct vm_page *pg, int *offp)
-{
-
- return vm_physseg_ge_p(seg, op, pframe, pg, offp) &&
- vm_physseg_lt_p(seg, op, pframe, pg, offp);
-}
-
-static inline bool
-vm_physseg_ge_p(struct vm_physseg *seg, int op, paddr_t pframe,
- const struct vm_page *pg, int *offp)
-{
-
- switch (op) {
- case VM_PHYSSEG_OP_PF:
- if (offp)
- *offp = pframe - seg->start;
- return pframe >= seg->start;
- case VM_PHYSSEG_OP_PG:
- if (offp)
- *offp = pg - seg->pgs;
- return pg >= seg->pgs;
- default:
- return false;
- }
-}
-
-static inline bool
-vm_physseg_lt_p(struct vm_physseg *seg, int op, paddr_t pframe,
- const struct vm_page *pg, int *offp)
-{
-
- switch (op) {
- case VM_PHYSSEG_OP_PF:
- return pframe < seg->end;
- case VM_PHYSSEG_OP_PG:
- return pg < seg->lastpg;
- default:
- return false;
- }
-}
-
/*
* PHYS_TO_VM_PAGE: find vm_page for a PA. used by MI code to get vm_pages
* back from an I/O mapping (ugh!). used in some MD code as well.
Index: src/sys/uvm/uvm_page.h
diff -u src/sys/uvm/uvm_page.h:1.67 src/sys/uvm/uvm_page.h:1.68
--- src/sys/uvm/uvm_page.h:1.67 Sun Nov 14 15:06:34 2010
+++ src/sys/uvm/uvm_page.h Thu Nov 25 04:45:30 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_page.h,v 1.67 2010/11/14 15:06:34 uebayasi Exp $ */
+/* $NetBSD: uvm_page.h,v 1.68 2010/11/25 04:45:30 uebayasi Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -238,8 +238,6 @@
int free_list; /* which free list they belong on */
struct vm_page *pgs; /* vm_page structures (from start) */
struct vm_page *lastpg; /* vm_page structure for end */
- SIMPLEQ_ENTRY(vm_physseg) list;
-
#ifdef __HAVE_PMAP_PHYSSEG
struct pmap_physseg pmseg; /* pmap specific (MD) data */
#endif
@@ -257,14 +255,12 @@
* physical memory config is stored in vm_physmem.
*/
-#define VM_PHYSMEM_PTR(i) (vm_physmem_ptrs[i])
-#define VM_PHYSMEM_PTR_SWAP(i, j) \
- do { VM_PHYSMEM_PTR(i) = VM_PHYSMEM_PTR(j); } while (0)
-
-extern struct vm_physseg *vm_physmem_ptrs[VM_PHYSSEG_MAX];
-extern int vm_nphysmem;
+#define VM_PHYSMEM_PTR(i) (&vm_physmem[i])
+#define VM_PHYSMEM_PTR_SWAP(i, j) \
+ do { vm_physmem[(i)] = vm_physmem[(j)]; } while (0)
-#define vm_nphysseg vm_nphysmem /* XXX backward compat */
+extern struct vm_physseg vm_physmem[VM_PHYSSEG_MAX];
+extern int vm_nphysseg;
/*
* prototypes: the following prototypes define the interface to pages
@@ -310,10 +306,6 @@
#define VM_PAGE_TO_PHYS(entry) uvm_vm_page_to_phys(entry)
-#ifdef __HAVE_VM_PAGE_MD
-#define VM_PAGE_TO_MD(pg) (&(pg)->mdpage)
-#endif
-
/*
* Compute the page color bucket for a given page.
*/
Index: src/sys/uvm/uvm_pglist.c
diff -u src/sys/uvm/uvm_pglist.c:1.50 src/sys/uvm/uvm_pglist.c:1.51
--- src/sys/uvm/uvm_pglist.c:1.50 Thu Nov 18 11:49:41 2010
+++ src/sys/uvm/uvm_pglist.c Thu Nov 25 04:45:30 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_pglist.c,v 1.50 2010/11/18 11:49:41 cegger Exp $ */
+/* $NetBSD: uvm_pglist.c,v 1.51 2010/11/25 04:45:30 uebayasi Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_pglist.c,v 1.50 2010/11/18 11:49:41 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_pglist.c,v 1.51 2010/11/25 04:45:30 uebayasi Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -59,20 +59,6 @@
#define STAT_DECR(v)
#endif
-#ifdef DEBUG
-static int
-vm_physmem_index(struct vm_physseg *ps)
-{
- int i;
-
- for (i = 0; i < vm_nphysmem; i++) {
- if (VM_PHYSMEM_PTR(i) == ps)
- return i;
- }
- return -1;
-}
-#endif
-
/*
* uvm_pglistalloc: allocate a list of pages
*
@@ -147,7 +133,7 @@
#endif
#ifdef PGALLOC_VERBOSE
printf("pgalloc: contig %d pgs from psi %ld\n", num,
- (long)(ps - VM_PHYSMEM_PTR(0)));
+ (long)(ps - vm_physmem));
#endif
KASSERT(mutex_owned(&uvm_fpageqlock));
@@ -178,11 +164,11 @@
* Make sure this is a managed physical page.
*/
- if (vm_physseg_find(try, &cidx) != vm_physmem_index(ps))
+ if (vm_physseg_find(try, &cidx) != ps - vm_physmem)
panic("pgalloc contig: botch1");
if (cidx != try - ps->start)
panic("pgalloc contig: botch2");
- if (vm_physseg_find(try + num - 1, &cidx) != vm_physmem_index(ps))
+ if (vm_physseg_find(try + num - 1, &cidx) != ps - vm_physmem)
panic("pgalloc contig: botch3");
if (cidx != try - ps->start + num - 1)
panic("pgalloc contig: botch4");
@@ -260,12 +246,12 @@
for (fl = 0; fl < VM_NFREELIST; fl++) {
#if (VM_PHYSSEG_STRAT == VM_PSTRAT_BIGFIRST)
- for (psi = vm_nphysmem - 1 ; psi >= 0 ; psi--)
+ for (psi = vm_nphysseg - 1 ; psi >= 0 ; psi--)
#else
- for (psi = 0 ; psi < vm_nphysmem ; psi++)
+ for (psi = 0 ; psi < vm_nphysseg ; psi++)
#endif
{
- ps = VM_PHYSMEM_PTR(psi);
+ ps = &vm_physmem[psi];
if (ps->free_list != fl)
continue;
@@ -306,7 +292,7 @@
#endif
#ifdef PGALLOC_VERBOSE
printf("pgalloc: simple %d pgs from psi %ld\n", num,
- (long)(ps - VM_PHYSMEM_PTR(0)));
+ (long)(ps - vm_physmem));
#endif
KASSERT(mutex_owned(&uvm_fpageqlock));
@@ -317,7 +303,7 @@
for (try = max(atop(low), ps->avail_start);
try < limit; try ++) {
#ifdef DEBUG
- if (vm_physseg_find(try, &cidx) != vm_physmem_index(ps))
+ if (vm_physseg_find(try, &cidx) != ps - vm_physmem)
panic("pgalloc simple: botch1");
if (cidx != (try - ps->start))
panic("pgalloc simple: botch2");
@@ -359,12 +345,12 @@
for (fl = 0; fl < VM_NFREELIST; fl++) {
#if (VM_PHYSSEG_STRAT == VM_PSTRAT_BIGFIRST)
- for (psi = vm_nphysmem - 1 ; psi >= 0 ; psi--)
+ for (psi = vm_nphysseg - 1 ; psi >= 0 ; psi--)
#else
- for (psi = 0 ; psi < vm_nphysmem ; psi++)
+ for (psi = 0 ; psi < vm_nphysseg ; psi++)
#endif
{
- ps = VM_PHYSMEM_PTR(psi);
+ ps = &vm_physmem[psi];
if (ps->free_list != fl)
continue;