ref: 3354a016d212b2fb591dbc1f19b67a0c0036a4e6
parent: 7c79528b76dfb1dc0caf3dfdb4a29c68ec482743
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun May 19 16:59:55 EDT 2013
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)
--- a/sys/src/9/port/devsd.c
+++ b/sys/src/9/port/devsd.c
@@ -847,9 +847,12 @@
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 @@
}
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 @@
}
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);
--- a/sys/src/9/port/sdscsi.c
+++ b/sys/src/9/port/sdscsi.c
@@ -384,8 +384,7 @@
SDreq *r;
long rlen;
- if((r = malloc(sizeof(SDreq))) == nil)
- error(Enomem);
+ r = smalloc(sizeof(SDreq));
r->unit = unit;
r->lun = lun;
again:
--
⑨