diff options
| -rw-r--r-- | sys/lib/acid/kernel | 11 | ||||
| -rw-r--r-- | sys/src/9/port/page.c | 23 | ||||
| -rw-r--r-- | sys/src/9/port/portdat.h | 7 | ||||
| -rw-r--r-- | sys/src/9/port/segment.c | 41 |
4 files changed, 51 insertions, 31 deletions
diff --git a/sys/lib/acid/kernel b/sys/lib/acid/kernel index 7d082ec12..688357a2e 100644 --- a/sys/lib/acid/kernel +++ b/sys/lib/acid/kernel @@ -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; } } diff --git a/sys/src/9/port/page.c b/sys/src/9/port/page.c index 50cb4efca..f9eda93f7 100644 --- a/sys/src/9/port/page.c +++ b/sys/src/9/port/page.c @@ -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); diff --git a/sys/src/9/port/portdat.h b/sys/src/9/port/portdat.h index 2cad12930..4edd4e732 100644 --- a/sys/src/9/port/portdat.h +++ b/sys/src/9/port/portdat.h @@ -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 diff --git a/sys/src/9/port/segment.c b/sys/src/9/port/segment.c index 1e263fd43..04923d9e7 100644 --- a/sys/src/9/port/segment.c +++ b/sys/src/9/port/segment.c @@ -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 |
