mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-07 09:00:28 +00:00
Do not access pv_table array for fictitious pages, since the array
does not cover the dynamically registered ficititious ranges, and fictitious pages mappings are not promoted. Offer a dummy struct md_page to fetch constant superpage pv list generation to satisfy logic. Also, by initializing the pv_dummy pv_list to empty, we can remove several explicit PG_FICTITIOUS tests. Reported and tested by: Michael Butler <imb@protected-networks.net> (previous version) Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D6728 Approved by: re (hrs)
This commit is contained in:
parent
eb4d6a1b3b
commit
b9c8a54dc3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=301853
|
@ -386,6 +386,7 @@ static struct mtx pv_chunks_mutex;
|
|||
static struct rwlock pv_list_locks[NPV_LIST_LOCKS];
|
||||
static u_long pv_invl_gen[NPV_LIST_LOCKS];
|
||||
static struct md_page *pv_table;
|
||||
static struct md_page pv_dummy;
|
||||
|
||||
/*
|
||||
* All those kernel PT submaps that BSD is so fond of
|
||||
|
@ -1264,6 +1265,7 @@ pmap_init(void)
|
|||
M_WAITOK | M_ZERO);
|
||||
for (i = 0; i < pv_npg; i++)
|
||||
TAILQ_INIT(&pv_table[i].pv_list);
|
||||
TAILQ_INIT(&pv_dummy.pv_list);
|
||||
|
||||
pmap_initialized = 1;
|
||||
for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) {
|
||||
|
@ -3920,11 +3922,10 @@ pmap_remove_all(vm_page_t m)
|
|||
("pmap_remove_all: page %p is not managed", m));
|
||||
SLIST_INIT(&free);
|
||||
lock = VM_PAGE_TO_PV_LIST_LOCK(m);
|
||||
pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
|
||||
pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy :
|
||||
pa_to_pvh(VM_PAGE_TO_PHYS(m));
|
||||
retry:
|
||||
rw_wlock(lock);
|
||||
if ((m->flags & PG_FICTITIOUS) != 0)
|
||||
goto small_mappings;
|
||||
while ((pv = TAILQ_FIRST(&pvh->pv_list)) != NULL) {
|
||||
pmap = PV_PMAP(pv);
|
||||
if (!PMAP_TRYLOCK(pmap)) {
|
||||
|
@ -3943,7 +3944,6 @@ pmap_remove_all(vm_page_t m)
|
|||
(void)pmap_demote_pde_locked(pmap, pde, va, &lock);
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
small_mappings:
|
||||
while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
|
||||
pmap = PV_PMAP(pv);
|
||||
if (!PMAP_TRYLOCK(pmap)) {
|
||||
|
@ -5743,11 +5743,10 @@ pmap_remove_write(vm_page_t m)
|
|||
if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
|
||||
return;
|
||||
lock = VM_PAGE_TO_PV_LIST_LOCK(m);
|
||||
pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
|
||||
pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy :
|
||||
pa_to_pvh(VM_PAGE_TO_PHYS(m));
|
||||
retry_pv_loop:
|
||||
rw_wlock(lock);
|
||||
if ((m->flags & PG_FICTITIOUS) != 0)
|
||||
goto small_mappings;
|
||||
TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_next, next_pv) {
|
||||
pmap = PV_PMAP(pv);
|
||||
if (!PMAP_TRYLOCK(pmap)) {
|
||||
|
@ -5771,7 +5770,6 @@ pmap_remove_write(vm_page_t m)
|
|||
lock, VM_PAGE_TO_PV_LIST_LOCK(m), m));
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
small_mappings:
|
||||
TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
|
||||
pmap = PV_PMAP(pv);
|
||||
if (!PMAP_TRYLOCK(pmap)) {
|
||||
|
@ -5877,12 +5875,11 @@ pmap_ts_referenced(vm_page_t m)
|
|||
cleared = 0;
|
||||
pa = VM_PAGE_TO_PHYS(m);
|
||||
lock = PHYS_TO_PV_LIST_LOCK(pa);
|
||||
pvh = pa_to_pvh(pa);
|
||||
pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy : pa_to_pvh(pa);
|
||||
rw_wlock(lock);
|
||||
retry:
|
||||
not_cleared = 0;
|
||||
if ((m->flags & PG_FICTITIOUS) != 0 ||
|
||||
(pvf = TAILQ_FIRST(&pvh->pv_list)) == NULL)
|
||||
if ((pvf = TAILQ_FIRST(&pvh->pv_list)) == NULL)
|
||||
goto small_mappings;
|
||||
pv = pvf;
|
||||
do {
|
||||
|
@ -6194,12 +6191,11 @@ pmap_clear_modify(vm_page_t m)
|
|||
*/
|
||||
if ((m->aflags & PGA_WRITEABLE) == 0)
|
||||
return;
|
||||
pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m));
|
||||
pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy :
|
||||
pa_to_pvh(VM_PAGE_TO_PHYS(m));
|
||||
lock = VM_PAGE_TO_PV_LIST_LOCK(m);
|
||||
rw_wlock(lock);
|
||||
restart:
|
||||
if ((m->flags & PG_FICTITIOUS) != 0)
|
||||
goto small_mappings;
|
||||
TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_next, next_pv) {
|
||||
pmap = PV_PMAP(pv);
|
||||
if (!PMAP_TRYLOCK(pmap)) {
|
||||
|
@ -6243,7 +6239,6 @@ pmap_clear_modify(vm_page_t m)
|
|||
}
|
||||
PMAP_UNLOCK(pmap);
|
||||
}
|
||||
small_mappings:
|
||||
TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
|
||||
pmap = PV_PMAP(pv);
|
||||
if (!PMAP_TRYLOCK(pmap)) {
|
||||
|
|
Loading…
Reference in a new issue