Bug 30798

Summary: contigfree() doesn't
Product: Base System Reporter: Andrew Gallatin <gallatin>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.4-RELEASE   
Hardware: Any   
OS: Any   

Description Andrew Gallatin 2001-09-24 21:20:01 UTC
When debugging an apparent memory leak in a 3rd party
device driver, I found what appears to be a serious problem with
contigfree() -- it doesn't appear to actually free the pages.

Fix: 

unknown
How-To-Repeat: 
I modified the syscall example kld to contigmalloc 1024 pages on load &
free them on unload.  Prior to the contigmalloc() it prints out the
number of wired pages, as well as the size of the free and cache
queues.  It prints this same information after the contigfree at
unload time. 

As you can see from the following output, the pages remain wired & are
never freed:

load:   wired: 3710, cache 8, free 119993
unload: wired: 4735, cache 8, free 118954
load:   wired: 4738, cache 8, free 118950
unload: wired: 5762, cache 8, free 117924
load:   wired: 5762, cache 8, free 117926
unload: wired: 6786, cache 8, free 116900
load:   wired: 6786, cache 8, free 116902
unload: wired: 7810, cache 8, free 115876


I've appended a modified version of the syscall module:



--- /usr/share/examples/kld/syscall/module/syscall.c	Wed Aug 15 14:40:49 2001
+++ syscall.c	Mon Sep 24 15:21:42 2001
@@ -33,6 +33,8 @@
 #include <sys/sysent.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/vmmeter.h>
 
 /*
  * The function for implementing the syscall.
@@ -64,6 +66,9 @@
  * The function called at load/unload.
  */
 
+void *contigmem;
+unsigned long size = PAGE_SIZE * 1024;
+
 static int
 load (struct module *module, int cmd, void *arg)
 {
@@ -71,10 +76,15 @@
 
 	switch (cmd) {
 	case MOD_LOAD :
-		printf ("syscall loaded at %d\n", offset);
+		printf("load:   wired: %d, cache %d, free %d\n",
+		    cnt.v_wire_count, cnt.v_cache_count, cnt.v_free_count);
+		contigmem = contigmalloc (size, M_DEVBUF, M_NOWAIT, 
+		    0x100000, 0xffffffff, PAGE_SIZE, 0);
 		break;
 	case MOD_UNLOAD :
-		printf ("syscall unloaded from %d\n", offset);
+		contigfree(contigmem, size, M_DEVBUF);
+		printf("unload: wired: %d, cache %d, free %d\n",
+		    cnt.v_wire_count, cnt.v_cache_count, cnt.v_free_count);
 		break;
 	default :
 		error = EINVAL;
Comment 1 Jens Schweikhardt freebsd_committer freebsd_triage 2003-08-06 20:28:35 UTC
State Changed
From-To: open->feedback

Is this still a problem?
Comment 2 Jens Schweikhardt freebsd_committer freebsd_triage 2003-08-07 17:25:10 UTC
State Changed
From-To: feedback->closed

Appears to be fixed by dillon's vm_contig v1.3 and 
MFC'ed to vm_page.c 1.147.2.9.