kernel: get rid of auxpage() and preserve cache index bits in Page.va in mount cache

the mount cache uses Page.va to store cached range offset and
limit, but mips kernel uses cache index bits from Page.va to
maintain page coloring. Page.va was not initialized by auxpage().

this change removes auxpage() which was primarily used only
by the mount cache and use newpage() with cache file offset
page as va so we will get a page of the right color.

mount cache keeps the index bits intact by only using the top
and buttom PGSHIFT bits of Page.va for the range offset/limit.
This commit is contained in:
cinap_lenrek 2015-03-16 05:46:08 +01:00
parent d0b1db98bc
commit 972cd5e3fc
4 changed files with 26 additions and 37 deletions

View file

@ -379,9 +379,9 @@ putmmu(uintptr va, uintptr pa, Page *pg)
if(l2pg != nil){
up->mmufree = l2pg->next;
} else {
l2pg = auxpage();
if(l2pg == nil)
pexit("out of memory", 1);
splx(s);
l2pg = newpage(0, 0, 0);
splhi();
}
l2pg->va = VA(kmap(l2pg));
up->l1page[va>>20] = l2pg;

View file

@ -205,6 +205,11 @@ ccache(Chan *c)
return nil;
}
enum {
VABITS = 8*sizeof(uintptr) - 2*PGSHIFT,
VAMASK = (((uintptr)1 << VABITS)-1) << PGSHIFT,
};
static Page*
cpage(Mntcache *m, ulong pn, ulong *po, ulong *pe)
{
@ -219,12 +224,19 @@ cpage(Mntcache *m, ulong pn, ulong *po, ulong *pe)
m->bitmap[pn/MAPBITS] &= ~b;
return nil;
}
/* see cachedata() below */
*po = (ulong)p->va & (BY2PG-1);
*pe = (ulong)p->va >> PGSHIFT;
*po = p->va & (BY2PG-1);
*pe = 1 + (p->va >> (PGSHIFT+VABITS));
assert(*po < *pe);
return p;
}
static void
cpageset(Page *p, ulong po, ulong pe)
{
assert(po < pe);
p->va = po | (p->va & VAMASK) | ((uintptr)pe - 1) << (PGSHIFT+VABITS);
}
int
cread(Chan *c, uchar *buf, int len, vlong off)
{
@ -253,7 +265,7 @@ cread(Chan *c, uchar *buf, int len, vlong off)
p = cpage(m, pn, &po, &pe);
if(p == nil)
break;
if(po >= pe || offset < po || offset >= pe){
if(offset < po || offset >= pe){
putpage(p);
break;
}
@ -326,8 +338,8 @@ cachedata(Mntcache *m, uchar *buf, int len, vlong off)
l = len;
p = cpage(m, pn, &po, &pe);
if(p != nil){
if(po >= pe || offset > pe || (offset+l) < po){
/* cached range empty or not extendable, set new cached range */
if(offset > pe || (offset+l) < po){
/* cached range not extendable, set new cached range */
po = offset;
pe = offset+l;
} else {
@ -338,13 +350,12 @@ cachedata(Mntcache *m, uchar *buf, int len, vlong off)
pe = offset+l;
}
} else {
p = auxpage();
if(p == nil){
if(needpages(nil) || waserror()){
invalidate(m, offset + pn*BY2PG, len);
break;
}
p->va = 0;
p = newpage(0, nil, pn*BY2PG);
poperror();
p->daddr = cacheaddr(m, pn);
cachedel(&fscache, p->daddr);
cachepage(p, &fscache);
@ -353,6 +364,7 @@ cachedata(Mntcache *m, uchar *buf, int len, vlong off)
po = offset;
pe = offset+l;
}
cpageset(p, po, pe);
k = kmap(p);
if(waserror()) {
@ -365,9 +377,6 @@ cachedata(Mntcache *m, uchar *buf, int len, vlong off)
memmove((uchar*)VA(k) + offset, buf, l);
poperror();
kunmap(k);
/* update cached range */
p->va = po | (pe << PGSHIFT);
putpage(p);
offset = 0;

View file

@ -234,26 +234,6 @@ putpage(Page *p)
freepages(p, p, 1);
}
Page*
auxpage(void)
{
Page *p;
lock(&palloc);
p = palloc.head;
if(p == nil || palloc.freecount < swapalloc.highwater) {
unlock(&palloc);
return nil;
}
palloc.head = p->next;
p->next = nil;
palloc.freecount--;
unlock(&palloc);
p->ref = 1;
return p;
}
void
copypage(Page *f, Page *t)
{

View file

@ -10,7 +10,6 @@ Block* allocb(int);
int anyhigher(void);
int anyready(void);
Image* attachimage(int, Chan*, uintptr, ulong);
Page* auxpage(void);
Block* bl2mem(uchar*, Block*, int);
int blocklen(Block*);
void bootlinks(void);
@ -185,6 +184,7 @@ void mul64fract(uvlong*, uvlong, uvlong);
void muxclose(Mnt*);
Chan* namec(char*, int, int, ulong);
void nameerror(char*, char*);
int needpages(void*);
Chan* newchan(void);
int newfd(Chan*);
Mhead* newmhead(Chan*);