svn commit: r366046 - head/sys/powerpc/aim

Brandon Bergren bdragon at FreeBSD.org
Wed Sep 23 01:33:55 UTC 2020


Author: bdragon
Date: Wed Sep 23 01:33:54 2020
New Revision: 366046
URL: https://svnweb.freebsd.org/changeset/base/366046

Log:
  [PowerPC64LE] Implement endian-independent dword atomic PTE lock.
  
  It's much easier to implement this in an endian-independent way when we
  don't also have to worry about masking half of the dword off.
  
  Given that this code ran on a machine that ran a poudriere bulk with no
  kernel oddities, I am relatively certain it is correctly implemented. ;)
  
  This should be a minor performance boost on BE as well.
  
  Sponsored by:	Tag1 Consulting, Inc.

Modified:
  head/sys/powerpc/aim/moea64_native.c

Modified: head/sys/powerpc/aim/moea64_native.c
==============================================================================
--- head/sys/powerpc/aim/moea64_native.c	Wed Sep 23 01:29:33 2020	(r366045)
+++ head/sys/powerpc/aim/moea64_native.c	Wed Sep 23 01:33:54 2020	(r366046)
@@ -633,15 +633,46 @@ static int
 atomic_pte_lock(volatile struct lpte *pte, uint64_t bitmask, uint64_t *oldhi)
 {
 	int	ret;
+#ifdef __powerpc64__
+	uint64_t temp;
+#else
 	uint32_t oldhihalf;
+#endif
 
 	/*
 	 * Note: in principle, if just the locked bit were set here, we
 	 * could avoid needing the eviction lock. However, eviction occurs
 	 * so rarely that it isn't worth bothering about in practice.
 	 */
-
+#ifdef __powerpc64__
+	/*
+	 * Note: Success of this sequence has the side effect of invalidating
+	 * the PTE, as we are setting it to LPTE_LOCKED and discarding the
+	 * other bits, including LPTE_V.
+	 */
 	__asm __volatile (
+		"1:\tldarx %1, 0, %3\n\t"	/* load old value */
+		"and. %0,%1,%4\n\t"		/* check if any bits set */
+		"bne 2f\n\t"			/* exit if any set */
+		"stdcx. %5, 0, %3\n\t"		/* attempt to store */
+		"bne- 1b\n\t"			/* spin if failed */
+		"li %0, 1\n\t"			/* success - retval = 1 */
+		"b 3f\n\t"			/* we've succeeded */
+		"2:\n\t"
+		"stdcx. %1, 0, %3\n\t"       	/* clear reservation (74xx) */
+		"li %0, 0\n\t"			/* failure - retval = 0 */
+		"3:\n\t"
+		: "=&r" (ret), "=&r"(temp), "=m" (pte->pte_hi)
+		: "r" ((volatile char *)&pte->pte_hi),
+		  "r" (htobe64(bitmask)), "r" (htobe64(LPTE_LOCKED)),
+		  "m" (pte->pte_hi)
+		: "cr0", "cr1", "cr2", "memory");
+	*oldhi = be64toh(temp);
+#else
+	/*
+	 * This code is used on bridge mode only.
+	 */
+	__asm __volatile (
 		"1:\tlwarx %1, 0, %3\n\t"	/* load old value */
 		"and. %0,%1,%4\n\t"		/* check if any bits set */
 		"bne 2f\n\t"			/* exit if any set */
@@ -660,6 +691,7 @@ atomic_pte_lock(volatile struct lpte *pte, uint64_t bi
 		: "cr0", "cr1", "cr2", "memory");
 
 	*oldhi = (pte->pte_hi & 0xffffffff00000000ULL) | oldhihalf;
+#endif
 
 	return (ret);
 }


More information about the svn-src-head mailing list