Subject: kern/11636: ubc vnode counter leak fix
To: None <gnats-bugs@gnats.netbsd.org>
From: None <lars@heidieker.de>
List: netbsd-bugs
Date: 12/05/2000 07:06:11
>Number:         11636
>Category:       kern
>Synopsis:       counter of vnode cache pages grow to high
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Dec 05 07:06:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Lars Heidieker
>Release:        NetBSD-current 5th of December 2000
>Organization:
	
>Environment:
	
System: NetBSD zeus 1.5L NetBSD 1.5L (zeus) #3: Tue Dec 5 15:46:39 CET 2000 root@zeus:/usr/src/sys/arch/i386/compile/zeus i386
Architecture: i386
Machine: i386
>Description:
	Within the routine uvn_findpage there is an bug that will show up under high memory loads. It is possible for uvm_pagealloc to return NULL but the counter (uvmexp.vnodepages) will be bumped anyway -- possibly more then once for a pageframe.
>How-To-Repeat:
	Just stress the memory subsystem and look at the vnode cache page counter. You will end up with more anonymous memory mappings that are resident plus vnode cache than you have physikal memory wich is impossible. Another indicator is: After reboot you might get the vnode cache down to about 100kb after some time you won't get it bellow a few megs and so on (This might explain a crash someone has reported) This will prevent the counter from being bumped to often.
>Fix:
	
	Insertation of a little if statement:
                /* nope?   allocate one now */
                if (pg == NULL) {
                        if (flags & UFP_NOALLOC) {
                                UVMHIST_LOG(ubchist, "noalloc", 0,0,0,0);
                                return 0;
                        }
                        if (uvmexp.vnodepages > 
                            (uvmexp.active + uvmexp.inactive + uvmexp.wired +
                             uvmexp.free) * 7 / 8) {
                                pg = NULL;
                        } else {
                                pg = uvm_pagealloc(uobj, offset, NULL, 0);
 Thats the one -------->        if (pg != NULL)
                                        uvmexp.vnodepages++;
                        }
                        if (pg == NULL) {
                                if (flags & UFP_NOWAIT) {
                                        UVMHIST_LOG(ubchist, "nowait",0,0,0,0);
                                        return 0;
                                }
                                simple_unlock(&uobj->vmobjlock);
                                uvm_wait("uvn_fp1");
                                simple_lock(&uobj->vmobjlock);
                                continue;
                        }
                        UVMHIST_LOG(ubchist, "alloced",0,0,0,0);
                        break;
                } else if (flags & UFP_NOCACHE) {
                        UVMHIST_LOG(ubchist, "nocache",0,0,0,0);
                        return 0;
                }

>Release-Note:
>Audit-Trail:
>Unformatted: