perf/core clang fixes:

Changes to make tools/{perf,lib/{bpf,traceevent,api}} build with
 CC=clang, to, for instance, take advantage of warnings (Arnaldo Carvalho de Melo):
 
 - Conditionally request some warning options not available on clang
 
 - Set the maximum optimization level to -O3 when using CC=clang, leave
   the previous setting of -O6 otherwise.
 
 - Make it an error to pass a signed value to OPTION_UINTEGER, so that
   we can remove abs(unsigned int) calls in 'perf bench futex'.
 
 - Make sure dprintf() is not defined before using that name in 'perf bench numa'
 
 - Avoid using field after variable sized type, its a GNU extension, use
   equivalent code.
 
 - Fix some bugs where some variables could be used unitialized,
   something not caught by gcc.
 
 - Fix some spots where we were testing struct->array[] members against
   NULL, it will always evaluate to 'true'.
 
 - Add missing parse_events_error() prototype in the bison file.
 
 There are still one problem when trying to build the python support, but
 this are the 'size' outputs for 'make -C tools/perf NO_LIBPYTHON' for
 gcc and clang builds:
 
   DW_AT_producer: clang version 4.0.0 (http://llvm.org/git/clang.git f5be8ba13adc4ba1011a7ccd60c844bd60427c1c) (ht
 
   $ size ~/bin/perf
      text    data     bss     dec     hex     filename
   3447514  831320 23901696  28180530  1ae0032 /home/acme/bin/perf
 
   DW_AT_producer: GNU C99 6.3.1 20161221 (Red Hat 6.3.1-1) -mtune=generic -march=x86-64 -ggdb3 -O6 -std=gnu99
 +-fno-omit-frame-pointer -funwind-tables -fstack-protector-all
 
   $ size ~/bin/perf
      text    data     bss     dec     hex     filename
   3671662  836480 23902752  28410894  1b1840e /home/acme/bin/perf
 
 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCAAGBQJYpHzlAAoJENZQFvNTUqpAtq8QAKrP64GRQDvoAS9bT6Zjvh/x
 xPcjD+XcMg+r/peFRQ1YOhKxmWCUwJweVIrl54e5yuOgXnClIXjnZcVwjqiJDHL3
 bGBDZss3hFWY5y0mO6Ny8ME0bgb4LKErCp81uobAbDQ6rxzSFId6plnJy7CgeX5L
 eB5FfnYWDPmgLY03nfyGwmR07NT8bDHeQu3yGruB8EDW7aQc8lMtqhRBAJEK6T1x
 oAabuimlU5CGqKxuCHOUqckr+rFbARNt76wvgzRcuVQnZ7h3llDXF0LaW2IEDaiM
 LRx+F//zE1BcklR/WgryWZBcaCFwF9jTvhzQRRhUAXPbLrKLak6+WFnJH1fcFL0l
 zyVpA6yqBVRaCYLt/OcVad40AGOjjEITpbgBfpzkHGEafzZAacddOn9okZyJvvQO
 LNFReECFvDoslJdyXHN5n9CwnkaD7PowkTCqr6SShKpft0oITy+SZYbNeCxi9YST
 HW3i6XisweGgLUjElA29pBfVj28Xe2PTKlOcEPcp/at2drFFLUSikCLZWOYSaJX7
 Or7EqhxI0G6OpPmvGt0FdQKUvoZ+YcAeR54RzEHMBmKNZ/GWTKbcFAQX9LQ9MNMn
 NrXEzwdbMxD9tkw4tfs6iEchEUYqEbOQdK/hWJRfeQE12QGKDtueJe1TI78kZbeL
 oEdmZMfMahOI9Lx4He6M
 =ge2k
 -----END PGP SIGNATURE-----

Merge tag 'perf-core-for-mingo-4.11-20170215' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core clang fixes from Arnaldo Carvalho de Melo:

Changes to make tools/{perf,lib/{bpf,traceevent,api}} build with
CC=clang, to, for instance, take advantage of warnings (Arnaldo Carvalho de Melo):

- Conditionally request some warning options not available on clang

- Set the maximum optimization level to -O3 when using CC=clang, leave
  the previous setting of -O6 otherwise.

- Make it an error to pass a signed value to OPTION_UINTEGER, so that
  we can remove abs(unsigned int) calls in 'perf bench futex'.

- Make sure dprintf() is not defined before using that name in 'perf bench numa'

- Avoid using field after variable sized type, its a GNU extension, use
  equivalent code.

- Fix some bugs where some variables could be used unitialized,
  something not caught by gcc.

- Fix some spots where we were testing struct->array[] members against
  NULL, it will always evaluate to 'true'.

- Add missing parse_events_error() prototype in the bison file.

There are still one problem when trying to build the python support, but
this are the 'size' outputs for 'make -C tools/perf NO_LIBPYTHON' for
gcc and clang builds:

  DW_AT_producer: clang version 4.0.0 (http://llvm.org/git/clang.git f5be8ba13adc4ba1011a7ccd60c844bd60427c1c) (ht

  $ size ~/bin/perf
     text    data     bss     dec     hex     filename
  3447514  831320 23901696  28180530  1ae0032 /home/acme/bin/perf

  DW_AT_producer: GNU C99 6.3.1 20161221 (Red Hat 6.3.1-1) -mtune=generic -march=x86-64 -ggdb3 -O6 -std=gnu99
+-fno-omit-frame-pointer -funwind-tables -fstack-protector-all

  $ size ~/bin/perf
     text    data     bss     dec     hex     filename
  3671662  836480 23902752  28410894  1b1840e /home/acme/bin/perf

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ingo Molnar 2017-02-16 20:53:13 +01:00
commit 0c8967c9df
22 changed files with 91 additions and 92 deletions

View File

@ -17,7 +17,13 @@ MAKEFLAGS += --no-print-directory
LIBFILE = $(OUTPUT)libapi.a
CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
ifeq ($(CC), clang)
CFLAGS += -O3
else
CFLAGS += -O6
endif
# Treat warnings as errors unless directed not to
ifneq ($(WERROR),0)

View File

@ -19,7 +19,13 @@ MAKEFLAGS += --no-print-directory
LIBFILE = $(OUTPUT)libsubcmd.a
CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC
ifeq ($(CC), clang)
CFLAGS += -O3
else
CFLAGS += -O6
endif
# Treat warnings as errors unless directed not to
ifneq ($(WERROR),0)

View File

@ -270,6 +270,8 @@ static int get_value(struct parse_opt_ctx_t *p,
}
if (get_arg(p, opt, flags, &arg))
return -1;
if (arg[0] == '-')
return opterror(opt, "expects an unsigned numerical value", flags);
*(unsigned int *)opt->value = strtol(arg, (char **)&s, 10);
if (*s)
return opterror(opt, "expects a numerical value", flags);
@ -302,6 +304,8 @@ static int get_value(struct parse_opt_ctx_t *p,
}
if (get_arg(p, opt, flags, &arg))
return -1;
if (arg[0] == '-')
return opterror(opt, "expects an unsigned numerical value", flags);
*(u64 *)opt->value = strtoull(arg, (char **)&s, 10);
if (*s)
return opterror(opt, "expects a numerical value", flags);

View File

@ -144,8 +144,12 @@ ifndef DEBUG
endif
ifeq ($(DEBUG),0)
ifeq ($(CC), clang)
CFLAGS += -O3
else
CFLAGS += -O6
endif
endif
ifdef PARSER_DEBUG
PARSER_DEBUG_BISON := -t

View File

@ -130,8 +130,6 @@ int bench_futex_hash(int argc, const char **argv,
}
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
nsecs = futexbench_sanitize_numeric(nsecs);
nfutexes = futexbench_sanitize_numeric(nfutexes);
sigfillset(&act.sa_mask);
act.sa_sigaction = toggle_done;
@ -139,8 +137,6 @@ int bench_futex_hash(int argc, const char **argv,
if (!nthreads) /* default to the number of CPUs */
nthreads = ncpus;
else
nthreads = futexbench_sanitize_numeric(nthreads);
worker = calloc(nthreads, sizeof(*worker));
if (!worker)

View File

@ -152,7 +152,6 @@ int bench_futex_lock_pi(int argc, const char **argv,
goto err;
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
nsecs = futexbench_sanitize_numeric(nsecs);
sigfillset(&act.sa_mask);
act.sa_sigaction = toggle_done;
@ -160,8 +159,6 @@ int bench_futex_lock_pi(int argc, const char **argv,
if (!nthreads)
nthreads = ncpus;
else
nthreads = futexbench_sanitize_numeric(nthreads);
worker = calloc(nthreads, sizeof(*worker));
if (!worker)

View File

@ -128,8 +128,6 @@ int bench_futex_requeue(int argc, const char **argv,
if (!nthreads)
nthreads = ncpus;
else
nthreads = futexbench_sanitize_numeric(nthreads);
worker = calloc(nthreads, sizeof(*worker));
if (!worker)

View File

@ -217,12 +217,8 @@ int bench_futex_wake_parallel(int argc, const char **argv,
sigaction(SIGINT, &act, NULL);
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
nwaking_threads = futexbench_sanitize_numeric(nwaking_threads);
if (!nblocked_threads)
nblocked_threads = ncpus;
else
nblocked_threads = futexbench_sanitize_numeric(nblocked_threads);
/* some sanity checks */
if (nwaking_threads > nblocked_threads || !nwaking_threads)

View File

@ -129,7 +129,6 @@ int bench_futex_wake(int argc, const char **argv,
}
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
nwakes = futexbench_sanitize_numeric(nwakes);
sigfillset(&act.sa_mask);
act.sa_sigaction = toggle_done;
@ -137,8 +136,6 @@ int bench_futex_wake(int argc, const char **argv,
if (!nthreads)
nthreads = ncpus;
else
nthreads = futexbench_sanitize_numeric(nthreads);
worker = calloc(nthreads, sizeof(*worker));
if (!worker)

View File

@ -7,7 +7,6 @@
#ifndef _FUTEX_H
#define _FUTEX_H
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
@ -100,7 +99,4 @@ static inline int pthread_attr_setaffinity_np(pthread_attr_t *attr,
}
#endif
/* User input sanitation */
#define futexbench_sanitize_numeric(__n) abs((__n))
#endif /* _FUTEX_H */

View File

@ -43,6 +43,7 @@
/*
* Debug printf:
*/
#undef dprintf
#define dprintf(x...) do { if (g && g->p.show_details >= 1) printf(x); } while (0)
struct thread_data {

View File

@ -655,22 +655,23 @@ record__finish_output(struct record *rec)
static int record__synthesize_workload(struct record *rec, bool tail)
{
struct {
struct thread_map map;
struct thread_map_data map_data;
} thread_map;
int err;
struct thread_map *thread_map;
if (rec->opts.tail_synthesize != tail)
return 0;
thread_map.map.nr = 1;
thread_map.map.map[0].pid = rec->evlist->workload.pid;
thread_map.map.map[0].comm = NULL;
return perf_event__synthesize_thread_map(&rec->tool, &thread_map.map,
thread_map = thread_map__new_by_tid(rec->evlist->workload.pid);
if (thread_map == NULL)
return -1;
err = perf_event__synthesize_thread_map(&rec->tool, thread_map,
process_synthesized_event,
&rec->session->machines.host,
rec->opts.sample_address,
rec->opts.proc_map_timeout);
thread_map__put(thread_map);
return err;
}
static int record__synthesize(struct record *rec, bool tail);

View File

@ -50,7 +50,8 @@ static int process_events(union perf_event **events, size_t count)
}
struct test_attr_event {
struct attr_event attr;
struct perf_event_header header;
struct perf_event_attr attr;
u64 id;
};
@ -71,21 +72,17 @@ int test__parse_no_sample_id_all(int subtest __maybe_unused)
int err;
struct test_attr_event event1 = {
.attr = {
.header = {
.type = PERF_RECORD_HEADER_ATTR,
.size = sizeof(struct test_attr_event),
},
},
.id = 1,
};
struct test_attr_event event2 = {
.attr = {
.header = {
.type = PERF_RECORD_HEADER_ATTR,
.size = sizeof(struct test_attr_event),
},
},
.id = 2,
};
struct mmap_event event3 = {

View File

@ -1448,7 +1448,7 @@ static bool ignore_missing_thread(struct perf_evsel *evsel,
return true;
}
static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
struct thread_map *threads)
{
int cpu, thread, nthreads;
@ -1459,6 +1459,30 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
if (perf_missing_features.write_backward && evsel->attr.write_backward)
return -EINVAL;
if (cpus == NULL) {
static struct cpu_map *empty_cpu_map;
if (empty_cpu_map == NULL) {
empty_cpu_map = cpu_map__dummy_new();
if (empty_cpu_map == NULL)
return -ENOMEM;
}
cpus = empty_cpu_map;
}
if (threads == NULL) {
static struct thread_map *empty_thread_map;
if (empty_thread_map == NULL) {
empty_thread_map = thread_map__new_by_tid(-1);
if (empty_thread_map == NULL)
return -ENOMEM;
}
threads = empty_thread_map;
}
if (evsel->system_wide)
nthreads = 1;
else
@ -1655,46 +1679,16 @@ void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads)
perf_evsel__free_fd(evsel);
}
static struct {
struct cpu_map map;
int cpus[1];
} empty_cpu_map = {
.map.nr = 1,
.cpus = { -1, },
};
static struct {
struct thread_map map;
int threads[1];
} empty_thread_map = {
.map.nr = 1,
.threads = { -1, },
};
int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
struct thread_map *threads)
{
if (cpus == NULL) {
/* Work around old compiler warnings about strict aliasing */
cpus = &empty_cpu_map.map;
}
if (threads == NULL)
threads = &empty_thread_map.map;
return __perf_evsel__open(evsel, cpus, threads);
}
int perf_evsel__open_per_cpu(struct perf_evsel *evsel,
struct cpu_map *cpus)
{
return __perf_evsel__open(evsel, cpus, &empty_thread_map.map);
return perf_evsel__open(evsel, cpus, NULL);
}
int perf_evsel__open_per_thread(struct perf_evsel *evsel,
struct thread_map *threads)
{
return __perf_evsel__open(evsel, &empty_cpu_map.map, threads);
return perf_evsel__open(evsel, NULL, threads);
}
static int perf_evsel__parse_id_sample(const struct perf_evsel *evsel,

View File

@ -23,4 +23,8 @@ $(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/in
$(call rule_mkdir)
$(call if_changed_dep,cc_o_c)
CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder -Wno-override-init
CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder
ifneq ($(CC), clang)
CFLAGS_intel-pt-insn-decoder.o += -Wno-override-init
endif

View File

@ -782,7 +782,7 @@ static u64 machine__get_running_kernel_start(struct machine *machine,
int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
{
enum map_type type;
int type;
u64 start = machine__get_running_kernel_start(machine, NULL);
/* In case of renewal the kernel map, destroy previous one */
@ -813,7 +813,7 @@ int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
void machine__destroy_kernel_maps(struct machine *machine)
{
enum map_type type;
int type;
for (type = 0; type < MAP__NR_TYPES; ++type) {
struct kmap *kmap;

View File

@ -2020,17 +2020,14 @@ static bool is_event_supported(u8 type, unsigned config)
.config = config,
.disabled = 1,
};
struct {
struct thread_map map;
int threads[1];
} tmap = {
.map.nr = 1,
.threads = { 0 },
};
struct thread_map *tmap = thread_map__new_by_tid(0);
if (tmap == NULL)
return false;
evsel = perf_evsel__new(&attr);
if (evsel) {
open_return = perf_evsel__open(evsel, NULL, &tmap.map);
open_return = perf_evsel__open(evsel, NULL, tmap);
ret = open_return >= 0;
if (open_return == -EACCES) {
@ -2042,7 +2039,7 @@ static bool is_event_supported(u8 type, unsigned config)
*
*/
evsel->attr.exclude_kernel = 1;
ret = perf_evsel__open(evsel, NULL, &tmap.map) >= 0;
ret = perf_evsel__open(evsel, NULL, tmap) >= 0;
}
perf_evsel__delete(evsel);
}

View File

@ -17,6 +17,8 @@
#include "parse-events.h"
#include "parse-events-bison.h"
void parse_events_error(YYLTYPE *loc, void *data, void *scanner, char const *msg);
#define ABORT_ON(val) \
do { \
if (val) \

View File

@ -945,12 +945,12 @@ static int check_info_data(struct perf_pmu_alias *alias,
* define unit, scale and snapshot, fail
* if there's more than one.
*/
if ((info->unit && alias->unit) ||
if ((info->unit && alias->unit[0]) ||
(info->scale && alias->scale) ||
(info->snapshot && alias->snapshot))
return -EINVAL;
if (alias->unit)
if (alias->unit[0])
info->unit = alias->unit;
if (alias->scale)

View File

@ -2061,7 +2061,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
bool is_kprobe)
{
struct symbol *sym = NULL;
struct map *map;
struct map *map = NULL;
u64 addr = tp->address;
int ret = -ENOENT;

View File

@ -1901,7 +1901,7 @@ int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
const char *symbol_name, u64 addr)
{
char *bracket;
enum map_type i;
int i;
struct ref_reloc_sym *ref;
ref = zalloc(sizeof(struct ref_reloc_sym));

View File

@ -32,7 +32,6 @@ EXTRA_WARNINGS += -Wold-style-definition
EXTRA_WARNINGS += -Wpacked
EXTRA_WARNINGS += -Wredundant-decls
EXTRA_WARNINGS += -Wshadow
EXTRA_WARNINGS += -Wstrict-aliasing=3
EXTRA_WARNINGS += -Wstrict-prototypes
EXTRA_WARNINGS += -Wswitch-default
EXTRA_WARNINGS += -Wswitch-enum
@ -40,6 +39,10 @@ EXTRA_WARNINGS += -Wundef
EXTRA_WARNINGS += -Wwrite-strings
EXTRA_WARNINGS += -Wformat
ifneq ($(CC), clang)
EXTRA_WARNINGS += -Wstrict-aliasing=3
endif
ifneq ($(findstring $(MAKEFLAGS), w),w)
PRINT_DIR = --no-print-directory
else