x86: Handle _SC_LEVEL1_ICACHE_LINESIZE [BZ #27444]
Commit Message
commit 2d651eb9265d1366d7b9e881bfddd46db9c1ecc4
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Fri Sep 18 07:55:14 2020 -0700
x86: Move x86 processor cache info to cpu_features
missed _SC_LEVEL1_ICACHE_LINESIZE.
1. Add level1_icache_linesize to struct cpu_features.
2. Initialize level1_icache_linesize by calling handle_intel,
handle_zhaoxin and handle_amd with _SC_LEVEL1_ICACHE_LINESIZE.
3. Return level1_icache_linesize for _SC_LEVEL1_ICACHE_LINESIZE.
---
sysdeps/x86/Makefile | 8 +++
sysdeps/x86/cacheinfo.c | 3 +
sysdeps/x86/dl-cacheinfo.h | 6 ++
sysdeps/x86/dl-diagnostics-cpu.c | 2 +
sysdeps/x86/include/cpu-features.h | 2 +
.../x86/tst-sysconf-cache-linesize-static.c | 1 +
sysdeps/x86/tst-sysconf-cache-linesize.c | 57 +++++++++++++++++++
7 files changed, 79 insertions(+)
create mode 100644 sysdeps/x86/tst-sysconf-cache-linesize-static.c
create mode 100644 sysdeps/x86/tst-sysconf-cache-linesize.c
Comments
On 3/6/21 2:11 PM, H.J. Lu via Libc-alpha wrote:
> commit 2d651eb9265d1366d7b9e881bfddd46db9c1ecc4
> Author: H.J. Lu <hjl.tools@gmail.com>
> Date: Fri Sep 18 07:55:14 2020 -0700
>
> x86: Move x86 processor cache info to cpu_features
>
> missed _SC_LEVEL1_ICACHE_LINESIZE.
LGTM.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
>
> 1. Add level1_icache_linesize to struct cpu_features.
> 2. Initialize level1_icache_linesize by calling handle_intel,
> handle_zhaoxin and handle_amd with _SC_LEVEL1_ICACHE_LINESIZE.
> 3. Return level1_icache_linesize for _SC_LEVEL1_ICACHE_LINESIZE.
> ---
> sysdeps/x86/Makefile | 8 +++
> sysdeps/x86/cacheinfo.c | 3 +
> sysdeps/x86/dl-cacheinfo.h | 6 ++
> sysdeps/x86/dl-diagnostics-cpu.c | 2 +
> sysdeps/x86/include/cpu-features.h | 2 +
> .../x86/tst-sysconf-cache-linesize-static.c | 1 +
> sysdeps/x86/tst-sysconf-cache-linesize.c | 57 +++++++++++++++++++
> 7 files changed, 79 insertions(+)
> create mode 100644 sysdeps/x86/tst-sysconf-cache-linesize-static.c
> create mode 100644 sysdeps/x86/tst-sysconf-cache-linesize.c
>
> diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
> index e1f9379fd8..06c9f84f51 100644
> --- a/sysdeps/x86/Makefile
> +++ b/sysdeps/x86/Makefile
> @@ -211,3 +211,11 @@ $(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \
> generated += check-cet.out
> endif
> endif
> +
> +ifeq ($(subdir),posix)
> +tests += \
> + tst-sysconf-cache-linesize \
> + tst-sysconf-cache-linesize-static
> +tests-static += \
> + tst-sysconf-cache-linesize-static
> +endif
OK. Add new test for static binary access of line size.
> diff --git a/sysdeps/x86/cacheinfo.c b/sysdeps/x86/cacheinfo.c
> index 7b8df45e3b..5ea4723ca6 100644
> --- a/sysdeps/x86/cacheinfo.c
> +++ b/sysdeps/x86/cacheinfo.c
> @@ -32,6 +32,9 @@ __cache_sysconf (int name)
> case _SC_LEVEL1_ICACHE_SIZE:
> return cpu_features->level1_icache_size;
>
> + case _SC_LEVEL1_ICACHE_LINESIZE:
> + return cpu_features->level1_icache_linesize;
OK. Return new struct member.
> +
> case _SC_LEVEL1_DCACHE_SIZE:
> return cpu_features->level1_dcache_size;
>
> diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
> index f3de206dc1..d9944250fc 100644
> --- a/sysdeps/x86/dl-cacheinfo.h
> +++ b/sysdeps/x86/dl-cacheinfo.h
> @@ -707,6 +707,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> long int core = -1;
> unsigned int threads = 0;
> unsigned long int level1_icache_size = -1;
> + unsigned long int level1_icache_linesize = -1;
OK. Struct member matches.
> unsigned long int level1_dcache_size = -1;
> unsigned long int level1_dcache_assoc = -1;
> unsigned long int level1_dcache_linesize = -1;
> @@ -726,6 +727,8 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
>
> level1_icache_size
> = handle_intel (_SC_LEVEL1_ICACHE_SIZE, cpu_features);
> + level1_icache_linesize
> + = handle_intel (_SC_LEVEL1_ICACHE_LINESIZE, cpu_features);
OK. Set member.
> level1_dcache_size = data;
> level1_dcache_assoc
> = handle_intel (_SC_LEVEL1_DCACHE_ASSOC, cpu_features);
> @@ -753,6 +756,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> shared = handle_zhaoxin (_SC_LEVEL3_CACHE_SIZE);
>
> level1_icache_size = handle_zhaoxin (_SC_LEVEL1_ICACHE_SIZE);
> + level1_icache_linesize = handle_zhaoxin (_SC_LEVEL1_ICACHE_LINESIZE);
OK. Handle alternatives.
> level1_dcache_size = data;
> level1_dcache_assoc = handle_zhaoxin (_SC_LEVEL1_DCACHE_ASSOC);
> level1_dcache_linesize = handle_zhaoxin (_SC_LEVEL1_DCACHE_LINESIZE);
> @@ -772,6 +776,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> shared = handle_amd (_SC_LEVEL3_CACHE_SIZE);
>
> level1_icache_size = handle_amd (_SC_LEVEL1_ICACHE_SIZE);
> + level1_icache_linesize = handle_amd (_SC_LEVEL1_ICACHE_LINESIZE);
OK. Likewise.
> level1_dcache_size = data;
> level1_dcache_assoc = handle_amd (_SC_LEVEL1_DCACHE_ASSOC);
> level1_dcache_linesize = handle_amd (_SC_LEVEL1_DCACHE_LINESIZE);
> @@ -833,6 +838,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> }
>
> cpu_features->level1_icache_size = level1_icache_size;
> + cpu_features->level1_icache_linesize = level1_icache_linesize;
OK. Set actual cpu_features.
> cpu_features->level1_dcache_size = level1_dcache_size;
> cpu_features->level1_dcache_assoc = level1_dcache_assoc;
> cpu_features->level1_dcache_linesize = level1_dcache_linesize;
> diff --git a/sysdeps/x86/dl-diagnostics-cpu.c b/sysdeps/x86/dl-diagnostics-cpu.c
> index 5d9713f8d9..5d04527ad1 100644
> --- a/sysdeps/x86/dl-diagnostics-cpu.c
> +++ b/sysdeps/x86/dl-diagnostics-cpu.c
> @@ -91,6 +91,8 @@ _dl_diagnostics_cpu (void)
> cpu_features->rep_stosb_threshold);
> print_cpu_features_value ("level1_icache_size",
> cpu_features->level1_icache_size);
> + print_cpu_features_value ("level1_icache_linesize",
> + cpu_features->level1_icache_linesize);
OK. Add it to diag printing.
> print_cpu_features_value ("level1_dcache_size",
> cpu_features->level1_dcache_size);
> print_cpu_features_value ("level1_dcache_assoc",
> diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
> index c5a779ba32..d042a2ebef 100644
> --- a/sysdeps/x86/include/cpu-features.h
> +++ b/sysdeps/x86/include/cpu-features.h
> @@ -876,6 +876,8 @@ struct cpu_features
> unsigned long int rep_stosb_threshold;
> /* _SC_LEVEL1_ICACHE_SIZE. */
> unsigned long int level1_icache_size;
> + /* _SC_LEVEL1_ICACHE_LINESIZE. */
> + unsigned long int level1_icache_linesize;
OK.
> /* _SC_LEVEL1_DCACHE_SIZE. */
> unsigned long int level1_dcache_size;
> /* _SC_LEVEL1_DCACHE_ASSOC. */
> diff --git a/sysdeps/x86/tst-sysconf-cache-linesize-static.c b/sysdeps/x86/tst-sysconf-cache-linesize-static.c
> new file mode 100644
> index 0000000000..152ae68821
> --- /dev/null
> +++ b/sysdeps/x86/tst-sysconf-cache-linesize-static.c
> @@ -0,0 +1 @@
> +#include "tst-sysconf-cache-linesize.c"
> diff --git a/sysdeps/x86/tst-sysconf-cache-linesize.c b/sysdeps/x86/tst-sysconf-cache-linesize.c
> new file mode 100644
> index 0000000000..642dbde5d2
> --- /dev/null
> +++ b/sysdeps/x86/tst-sysconf-cache-linesize.c
> @@ -0,0 +1,57 @@
> +/* Test system cache line sizes.
> + Copyright (C) 2021 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <array_length.h>
> +
> +static struct
> +{
> + const char *name;
> + int _SC_val;
> +} sc_options[] =
> + {
> +#define N(name) { "_SC_"#name, _SC_##name }
> + N (LEVEL1_ICACHE_LINESIZE),
> + N (LEVEL1_DCACHE_LINESIZE),
> + N (LEVEL2_CACHE_LINESIZE)
> + };
> +
> +static int
> +do_test (void)
> +{
> + int result = EXIT_SUCCESS;
> +
> + for (int i = 0; i < array_length (sc_options); ++i)
> + {
> + long int scret = sysconf (sc_options[i]._SC_val);
> + if (scret < 0)
> + {
> + printf ("sysconf (%s) returned < 0 (%ld)\n",
> + sc_options[i].name, scret);
> + result = EXIT_FAILURE;
OK. Expect that sysconf knows the value and returns a non-error return.
> + }
> + else
> + printf ("sysconf (%s): %ld\n", sc_options[i].name, scret);
> + }
> +
> + return result;
> +}
> +
> +#include <support/test-driver.c>
>
On Mon, Mar 15, 2021 at 5:32 AM Carlos O'Donell <carlos@redhat.com> wrote:
>
> On 3/6/21 2:11 PM, H.J. Lu via Libc-alpha wrote:
> > commit 2d651eb9265d1366d7b9e881bfddd46db9c1ecc4
> > Author: H.J. Lu <hjl.tools@gmail.com>
> > Date: Fri Sep 18 07:55:14 2020 -0700
> >
> > x86: Move x86 processor cache info to cpu_features
> >
> > missed _SC_LEVEL1_ICACHE_LINESIZE.
>
> LGTM.
>
> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
>
> >
> > 1. Add level1_icache_linesize to struct cpu_features.
> > 2. Initialize level1_icache_linesize by calling handle_intel,
> > handle_zhaoxin and handle_amd with _SC_LEVEL1_ICACHE_LINESIZE.
> > 3. Return level1_icache_linesize for _SC_LEVEL1_ICACHE_LINESIZE.
> > ---
> > sysdeps/x86/Makefile | 8 +++
> > sysdeps/x86/cacheinfo.c | 3 +
> > sysdeps/x86/dl-cacheinfo.h | 6 ++
> > sysdeps/x86/dl-diagnostics-cpu.c | 2 +
> > sysdeps/x86/include/cpu-features.h | 2 +
> > .../x86/tst-sysconf-cache-linesize-static.c | 1 +
> > sysdeps/x86/tst-sysconf-cache-linesize.c | 57 +++++++++++++++++++
> > 7 files changed, 79 insertions(+)
> > create mode 100644 sysdeps/x86/tst-sysconf-cache-linesize-static.c
> > create mode 100644 sysdeps/x86/tst-sysconf-cache-linesize.c
> >
> > diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
> > index e1f9379fd8..06c9f84f51 100644
> > --- a/sysdeps/x86/Makefile
> > +++ b/sysdeps/x86/Makefile
> > @@ -211,3 +211,11 @@ $(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \
> > generated += check-cet.out
> > endif
> > endif
> > +
> > +ifeq ($(subdir),posix)
> > +tests += \
> > + tst-sysconf-cache-linesize \
> > + tst-sysconf-cache-linesize-static
> > +tests-static += \
> > + tst-sysconf-cache-linesize-static
> > +endif
>
> OK. Add new test for static binary access of line size.
>
> > diff --git a/sysdeps/x86/cacheinfo.c b/sysdeps/x86/cacheinfo.c
> > index 7b8df45e3b..5ea4723ca6 100644
> > --- a/sysdeps/x86/cacheinfo.c
> > +++ b/sysdeps/x86/cacheinfo.c
> > @@ -32,6 +32,9 @@ __cache_sysconf (int name)
> > case _SC_LEVEL1_ICACHE_SIZE:
> > return cpu_features->level1_icache_size;
> >
> > + case _SC_LEVEL1_ICACHE_LINESIZE:
> > + return cpu_features->level1_icache_linesize;
>
> OK. Return new struct member.
>
> > +
> > case _SC_LEVEL1_DCACHE_SIZE:
> > return cpu_features->level1_dcache_size;
> >
> > diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
> > index f3de206dc1..d9944250fc 100644
> > --- a/sysdeps/x86/dl-cacheinfo.h
> > +++ b/sysdeps/x86/dl-cacheinfo.h
> > @@ -707,6 +707,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> > long int core = -1;
> > unsigned int threads = 0;
> > unsigned long int level1_icache_size = -1;
> > + unsigned long int level1_icache_linesize = -1;
>
> OK. Struct member matches.
>
> > unsigned long int level1_dcache_size = -1;
> > unsigned long int level1_dcache_assoc = -1;
> > unsigned long int level1_dcache_linesize = -1;
> > @@ -726,6 +727,8 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> >
> > level1_icache_size
> > = handle_intel (_SC_LEVEL1_ICACHE_SIZE, cpu_features);
> > + level1_icache_linesize
> > + = handle_intel (_SC_LEVEL1_ICACHE_LINESIZE, cpu_features);
>
> OK. Set member.
>
> > level1_dcache_size = data;
> > level1_dcache_assoc
> > = handle_intel (_SC_LEVEL1_DCACHE_ASSOC, cpu_features);
> > @@ -753,6 +756,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> > shared = handle_zhaoxin (_SC_LEVEL3_CACHE_SIZE);
> >
> > level1_icache_size = handle_zhaoxin (_SC_LEVEL1_ICACHE_SIZE);
> > + level1_icache_linesize = handle_zhaoxin (_SC_LEVEL1_ICACHE_LINESIZE);
>
> OK. Handle alternatives.
>
> > level1_dcache_size = data;
> > level1_dcache_assoc = handle_zhaoxin (_SC_LEVEL1_DCACHE_ASSOC);
> > level1_dcache_linesize = handle_zhaoxin (_SC_LEVEL1_DCACHE_LINESIZE);
> > @@ -772,6 +776,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> > shared = handle_amd (_SC_LEVEL3_CACHE_SIZE);
> >
> > level1_icache_size = handle_amd (_SC_LEVEL1_ICACHE_SIZE);
> > + level1_icache_linesize = handle_amd (_SC_LEVEL1_ICACHE_LINESIZE);
>
> OK. Likewise.
>
> > level1_dcache_size = data;
> > level1_dcache_assoc = handle_amd (_SC_LEVEL1_DCACHE_ASSOC);
> > level1_dcache_linesize = handle_amd (_SC_LEVEL1_DCACHE_LINESIZE);
> > @@ -833,6 +838,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
> > }
> >
> > cpu_features->level1_icache_size = level1_icache_size;
> > + cpu_features->level1_icache_linesize = level1_icache_linesize;
>
> OK. Set actual cpu_features.
>
> > cpu_features->level1_dcache_size = level1_dcache_size;
> > cpu_features->level1_dcache_assoc = level1_dcache_assoc;
> > cpu_features->level1_dcache_linesize = level1_dcache_linesize;
> > diff --git a/sysdeps/x86/dl-diagnostics-cpu.c b/sysdeps/x86/dl-diagnostics-cpu.c
> > index 5d9713f8d9..5d04527ad1 100644
> > --- a/sysdeps/x86/dl-diagnostics-cpu.c
> > +++ b/sysdeps/x86/dl-diagnostics-cpu.c
> > @@ -91,6 +91,8 @@ _dl_diagnostics_cpu (void)
> > cpu_features->rep_stosb_threshold);
> > print_cpu_features_value ("level1_icache_size",
> > cpu_features->level1_icache_size);
> > + print_cpu_features_value ("level1_icache_linesize",
> > + cpu_features->level1_icache_linesize);
>
> OK. Add it to diag printing.
>
> > print_cpu_features_value ("level1_dcache_size",
> > cpu_features->level1_dcache_size);
> > print_cpu_features_value ("level1_dcache_assoc",
> > diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
> > index c5a779ba32..d042a2ebef 100644
> > --- a/sysdeps/x86/include/cpu-features.h
> > +++ b/sysdeps/x86/include/cpu-features.h
> > @@ -876,6 +876,8 @@ struct cpu_features
> > unsigned long int rep_stosb_threshold;
> > /* _SC_LEVEL1_ICACHE_SIZE. */
> > unsigned long int level1_icache_size;
> > + /* _SC_LEVEL1_ICACHE_LINESIZE. */
> > + unsigned long int level1_icache_linesize;
>
> OK.
>
> > /* _SC_LEVEL1_DCACHE_SIZE. */
> > unsigned long int level1_dcache_size;
> > /* _SC_LEVEL1_DCACHE_ASSOC. */
> > diff --git a/sysdeps/x86/tst-sysconf-cache-linesize-static.c b/sysdeps/x86/tst-sysconf-cache-linesize-static.c
> > new file mode 100644
> > index 0000000000..152ae68821
> > --- /dev/null
> > +++ b/sysdeps/x86/tst-sysconf-cache-linesize-static.c
> > @@ -0,0 +1 @@
> > +#include "tst-sysconf-cache-linesize.c"
> > diff --git a/sysdeps/x86/tst-sysconf-cache-linesize.c b/sysdeps/x86/tst-sysconf-cache-linesize.c
> > new file mode 100644
> > index 0000000000..642dbde5d2
> > --- /dev/null
> > +++ b/sysdeps/x86/tst-sysconf-cache-linesize.c
> > @@ -0,0 +1,57 @@
> > +/* Test system cache line sizes.
> > + Copyright (C) 2021 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
> > + <https://www.gnu.org/licenses/>. */
> > +
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <unistd.h>
> > +#include <array_length.h>
> > +
> > +static struct
> > +{
> > + const char *name;
> > + int _SC_val;
> > +} sc_options[] =
> > + {
> > +#define N(name) { "_SC_"#name, _SC_##name }
> > + N (LEVEL1_ICACHE_LINESIZE),
> > + N (LEVEL1_DCACHE_LINESIZE),
> > + N (LEVEL2_CACHE_LINESIZE)
> > + };
> > +
> > +static int
> > +do_test (void)
> > +{
> > + int result = EXIT_SUCCESS;
> > +
> > + for (int i = 0; i < array_length (sc_options); ++i)
> > + {
> > + long int scret = sysconf (sc_options[i]._SC_val);
> > + if (scret < 0)
> > + {
> > + printf ("sysconf (%s) returned < 0 (%ld)\n",
> > + sc_options[i].name, scret);
> > + result = EXIT_FAILURE;
>
> OK. Expect that sysconf knows the value and returns a non-error return.
>
> > + }
> > + else
> > + printf ("sysconf (%s): %ld\n", sc_options[i].name, scret);
> > + }
> > +
> > + return result;
> > +}
> > +
> > +#include <support/test-driver.c>
> >
>
I am backporting it to 2.33 branch.
@@ -211,3 +211,11 @@ $(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \
generated += check-cet.out
endif
endif
+
+ifeq ($(subdir),posix)
+tests += \
+ tst-sysconf-cache-linesize \
+ tst-sysconf-cache-linesize-static
+tests-static += \
+ tst-sysconf-cache-linesize-static
+endif
@@ -32,6 +32,9 @@ __cache_sysconf (int name)
case _SC_LEVEL1_ICACHE_SIZE:
return cpu_features->level1_icache_size;
+ case _SC_LEVEL1_ICACHE_LINESIZE:
+ return cpu_features->level1_icache_linesize;
+
case _SC_LEVEL1_DCACHE_SIZE:
return cpu_features->level1_dcache_size;
@@ -707,6 +707,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
long int core = -1;
unsigned int threads = 0;
unsigned long int level1_icache_size = -1;
+ unsigned long int level1_icache_linesize = -1;
unsigned long int level1_dcache_size = -1;
unsigned long int level1_dcache_assoc = -1;
unsigned long int level1_dcache_linesize = -1;
@@ -726,6 +727,8 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
level1_icache_size
= handle_intel (_SC_LEVEL1_ICACHE_SIZE, cpu_features);
+ level1_icache_linesize
+ = handle_intel (_SC_LEVEL1_ICACHE_LINESIZE, cpu_features);
level1_dcache_size = data;
level1_dcache_assoc
= handle_intel (_SC_LEVEL1_DCACHE_ASSOC, cpu_features);
@@ -753,6 +756,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
shared = handle_zhaoxin (_SC_LEVEL3_CACHE_SIZE);
level1_icache_size = handle_zhaoxin (_SC_LEVEL1_ICACHE_SIZE);
+ level1_icache_linesize = handle_zhaoxin (_SC_LEVEL1_ICACHE_LINESIZE);
level1_dcache_size = data;
level1_dcache_assoc = handle_zhaoxin (_SC_LEVEL1_DCACHE_ASSOC);
level1_dcache_linesize = handle_zhaoxin (_SC_LEVEL1_DCACHE_LINESIZE);
@@ -772,6 +776,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
shared = handle_amd (_SC_LEVEL3_CACHE_SIZE);
level1_icache_size = handle_amd (_SC_LEVEL1_ICACHE_SIZE);
+ level1_icache_linesize = handle_amd (_SC_LEVEL1_ICACHE_LINESIZE);
level1_dcache_size = data;
level1_dcache_assoc = handle_amd (_SC_LEVEL1_DCACHE_ASSOC);
level1_dcache_linesize = handle_amd (_SC_LEVEL1_DCACHE_LINESIZE);
@@ -833,6 +838,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
}
cpu_features->level1_icache_size = level1_icache_size;
+ cpu_features->level1_icache_linesize = level1_icache_linesize;
cpu_features->level1_dcache_size = level1_dcache_size;
cpu_features->level1_dcache_assoc = level1_dcache_assoc;
cpu_features->level1_dcache_linesize = level1_dcache_linesize;
@@ -91,6 +91,8 @@ _dl_diagnostics_cpu (void)
cpu_features->rep_stosb_threshold);
print_cpu_features_value ("level1_icache_size",
cpu_features->level1_icache_size);
+ print_cpu_features_value ("level1_icache_linesize",
+ cpu_features->level1_icache_linesize);
print_cpu_features_value ("level1_dcache_size",
cpu_features->level1_dcache_size);
print_cpu_features_value ("level1_dcache_assoc",
@@ -876,6 +876,8 @@ struct cpu_features
unsigned long int rep_stosb_threshold;
/* _SC_LEVEL1_ICACHE_SIZE. */
unsigned long int level1_icache_size;
+ /* _SC_LEVEL1_ICACHE_LINESIZE. */
+ unsigned long int level1_icache_linesize;
/* _SC_LEVEL1_DCACHE_SIZE. */
unsigned long int level1_dcache_size;
/* _SC_LEVEL1_DCACHE_ASSOC. */
new file mode 100644
@@ -0,0 +1 @@
+#include "tst-sysconf-cache-linesize.c"
new file mode 100644
@@ -0,0 +1,57 @@
+/* Test system cache line sizes.
+ Copyright (C) 2021 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <array_length.h>
+
+static struct
+{
+ const char *name;
+ int _SC_val;
+} sc_options[] =
+ {
+#define N(name) { "_SC_"#name, _SC_##name }
+ N (LEVEL1_ICACHE_LINESIZE),
+ N (LEVEL1_DCACHE_LINESIZE),
+ N (LEVEL2_CACHE_LINESIZE)
+ };
+
+static int
+do_test (void)
+{
+ int result = EXIT_SUCCESS;
+
+ for (int i = 0; i < array_length (sc_options); ++i)
+ {
+ long int scret = sysconf (sc_options[i]._SC_val);
+ if (scret < 0)
+ {
+ printf ("sysconf (%s) returned < 0 (%ld)\n",
+ sc_options[i].name, scret);
+ result = EXIT_FAILURE;
+ }
+ else
+ printf ("sysconf (%s): %ld\n", sc_options[i].name, scret);
+ }
+
+ return result;
+}
+
+#include <support/test-driver.c>