Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151380601
D55312.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D55312.id.diff
View Options
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -147,6 +147,19 @@
#define PV_LOCK_RD_ASSERT(pa) rw_assert(PV_LOCKPTR(pa), RA_RLOCKED)
#define PV_LOCK_WR_ASSERT(pa) rw_assert(PV_LOCKPTR(pa), RA_WLOCKED)
+#define CHANGE_PV_LIST_WR_LOCK_TO_PHYS(lockp, pa) do { \
+ struct rwlock **_lockp = (lockp); \
+ struct rwlock *_new_lock; \
+ \
+ _new_lock = PV_LOCKPTR(pa); \
+ if (_new_lock != *_lockp) { \
+ if (*_lockp != NULL) \
+ rw_unlock(*_lockp); \
+ *_lockp = _new_lock; \
+ rw_wlock(*lockp); \
+ } \
+} while (0)
+
#define PV_PAGE_WR_LOCK(m) PV_WR_LOCK(VM_PAGE_TO_PHYS(m))
#define PV_PAGE_RD_LOCK(m) PV_RD_LOCK(VM_PAGE_TO_PHYS(m))
#define PV_PAGE_UNLOCK(m) PV_UNLOCK(VM_PAGE_TO_PHYS(m))
@@ -250,6 +263,8 @@
struct pvo_head *pvo_head, struct pvo_entry **oldpvo);
static void moea64_pvo_remove_from_pmap(struct pvo_entry *pvo);
static void moea64_pvo_remove_from_page(struct pvo_entry *pvo);
+static void moea64_pvo_remove_from_page_single_locked(struct pvo_entry *pvo,
+ struct rwlock **lockp);
static void moea64_pvo_remove_from_page_locked(
struct pvo_entry *pvo, vm_page_t m);
static struct pvo_entry *moea64_pvo_find_va(pmap_t, vm_offset_t);
@@ -328,8 +343,9 @@
static void moea64_align_superpage(vm_object_t, vm_ooffset_t,
vm_offset_t *, vm_size_t);
-static int moea64_sp_enter(pmap_t pmap, vm_offset_t va,
- vm_page_t m, vm_prot_t prot, u_int flags, int8_t psind);
+static int moea64_sp_enter_single(pmap_t pmap, vm_offset_t va,
+ vm_page_t m, vm_prot_t prot, u_int flags, int8_t psind,
+ struct rwlock **lockp);
static struct pvo_entry *moea64_sp_remove(struct pvo_entry *sp,
struct pvo_dlist *tofree);
@@ -360,6 +376,8 @@
vm_page_t *mb, vm_offset_t b_offset, int xfersize);
void moea64_copy_pages_dmap(vm_page_t *ma, vm_offset_t a_offset,
vm_page_t *mb, vm_offset_t b_offset, int xfersize);
+static int moea64_enter_single(pmap_t, vm_offset_t, vm_page_t, vm_prot_t,
+ u_int flags, int8_t psind, struct rwlock **lockp);
int moea64_enter(pmap_t, vm_offset_t, vm_page_t, vm_prot_t,
u_int flags, int8_t psind);
void moea64_enter_object(pmap_t, vm_offset_t, vm_offset_t, vm_page_t,
@@ -1611,8 +1629,8 @@
*/
int
-moea64_enter(pmap_t pmap, vm_offset_t va, vm_page_t m,
- vm_prot_t prot, u_int flags, int8_t psind)
+moea64_enter_single(pmap_t pmap, vm_offset_t va, vm_page_t m,
+ vm_prot_t prot, u_int flags, int8_t psind, struct rwlock **lockp)
{
struct pvo_entry *pvo, *oldpvo, *tpvo;
struct pvo_head *pvo_head;
@@ -1628,7 +1646,8 @@
}
if (psind > 0)
- return (moea64_sp_enter(pmap, va, m, prot, flags, psind));
+ return (moea64_sp_enter_single(pmap, va, m, prot, flags,
+ psind, lockp));
pvo = alloc_pvo_entry(0);
if (pvo == NULL)
@@ -1650,7 +1669,8 @@
pvo->pvo_vaddr |= PVO_MANAGED;
}
- PV_WR_LOCK(pa);
+ CHANGE_PV_LIST_WR_LOCK_TO_PHYS(lockp, pa);
+
PMAP_LOCK(pmap);
if (pvo->pvo_pmap == NULL)
init_pvo_entry(pvo, pmap, va);
@@ -1685,7 +1705,6 @@
/* Then just clean up and go home */
PMAP_UNLOCK(pmap);
- PV_UNLOCK(pa);
free_pvo_entry(pvo);
pvo = NULL;
goto out;
@@ -1698,11 +1717,10 @@
}
}
PMAP_UNLOCK(pmap);
- PV_UNLOCK(pa);
/* Free any dead pages */
if (error == EEXIST) {
- moea64_pvo_remove_from_page(oldpvo);
+ moea64_pvo_remove_from_page_single_locked(oldpvo, lockp);
free_pvo_entry(oldpvo);
}
@@ -1740,6 +1758,20 @@
return (KERN_SUCCESS);
}
+int
+moea64_enter(pmap_t pmap, vm_offset_t va, vm_page_t m,
+ vm_prot_t prot, u_int flags, int8_t psind)
+{
+ struct rwlock *lock = NULL;
+ int ret;
+
+ ret = moea64_enter_single(pmap, va, m, prot, flags, psind, &lock);
+ if (lock != NULL)
+ rw_unlock(lock);
+
+ return (ret);
+}
+
static void
moea64_syncicache(pmap_t pmap, vm_offset_t va, vm_paddr_t pa,
vm_size_t sz)
@@ -1793,6 +1825,7 @@
moea64_enter_object(pmap_t pm, vm_offset_t start, vm_offset_t end,
vm_page_t m_start, vm_prot_t prot)
{
+ struct rwlock *lock = NULL;
struct pctrie_iter pages;
vm_page_t m;
vm_offset_t va;
@@ -1803,6 +1836,7 @@
vm_page_iter_limit_init(&pages, m_start->object,
m_start->pindex + atop(end - start));
m = vm_radix_iter_lookup(&pages, m_start->pindex);
+
while (m != NULL) {
va = start + ptoa(m->pindex - m_start->pindex);
if ((va & HPT_SP_MASK) == 0 && va + HPT_SP_SIZE <= end &&
@@ -1810,14 +1844,16 @@
psind = 1;
else
psind = 0;
- moea64_enter(pm, va, m, prot &
+ moea64_enter_single(pm, va, m, prot &
(VM_PROT_READ | VM_PROT_EXECUTE),
- PMAP_ENTER_NOSLEEP | PMAP_ENTER_QUICK_LOCKED, psind);
+ PMAP_ENTER_NOSLEEP | PMAP_ENTER_QUICK_LOCKED, psind, &lock);
if (psind == 1)
m = vm_radix_iter_jump(&pages, HPT_SP_SIZE / PAGE_SIZE);
else
m = vm_radix_iter_step(&pages);
}
+ if (lock != NULL)
+ rw_unlock(lock);
}
void
@@ -2665,6 +2701,7 @@
{
struct pvo_entry *pvo, *tpvo;
struct pvo_dlist tofree;
+ struct rwlock *lock = NULL;
SLIST_INIT(&tofree);
@@ -2686,9 +2723,12 @@
while (!SLIST_EMPTY(&tofree)) {
pvo = SLIST_FIRST(&tofree);
SLIST_REMOVE_HEAD(&tofree, pvo_dlink);
- moea64_pvo_remove_from_page(pvo);
+ moea64_pvo_remove_from_page_single_locked(pvo, &lock);
free_pvo_entry(pvo);
}
+
+ if (lock != NULL)
+ rw_unlock(lock);
}
static void
@@ -2732,6 +2772,7 @@
{
struct pvo_entry *pvo;
struct pvo_dlist tofree;
+ struct rwlock *lock = NULL;
/*
* Perform an unsynchronized read. This is, however, safe.
@@ -2747,9 +2788,12 @@
while (!SLIST_EMPTY(&tofree)) {
pvo = SLIST_FIRST(&tofree);
SLIST_REMOVE_HEAD(&tofree, pvo_dlink);
- moea64_pvo_remove_from_page(pvo);
+ moea64_pvo_remove_from_page_single_locked(pvo, &lock);
free_pvo_entry(pvo);
}
+
+ if (lock != NULL)
+ rw_unlock(lock);
}
/*
@@ -2994,6 +3038,19 @@
PV_UNLOCK(PVO_PADDR(pvo));
}
+static void
+moea64_pvo_remove_from_page_single_locked(struct pvo_entry *pvo,
+ struct rwlock **lockp)
+{
+ vm_page_t pg = NULL;
+
+ if (pvo->pvo_vaddr & PVO_MANAGED)
+ pg = PHYS_TO_VM_PAGE(PVO_PADDR(pvo));
+
+ CHANGE_PV_LIST_WR_LOCK_TO_PHYS(lockp, PVO_PADDR(pvo));
+ moea64_pvo_remove_from_page_locked(pvo, pg);
+}
+
static struct pvo_entry *
moea64_pvo_find_va(pmap_t pm, vm_offset_t va)
{
@@ -3569,7 +3626,7 @@
/* Helpers */
static __inline void
-moea64_pvo_cleanup(struct pvo_dlist *tofree)
+moea64_pvo_cleanup_locked(struct pvo_dlist *tofree, struct rwlock **lockp)
{
struct pvo_entry *pvo;
@@ -3578,7 +3635,7 @@
pvo = SLIST_FIRST(tofree);
SLIST_REMOVE_HEAD(tofree, pvo_dlink);
if (pvo->pvo_vaddr & PVO_DEAD)
- moea64_pvo_remove_from_page(pvo);
+ moea64_pvo_remove_from_page_single_locked(pvo, lockp);
free_pvo_entry(pvo);
}
}
@@ -3646,8 +3703,8 @@
/* Superpage ops */
static int
-moea64_sp_enter(pmap_t pmap, vm_offset_t va, vm_page_t m,
- vm_prot_t prot, u_int flags, int8_t psind)
+moea64_sp_enter_single(pmap_t pmap, vm_offset_t va, vm_page_t m,
+ vm_prot_t prot, u_int flags, int8_t psind, struct rwlock **lockp)
{
struct pvo_entry *pvo, **pvos;
struct pvo_head *pvo_head;
@@ -3696,7 +3753,7 @@
}
}
- PV_WR_LOCK(spa);
+ CHANGE_PV_LIST_WR_LOCK_TO_PHYS(lockp, spa);
PMAP_LOCK(pmap);
/* Note: moea64_remove_locked() also clears cached REF/CHG bits. */
@@ -3735,11 +3792,11 @@
}
PMAP_UNLOCK(pmap);
- PV_UNLOCK(spa);
sync = (sm->a.flags & PGA_EXECUTABLE) == 0;
/* Note: moea64_pvo_cleanup() also clears page prot. flags. */
- moea64_pvo_cleanup(&tofree);
+ moea64_pvo_cleanup_locked(&tofree, lockp);
+
pvo = pvos[0];
/* Set vm page flags */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 9, 12:43 AM (8 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28819827
Default Alt Text
D55312.id.diff (7 KB)
Attached To
Mode
D55312: powerpc: implement lock iteration for mmu_oea64 pmap
Attached
Detach File
Event Timeline
Log In to Comment