From 26d36c3ae2fd6ae40148be58589ea5e81b0ca341 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Tue, 22 Jan 2019 22:06:42 +0100 Subject: devswap: simplify, don't panic when writing swapfile fails always start the pager kproc in swapinit(), simplifying kickpager(). allow zero conf.nswap and conf.nswppo. avoid allocating the reference map and iolist arrays in that case. use ulong for ioptr and iolist indices. don't panic when writing pages out to the swapfile fails. just requeue the page in the io transaction list so we will try again next time executeio() is run or just free the page when the swap reference was dropped. remove unused pagersummary() function. --- sys/src/9/port/devswap.c | 78 ++++++++++++++++++++++-------------------------- sys/src/9/port/portfns.h | 1 - 2 files changed, 35 insertions(+), 44 deletions(-) diff --git a/sys/src/9/port/devswap.c b/sys/src/9/port/devswap.c index 7cd4446c1..745303d74 100644 --- a/sys/src/9/port/devswap.c +++ b/sys/src/9/port/devswap.c @@ -23,23 +23,35 @@ static uchar *swapbuf; static AESstate *swapkey; static Page **iolist; -static int ioptr; +static ulong ioptr; static ushort ageclock; static void swapinit(void) { - swapalloc.swmap = xalloc(conf.nswap); + while(conf.nswap && conf.nswppo){ + swapalloc.swmap = xalloc(conf.nswap); + if(swapalloc.swmap == nil) + break; + iolist = xalloc(conf.nswppo*sizeof(Page*)); + if(iolist == nil){ + xfree(swapalloc.swmap); + swapalloc.swmap = nil; + } + break; + } + + if(swapalloc.swmap == nil || iolist == nil) + conf.nswap = conf.nswppo = 0; + swapalloc.top = &swapalloc.swmap[conf.nswap]; swapalloc.alloc = swapalloc.swmap; swapalloc.last = swapalloc.swmap; swapalloc.free = conf.nswap; swapalloc.xref = 0; - iolist = xalloc(conf.nswppo*sizeof(Page*)); - if(swapalloc.swmap == nil || iolist == nil) - panic("swapinit: not enough memory"); + kproc("pager", pager, 0); } static uintptr @@ -116,12 +128,7 @@ swapcount(uintptr daddr) void kickpager(void) { - static Ref started; - - if(started.ref || incref(&started) != 1) - wakeup(&swapalloc.r); - else - kproc("pager", pager, 0); + wakeup(&swapalloc.r); } static int @@ -204,7 +211,7 @@ pager(void*) } qunlock(&p->seglock); - if(ioptr > 0) { + if(ioptr) { up->psstate = "I/O"; executeio(); } @@ -331,28 +338,13 @@ pagepte(int type, Page **pg) } } -void -pagersummary(void) -{ - print("%lud/%lud memory %lud/%lud swap %d iolist\n", - palloc.user-palloc.freecount, - palloc.user, conf.nswap-swapalloc.free, conf.nswap, - ioptr); -} - static void executeio(void) { Page *outp; - int i, n; - Chan *c; - char *kaddr; - KMap *k; - - c = swapimage.c; - for(i = 0; i < ioptr; i++) { - if(ioptr > conf.nswppo) - panic("executeio: ioptr %d > %d", ioptr, conf.nswppo); + ulong i, j; + + for(i = j = 0; i < ioptr; i++) { outp = iolist[i]; assert(outp->ref > 0); @@ -361,16 +353,15 @@ executeio(void) /* only write when swap address still in use */ if(swapcount(outp->daddr) > 1){ - k = kmap(outp); - kaddr = (char*)VA(k); - - if(waserror()) - panic("executeio: page outp I/O error"); - - n = devtab[c->type]->write(c, kaddr, BY2PG, outp->daddr); - if(n != BY2PG) - nexterror(); - + Chan *c = swapimage.c; + KMap *k = kmap(outp); + if(waserror()){ + kunmap(k); + iolist[j++] = outp; + continue; + } + if(devtab[c->type]->write(c, (char*)VA(k), BY2PG, outp->daddr) != BY2PG) + error(Eshort); kunmap(k); poperror(); } @@ -381,7 +372,8 @@ executeio(void) /* Free up the page after I/O */ putpage(outp); } - ioptr = 0; + ioptr = j; + if(j) print("executeio (%lud/%lud): %s\n", j, i, up->errstr); } int @@ -416,9 +408,9 @@ setswapchan(Chan *c) n = devtab[c->type]->stat(c, buf, sizeof buf); if(n <= 0 || convM2D(buf, n, &d, nil) == 0) error("stat failed in setswapchan"); - if(d.length < conf.nswppo*BY2PG) + if(d.length < (vlong)conf.nswppo*BY2PG) error("swap device too small"); - if(d.length < conf.nswap*BY2PG){ + if(d.length < (vlong)conf.nswap*BY2PG){ conf.nswap = d.length/BY2PG; swapalloc.top = &swapalloc.swmap[conf.nswap]; swapalloc.free = conf.nswap; diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h index 004017145..7360e93e9 100644 --- a/sys/src/9/port/portfns.h +++ b/sys/src/9/port/portfns.h @@ -208,7 +208,6 @@ void pagechainhead(Page*); void pageinit(void); ulong pagenumber(Page*); ulong pagereclaim(Image*, ulong); -void pagersummary(void); void panic(char*, ...); Cmdbuf* parsecmd(char *a, int n); void pathclose(Path*); -- cgit v1.2.3