Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Aug 1996 05:29:56 -0400 (EDT)
From:      Dave Chapeskie <dchapes@zeus.leitch.com>
To:        FreeBSD-hackers@freebsd.org
Cc:        davidg@freebsd.org
Subject:   kernel vm_page_alloc_contig() can indirectly cause kernel page faults
Message-ID:  <199608240929.FAA05695@ale.zeus.leitch.com>

next in thread | raw e-mail | index | archive | help
[Small patch which I'd like committed follows my rather wordy description]

    I have a scenario where I need large amounts of contiguous
memory (8-16MB).  A colleague of mine tossed together a contiguous
memory driver which uses vm_page_alloc_contig() from sys/vm/vm_page.c
to alloc contiguous memory at startup and then makes it available
to user processes to mmap that memory in.

    In using this memory we've been plagued with kernel page faults,
commonly at vmapbuf+0x86 when using the memory in a read(2) or
write(2) call.  In tracking this down I found that there were no
problems in the first 4MB or so of memory and that the problems
only occurred when the virtual address (in the contig driver)
crossed a page directory boundary (ie the top 10 bits changed).

    I believe the problem can be traced back to vm_page_alloc_contig()
which wires down the pages directly with vm_page_wire().  Obviously
the memory must be wired if it is to stay contiguous.  The problem,
I believe, is that the rest of the vm system isn't told that this
memory is wired down.

    I imagine this problem isn't normally seen since vm_page_alloc_contig()
maps the memory into the kernel map which has other pages mapped
which will cause the entire page directory entry to be wired in.
This would explain why I don't see the problem until the memory
spreads into the next PDE.

    The following small patch makes everything work dandy for me.
It lets vm_map_pageable() do the dirty work of making sure the
entire vm system knows the memory is wired, in particular it tells
the pmap so that the new PDE gets wired.


    Can a vm guru take a look at this and commit it (or tell me
another way to fix my problem).  I should be able to provide code
that demonstrates the failure if it's required (I'd have to ask
the guy that wrote it and my boss first).


Diff is relative to $Id: vm_page.c,v 1.32.4.1 1996/06/19 07:22:45 davidg Exp $
from 2.1.5-RELEASE
 
*** sys/vm/vm_page.c.orig	Sat Aug 24 05:15:34 1996
--- sys/vm/vm_page.c	Sat Aug 24 05:16:32 1996
***************
*** 746,755 ****
  		m->bmapped = 0;
  		m->busy = 0;
  		vm_page_insert(m, kernel_object, tmp_addr - VM_MIN_KERNEL_ADDRESS);
- 		vm_page_wire(m);
  		pmap_kenter(tmp_addr, VM_PAGE_TO_PHYS(m));
  		tmp_addr += PAGE_SIZE;
  	}
  
  	splx(s);
  	return (addr);
--- 746,756 ----
  		m->bmapped = 0;
  		m->busy = 0;
  		vm_page_insert(m, kernel_object, tmp_addr - VM_MIN_KERNEL_ADDRESS);
  		pmap_kenter(tmp_addr, VM_PAGE_TO_PHYS(m));
  		tmp_addr += PAGE_SIZE;
  	}
+ 
+ 	vm_map_pageable(kernel_map, addr, addr + size, FALSE);
  
  	splx(s);
  	return (addr);

-- 
Dave Chapeskie
Leitch Technology International Inc.
Email: dchapes@zeus.leitch.com



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199608240929.FAA05695>