aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/x86
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-05-13 07:18:35 -0700
commit9e4ec3e81614164314bffe648e9446f17adc5fb7 (patch)
treee6cf84d13c33651d11aac638e7b46afe5b66bec0 /sysdeps/x86
parent4cf6c72fd2a482e7499c29162349810029632c3f (diff)
downloadglibc-9e4ec3e81614164314bffe648e9446f17adc5fb7.zip
glibc-9e4ec3e81614164314bffe648e9446f17adc5fb7.tar.gz
glibc-9e4ec3e81614164314bffe648e9446f17adc5fb7.tar.bz2
Support non-inclusive caches on Intel processors
* sysdeps/x86/cacheinfo.c (init_cacheinfo): Check and support non-inclusive caches on Intel processors.
Diffstat (limited to 'sysdeps/x86')
-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 143b333..8408624 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)