2022-12-28 00:45:26

by Ahelenia Ziemiańska

[permalink] [raw]
Subject: [PATCH 1/2] perf python: fix clang feature detection littering

This left behind tools/perf/a.out,
not .gitignored and not removed by make clean.

Fixes: commit 5508672d7f4949f15c316ffd947228f130498534 ("perf python:
Remove -mcet and -fcf-protection when building with clang")
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
---
tools/perf/util/setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index c294db713677..58239e1cdb2a 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -16,7 +16,7 @@ cc_is_clang = b"clang version" in Popen([cc, "-v"], stderr=PIPE).stderr.readline
src_feature_tests = getenv('srctree') + '/tools/build/feature'

def clang_has_option(option):
- cc_output = Popen([cc, cc_options + option, path.join(src_feature_tests, "test-hello.c") ], stderr=PIPE).stderr.readlines()
+ cc_output = Popen([cc, cc_options + option + "-o /dev/null", path.join(src_feature_tests, "test-hello.c") ], stderr=PIPE).stderr.readlines()
return [o for o in cc_output if ((b"unknown argument" in o) or (b"is not supported" in o))] == [ ]

if cc_is_clang:
--
2.30.2


Attachments:
(No filename) (1.14 kB)
signature.asc (849.00 B)
Download all attachments

2022-12-28 02:14:18

by Ahelenia Ziemiańska

[permalink] [raw]
Subject: [PATCH v2 3/4] perf python: don't run the linker for clang feature tests

This, for me, slightly-more-than-halves the time it takes to run
for a in "-mcet" "-fcf-protection" "-fstack-clash-protection" \
"-fstack-protector-strong" "-fno-semantic-interposition" \
"-ffat-lto-objects"; do
sh -c '$CC "$@"' '' "$a" -o /dev/null ../build/feature/test-hello.c; done
from just over 600ms.

Signed-off-by: Ahelenia Ziemiańska <[email protected]>
---
tools/perf/util/setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index ba0b1e078855..0a557f2bf357 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -6,7 +6,7 @@ cc_is_clang = b"clang version" in Popen(["/bin/sh", "-c", "$CC -v"], stderr=PIPE
src_feature_tests = getenv('srctree') + '/tools/build/feature'

def clang_has_option(option):
- cc_output = Popen(["/bin/sh", "-c", '$CC "$@"', "", option, "-o", "/dev/null", path.join(src_feature_tests, "test-hello.c")], stderr=PIPE).stderr.readlines()
+ cc_output = Popen(["/bin/sh", "-c", '$CC "$@"', "", option, "-c", "-o", "/dev/null", path.join(src_feature_tests, "test-hello.c")], stderr=PIPE).stderr.readlines()
return [o for o in cc_output if ((b"unknown argument" in o) or (b"is not supported" in o))] == [ ]

if cc_is_clang:
--
2.30.2


Attachments:
(No filename) (1.32 kB)
signature.asc (849.00 B)
Download all attachments

2022-12-28 02:21:38

by Ahelenia Ziemiańska

[permalink] [raw]
Subject: [PATCH v2 2/4] perf python: fix clang feature detection littering

This left behind tools/perf/a.out,
not .gitignored and not removed by make clean.

Fixes: commit 5508672d7f4949f15c316ffd947228f130498534 ("perf python:
Remove -mcet and -fcf-protection when building with clang")
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
---
tools/perf/util/setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index 1cee26c63613..ba0b1e078855 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -6,7 +6,7 @@ cc_is_clang = b"clang version" in Popen(["/bin/sh", "-c", "$CC -v"], stderr=PIPE
src_feature_tests = getenv('srctree') + '/tools/build/feature'

def clang_has_option(option):
- cc_output = Popen(["/bin/sh", "-c", '$CC "$@"', "", option, path.join(src_feature_tests, "test-hello.c")], stderr=PIPE).stderr.readlines()
+ cc_output = Popen(["/bin/sh", "-c", '$CC "$@"', "", option, "-o", "/dev/null", path.join(src_feature_tests, "test-hello.c")], stderr=PIPE).stderr.readlines()
return [o for o in cc_output if ((b"unknown argument" in o) or (b"is not supported" in o))] == [ ]

if cc_is_clang:
--
2.30.2


Attachments:
(No filename) (1.17 kB)
signature.asc (849.00 B)
Download all attachments

2022-12-28 02:43:33

by Ahelenia Ziemiańska

[permalink] [raw]
Subject: [PATCH v2 4/4] perf python: only check for the clang features we care about removing

Instead of checking for all 6 flags every time for both fields,
only check for the ones we already know are in there.

This means instead of running 2*6 processes, we run, on my Bullseye system,
just one (for -fstack-protector-strong)! This reduces the run-time by
appx. (2*6-1)*.05=550ms (or, without the -c patch, 1.1s).

Signed-off-by: Ahelenia Ziemiańska <[email protected]>
---
tools/perf/util/setup.py | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index 0a557f2bf357..f4b94c0f9055 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -14,18 +14,9 @@ if cc_is_clang:
vars = get_config_vars()
for var in ('CFLAGS', 'OPT'):
vars[var] = sub("-specs=[^ ]+", "", vars[var])
- if not clang_has_option("-mcet"):
- vars[var] = sub("-mcet", "", vars[var])
- if not clang_has_option("-fcf-protection"):
- vars[var] = sub("-fcf-protection", "", vars[var])
- if not clang_has_option("-fstack-clash-protection"):
- vars[var] = sub("-fstack-clash-protection", "", vars[var])
- if not clang_has_option("-fstack-protector-strong"):
- vars[var] = sub("-fstack-protector-strong", "", vars[var])
- if not clang_has_option("-fno-semantic-interposition"):
- vars[var] = sub("-fno-semantic-interposition", "", vars[var])
- if not clang_has_option("-ffat-lto-objects"):
- vars[var] = sub("-ffat-lto-objects", "", vars[var])
+ for opt in ("-mcet", "-fcf-protection", "-fstack-clash-protection", "-fstack-protector-strong", "-fno-semantic-interposition", "-ffat-lto-objects"):
+ if vars[var].find(opt) != -1 and not clang_has_option(opt):
+ vars[var] = vars[var].replace(opt, "")

from setuptools import setup, Extension

--
2.30.2


Attachments:
(No filename) (1.90 kB)
signature.asc (849.00 B)
Download all attachments

2022-12-28 02:45:24

by Ahelenia Ziemiańska

[permalink] [raw]
Subject: [PATCH v2 1/4] perf python: make clang feature detection work

As it stands, it's /entirely/ broken: cc_options is pasted together
with the tested option /as a single argument/.

For example, for CC='cc -O3', this will run (the equivalent of)
cc "-O3 -mcet" ../build/feature/test-heello.c
cc "-O3 -fcf-protection" ../build/feature/test-heello.c
..
which, obviously, doesn't work, and has /never/ worked. The commit
referenced in Fixes: is just the first one that uses this approach.

Instead of emulating shell tokenisation and turning tokens into words
badly (well, we barely do it, which is even more alarming. the only way
I can foresee this having ever worked for anyone is if it, very literally,
returned False for /every/ clang_has_option() invocation with
non-single-token $CC, which, I mean, sure, but it means that every clang
build like this has all hardening off), just... run these through the
shell, like they will be at point-of-use anyway.

As a demo, with CC='/tmp/cc -O3' and /tmp/cc consisting of
#!/bin/sh
echo "$*" | grep -qFe '-mcet' && printf 'CC:"%s"\n' "$@" "" > /dev/tty
exec cc "$@"
before:
AR /mnt/filling/store/nabijaczleweli/code/linux/tools/perf/libsubcmd/libsubcmd.a
CC:"-O3 -mcet"
CC:"/mnt/filling/store/nabijaczleweli/code/linux/tools/build/feature/test-hello.c"
CC:""
CC:"-O3 -mcet"
CC:"/mnt/filling/store/nabijaczleweli/code/linux/tools/build/feature/test-hello.c"
CC:""
LD /mnt/filling/store/nabijaczleweli/code/linux/tools/perf/libbpf/staticobjs/libbpf-in.o
after:
GEN python/perf.cpython-39-x86_64-linux-gnu.so
CC:"-O3"
CC:"-mcet"
CC:"/mnt/filling/store/nabijaczleweli/code/linux/tools/build/feature/test-hello.c"
CC:""
CC:"-O3"
CC:"-mcet"
CC:"/mnt/filling/store/nabijaczleweli/code/linux/tools/build/feature/test-hello.c"
CC:""
LD /mnt/filling/store/nabijaczleweli/code/linux/tools/perf/libbpf/staticobjs/libbpf-in.o

Fixes: commit 3cad53a6f9cdb ("perf python: Account for multiple words in
CC")
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
---
tools/perf/util/setup.py | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index c294db713677..1cee26c63613 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -2,21 +2,11 @@ from os import getenv, path
from subprocess import Popen, PIPE
from re import sub

-cc = getenv("CC")
-
-# Check if CC has options, as is the case in yocto, where it uses CC="cc --sysroot..."
-cc_tokens = cc.split()
-if len(cc_tokens) > 1:
- cc = cc_tokens[0]
- cc_options = " ".join([str(e) for e in cc_tokens[1:]]) + " "
-else:
- cc_options = ""
-
-cc_is_clang = b"clang version" in Popen([cc, "-v"], stderr=PIPE).stderr.readline()
+cc_is_clang = b"clang version" in Popen(["/bin/sh", "-c", "$CC -v"], stderr=PIPE).stderr.readline()
src_feature_tests = getenv('srctree') + '/tools/build/feature'

def clang_has_option(option):
- cc_output = Popen([cc, cc_options + option, path.join(src_feature_tests, "test-hello.c") ], stderr=PIPE).stderr.readlines()
+ cc_output = Popen(["/bin/sh", "-c", '$CC "$@"', "", option, path.join(src_feature_tests, "test-hello.c")], stderr=PIPE).stderr.readlines()
return [o for o in cc_output if ((b"unknown argument" in o) or (b"is not supported" in o))] == [ ]

if cc_is_clang:
--
2.30.2


Attachments:
(No filename) (3.36 kB)
signature.asc (849.00 B)
Download all attachments