version 1.164.10.1, 2008/01/01 15:39:18 |
version 1.164.10.2, 2008/01/20 16:03:57 |
|
|
#include "opt_lockdebug.h" |
#include "opt_lockdebug.h" |
#include "opt_multiprocessor.h" |
#include "opt_multiprocessor.h" |
|
|
#include <sys/types.h> |
|
#include <sys/param.h> |
#include <sys/param.h> |
|
#include <sys/types.h> |
#include <sys/kernel.h> |
#include <sys/kernel.h> |
#include <sys/systm.h> |
#include <sys/systm.h> |
#include <sys/proc.h> |
#include <sys/proc.h> |
|
|
#include <sys/user.h> |
#include <sys/user.h> |
#include <sys/pool.h> |
#include <sys/pool.h> |
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
|
#include <sys/cpu.h> |
|
|
#include <uvm/uvm.h> |
#include <uvm/uvm.h> |
|
|
|
|
/* |
/* |
* main pv_entry manipulation functions: |
* main pv_entry manipulation functions: |
* pmap_enter_pv: enter a mapping onto a vm_page list |
* pmap_enter_pv: enter a mapping onto a vm_page list |
* pmap_remove_pv: remove a mappiing from a vm_page list |
* pmap_remove_pv: remove a mapping from a vm_page list |
* |
* |
* NOTE: pmap_enter_pv expects to lock the pvh itself |
* NOTE: pmap_enter_pv expects to lock the pvh itself |
* pmap_remove_pv expects te caller to lock the pvh before calling |
* pmap_remove_pv expects te caller to lock the pvh before calling |
Line 946 pmap_use_l1(pmap_t pm) |
|
Line 947 pmap_use_l1(pmap_t pm) |
|
* Access to an L1 by the kernel pmap must not affect |
* Access to an L1 by the kernel pmap must not affect |
* the LRU list. |
* the LRU list. |
*/ |
*/ |
if (current_intr_depth || pm == pmap_kernel()) |
if (cpu_intr_p() || pm == pmap_kernel()) |
return; |
return; |
|
|
l1 = pm->pm_l1; |
l1 = pm->pm_l1; |
Line 1299 pmap_get_vac_flags(const struct vm_page |
|
Line 1300 pmap_get_vac_flags(const struct vm_page |
|
{ |
{ |
int kidx, uidx; |
int kidx, uidx; |
|
|
|
if (pg->mdpage.pvh_list == NULL) |
|
return -1; |
|
|
kidx = 0; |
kidx = 0; |
if (pg->mdpage.kro_mappings || pg->mdpage.krw_mappings > 1) |
if (pg->mdpage.kro_mappings || pg->mdpage.krw_mappings > 1) |
kidx |= 1; |
kidx |= 1; |
Line 2250 pmap_enter(pmap_t pm, vaddr_t va, paddr_ |
|
Line 2254 pmap_enter(pmap_t pm, vaddr_t va, paddr_ |
|
* going to make _that_ much difference overall. |
* going to make _that_ much difference overall. |
*/ |
*/ |
|
|
#define PMAP_REMOVE_CLEAN_LIST_SIZE 3 |
#define PMAP_REMOVE_CLEAN_LIST_SIZE 10 |
|
|
void |
void |
pmap_do_remove(pmap_t pm, vaddr_t sva, vaddr_t eva, int skip_wired) |
pmap_do_remove(pmap_t pm, vaddr_t sva, vaddr_t eva, int skip_wired) |
Line 2263 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
Line 2267 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
vaddr_t va; |
vaddr_t va; |
pt_entry_t *pte; |
pt_entry_t *pte; |
} cleanlist[PMAP_REMOVE_CLEAN_LIST_SIZE]; |
} cleanlist[PMAP_REMOVE_CLEAN_LIST_SIZE]; |
u_int mappings, is_exec, is_refd; |
u_int mappings, pte_entries, is_exec, is_refd; |
|
|
NPDEBUG(PDB_REMOVE, printf("pmap_do_remove: pmap=%p sva=%08lx " |
NPDEBUG(PDB_REMOVE, printf("pmap_do_remove: pmap=%p sva=%08lx " |
"eva=%08lx\n", pm, sva, eva)); |
"eva=%08lx\n", pm, sva, eva)); |
Line 2284 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
Line 2288 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
total = 0; |
total = 0; |
|
|
while (sva < eva) { |
while (sva < eva) { |
|
pt_entry_t *startPteSync; |
|
bool need_pte_sync = false; |
/* |
/* |
* Do one L2 bucket's worth at a time. |
* Do one L2 bucket's worth at a time. |
*/ |
*/ |
Line 2297 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
Line 2303 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
continue; |
continue; |
} |
} |
|
|
ptep = &l2b->l2b_kva[l2pte_index(sva)]; |
startPteSync = ptep = &l2b->l2b_kva[l2pte_index(sva)]; |
|
|
for (mappings = 0; sva < next_bucket; sva += PAGE_SIZE, ptep++){ |
for (mappings = 0, pte_entries = 0; sva < next_bucket; |
|
sva += PAGE_SIZE, ptep++){ |
struct vm_page *pg; |
struct vm_page *pg; |
pt_entry_t pte; |
pt_entry_t pte; |
paddr_t pa; |
paddr_t pa; |
|
|
pte = *ptep; |
pte = *ptep; |
|
pte_entries++; |
|
|
if (pte == 0) { |
if (pte == 0) { |
/* Nothing here, move along */ |
/* Nothing here, move along */ |
Line 2357 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
Line 2365 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
PTE_SYNC_CURRENT(pm, ptep); |
PTE_SYNC_CURRENT(pm, ptep); |
continue; |
continue; |
} |
} |
|
need_pte_sync = true; |
|
|
if (cleanlist_idx < PMAP_REMOVE_CLEAN_LIST_SIZE) { |
if (cleanlist_idx < PMAP_REMOVE_CLEAN_LIST_SIZE) { |
/* Add to the clean list. */ |
/* Add to the clean list. */ |
Line 2368 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
Line 2377 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
if (cleanlist_idx == PMAP_REMOVE_CLEAN_LIST_SIZE) { |
if (cleanlist_idx == PMAP_REMOVE_CLEAN_LIST_SIZE) { |
/* Nuke everything if needed. */ |
/* Nuke everything if needed. */ |
pmap_idcache_wbinv_all(pm); |
pmap_idcache_wbinv_all(pm); |
pmap_tlb_flushID(pm); |
|
|
|
/* |
/* |
* Roll back the previous PTE list, |
* Roll back the previous PTE list, |
Line 2379 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
Line 2387 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
*cleanlist[cnt].pte = 0; |
*cleanlist[cnt].pte = 0; |
} |
} |
*ptep = 0; |
*ptep = 0; |
PTE_SYNC(ptep); |
|
cleanlist_idx++; |
cleanlist_idx++; |
pm->pm_remove_all = true; |
pm->pm_remove_all = true; |
} else { |
} else { |
*ptep = 0; |
*ptep = 0; |
PTE_SYNC(ptep); |
|
if (pm->pm_remove_all == false) { |
if (pm->pm_remove_all == false) { |
if (is_exec) |
if (is_exec) |
pmap_tlb_flushID_SE(pm, sva); |
pmap_tlb_flushID_SE(pm, sva); |
Line 2431 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
Line 2437 pmap_do_remove(pmap_t pm, vaddr_t sva, v |
|
pmap_idcache_wbinv_all(pm); |
pmap_idcache_wbinv_all(pm); |
pm->pm_remove_all = true; |
pm->pm_remove_all = true; |
} |
} |
|
} else if (need_pte_sync){ |
|
/* PTE_SYNC everything from this loop */ |
|
if (PMAP_NEEDS_PTE_SYNC && |
|
pmap_is_cached(pm)) |
|
{ |
|
PTE_SYNC_RANGE(startPteSync, pte_entries); |
|
#if 0 |
|
printf("pmap_remove: pte syncing %p, " |
|
"for %d entries and %d mappings\n", |
|
startPteSync, pte_entries, mappings); |
|
#endif |
|
} |
} |
} |
|
|
|
|
pmap_free_l2_bucket(pm, l2b, mappings); |
pmap_free_l2_bucket(pm, l2b, mappings); |
pm->pm_stats.resident_count -= mappings; |
pm->pm_stats.resident_count -= mappings; |
} |
} |