Commit Graph

238 Commits

Author SHA1 Message Date
thorpej
8e06a75bcb Fix an operator precedence error which caused msync(2) to fail to pass
the PGO_CLEANIT flag to the object pagers.  Fixes PR #7978, from
Matthias Pfaller.
1999-07-14 21:06:30 +00:00
kleink
e79a283e47 XSH5: change function signature to `void *sbrk(intptr_t)'. 1999-07-12 21:55:19 +00:00
thorpej
ff05773b4a Back out the change I made yesterday. It seems to cause some trouble
for some folks.
1999-07-11 17:47:12 +00:00
thorpej
a0555db3e0 Simplify uvm_fault_unwire_locked() a little. 1999-07-10 21:46:56 +00:00
thorpej
c0389be5da Make a comment reflect reality. 1999-07-10 20:40:23 +00:00
thorpej
d75fb0f6b0 Slightly better test for "object with no real pages". Test for NULL
pgo_releasepg rather than if the pager is the device pager.
1999-07-10 20:29:24 +00:00
thorpej
3ebbe095e0 Change the pmap_extract() interface to:
boolean_t pmap_extract(pmap_t, vaddr_t, paddr_t *);
This makes it possible for the pmap to map physical address 0.
1999-07-08 18:05:21 +00:00
thorpej
6885fbe3d1 Teeny bit of style policing. 1999-07-08 01:02:44 +00:00
thorpej
ec74ea9486 Correct a comment. 1999-07-08 00:52:45 +00:00
thorpej
4ef1f3670d Fix a thinko which could cause a NULL pointer deref, in the PGO_FREE
case.
1999-07-07 21:51:35 +00:00
thorpej
62dcdc109b In the PGO_FREE case of uvm_map_clean()'s amap cleaning, skip wired
pages.

XXX This should be handled better in the future, probably by marking the
XXX page as released, and making uvm_pageunwire() free the page when
XXX the wire count on a released page reaches zero.
1999-07-07 21:04:22 +00:00
thorpej
4e398a6ded Add some more meat to madvise(2):
* Implement MADV_DONTNEED: deactivate pages in the specified range,
  semantics similar to Solaris's MADV_DONTNEED.
* Add MADV_FREE: free pages and swap resources associated with the
  specified range, causing the range to be reloaded from backing
  store (vnodes) or zero-fill (anonymous), semantics like FreeBSD's
  MADV_FREE and like Digital UNIX's MADV_DONTNEED (isn't it SO GREAT
  that madvise(2) isn't standardized!?)

As part of this, move the non-map-modifying advice handling out of
uvm_map_advise(), and into sys_madvise().

As another part, implement general amap cleaning in uvm_map_clean(), and
change uvm_map_clean() to only push dirty pages to disk if PGO_CLEANIT
is set in its flags (and update sys___msync13() accordingly).  XXX Add
a patchable global "amap_clean_works", defaulting to 1, which can disable
the amap cleaning code, just in case problems are unearthed; this gives
a developer/user a quick way to recover and send a bug report (e.g. boot
into DDB and change the value).

XXX Still need to implement a real uao_flush().

XXX Need to update the manual page.

With these changes, rebuilding libc will automatically cause the new
malloc(3) to use MADV_FREE to actually release pages and swap resources
when it decides that can be done.
1999-07-07 06:02:21 +00:00
thorpej
f631c1adae Update a comment in uao_flush(). 1999-07-07 05:32:26 +00:00
thorpej
121fe0bc26 Don't bother returning the "slot" number from amap_add():
* Nothing currently uses this return value.
* It's arguably an abstraction violation.

Fix amap_unadd()'s API to be consistent w/ amap_add()'s: rather than
take a vm_amap * and a slot number, take a vm_aref * and an offset.

It's now actually possible to use amap_unadd() to remove an anon from
an amap.
1999-07-07 05:31:40 +00:00
cgd
c1b7b40399 from the comment added to the code:
> XXX (in)sanity check.  We don't do proper datasize checking
> XXX for anonymous (or private writable) mmap().  However,
> XXX know that if we're trying to allocate more than the amount
> XXX remaining under our current data size limit, _that_ should
> XXX be disallowed.
This is one link on the chain of lossage known as PR#7897.  It's
definitely not the right fix, but it's better than nothing.
1999-07-06 02:31:05 +00:00
cgd
5cc6a54251 fix allocation handling bugs in amap_alloc1(). if the first or second
sub-structure malloc() failed, it was quite likely that the function
would return success incorrectly.  This is this direct cause of the bug
reported in PR#7897.  (Thanks to chs for helping to track it down.)
1999-07-06 02:15:53 +00:00
thorpej
3c83723113 Bring in additional uvmexp members from chs-ubc2, so that VM stats can
be read no matter which kernel you're running.
1999-07-02 23:20:58 +00:00
thorpej
11c67d01a5 Fix a corner case locking error, which could lead to map corruption in
SMP environments.  See comments in <vm/vm_map.h> for details.
1999-07-01 20:07:05 +00:00
thorpej
c859e43fbb Fix tyop. From Bill Studenmund. 1999-07-01 18:40:39 +00:00
thorpej
abb48c5b71 Protect prototypes, certain macros, and inlines from userland. 1999-06-21 17:25:11 +00:00
thorpej
72fcd1784e Fix a typo. 1999-06-19 00:11:17 +00:00
thorpej
9e9f068f43 Add the guts of mlockall(MCL_FUTURE). This requires that a process's
"memlock" resource limit to uvm_mmap().  Update all calls accordingly.
1999-06-18 05:13:45 +00:00
thorpej
01ac9b6529 In sys_mmap():
- rather than treating MAP_COPY like MAP_PRIVATE by sheer virtue of it not
  being MAP_SHARED, actually convert the MAP_COPY flag into MAP_PRIVATE.
- return EINVAL if MAP_SHARED and MAP_PRIVATE are both included in flags.
1999-06-17 21:05:19 +00:00
thorpej
0288ffb53a pmap_change_wiring() -> pmap_unwire(). 1999-06-17 19:23:20 +00:00
thorpej
f5a527bb4e Remove pmap_pageable(); no pmap implements it, and it is not really useful,
because pmap_enter()/pmap_change_wiring() (soon to be pmap_unwire())
communicate the information in greater detail.
1999-06-17 18:21:21 +00:00
thorpej
12347b2657 Make uvm_vslock() return the error code from uvm_fault_wire(). All places
which use uvm_vslock() should now test the return value.  If it's not
KERN_SUCCESS, wiring the pages failed, so the operation which is using
uvm_vslock() should error out.

XXX We currently just EFAULT a failed uvm_vslock().  We may want to do
more about translating error codes in the future.
1999-06-17 15:47:22 +00:00
thorpej
1f97ad987f In uvm_useracc(), make sure we have a read lock on the map before
calling uvm_map_checkprot().
1999-06-17 05:57:33 +00:00
thorpej
f274deb90a The i386 and pc532 pmaps are officially fixed. 1999-06-17 00:24:10 +00:00
thorpej
d1d9b366cd When unwiring a range in uvm_fault_unwire_locked(), don't call
pmap_change_wiring(...,FALSE) unless the map entry claims the address
is unwired.  This fixes the following scenario, as described on
tech-kern@netbsd.org on Wed 6/16/1999 12:25:23:

	- User mlock(2)'s a buffer, to guarantee it will never become
	  non-resident while he is using it.

	- User then does physio to that buffer.  Physio calls uvm_vslock()
	  to lock down the pages and ensure that page faults do not happen
	  while the I/O is in progress (possibly in interrupt context).

	- Physio does the I/O.

	- Physio calls uvm_vsunlock().  This calls uvm_fault_unwire().

	  >>> HERE IS WHERE THE PROBLEM OCCURS <<<

	  uvm_fault_unwire() calls pmap_change_wiring(..., FALSE),
	  which now gives the pmap free reign to recycle the mapping
	  information for that page, which is illegal; the mapping is
	  still wired (due to the mlock(2)), but now access of the
	  page could cause a non-protection page fault (disallowed).

	  NOTE: This could eventually lead to a panic when the user
	  subsequently munlock(2)'s the buffer and the mapping info
	  has been recycled for use by another mapping!
1999-06-16 23:02:40 +00:00
thorpej
b861180119 * Rename uvm_fault_unwire() to uvm_fault_unwire_locked(), and require that
the map be at least read-locked to call this function.  This requirement
  will be taken advantage of in a future commit.
* Write a uvm_fault_unwire() wrapper which read-locks the map and calls
  uvm_fault_unwire_locked().
* Update the comments describing the locking contraints of uvm_fault_wire()
  and uvm_fault_unwire().
1999-06-16 22:11:23 +00:00
thorpej
42c671ffba Modify uvm_map_pageable() and uvm_map_pageable_all() to follow POSIX 1003.1b
semantics.  That is, regardless of the number of mlock/mlockall calls,
an munlock/munlockall actually unlocks the region (i.e. sets wiring count
to 0).

Add a comment describing why uvm_map_pageable() should not be used for
transient page wirings (e.g. for physio) -- note, it's currently only
(ab)used in this way by a few pieces of code which are known to be
broken, i.e. the Amiga and Atari pmaps, and i386 and pc532 if PMAP_NEW is
not used.  The i386 GDT code uses uvm_map_pageable(), but in a safe
way, and could be trivially converted to use uvm_fault_wire() instead.
1999-06-16 19:34:24 +00:00
thorpej
23c6eb95d3 Remove a incorrect-and-no-longer-relevant comment. 1999-06-16 18:43:28 +00:00
minoura
ff8fb3ef82 Remove extra ]. 1999-06-16 17:25:39 +00:00
thorpej
ee9703dea9 Add a macro to test if a map entry is wired. 1999-06-16 00:29:04 +00:00
thorpej
c5a43ae10c Several changes, developed and tested concurrently:
* Provide POSIX 1003.1b mlockall(2) and munlockall(2) system calls.
  MCL_CURRENT is presently implemented.  MCL_FUTURE is not fully
  implemented.  Also, the same one-unlock-for-every-lock caveat
  currently applies here as it does to mlock(2).  This will be
  addressed in a future commit.
* Provide the mincore(2) system call, with the same semantics as
  Solaris.
* Clean up the error recovery in uvm_map_pageable().
* Fix a bug where a process would hang if attempting to mlock a
  zero-fill region where none of the pages in that region are resident.
  [ This fix has been submitted for inclusion in 1.4.1 ]
1999-06-15 23:27:47 +00:00
thorpej
45e5ec934e Use a more descriptive wait message for VM map locks. 1999-06-14 22:05:23 +00:00
thorpej
5de7bac9b1 Print the maps flags in "show map" from DDB. 1999-06-07 16:31:42 +00:00
thorpej
2c3dc83a64 Keep interrupt-safe maps on an additional queue. In uvm_fault(), if we're
looking up a kernel address, check to see if the address is on this
"interrupt-safe" list.  If so, return failure immediately.  This prevents
a locking screw if a page fault is taken on an interrupt-safe map in or
out of interrupt context.
1999-06-04 23:38:41 +00:00
thorpej
8c59c67288 Just say no to interrupt-safe maps. 1999-06-03 00:05:45 +00:00
thorpej
acf81da21e A page fault on a non-pageable map is always fatal. 1999-06-02 23:26:21 +00:00
thorpej
779ecdd773 Simplify the last even more; We downgraded to a shared (read) lock, so
setting recursive has no effect!  The kernel lock manager doesn't allow
an exclusive recursion into a shared lock.  This situation must simply
be avoided.  The only place where this might be a problem is the (ab)use
of uvm_map_pageable() in the Utah-derived pmaps for m68k (they should
either toss the iffy scheme they use completely, or use something like
uvm_fault_wire()).

In addition, once we have looped over uvm_fault_wire(), only upgrade to
an exclusive (write) lock if we need to modify the map again (i.e.
wiring a page failed).
1999-06-02 22:40:51 +00:00
thorpej
0723d57281 Clean up the locking mess in uvm_map_pageable() a little... Most importantly,
don't unlock a kernel map (!!!) and then relock it later; a recursive lock,
as it used in the user map case, is fine.  Also, don't change map entries
while only holding a read lock on the map.  Instead, if we fail to wire
a page, clear recursive locking, and upgrade back to a write lock before
dropping the wiring count on the remaining map entries.
1999-06-02 21:23:08 +00:00
mrg
2332079d3f unlock the map for unknown arguments to uvm_map_advise. from Soren S. Jorvang in PR kern/7681 1999-05-31 23:36:23 +00:00
thorpej
fb36fe649a A little spring cleaning in the unwire case of uvm_map_pageable(). 1999-05-28 22:54:12 +00:00
thorpej
8d8badbd8f Make uvm_fault_unwire() take a vm_map_t, rather than a pmap_t, for
consistency.  Use this opportunity for checking for intrsafe map use
in this routine (which is illegal).
1999-05-28 20:49:51 +00:00
thorpej
108b13d5a9 Make "intrsafe" maps locked only by exclusive spin locks, never sleep
locks (and thus, never shared locks).  Move the "set/clear recursive"
functions to uvm_map.c, which is the only placed they're used (and
they should go away anyhow).  Delete some unused cruft.
1999-05-28 20:31:42 +00:00
thorpej
5920638afe Change the main comment block to indicate why PMAP_NEW (specifically,
pmap_kenter*()) is not required for {O,A}->K page loans.
1999-05-27 21:50:03 +00:00
thorpej
80de1e9903 Upon further investigation, in uvm_map_pageable(), entry->protection is the
right access_type to pass to uvm_fault_wire().  This way, if the entry has
VM_PROT_WRITE, and the entry is marked COW, the copy will happen immediately
in uvm_fault(), as if the access were performed.
1999-05-26 23:53:48 +00:00
thorpej
6b655611b1 Wired kernel mappings are wired; pass VM_PROT_READ|VM_PROT_WRITE for
access_type to pmap_enter() to ensure that when these mappings are accessed,
possibly in interrupt context, that they won't cause mod/ref emulation
page faults.
1999-05-26 19:27:49 +00:00
thorpej
2580d306ab Change the vm_map's "entries_pageable" member to a r/o flags member, which
has PAGEABLE and INTRSAFE flags.  PAGEABLE now really means "pageable",
not "allocate vm_map_entry's from non-static pool", so update all map
creations to reflect that.  INTRSAFE maps are maps that are used in
interrupt context (e.g. kmem_map, mb_map), and thus use the static
map entry pool (XXX as does kernel_map, for now).  This will eventually
change now these maps are locked, as well.
1999-05-26 19:16:28 +00:00