kernel: make image cache not hold onto the channel, remove nocache flag
the image cache should not hold onto the text file channel when not neccesary. now, the image keeps track of the number of page cache references in Image.pgref. if the number of page cache references and Image.ref are equal, this means all the references to this image are from the page cache. so no segments are using this image. in that case, we can close the channel, but keep the Image in the hash table. when attachimage() finds our image, it will check if Image.c is nil and reattach the channel to the image before it is used. the Image.nocache flag isnt needed anymore.
This commit is contained in:
parent
18e515511f
commit
2bc9e8e5e3
4 changed files with 51 additions and 31 deletions
|
@ -29,9 +29,18 @@ defn path(p) {
|
|||
// print Image cache contents
|
||||
IHASHSIZE = 64;
|
||||
defn imagecacheline(h) {
|
||||
local d, p, q;
|
||||
|
||||
while h != 0 do {
|
||||
complex Image h;
|
||||
print (h\X, " ", qid(h.qid), " type ", h.type\D, " ref ", h.ref, " next ", h.next\X, " ", path(h.c.path), "\n");
|
||||
|
||||
d=(Dev)(*(devtab+4*h.type));
|
||||
p = "*closed*";
|
||||
if h.c != 0 then
|
||||
p = path(h.c.path);
|
||||
q = h.qid;
|
||||
print (h\X, " ref=", h.ref, " pgref=", h.pgref, "\t#", d.dc\r, h.dev\D, " (",
|
||||
q.path, " ", q.vers\D, " ", q.type\X, ") ", p, "\n");
|
||||
h = h.hash;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -228,9 +228,6 @@ putpage(Page *p)
|
|||
return;
|
||||
}
|
||||
|
||||
if(p->image && p->image->nocache)
|
||||
uncachepage(p);
|
||||
|
||||
if(p->image && p->image != &swapimage)
|
||||
pagechaintail(p);
|
||||
else
|
||||
|
@ -294,8 +291,8 @@ duppage(Page *p) /* Always call with p locked */
|
|||
return;
|
||||
}
|
||||
|
||||
/* No freelist cache with uncached image or when memory is very low */
|
||||
if(p->image->nocache || palloc.freecount < swapalloc.highwater) {
|
||||
/* No freelist cache when memory is very low */
|
||||
if(palloc.freecount < swapalloc.highwater) {
|
||||
unlock(&palloc);
|
||||
uncachepage(p);
|
||||
return;
|
||||
|
@ -360,8 +357,10 @@ void
|
|||
uncachepage(Page *p) /* Always called with a locked page */
|
||||
{
|
||||
Page **l, *f;
|
||||
Image *i;
|
||||
|
||||
if(p->image == 0)
|
||||
i = p->image;
|
||||
if(i == 0)
|
||||
return;
|
||||
|
||||
lock(&palloc.hashlock);
|
||||
|
@ -374,9 +373,13 @@ uncachepage(Page *p) /* Always called with a locked page */
|
|||
l = &f->hash;
|
||||
}
|
||||
unlock(&palloc.hashlock);
|
||||
putimage(p->image);
|
||||
p->image = 0;
|
||||
p->daddr = 0;
|
||||
|
||||
lock(i);
|
||||
i->pgref--;
|
||||
unlock(i);
|
||||
putimage(i);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -392,7 +395,11 @@ cachepage(Page *p, Image *i)
|
|||
if(p->image)
|
||||
panic("cachepage");
|
||||
|
||||
incref(i);
|
||||
lock(i);
|
||||
i->ref++;
|
||||
i->pgref++;
|
||||
unlock(i);
|
||||
|
||||
lock(&palloc.hashlock);
|
||||
p->image = i;
|
||||
l = &pghash(p->daddr);
|
||||
|
|
|
@ -344,16 +344,15 @@ struct Swapalloc
|
|||
struct Image
|
||||
{
|
||||
Ref;
|
||||
Chan *c; /* channel to text file */
|
||||
long pgref; /* number of cached pages (pgref <= ref) */
|
||||
Chan *c; /* channel to text file, nil when not used */
|
||||
Qid qid; /* Qid for page cache coherence */
|
||||
Qid mqid;
|
||||
Chan *mchan;
|
||||
ulong dev; /* Device id of owning channel */
|
||||
ushort type; /* Device type of owning channel */
|
||||
Segment *s; /* TEXT segment for image if running */
|
||||
Image *hash; /* Qid hash chains */
|
||||
Image *next; /* Free list */
|
||||
char notext; /* no file associated */
|
||||
char nocache; /* no freelist page caching */
|
||||
};
|
||||
|
||||
struct Pte
|
||||
|
|
|
@ -247,12 +247,8 @@ attachimage(int type, Chan *c, ulong base, ulong len)
|
|||
for(i = ihash(c->qid.path); i; i = i->hash) {
|
||||
if(c->qid.path == i->qid.path) {
|
||||
lock(i);
|
||||
if(eqqid(c->qid, i->qid) &&
|
||||
eqqid(c->mqid, i->mqid) &&
|
||||
c->mchan == i->mchan &&
|
||||
c->type == i->type) {
|
||||
if(eqchantdqid(c, i->type, i->dev, i->qid, 0) && c->qid.type == i->qid.type)
|
||||
goto found;
|
||||
}
|
||||
unlock(i);
|
||||
}
|
||||
}
|
||||
|
@ -274,18 +270,20 @@ attachimage(int type, Chan *c, ulong base, ulong len)
|
|||
imagealloc.free = i->next;
|
||||
|
||||
lock(i);
|
||||
incref(c);
|
||||
i->nocache = (c->flag & CCACHE) == 0;
|
||||
c->flag &= ~CCACHE;
|
||||
i->c = c;
|
||||
i->type = c->type;
|
||||
i->dev = c->dev;
|
||||
i->qid = c->qid;
|
||||
i->mqid = c->mqid;
|
||||
i->mchan = c->mchan;
|
||||
|
||||
l = &ihash(c->qid.path);
|
||||
i->hash = *l;
|
||||
*l = i;
|
||||
|
||||
found:
|
||||
if(i->c == nil){
|
||||
i->c = c;
|
||||
c->flag &= ~CCACHE;
|
||||
incref(c);
|
||||
}
|
||||
unlock(&imagealloc);
|
||||
|
||||
if(i->s == 0) {
|
||||
|
@ -360,12 +358,21 @@ putimage(Image *i)
|
|||
if(i->notext)
|
||||
return;
|
||||
|
||||
c = nil;
|
||||
lock(i);
|
||||
if(--i->ref == 0) {
|
||||
if(--i->ref == i->pgref){
|
||||
/*
|
||||
* all remaining references to this image are from the
|
||||
* page cache now. close the channel as we can reattach
|
||||
* the chan on attachimage()
|
||||
*/
|
||||
c = i->c;
|
||||
i->c = nil;
|
||||
}
|
||||
if(i->ref == 0){
|
||||
l = &ihash(i->qid.path);
|
||||
mkqid(&i->qid, ~0, ~0, QTFILE);
|
||||
unlock(i);
|
||||
c = i->c;
|
||||
|
||||
lock(&imagealloc);
|
||||
for(f = *l; f; f = f->hash) {
|
||||
|
@ -375,15 +382,13 @@ putimage(Image *i)
|
|||
}
|
||||
l = &f->hash;
|
||||
}
|
||||
|
||||
i->next = imagealloc.free;
|
||||
imagealloc.free = i;
|
||||
unlock(&imagealloc);
|
||||
|
||||
} else
|
||||
unlock(i);
|
||||
if(c)
|
||||
ccloseq(c); /* does not block */
|
||||
return;
|
||||
}
|
||||
unlock(i);
|
||||
}
|
||||
|
||||
long
|
||||
|
|
Loading…
Reference in a new issue