about summary refs log tree commit diff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-05-13 07:18:25 -0700
committerH.J. Lu <hjl.tools@gmail.com>2016-06-06 13:17:30 -0700
commit6118b2d23016ec790b99b9331c3d7a45d588134e (patch)
tree1927e709e0f673d6140cb484f19f4311725621d4
parent8642c9a553d8ce8a3a0496ed11fed5a575d338c5 (diff)
downloadglibc-6118b2d23016ec790b99b9331c3d7a45d588134e.tar.gz
glibc-6118b2d23016ec790b99b9331c3d7a45d588134e.tar.xz
glibc-6118b2d23016ec790b99b9331c3d7a45d588134e.zip
Support non-inclusive caches on Intel processors
	* sysdeps/x86/cacheinfo.c (init_cacheinfo): Check and support
	non-inclusive caches on Intel processors.
-rw-r--r--sysdeps/x86/cacheinfo.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sysdeps/x86/cacheinfo.c b/sysdeps/x86/cacheinfo.c
index ba29beeee2..df813cfcd7 100644
--- a/sysdeps/x86/cacheinfo.c
+++ b/sysdeps/x86/cacheinfo.c
@@ -492,6 +492,9 @@ init_cacheinfo (void)
     {
       data = handle_intel (_SC_LEVEL1_DCACHE_SIZE, max_cpuid);
 
+      long int core = handle_intel (_SC_LEVEL2_CACHE_SIZE, max_cpuid);
+      bool inclusive_cache = true;
+
       /* Try L3 first.  */
       level  = 3;
       shared = handle_intel (_SC_LEVEL3_CACHE_SIZE, max_cpuid);
@@ -500,7 +503,7 @@ init_cacheinfo (void)
 	{
 	  /* Try L2 otherwise.  */
 	  level  = 2;
-	  shared = handle_intel (_SC_LEVEL2_CACHE_SIZE, max_cpuid);
+	  shared = core;
 	}
 
       /* Figure out the number of logical threads that share the
@@ -526,6 +529,9 @@ init_cacheinfo (void)
 	    }
 	  while (((eax >> 5) & 0x7) != level);
 
+	  /* Check if cache is inclusive of lower cache levels.  */
+	  inclusive_cache = (edx & 0x2) != 0;
+
 	  threads = (eax >> 14) & 0x3ff;
 
 	  /* If max_cpuid >= 11, THREADS is the maximum number of
@@ -592,6 +598,10 @@ init_cacheinfo (void)
 	 threads.  */
       if (shared > 0 && threads > 0)
 	shared /= threads;
+
+      /* Account for non-inclusive L2 and L3 caches.  */
+      if (level == 3 && !inclusive_cache)
+	shared += core;
     }
   /* This spells out "AuthenticAMD".  */
   else if (is_amd)