Skip site navigation (1)Skip section navigation (2)
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>