Subject: uvm_vslock / uvm_vsunlock problems
To: None <tech-kern@netbsd.org>
From: Stephan Uphoff <ups@stups.com>
List: tech-kern
Date: 07/10/2003 19:30:37
Hi,

uvm_vslock() is used in physio and sys___sysctl to wire user process memory.
uvm_vsunlock() later unwires the memory if it is not in a wired map entry.

Problem 1:
-----------
uvm_vslock assumes that once a page is wired - it will stay wired until
uvm_vsunlock (potentially) unwires it.
This is not true for mmaped file pages when the file is truncated.
(All managed mappings are released - page is freed)

Problem 2:
----------
The uvm_vslock() / uvm_vsunlock() pair assumes only one thread 
of control per address space.
Because of clone(2) or scheduler activations (lwps) this is no longer always
true.

Problem 3:
----------
uvm_vslock indirectly calls uvm_fault.
If uvm_fault is called without an VM_PROT_WRITE 
bit in accesstype to wire a loaned page it will not
break the loan.
This can cause the buffer created by physio to eventual map to the
wrong pages and could break a KASSERT in uvm_pagefree.


Solutions:
----------
sys___sysctl can probably use a kernel buffer for the (hopefully few) 
occasions
where copying is not allowed to block. (And copyout from the kernel buffer
when it is save to do so)
( I assume this is the reason for the wiring but was too lazy to verify ) 

The uvm_fault problem (3) could be fixed by always breaking loans on wire 
faults.

I believe due to the first two problems physio can not be made to work 
correctly without resorting to mechanisms closely related to page loaning. 
(or the use of bounce buffers :-)
Unfortunately this will need a major effort.


	Stephan