kernel: keep cached pages continuous at the end of the page list on imagereclaim()
imagereclaim() sabotaged itself by breaking the invariant that cached pages are kept at the end of the page list. once we made a hole of uncached pages, we would stop reclaiming cached pages before it as the loop breaks once it hits a uncached page. (we iterate backwards from the tail to the head of the pagelist until pages have been reclaimed or we hit a uncached page). the solution is to move pages to the head of the pagelist after removing them from the image cache.
This commit is contained in:
parent
60c3c3b3db
commit
521a34d33b
3 changed files with 9 additions and 3 deletions
|
@ -64,7 +64,7 @@ pageinit(void)
|
|||
print("%ldM swap\n", vkb/1024);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
pageunchain(Page *p)
|
||||
{
|
||||
if(canlock(&palloc))
|
||||
|
|
|
@ -202,6 +202,7 @@ int okaddr(uintptr, ulong, int);
|
|||
int openmode(ulong);
|
||||
Block* packblock(Block*);
|
||||
Block* padblock(Block*, int);
|
||||
void pageunchain(Page*);
|
||||
void pagechainhead(Page*);
|
||||
void pageinit(void);
|
||||
ulong pagenumber(Page*);
|
||||
|
|
|
@ -313,7 +313,7 @@ static void
|
|||
imagereclaim(void)
|
||||
{
|
||||
int n;
|
||||
Page *p;
|
||||
Page *p, *x;
|
||||
uvlong ticks;
|
||||
|
||||
irstats.calls++;
|
||||
|
@ -329,11 +329,16 @@ imagereclaim(void)
|
|||
* end of the list (see putpage) so start there and work
|
||||
* backward.
|
||||
*/
|
||||
for(p = palloc.tail; p && p->image && (n<1000 || !imagealloc.free); p = p->prev) {
|
||||
for(p = palloc.tail; p && p->image && (n<1000 || !imagealloc.free); p = x) {
|
||||
x = p->prev;
|
||||
if(p->ref == 0 && canlock(p)) {
|
||||
if(p->ref == 0 && p->image && !p->image->notext) {
|
||||
n++;
|
||||
uncachepage(p);
|
||||
|
||||
/* move to head to maintain the invariant above */
|
||||
pageunchain(p);
|
||||
pagechainhead(p);
|
||||
}
|
||||
unlock(p);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue