From f97798e710929c0acb2b110c1cc16b1b267039a0 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 19 May 2013 20:59:55 +0200 Subject: devsd: don't raise Enomem error if sdmalloc() fails, instead wait for the memory to become available filesystems do not handle i/o errors well (cwfs will abandon the blocks), and temporary exhaustion of kernel memory (because of too many i/o's in parallel) causes read and write on the partition to fail. i think it is better to wait for the memory to become available in this case. the single allocation is at max SDmaxio bytes, which makes it likely to become available. if we havnt even enought fo that, then rebooting the machine would be the best option. (aux/reboot) --- sys/src/9/port/devsd.c | 20 +++++++++++++------- sys/src/9/port/sdscsi.c | 3 +-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/sys/src/9/port/devsd.c b/sys/src/9/port/devsd.c index 0c53b6e47..38b9a4548 100644 --- a/sys/src/9/port/devsd.c +++ b/sys/src/9/port/devsd.c @@ -847,9 +847,12 @@ sdbio(Chan* c, int write, char* a, long len, uvlong off) b = (uchar*)a; allocd = 0; }else{ - b = sdmalloc(nb*unit->secsize); - if(b == nil) - error(Enomem); + while((b = sdmalloc(nb*unit->secsize)) == nil){ + if(!waserror()){ + tsleep(&up->sleep, return0, 0, 100); + poperror(); + } + } allocd = 1; } if(waserror()){ @@ -929,8 +932,12 @@ sdrio(SDreq* r, void* a, long n) } data = nil; - if(n > 0 && (data = sdmalloc(n)) == nil) - error(Enomem); + while(n > 0 && (data = sdmalloc(n)) == nil){ + if(!waserror()){ + tsleep(&up->sleep, return0, 0, 100); + poperror(); + } + } if(waserror()){ sdfree(data); r->data = nil; @@ -1484,8 +1491,7 @@ sdwrite(Chan* c, void* a, long n, vlong off) } if(n < 6 || n > sizeof(req->cmd)) error(Ebadarg); - if((req = malloc(sizeof(SDreq))) == nil) - error(Enomem); + req = smalloc(sizeof(SDreq)); req->unit = unit; if(waserror()){ free(req); diff --git a/sys/src/9/port/sdscsi.c b/sys/src/9/port/sdscsi.c index defad953e..e6b53c0b8 100644 --- a/sys/src/9/port/sdscsi.c +++ b/sys/src/9/port/sdscsi.c @@ -384,8 +384,7 @@ scsibio(SDunit* unit, int lun, int write, void* data, long nb, uvlong bno) SDreq *r; long rlen; - if((r = malloc(sizeof(SDreq))) == nil) - error(Enomem); + r = smalloc(sizeof(SDreq)); r->unit = unit; r->lun = lun; again: -- cgit v1.2.3