Date: Sat, 1 Mar 1997 21:17:49 +0100 (MET) From: Tor Egge <Tor.Egge@idt.ntnu.no> To: FreeBSD-gnats-submit@freebsd.org Subject: kern/2840: mlock+minherit+fork+munlock causes panics or freezes Message-ID: <199703012017.VAA00598@ikke.idt.unit.no> Resent-Message-ID: <199703012020.MAA27606@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 2840 >Category: kern >Synopsis: mlock+minherit+fork+munlock causes panics or freezes >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Mar 1 12:20:01 PST 1997 >Last-Modified: >Originator: Tor Egge >Organization: Norwegian University of Science and Technology, Trondheim, Norway >Release: FreeBSD 3.0-CURRENT i386 >Environment: FreeBSD ikke.idt.unit.no 3.0-CURRENT FreeBSD 3.0-CURRENT #2: Sat Feb 1 03:55:57 MET 1997 root@ikke.idt.unit.no:/usr/src/sys-UP/compile/TEGGE i386 >Description: Accounting of wired pages is not consistent under all circumstances. By using mlock() and minherit(), then fork(), then munlock() in both child and parent processes, the wired count is reduced by both munlocks(), causing a too small (or even negative) value.for wired count. Other side effects are freezes (i.e. kernel is alive, but all programs hangs), or panics. >How-To-Repeat: Look at wire count (using top or systat). Run the appended program as root. If the program crashes, run it again. Look at wire count again. --- #include <sys/types.h> #include <sys/param.h> #include <sys/time.h> #include <time.h> #include <string.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <errno.h> #include <sys/wait.h> #include <sys/mman.h> #include <vm/vm.h> #include <vm/vm_inherit.h> int main(int argc,char **argv) { int i; int j; char *a; char *b; char *aend; char *p; size_t alen; size_t blen; pid_t pid; int wres; int sum; int res; alen = 1024 * 1024 * 1; blen = 1024 * 1024 * 1; a = malloc(alen); assert(a); aend = a + alen; sum = 0; for (p=a;p<aend;p++) sum += *p; res = minherit(a,alen,VM_INHERIT_SHARE); printf("minherit: a=%p, alen=0x%x, res=%d, errno=%d\n",a,alen, res,errno); for (j=0;j<10;j++) { b = malloc(blen); assert(b); res = mlock(b,blen); printf("mlock: res=%d, errno=%d\n",res,errno); printf("pass %d\n",j); for (i=0;i<3;i++) { pid = fork(); if (pid<0) { perror("fork"); exit(1); } if (pid==0) { munlock(b,blen); printf("munlock: res=%d, errno=%d\n",res,errno); free(b); sleep(2); exit(0); } } for (p=a;p<aend;p++) sum += *p; sleep(3); while (waitpid(-1,&wres,WNOHANG)>0) { /* */ } munlock(b,blen); printf("munlock: res=%d, errno=%d\n",res,errno); free(b); } exit(0); } >Fix: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703012017.VAA00598>