home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!munnari.oz.au!manuel.anu.edu.au!dubhe.anu.edu.au!sirius.anu.edu.au!not-for-mail
- From: paulus@cs.anu.edu.au (Paul Mackerras)
- Newsgroups: comp.unix.bsd
- Subject: Bug + fix: page leak in VM system
- Date: 22 Jan 1993 15:19:37 +1100
- Organization: Computer Science Department, ANU, Australia
- Lines: 74
- Message-ID: <1jnskpINN2a0@sirius.anu.edu.au>
- NNTP-Posting-Host: sirius.anu.edu.au
- Keywords: VM system, bug, memory leak
-
- I have found a bug in the new Mach-derived VM system in BSD Unix (as
- in the NET/2 release and 386BSD) which causes it to lose physical
- pages, resulting in less memory for running programs and increased
- likelihood of thrashing.
-
- The bug is that the call to vm_page_deactivate() at line 531 of
- vm_fault.c does not put the (now no longer needed) page back on the
- inactive list, because vm_page_deactivate() only does anything with
- active pages. Consequently, the page is then not on the active,
- inactive or free lists and is effectively not available for use. (It
- is not lost forever, though, because it is still on its object's page
- queue.)
-
- The situation where this occurs is basically the following:
- 1. A process has a copy-on-write mapping, e.g. to the data
- segment of an executable file.
- 2. The process reads a page in the copy-on-write region.
- The VM system allocates a page and reads in the data from
- the file.
- 3. The process writes to the page. The VM system allocates
- a second page, copies the first page to it, and then
- loses the first page :-(.
-
- The following patch corrects the problem.
-
- Paul Mackerras
- Dept. Computer Science,
- Australian National University.
- paulus@cs.anu.edu.au
-
- -----------------------------------------------------------------------------
- *** vm_page-orig.c Fri Jan 22 09:54:01 1993
- --- vm_page.c Fri Jan 22 09:52:51 1993
- ***************
- *** 687,701 ****
- /*
- * Only move active pages -- ignore locked or already
- * inactive ones.
- */
-
- ! if (m->active) {
- pmap_clear_reference(VM_PAGE_TO_PHYS(m));
- ! queue_remove(&vm_page_queue_active, m, vm_page_t, pageq);
- queue_enter(&vm_page_queue_inactive, m, vm_page_t, pageq);
- - m->active = FALSE;
- m->inactive = TRUE;
- - vm_page_active_count--;
- vm_page_inactive_count++;
- if (pmap_is_modified(VM_PAGE_TO_PHYS(m)))
- m->clean = FALSE;
- --- 687,708 ----
- /*
- * Only move active pages -- ignore locked or already
- * inactive ones.
- + *
- + * XXX: sometimes we get pages which aren't wired down
- + * or on any queue - we need to put them on the inactive
- + * queue also, otherwise we lose track of them.
- + * Paul Mackerras (paulus@cs.anu.edu.au) 9-Jan-93.
- */
-
- ! if (!m->inactive && m->wire_count == 0) {
- pmap_clear_reference(VM_PAGE_TO_PHYS(m));
- ! if (m->active) {
- ! queue_remove(&vm_page_queue_active, m, vm_page_t, pageq);
- ! m->active = FALSE;
- ! vm_page_active_count--;
- ! }
- queue_enter(&vm_page_queue_inactive, m, vm_page_t, pageq);
- m->inactive = TRUE;
- vm_page_inactive_count++;
- if (pmap_is_modified(VM_PAGE_TO_PHYS(m)))
- m->clean = FALSE;
-
-