Date: Mon, 24 Sep 2001 16:15:39 -0400 (EDT) From: gallatin@cs.duke.edu To: FreeBSD-gnats-submit@freebsd.org Subject: kern/30798: contigfree() doesn't Message-ID: <200109242015.f8OKFdP66601@grasshopper.cs.duke.edu>
next in thread | raw e-mail | index | archive | help
>Number: 30798
>Category: kern
>Synopsis: contigfree() doesn't
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Sep 24 13:20:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:
>Release: FreeBSD 4.4-RELEASE i386
>Organization:
>Environment:
System: FreeBSD ugly 4.4-RELEASE FreeBSD 4.4-RELEASE #3: Mon Sep 24 15:01:31 EDT 2001 gallatin@ugly:/usr/src/sys/compile/SMP i386
>Description:
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.
>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;
>Fix:
unknown
>Release-Note:
>Audit-Trail:
>Unformatted:
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?200109242015.f8OKFdP66601>
