i386/74327: [PATCH] mlock() causes physical memory leakage
Denis Koreshkov
deniskv at mail.ru
Wed Nov 24 10:20:27 PST 2004
>Number: 74327
>Category: i386
>Synopsis: mlock() causes physical memory leakage
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-i386
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Nov 24 18:20:26 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Denis Koreshkov
>Release: FreeBSD 4.10-RELEASE i386
>Organization:
>Environment:
System: FreeBSD doscrypt 4.8-RELEASE FreeBSD 4.8-RELEASE #0: Sat Oct 30 02:38:01 MSD 2004 root at doscrypt:/usr/obj/usr/src/sys/LITE i386
>Description:
On FreeBSD/i386, mlock()'ing an memory area cause underlying
pages to become unusable (to both kernel and applications)
following exit(), when the following conditions are met:
1) The area had already been accessed before
a call to mlock(), and
2) No corresponding call to munlock() had been
issued before exit().
>How-To-Repeat:
1) malloc() a few megs of memory,
2) bzero() it,
3) mlock() it,
4) exit().
sysctl vm.stats.vm.v_wire_count will have grown
by the amount of pages locked
>Fix:
The bug is confined in pmap_enter() (file sys/i386/i386/pmap.c)
One should toggle PG_W bit of pte to reflect wiring
changes, as vm_fault_user_wire() does vm_fault() to
bring pages into physmem.
*** sys/i386/i386/pmap.c.orig Sun Nov 14 11:12:34 2004
--- sys/i386/i386/pmap.c Sun Nov 14 11:21:25 2004
***************
*** 1962,1971 ****
* are valid mappings in them. Hence, if a user page is wired,
* the PT page will be also.
*/
! if (wired && ((origpte & PG_W) == 0))
pmap->pm_stats.wired_count++;
! else if (!wired && (origpte & PG_W))
pmap->pm_stats.wired_count--;
#if defined(PMAP_DIAGNOSTIC)
if (pmap_nw_modified((pt_entry_t) origpte)) {
--- 1962,1974 ----
* are valid mappings in them. Hence, if a user page is wired,
* the PT page will be also.
*/
! if (wired && ((origpte & PG_W) == 0)) {
! *pte |= PG_W;
pmap->pm_stats.wired_count++;
! } else if (!wired && (origpte & PG_W)) {
! *pte &= ~PG_W;
pmap->pm_stats.wired_count--;
+ }
#if defined(PMAP_DIAGNOSTIC)
if (pmap_nw_modified((pt_entry_t) origpte)) {
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-i386
mailing list