arm pmap locking

Alan Cox alc at rice.edu
Thu Sep 27 16:29:23 UTC 2012


On 09/26/2012 01:13, John-Mark Gurney wrote:
> Alan Cox wrote this message on Tue, Sep 25, 2012 at 10:50 -0500:
>> On 09/16/2012 22:33, John-Mark Gurney wrote:
>>> Still getting the LOR..  It always right after boot..  after trying
>>> to mount root and warning about no time-of-day clock, but before setting
>>> hostuuid..
>> Could you please try the attached patch on your armv6 BEAGLEBONE?  My
>> hope is that this addresses the root cause of the LORs involving the
>> pmap lock.
> Good news...  That patch boots and doesn't have the LOR...
>
> FreeBSD 10.0-CURRENT #10 r240947M: Mon Sep 24 17:01:11 PDT 2012
>      jmg at pcbsd-779:/usr/obj/arm.armv6/usr/src.HEAD/sys/helium arm
>
> [...]
>
> Trying to mount root from ufs:mmcsd0s2 []...
> warning: no time-of-day clock registered, system time will not be set accurately
> Setting hostuuid: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
>
> Thanks for your work tracking it down!
>

Great.  Now that the LOR is out of the way, let's try further 
simplifications to the locking.  I don't believe that 
pmap_alloc_l2_bucket() needs to unlock and relock around every 
allocation.  Here is another patch to eliminate that.  Also, the patch 
replaces an explicit bzero() call with M_ZERO.

Alan

-------------- next part --------------
Index: arm/arm/pmap-v6.c
===================================================================
--- arm/arm/pmap-v6.c	(revision 240983)
+++ arm/arm/pmap-v6.c	(working copy)
@@ -607,36 +607,20 @@ pmap_alloc_l2_bucket(pmap_t pm, vm_offset_t va)
 	l1idx = L1_IDX(va);
 
 	PMAP_ASSERT_LOCKED(pm);
-	rw_assert(&pvh_global_lock, RA_WLOCKED);
 	if ((l2 = pm->pm_l2[L2_IDX(l1idx)]) == NULL) {
 		/*
 		 * No mapping at this address, as there is
 		 * no entry in the L1 table.
 		 * Need to allocate a new l2_dtable.
 		 */
-		PMAP_UNLOCK(pm);
-		rw_wunlock(&pvh_global_lock);
-		if ((l2 = uma_zalloc(l2table_zone, M_NOWAIT)) == NULL) {
-			rw_wlock(&pvh_global_lock);
-			PMAP_LOCK(pm);
+		l2 = uma_zalloc(l2table_zone, M_NOWAIT | M_ZERO);
+		if (l2 == NULL)
 			return (NULL);
-		}
-		rw_wlock(&pvh_global_lock);
-		PMAP_LOCK(pm);
-		if (pm->pm_l2[L2_IDX(l1idx)] != NULL) {
-			/*
-			 * Someone already allocated the l2_dtable while
-			 * we were doing the same.
-			 */
-			uma_zfree(l2table_zone, l2);
-			l2 = pm->pm_l2[L2_IDX(l1idx)];
-		} else {
-			bzero(l2, sizeof(*l2));
-			/*
-			 * Link it into the parent pmap
-			 */
-			pm->pm_l2[L2_IDX(l1idx)] = l2;
-		}
+
+		/*
+		 * Link it into the parent pmap.
+		 */
+		pm->pm_l2[L2_IDX(l1idx)] = l2;
 	}
 
 	l2b = &l2->l2_bucket[L2_BUCKET(l1idx)];
@@ -651,17 +635,7 @@ pmap_alloc_l2_bucket(pmap_t pm, vm_offset_t va)
 		 * No L2 page table has been allocated. Chances are, this
 		 * is because we just allocated the l2_dtable, above.
 		 */
-		PMAP_UNLOCK(pm);
-		rw_wunlock(&pvh_global_lock);
 		ptep = uma_zalloc(l2zone, M_NOWAIT);
-		rw_wlock(&pvh_global_lock);
-		PMAP_LOCK(pm);
-		if (l2b->l2b_kva != 0) {
-			/* We lost the race. */
-			uma_zfree(l2zone, ptep);
-			return (l2b);
-		}
-		l2b->l2b_phys = vtophys(ptep);
 		if (ptep == NULL) {
 			/*
 			 * Oops, no more L2 page tables available at this
@@ -677,6 +651,7 @@ pmap_alloc_l2_bucket(pmap_t pm, vm_offset_t va)
 
 		l2->l2_occupancy++;
 		l2b->l2b_kva = ptep;
+		l2b->l2b_phys = pmap_kextract((vm_offset_t)ptep);
 		l2b->l2b_l1idx = l1idx;
 	}
 


More information about the freebsd-arm mailing list