]> git.lizzy.rs Git - plan9front.git/commitdiff
kernel: make image cache not hold onto the channel, remove nocache flag
authorcinap_lenrek <cinap_lenrek@gmx.de>
Fri, 8 Nov 2013 21:31:26 +0000 (22:31 +0100)
committercinap_lenrek <cinap_lenrek@gmx.de>
Fri, 8 Nov 2013 21:31:26 +0000 (22:31 +0100)
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.

sys/lib/acid/kernel
sys/src/9/port/page.c
sys/src/9/port/portdat.h
sys/src/9/port/segment.c

index 7d082ec120310c0c2c758f36189984a778d080db..688357a2e90d785097d5b0fe3fe16600f031faf6 100644 (file)
@@ -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;
        }
 }
index 50cb4efca57c6e63eca36ca6e74464fb5db98efe..f9eda93f7fa546aa023dceea3015fa3361f36673 100644 (file)
@@ -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);
index 2cad129302e93c198fea1f9f3ff2a117c0754708..4edd4e732282fe67e67d8146febdeaf648ae8a18 100644 (file)
@@ -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
index 1e263fd432469ccc042d8c7d2d2bada0c239cc19..04923d9e795f085d5cc0c7e357ac053687003563 100644 (file)
@@ -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