tventi: throw away dcache read-ahead code - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 12c0e45f796863966ef7ab96b30df50a562ddb13
 (DIR) parent b41e39aa1a726c08d5e9d5db55f2a4661aef2c42
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Mon, 24 Sep 2007 22:32:46 -0400
       
       venti: throw away dcache read-ahead code
       
       Diffstat:
         M src/cmd/venti/srv/dcache.c          |     181 +++++--------------------------
       
       1 file changed, 27 insertions(+), 154 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/venti/srv/dcache.c b/src/cmd/venti/srv/dcache.c
       t@@ -55,12 +55,6 @@ struct DCache
                u8int                *mem;                        /* memory for all block descriptors */
                int                ndirty;                        /* number of dirty blocks */
                int                maxdirty;                /* max. number of dirty blocks */
       -        Channel        *ra;
       -        u8int                *rabuf;
       -        u32int                ramax;
       -        u32int                rasize;
       -        u64int                raaddr;
       -        Part                *rapart;
        
                AState        diskstate;
                AState        state;
       t@@ -82,7 +76,6 @@ static void        delheap(DBlock *db);
        static void        fixheap(int i, DBlock *b);
        static void        flushproc(void*);
        static void        writeproc(void*);
       -static void raproc(void*);
        
        void
        initdcache(u32int mem)
       t@@ -109,7 +102,6 @@ initdcache(u32int mem)
                dcache.blocks = MKNZ(DBlock, nblocks);
                dcache.write = MKNZ(DBlock*, nblocks);
                dcache.mem = MKNZ(u8int, (nblocks+1+128) * blocksize);
       -        dcache.ra = chancreate(sizeof(Ra), 0);
        
                last = nil;
                p = (u8int*)(((ulong)dcache.mem+blocksize-1)&~(ulong)(blocksize-1));
       t@@ -121,10 +113,6 @@ initdcache(u32int mem)
                        b->next = last;
                        last = b;
                }
       -        dcache.rabuf = &p[i*blocksize];
       -        dcache.ramax = 128*blocksize;
       -        dcache.raaddr = 0;
       -        dcache.rapart = nil;
        
                dcache.free = last;
                dcache.nheap = 0;
       t@@ -133,7 +121,6 @@ initdcache(u32int mem)
        
                vtproc(flushproc, nil);
                vtproc(delaykickroundproc, &dcache.round);
       -        vtproc(raproc, nil);
        }
        
        void
       t@@ -156,115 +143,6 @@ diskstate(void)
                return a;
        }
        
       -static void
       -raproc(void *v)
       -{
       -        Ra ra;
       -        DBlock *b;
       -
       -        USED(v);
       -        while(recv(dcache.ra, &ra) == 1){
       -                if(ra.part->size <= ra.addr)
       -                        continue;
       -                b = _getdblock(ra.part, ra.addr, OREAD, 2);
       -                putdblock(b);
       -        }
       -}
       -
       -/*
       - * We do readahead a whole arena at a time now,
       - * so dreadahead is a no-op.  The original implementation
       - * is in unused_dreadahead below.
       - */
       -void
       -dreadahead(Part *part, u64int addr, int miss)
       -{
       -        USED(part);
       -        USED(addr);
       -        USED(miss);
       -}
       -
       -void
       -unused_dreadahead(Part *part, u64int addr, int miss)
       -{
       -        Ra ra;
       -        static struct {
       -                Part *part;
       -                u64int addr;
       -        } lastmiss;
       -        static struct {
       -                Part *part;
       -                u64int addr;
       -                int dir;
       -        } lastra;
       -
       -        if(miss){
       -                if(lastmiss.part==part && lastmiss.addr==addr-dcache.size){
       -                XRa:
       -                        lastra.part = part;
       -                        lastra.dir = addr-lastmiss.addr;
       -                        lastra.addr = addr+lastra.dir;
       -                        ra.part = part;
       -                        ra.addr = lastra.addr;
       -                        nbsend(dcache.ra, &ra);
       -                }else if(lastmiss.part==part && lastmiss.addr==addr+dcache.size){
       -                        addr -= dcache.size;
       -                        goto XRa;
       -                }
       -        }else{
       -                if(lastra.part==part && lastra.addr==addr){
       -                        lastra.addr += lastra.dir;
       -                        ra.part = part;
       -                        ra.addr = lastra.addr;
       -                        nbsend(dcache.ra, &ra);
       -                }
       -        }
       -
       -        if(miss){
       -                lastmiss.part = part;
       -                lastmiss.addr = addr;
       -        }
       -}
       -
       -int
       -rareadpart(Part *part, u64int addr, u8int *buf, uint n, int load)
       -{
       -        uint nn;
       -        static RWLock ralock;
       -
       -        rlock(&ralock);
       -        if(dcache.rapart==part && dcache.raaddr <= addr && addr+n <= dcache.raaddr+dcache.rasize){
       -                memmove(buf, dcache.rabuf+(addr-dcache.raaddr), n);
       -                runlock(&ralock);
       -                return 0;
       -        }
       -        if(load != 2 || addr >= part->size){        /* addr >= part->size: let readpart do the error */        
       -                runlock(&ralock);
       -                diskaccess(0);
       -                return readpart(part, addr, buf, n);
       -        }
       -
       -        runlock(&ralock);
       -        wlock(&ralock);
       -fprint(2, "raread %s %llx\n", part->name, addr);
       -        nn = dcache.ramax;
       -        if(addr+nn > part->size)
       -                nn = part->size - addr;
       -        diskaccess(0);
       -        if(readpart(part, addr, dcache.rabuf, nn) < 0){
       -                wunlock(&ralock);
       -                return -1;
       -        }
       -        memmove(buf, dcache.rabuf, n);        
       -        dcache.rapart = part;
       -        dcache.rasize = nn;
       -        dcache.raaddr = addr;
       -        wunlock(&ralock);
       -
       -        addstat(StatApartReadBytes, nn-n);
       -        return 0;
       -}
       -
        static u32int
        pbhash(u64int addr)
        {
       t@@ -313,16 +191,8 @@ _getdblock(Part *part, u64int addr, int mode, int load)
        again:
                for(b = dcache.heads[h]; b != nil; b = b->next){
                        if(b->part == part && b->addr == addr){
       -                        /*
       -                        qlock(&stats.lock);
       -                        stats.pchit++;
       -                        qunlock(&stats.lock);
       -                        */
       -                        if(load){
       +                        if(load)
                                        addstat(StatDcacheHit, 1);
       -                                if(load != 2 && mode != OWRITE)
       -                                        dreadahead(part, b->addr, 0);
       -                        }
                                goto found;
                        }
                }
       t@@ -367,8 +237,6 @@ ZZZ this is not reasonable
                b->addr = addr;
                b->part = part;
                b->size = 0;
       -        if(load != 2 && mode != OWRITE)
       -                dreadahead(part, b->addr, 1);
        
        found:
                b->ref++;
       t@@ -377,6 +245,11 @@ found:
                if(b->heap != TWID32)
                        fixheap(b->heap, b);
        
       +        if((mode == ORDWR || mode == OWRITE) && part->writechan == nil){
       +                trace(TraceBlock, "getdblock allocwriteproc %s", part->name);
       +                part->writechan = chancreate(sizeof(DBlock*), dcache.nblocks);
       +                vtproc(writeproc, part);
       +        }
                qunlock(&dcache.lock);
        
                trace(TraceBlock, "getdblock lock");
       t@@ -400,7 +273,8 @@ found:
                                        memset(&b->data[b->size], 0, size - b->size);
                                else{
                                        trace(TraceBlock, "getdblock readpart %s 0x%llux", part->name, addr);
       -                                if(rareadpart(part, addr + b->size, &b->data[b->size], size - b->size, load) < 0){
       +                                diskaccess(0);
       +                                if(readpart(part, addr + b->size, &b->data[b->size], size - b->size) < 0){
                                                b->mode = ORDWR;        /* so putdblock wunlocks */
                                                putdblock(b);
                                                return nil;
       t@@ -450,10 +324,9 @@ void
        dirtydblock(DBlock *b, int dirty)
        {
                int odirty;
       -        Part *p;
       -
        
       -        trace(TraceBlock, "dirtydblock enter %s 0x%llux %d from 0x%lux", b->part->name, b->addr, dirty, getcallerpc(&b));
       +        trace(TraceBlock, "dirtydblock enter %s 0x%llux %d from 0x%lux",
       +                b->part->name, b->addr, dirty, getcallerpc(&b));
                assert(b->ref != 0);
                assert(b->mode==ORDWR || b->mode==OWRITE);
        
       t@@ -463,13 +336,6 @@ dirtydblock(DBlock *b, int dirty)
                else
                        b->dirty = dirty;
        
       -        p = b->part;
       -        if(p->writechan == nil){
       -                trace(TraceBlock, "dirtydblock allocwriteproc %s", p->name);
       -                /* XXX hope this doesn't fail! */
       -                p->writechan = chancreate(sizeof(DBlock*), dcache.nblocks);
       -                vtproc(writeproc, p);
       -        }
                qlock(&dcache.lock);
                if(!odirty){
                        dcache.ndirty++;
       t@@ -779,13 +645,13 @@ flushproc(void *v)
                        waitforkick(&dcache.round);
        
                        trace(TraceWork, "start");
       +                t0 = nsec()/1000;
       +                trace(TraceProc, "build t=%lud", (ulong)(nsec()/1000)-t0);
       +
                        qlock(&dcache.lock);
                        as = dcache.state;
                        qunlock(&dcache.lock);
        
       -                t0 = nsec()/1000;
       -
       -                trace(TraceProc, "build t=%lud", (ulong)(nsec()/1000)-t0);
                        write = dcache.write;
                        n = 0;
                        for(i=0; i<dcache.nblocks; i++){
       t@@ -800,20 +666,26 @@ flushproc(void *v)
                        trace(TraceProc, "writeblocks t=%lud", (ulong)(nsec()/1000)-t0);
                        i = 0;
                        for(j=1; j<DirtyMax; j++){
       -                        trace(TraceProc, "writeblocks.%d t=%lud", j, (ulong)(nsec()/1000)-t0);
       +                        trace(TraceProc, "writeblocks.%d t=%lud",
       +                                j, (ulong)(nsec()/1000)-t0);
                                i += parallelwrites(write+i, write+n, j);
                        }
                        if(i != n){
                                fprint(2, "in flushproc i=%d n=%d\n", i, n);
                                for(i=0; i<n; i++)
       -                                fprint(2, "\tblock %d: dirty=%d\n", i, write[i]->dirty);
       +                                fprint(2, "\tblock %d: dirty=%d\n",
       +                                        i, write[i]->dirty);
                                abort();
                        }
        
       -/* XXX
       -* the locking here is suspect.  what if a block is redirtied
       -* after the write happens?  we'll still decrement dcache.ndirty here.
       -*/
       +                /*
       +                 * b->dirty is protected by b->lock while ndirty is protected
       +                 * by dcache.lock, so the --ndirty below is the delayed one
       +                 * from clearing b->dirty in the write proc.  It may happen
       +                 * that some other proc has come along and redirtied b since
       +                 * the write.  That's okay, it just means that ndirty may be
       +                 * one too high until we catch up and do the decrement.
       +                 */
                        trace(TraceProc, "undirty.%d t=%lud", j, (ulong)(nsec()/1000)-t0);
                        qlock(&dcache.lock);
                        dcache.diskstate = as;
       t@@ -850,7 +722,8 @@ writeproc(void *v)
                        trace(TraceProc, "writepart %s 0x%llux", p->name, b->addr);
                        diskaccess(0);
                        if(writepart(p, b->addr, b->data, b->size) < 0)
       -                        fprint(2, "write error: %r\n"); /* XXX details! */
       +                        fprint(2, "%s: writeproc: part %s addr 0x%llux: write error: %r\n",
       +                                argv0, p->name, b->addr);
                        addstat(StatApartWrite, 1);
                        addstat(StatApartWriteBytes, b->size);
                        b->dirty = 0;