commit 12c0e45f796863966ef7ab96b30df50a562ddb13 from: Russ Cox date: Tue Sep 25 02:32:46 2007 UTC venti: throw away dcache read-ahead code commit - b41e39aa1a726c08d5e9d5db55f2a4661aef2c42 commit + 12c0e45f796863966ef7ab96b30df50a562ddb13 blob - 9066296f702060750dcc9ec264db60e1662a14c4 blob + f0cb531848c9a2b2456f1d94508f5a326ee7696a --- src/cmd/venti/srv/dcache.c +++ src/cmd/venti/srv/dcache.c @@ -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; @@ -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) @@ -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)); @@ -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; @@ -133,7 +121,6 @@ initdcache(u32int mem) vtproc(flushproc, nil); vtproc(delaykickroundproc, &dcache.round); - vtproc(raproc, nil); } void @@ -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) { @@ -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; } } @@ -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++; @@ -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"); @@ -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; @@ -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); @@ -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++; @@ -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; idirty); + 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; @@ -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;