- set daddr to ~0 by default - don't try silly things in the pager that clearly can't work Reference: /n/atom/patch/applied/pagerclean Date: Thu Jun 12 04:50:00 CES 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/port/page.c Thu Jun 12 04:49:29 2014 +++ /sys/src/nix/port/page.c Thu Jun 12 04:49:33 2014 @@ -106,6 +106,7 @@ pg->pgszi = si; /* size index */ incref(&pga.pgsza[si].npages); pg->color = color; + pg->ref = 1; return pg; } @@ -199,9 +200,10 @@ KMap *k; Pgsza *pa; int i, dontalloc, si; - static int once; si = getpgszi(size); + if(si == -1) + panic("newpage: getpgszi %lux %d %#p", size, color, getcallerpc(&size)); pa = &pga.pgsza[si]; lock(&pga); @@ -222,19 +224,22 @@ pageunchain(p); break; } + unlock(&pga); /* * 2. try to allocate a new one from physical memory */ p = pgalloc(size, color); - if(p != nil) - break; + if(p != nil){ + p->va = va; + p->daddr = ~0; + goto Clear; + } /* * 3. out of memory, try with the pager. * but release the segment (if any) while in the pager. */ - unlock(&pga); dontalloc = 0; if(s != nil && *s != nil) { @@ -265,11 +270,13 @@ p->ref++; p->va = va; p->modref = 0; + p->daddr = ~0; for(i = 0; i < nelem(p->cachectl); i++) p->cachectl[i] = PG_NEWCOL; unlock(p); unlock(&pga); +Clear: if(clear) { k = kmap(p); memset((void*)VA(k), 0, m->pgsz[p->pgszi]); @@ -314,9 +321,9 @@ if(pga.r.p != nil) wakeup(&pga.r); unlock(p); + unlock(&pga); if(rlse) pgfree(p); - unlock(&pga); } /* @@ -381,14 +388,16 @@ for(f = *l; f; f = f->hash){ if(f == p){ *l = p->hash; - break; + goto found; } l = &f->hash; } + panic("uncachpage"); +found: unlock(&pga.hashlock); putimage(p->image); p->image = 0; - p->daddr = 0; + p->daddr = ~0; } void --- /sys/src/nix/port/pager.c Thu Jun 12 04:49:40 2014 +++ /sys/src/nix/port/pager.c Thu Jun 12 04:49:42 2014 @@ -208,9 +208,7 @@ p = pgalloc(m->pgsz[pgszi], color); if(p != nil){ - lock(&pga); - pagechainhead(p); - unlock(&pga); + putpage(p); return 0; } return -1; @@ -243,36 +241,21 @@ { Pgsza *pa; - if(DBGFLG>1) - DBG("kickpager() %#p\n", up); + DBG("kickpager: %s:%d color %d\n", up->text, up->pid, color); if(waserror()) panic("error in kickpager"); qlock(&pagerlck); pa = &pga.pgsza[pgszi]; /* - * 1. did anyone else release one for us in the mean time? - */ - if(hascolor(pa->head, color)) - goto Done; - - /* - * 2. try allocating from physical memory - */ - tryalloc(pgszi, color); - if(hascolor(pa->head, color)) - goto Done; - - /* * If pgszi is <= text page size, try releasing text pages. */ if(m->pgsz[pgszi] <= 2*MiB){ pstats.ntext++; DBG("kickpager() up %#p: reclaiming text pages\n", up); pageouttext(pgszi, color); - tryalloc(pgszi, color); - if(hascolor(pa->head, color)){ - DBG("kickpager() found %ud free\n", pa->freecount); + if(tryalloc(pgszi, color) == 0){ + DBG("kickpager: pageouttext found %ud free\n", pa->freecount); goto Done; } } @@ -282,9 +265,8 @@ */ pstats.nbig++; freepages(pgszi+1, 1); - tryalloc(pgszi, color); - if(hascolor(pa->head, color)){ - DBG("kickpager() found %ud free\n", pa->freecount); + if(tryalloc(pgszi, color) == 0){ + DBG("kickpager: big found %ud free\n", pa->freecount); goto Done; } @@ -294,9 +276,8 @@ pstats.nall++; DBG("kickpager() up %#p: releasing all pages\n", up); freepages(0, 0); - tryalloc(pgszi, color); - if(pa->freecount > 0){ - DBG("kickpager() found %ud free\n", pa->freecount); + if(tryalloc(pgszi, color) == 0){ + DBG("kickpager: freepages found %ud free\n", pa->freecount); goto Done; } @@ -312,8 +293,6 @@ Done: poperror(); qunlock(&pagerlck); - if(DBGFLG>1) - DBG("kickpager() done %#p\n", up); } void