Date: Mon, 12 Oct 1998 11:40:01 -0700 (PDT) From: dag-erli@ifi.uio.no (Dag-Erling C. =?iso-8859-1?Q?Sm=F8rgrav?= ) To: freebsd-bugs@FreeBSD.ORG Subject: Re: bin/8275: w/top/etc randomly fail with 'Cannot allocate memory' Message-ID: <199810121840.LAA26956@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/8275; it has been noted by GNATS. From: dag-erli@ifi.uio.no (Dag-Erling C. =?iso-8859-1?Q?Sm=F8rgrav?= ) To: Kevin Day <toasty@home.dragondata.com> Cc: root@shell1.dragondata.com, FreeBSD-gnats-submit@FreeBSD.ORG Subject: Re: bin/8275: w/top/etc randomly fail with 'Cannot allocate memory' Date: 12 Oct 1998 20:35:27 +0200 Kevin Day <toasty@home.dragondata.com> writes: > With 18MB free, and 60MB sitting in a cache, I can't see that I'm out of > just raw memory... Our of mbufs? Out of some fixed kind of memory? That's > what I don't know - what memory am I running out of? If you read the kvm_getprocs() code (in src/lib/libkvm/kvm_proc.c) you'll notice the only case in which it prints out an error message is if sysctl() fails. sysctl(3) mentions that sysctl() will fail and set errno to ENOMEM if "The length pointed to by oldlenp is too short to hold the requested value." What seems to happen is that between the first and the second call to sysctl, the size of the data has grown (because the number of running processes is growing fast), so the buffer we allocate is no longer big enough. The best way to fix this is to retry the sysctl() with a larger buffer if/when it fails with ENOMEM. If my reasoning is correct, the following (untested) patch should solve this: Index: kvm_proc.c =================================================================== RCS file: /home/ncvs/src/lib/libkvm/kvm_proc.c,v retrieving revision 1.21 diff -u -r1.21 kvm_proc.c --- kvm_proc.c 1998/09/16 04:17:46 1.21 +++ kvm_proc.c 1998/10/12 18:33:58 @@ -302,10 +302,15 @@ _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); } - kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); - if (kd->procbase == 0) - return (0); - st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4, kd->procbase, &size, NULL, 0); + kd->procbase = 0; + do { + kd->procbase = (struct kinfo_proc *)_kvm_realloc(kd, + size); + if (kd->procbase == 0) + return (0); + st = sysctl(mib, op == KERN_PROC_ALL ? 3 : 4, + kd->procbase, &size, NULL, 0); + } while (st == -1 && errno == ENOMEM); if (st == -1) { _kvm_syserr(kd, kd->program, "kvm_getprocs"); return (0); Of course, there is no guarantee that the loop will terminate before the process table goes full, but if you're seeing this problem in the first place it shouldn't take too long to fill up :) Now if only jkh will come out of his trance and answer some mail so I can get his approval to commit it... DES -- Dag-Erling Smørgrav - dag-erli@ifi.uio.no To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199810121840.LAA26956>