version 1.191, 2011/11/28 14:06:59 |
version 1.191.2.1, 2012/02/18 07:35:58 |
Line 169 static const struct uvm_advice uvmadvice |
|
Line 169 static const struct uvm_advice uvmadvice |
|
*/ |
*/ |
|
|
/* |
/* |
|
* externs from other modules |
|
*/ |
|
|
|
extern int start_init_exec; /* Is init_main() done / init running? */ |
|
|
|
/* |
* inline functions |
* inline functions |
*/ |
*/ |
|
|
Line 583 uvmfault_promote(struct uvm_faultinfo *u |
|
Line 589 uvmfault_promote(struct uvm_faultinfo *u |
|
if (*spare != NULL) { |
if (*spare != NULL) { |
anon = *spare; |
anon = *spare; |
*spare = NULL; |
*spare = NULL; |
} else if (ufi->map != kernel_map) { |
|
anon = uvm_analloc(); |
|
} else { |
} else { |
UVMHIST_LOG(maphist, "kernel_map, unlock and retry", 0,0,0,0); |
anon = uvm_analloc(); |
|
|
/* |
|
* we can't allocate anons with kernel_map locked. |
|
*/ |
|
|
|
uvm_page_unbusy(&uobjpage, 1); |
|
uvmfault_unlockall(ufi, amap, uobj); |
|
|
|
*spare = uvm_analloc(); |
|
if (*spare == NULL) { |
|
goto nomem; |
|
} |
|
KASSERT((*spare)->an_lock == NULL); |
|
error = ERESTART; |
|
goto done; |
|
} |
} |
if (anon) { |
if (anon) { |
|
|
Line 636 uvmfault_promote(struct uvm_faultinfo *u |
|
Line 625 uvmfault_promote(struct uvm_faultinfo *u |
|
/* unlock and fail ... */ |
/* unlock and fail ... */ |
uvm_page_unbusy(&uobjpage, 1); |
uvm_page_unbusy(&uobjpage, 1); |
uvmfault_unlockall(ufi, amap, uobj); |
uvmfault_unlockall(ufi, amap, uobj); |
nomem: |
|
if (!uvm_reclaimable()) { |
if (!uvm_reclaimable()) { |
UVMHIST_LOG(maphist, "out of VM", 0,0,0,0); |
UVMHIST_LOG(maphist, "out of VM", 0,0,0,0); |
uvmexp.fltnoanon++; |
uvmexp.fltnoanon++; |
|
|
uvm_fault_internal(struct vm_map *orig_map, vaddr_t vaddr, |
uvm_fault_internal(struct vm_map *orig_map, vaddr_t vaddr, |
vm_prot_t access_type, int fault_flag) |
vm_prot_t access_type, int fault_flag) |
{ |
{ |
|
struct cpu_data *cd; |
|
struct uvm_cpu *ucpu; |
struct uvm_faultinfo ufi; |
struct uvm_faultinfo ufi; |
struct uvm_faultctx flt = { |
struct uvm_faultctx flt = { |
.access_type = access_type, |
.access_type = access_type, |
Line 813 uvm_fault_internal(struct vm_map *orig_m |
|
Line 803 uvm_fault_internal(struct vm_map *orig_m |
|
struct vm_anon *anons_store[UVM_MAXRANGE], **anons; |
struct vm_anon *anons_store[UVM_MAXRANGE], **anons; |
struct vm_page *pages_store[UVM_MAXRANGE], **pages; |
struct vm_page *pages_store[UVM_MAXRANGE], **pages; |
int error; |
int error; |
|
#if 0 |
|
uintptr_t delta, delta2, delta3; |
|
#endif |
UVMHIST_FUNC("uvm_fault"); UVMHIST_CALLED(maphist); |
UVMHIST_FUNC("uvm_fault"); UVMHIST_CALLED(maphist); |
|
|
UVMHIST_LOG(maphist, "(map=0x%x, vaddr=0x%x, at=%d, ff=%d)", |
UVMHIST_LOG(maphist, "(map=0x%x, vaddr=0x%x, at=%d, ff=%d)", |
orig_map, vaddr, access_type, fault_flag); |
orig_map, vaddr, access_type, fault_flag); |
|
|
curcpu()->ci_data.cpu_nfault++; |
cd = &(curcpu()->ci_data); |
|
cd->cpu_nfault++; |
|
ucpu = cd->cpu_uvm; |
|
|
|
/* Don't flood RNG subsystem with samples. */ |
|
if (cd->cpu_nfault % 503) |
|
goto norng; |
|
#if 0 |
|
/* |
|
* Avoid trying to count "entropy" for accesses of regular |
|
* stride, by checking the 1st, 2nd, 3rd order differentials |
|
* of vaddr, like the rnd code does internally with sample times. |
|
* |
|
* XXX If the selection of only every 503rd fault above is |
|
* XXX removed, this code should exclude most samples, but |
|
* XXX does not, and is therefore disabled. |
|
*/ |
|
if (ucpu->last_fltaddr > (uintptr_t)trunc_page(vaddr)) |
|
delta = ucpu->last_fltaddr - (uintptr_t)trunc_page(vaddr); |
|
else |
|
delta = (uintptr_t)trunc_page(vaddr) - ucpu->last_fltaddr; |
|
|
|
if (ucpu->last_delta > delta) |
|
delta2 = ucpu->last_delta - delta; |
|
else |
|
delta2 = delta - ucpu->last_delta; |
|
|
|
if (ucpu->last_delta2 > delta2) |
|
delta3 = ucpu->last_delta2 - delta2; |
|
else |
|
delta3 = delta2 - ucpu->last_delta2; |
|
|
|
ucpu->last_fltaddr = (uintptr_t)vaddr; |
|
ucpu->last_delta = delta; |
|
ucpu->last_delta2 = delta2; |
|
|
|
if (delta != 0 && delta2 != 0 && delta3 != 0) |
|
#endif |
|
/* Don't count anything until user interaction is possible */ |
|
if (__predict_true(start_init_exec)) { |
|
kpreempt_disable(); |
|
rnd_add_uint32(&ucpu->rs, |
|
sizeof(vaddr_t) == sizeof(uint32_t) ? |
|
(uint32_t)vaddr : sizeof(vaddr_t) == |
|
sizeof(uint64_t) ? |
|
(uint32_t)(vaddr & 0x00000000ffffffff) : |
|
(uint32_t)(cd->cpu_nfault & 0x00000000ffffffff)); |
|
kpreempt_enable(); |
|
} |
|
norng: |
/* |
/* |
* init the IN parameters in the ufi |
* init the IN parameters in the ufi |
*/ |
*/ |