Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Jun 2012 20:25:13 +0000 (UTC)
From:      Alan Cox <alc@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r237855 - in head/sys/amd64: amd64 include
Message-ID:  <201206302025.q5UKPDav039907@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alc
Date: Sat Jun 30 20:25:12 2012
New Revision: 237855
URL: http://svn.freebsd.org/changeset/base/237855

Log:
  Optimize reserve_pv_entries() using the popcnt instruction.

Modified:
  head/sys/amd64/amd64/pmap.c
  head/sys/amd64/include/cpufunc.h

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c	Sat Jun 30 20:23:59 2012	(r237854)
+++ head/sys/amd64/amd64/pmap.c	Sat Jun 30 20:25:12 2012	(r237855)
@@ -2408,9 +2408,15 @@ reserve_pv_entries(pmap_t pmap, int need
 retry:
 	avail = 0;
 	TAILQ_FOREACH(pc, &pmap->pm_pvchunk, pc_list) {
-		free = popcnt_pc_map_elem(pc->pc_map[0]);
-		free += popcnt_pc_map_elem(pc->pc_map[1]);
-		free += popcnt_pc_map_elem(pc->pc_map[2]);
+		if ((cpu_feature2 & CPUID2_POPCNT) == 0) {
+			free = popcnt_pc_map_elem(pc->pc_map[0]);
+			free += popcnt_pc_map_elem(pc->pc_map[1]);
+			free += popcnt_pc_map_elem(pc->pc_map[2]);
+		} else {
+			free = popcntq(pc->pc_map[0]);
+			free += popcntq(pc->pc_map[1]);
+			free += popcntq(pc->pc_map[2]);
+		}
 		if (free == 0)
 			break;
 		avail += free;

Modified: head/sys/amd64/include/cpufunc.h
==============================================================================
--- head/sys/amd64/include/cpufunc.h	Sat Jun 30 20:23:59 2012	(r237854)
+++ head/sys/amd64/include/cpufunc.h	Sat Jun 30 20:25:12 2012	(r237855)
@@ -273,6 +273,15 @@ outw(u_int port, u_short data)
 	__asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port));
 }
 
+static __inline u_long
+popcntq(u_long mask)
+{
+	u_long result;
+
+	__asm __volatile("popcntq %1,%0" : "=r" (result) : "rm" (mask));
+	return (result);
+}
+
 static __inline void
 mfence(void)
 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206302025.q5UKPDav039907>