diff mbox

[3/3] Add cache info for powerpc64

Message ID 20170608225728.26779-4-rth@twiddle.net
State New
Headers show

Commit Message

Richard Henderson June 8, 2017, 10:57 p.m. UTC
The actual cache info was added for 4.11, but have a guess at the
L1 linesizes using info provided by older kernels.

	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysconf.c: New file.

Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Steven Munroe <sjmunroe@us.ibm.com>
---
 .../unix/sysv/linux/powerpc/powerpc64/sysconf.c    | 90 ++++++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/sysconf.c

Comments

Florian Weimer June 9, 2017, 6:58 a.m. UTC | #1
On 06/09/2017 12:57 AM, Richard Henderson wrote:
> +    case _SC_LEVEL1_ICACHE_SIZE:
> +      return getauxval(AT_L1I_CACHESIZE);

Style (missing space) and potential namespace violation (should be
__getauxval).

Thanks,
Florian
Tulio Magno Quites Machado Filho June 9, 2017, 1:12 p.m. UTC | #2
Richard Henderson <rth@twiddle.net> writes:

> The actual cache info was added for 4.11, but have a guess at the
> L1 linesizes using info provided by older kernels.
>
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysconf.c: New file.

There is already a patch reviewed and approved here:
https://patchwork.sourceware.org/patch/20202/

But this patch is blocked because it depends on another patch that's waiting
for review:
https://patchwork.sourceware.org/patch/20582/
Richard Henderson June 9, 2017, 8:07 p.m. UTC | #3
On 06/09/2017 06:12 AM, Tulio Magno Quites Machado Filho wrote:
> Richard Henderson <rth@twiddle.net> writes:
> 
>> The actual cache info was added for 4.11, but have a guess at the
>> L1 linesizes using info provided by older kernels.
>>
>> 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysconf.c: New file.
> 
> There is already a patch reviewed and approved here:
> https://patchwork.sourceware.org/patch/20202/


> +static long
> +auxv2sysconf (unsigned long type)
> +{
> +  long rc;
> +  rc = getauxval (type);
> +  if (rc == 0)
> +  {
> +    __set_errno (EINVAL);
> +    rc = -1;
> +  }
> +  return rc;

Setting EINVAL is wrong.  That would imply that the _SC_* name supplied by the 
caller is invalid somehow.

The return value should be 0 when the cache parameter is unknown, and -1 only 
when it is known that the cache level does not exist.

You should be using __getauxval to match the hidden_proto...

> 
> But this patch is blocked because it depends on another patch that's waiting
> for review:
> https://patchwork.sourceware.org/patch/20582/
> 

... defined here.  But this second patch does look right.


r~
diff mbox

Patch

diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysconf.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysconf.c
new file mode 100644
index 0000000..9cac9df
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysconf.c
@@ -0,0 +1,90 @@ 
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/auxv.h>
+
+
+static long int linux_sysconf (int name);
+
+/* Get the value of the system variable NAME.  */
+long int
+__sysconf (int name)
+{
+  unsigned long tmp;
+
+  /* The auxv entries describing the proper cache geometry were
+     added for kernel 4.11.  Thankfully, getauxval returns 0 when
+     the entry isn't present and is also the return from sysconf
+     when the value is unknown.
+
+     For the L1 linesize names, when the proper auxv entries are
+     not present, we fall back on older auxv entries that provide
+     the "block" linesize used for cache flushing.  It is a fair
+     guess that this does in fact correspond to the L1 shape.  */
+  switch (name)
+    {
+    case _SC_LEVEL1_ICACHE_SIZE:
+      return getauxval(AT_L1I_CACHESIZE);
+    case _SC_LEVEL1_ICACHE_ASSOC:
+      return (getauxval(AT_L1I_CACHEGEOMETRY) >> 16) & 0xffff;
+    case _SC_LEVEL1_ICACHE_LINESIZE:
+      tmp = getauxval(AT_L1I_CACHEGEOMETRY);
+      if (tmp)
+        return tmp & 0xffff;
+      return getauxval(AT_ICACHEBSIZE);
+
+    case _SC_LEVEL1_DCACHE_SIZE:
+      return getauxval(AT_L1D_CACHESIZE);
+    case _SC_LEVEL1_DCACHE_ASSOC:
+      return (getauxval(AT_L1D_CACHEGEOMETRY) >> 16) & 0xffff;
+    case _SC_LEVEL1_DCACHE_LINESIZE:
+      tmp = getauxval(AT_L1D_CACHEGEOMETRY);
+      if (tmp)
+        return tmp & 0xffff;
+      return getauxval(AT_DCACHEBSIZE);
+
+    case _SC_LEVEL2_CACHE_SIZE:
+      return getauxval(AT_L2_CACHESIZE);
+    case _SC_LEVEL2_CACHE_ASSOC:
+      return (getauxval(AT_L2_CACHEGEOMETRY) >> 16) & 0xffff;
+    case _SC_LEVEL2_CACHE_LINESIZE:
+      return getauxval(AT_L2_CACHEGEOMETRY) & 0xffff;
+
+    case _SC_LEVEL3_CACHE_SIZE:
+      return getauxval(AT_L3_CACHESIZE);
+    case _SC_LEVEL3_CACHE_ASSOC:
+      return (getauxval(AT_L3_CACHEGEOMETRY) >> 16) & 0xffff;
+    case _SC_LEVEL3_CACHE_LINESIZE:
+      return getauxval(AT_L3_CACHEGEOMETRY) & 0xffff;
+
+    case _SC_LEVEL4_CACHE_SIZE:
+    case _SC_LEVEL4_CACHE_ASSOC:
+    case _SC_LEVEL4_CACHE_LINESIZE:
+      return 0;
+    }
+
+  return linux_sysconf (name);
+}
+
+/* Now the generic Linux version.  */
+#undef __sysconf
+#define __sysconf static linux_sysconf
+#include <sysdeps/unix/sysv/linux/sysconf.c>