Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf events: Prefer union over variable length array

It is possible for casts to introduce alignment issues, prefer a union
for perf_record_event_update.

Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexey Bayduraev <alexey.v.bayduraev@linux.intel.com>
Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
Cc: Colin Ian King <colin.king@intel.com>
Cc: Dave Marchevsky <davemarchevsky@fb.com>
Cc: German Gomez <german.gomez@arm.com>
Cc: Gustavo A. R. Silva <gustavoars@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Kees Kook <keescook@chromium.org>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Cc: Song Liu <songliubraving@fb.com>
Cc: Stephane Eranian <eranian@google.com>
Link: https://lore.kernel.org/r/20220614143353.1559597-6-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
d773c999 3657ad4b

+27 -34
+10 -1
tools/lib/perf/include/perf/event.h
··· 233 233 struct perf_event_header header; 234 234 __u64 type; 235 235 __u64 id; 236 - char data[]; 236 + union { 237 + /* Used when type == PERF_EVENT_UPDATE__SCALE. */ 238 + struct perf_record_event_update_scale scale; 239 + /* Used when type == PERF_EVENT_UPDATE__UNIT. */ 240 + char unit[0]; 241 + /* Used when type == PERF_EVENT_UPDATE__NAME. */ 242 + char name[0]; 243 + /* Used when type == PERF_EVENT_UPDATE__CPUS. */ 244 + struct perf_record_event_update_cpus cpus; 245 + }; 237 246 }; 238 247 239 248 #define MAX_EVENT_NAME 64
+4 -10
tools/perf/tests/event_update.c
··· 21 21 22 22 TEST_ASSERT_VAL("wrong id", ev->id == 123); 23 23 TEST_ASSERT_VAL("wrong id", ev->type == PERF_EVENT_UPDATE__UNIT); 24 - TEST_ASSERT_VAL("wrong unit", !strcmp(ev->data, "KRAVA")); 24 + TEST_ASSERT_VAL("wrong unit", !strcmp(ev->unit, "KRAVA")); 25 25 return 0; 26 26 } 27 27 ··· 31 31 struct machine *machine __maybe_unused) 32 32 { 33 33 struct perf_record_event_update *ev = (struct perf_record_event_update *)event; 34 - struct perf_record_event_update_scale *ev_data; 35 - 36 - ev_data = (struct perf_record_event_update_scale *)ev->data; 37 34 38 35 TEST_ASSERT_VAL("wrong id", ev->id == 123); 39 36 TEST_ASSERT_VAL("wrong id", ev->type == PERF_EVENT_UPDATE__SCALE); 40 - TEST_ASSERT_VAL("wrong scale", ev_data->scale == 0.123); 37 + TEST_ASSERT_VAL("wrong scale", ev->scale.scale == 0.123); 41 38 return 0; 42 39 } 43 40 ··· 53 56 54 57 TEST_ASSERT_VAL("wrong id", ev->id == 123); 55 58 TEST_ASSERT_VAL("wrong id", ev->type == PERF_EVENT_UPDATE__NAME); 56 - TEST_ASSERT_VAL("wrong name", !strcmp(ev->data, tmp->name)); 59 + TEST_ASSERT_VAL("wrong name", !strcmp(ev->name, tmp->name)); 57 60 return 0; 58 61 } 59 62 ··· 63 66 struct machine *machine __maybe_unused) 64 67 { 65 68 struct perf_record_event_update *ev = (struct perf_record_event_update *)event; 66 - struct perf_record_event_update_cpus *ev_data; 67 69 struct perf_cpu_map *map; 68 70 69 - ev_data = (struct perf_record_event_update_cpus *) ev->data; 70 - 71 - map = cpu_map__new_data(&ev_data->cpus); 71 + map = cpu_map__new_data(&ev->cpus.cpus); 72 72 73 73 TEST_ASSERT_VAL("wrong id", ev->id == 123); 74 74 TEST_ASSERT_VAL("wrong type", ev->type == PERF_EVENT_UPDATE__CPUS);
+8 -16
tools/perf/util/header.c
··· 4295 4295 size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) 4296 4296 { 4297 4297 struct perf_record_event_update *ev = &event->event_update; 4298 - struct perf_record_event_update_scale *ev_scale; 4299 - struct perf_record_event_update_cpus *ev_cpus; 4300 4298 struct perf_cpu_map *map; 4301 4299 size_t ret; 4302 4300 ··· 4302 4304 4303 4305 switch (ev->type) { 4304 4306 case PERF_EVENT_UPDATE__SCALE: 4305 - ev_scale = (struct perf_record_event_update_scale *)ev->data; 4306 - ret += fprintf(fp, "... scale: %f\n", ev_scale->scale); 4307 + ret += fprintf(fp, "... scale: %f\n", ev->scale.scale); 4307 4308 break; 4308 4309 case PERF_EVENT_UPDATE__UNIT: 4309 - ret += fprintf(fp, "... unit: %s\n", ev->data); 4310 + ret += fprintf(fp, "... unit: %s\n", ev->unit); 4310 4311 break; 4311 4312 case PERF_EVENT_UPDATE__NAME: 4312 - ret += fprintf(fp, "... name: %s\n", ev->data); 4313 + ret += fprintf(fp, "... name: %s\n", ev->name); 4313 4314 break; 4314 4315 case PERF_EVENT_UPDATE__CPUS: 4315 - ev_cpus = (struct perf_record_event_update_cpus *)ev->data; 4316 4316 ret += fprintf(fp, "... "); 4317 4317 4318 - map = cpu_map__new_data(&ev_cpus->cpus); 4318 + map = cpu_map__new_data(&ev->cpus.cpus); 4319 4319 if (map) 4320 4320 ret += cpu_map__fprintf(map, fp); 4321 4321 else ··· 4370 4374 struct evlist **pevlist) 4371 4375 { 4372 4376 struct perf_record_event_update *ev = &event->event_update; 4373 - struct perf_record_event_update_scale *ev_scale; 4374 - struct perf_record_event_update_cpus *ev_cpus; 4375 4377 struct evlist *evlist; 4376 4378 struct evsel *evsel; 4377 4379 struct perf_cpu_map *map; ··· 4389 4395 switch (ev->type) { 4390 4396 case PERF_EVENT_UPDATE__UNIT: 4391 4397 free((char *)evsel->unit); 4392 - evsel->unit = strdup(ev->data); 4398 + evsel->unit = strdup(ev->unit); 4393 4399 break; 4394 4400 case PERF_EVENT_UPDATE__NAME: 4395 4401 free(evsel->name); 4396 - evsel->name = strdup(ev->data); 4402 + evsel->name = strdup(ev->name); 4397 4403 break; 4398 4404 case PERF_EVENT_UPDATE__SCALE: 4399 - ev_scale = (struct perf_record_event_update_scale *)ev->data; 4400 - evsel->scale = ev_scale->scale; 4405 + evsel->scale = ev->scale.scale; 4401 4406 break; 4402 4407 case PERF_EVENT_UPDATE__CPUS: 4403 - ev_cpus = (struct perf_record_event_update_cpus *)ev->data; 4404 - map = cpu_map__new_data(&ev_cpus->cpus); 4408 + map = cpu_map__new_data(&ev->cpus.cpus); 4405 4409 if (map) { 4406 4410 perf_cpu_map__put(evsel->core.own_cpus); 4407 4411 evsel->core.own_cpus = map;
+5 -7
tools/perf/util/synthetic-events.c
··· 1955 1955 if (ev == NULL) 1956 1956 return -ENOMEM; 1957 1957 1958 - strlcpy(ev->data, evsel->unit, size + 1); 1958 + strlcpy(ev->unit, evsel->unit, size + 1); 1959 1959 err = process(tool, (union perf_event *)ev, NULL, NULL); 1960 1960 free(ev); 1961 1961 return err; ··· 1972 1972 if (ev == NULL) 1973 1973 return -ENOMEM; 1974 1974 1975 - ev_data = (struct perf_record_event_update_scale *)ev->data; 1976 - ev_data->scale = evsel->scale; 1975 + ev->scale.scale = evsel->scale; 1977 1976 err = process(tool, (union perf_event *)ev, NULL, NULL); 1978 1977 free(ev); 1979 1978 return err; ··· 1989 1990 if (ev == NULL) 1990 1991 return -ENOMEM; 1991 1992 1992 - strlcpy(ev->data, evsel->name, len + 1); 1993 + strlcpy(ev->name, evsel->name, len + 1); 1993 1994 err = process(tool, (union perf_event *)ev, NULL, NULL); 1994 1995 free(ev); 1995 1996 return err; ··· 1998 1999 int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evsel *evsel, 1999 2000 perf_event__handler_t process) 2000 2001 { 2001 - size_t size = sizeof(struct perf_record_event_update); 2002 + size_t size = sizeof(struct perf_event_header) + sizeof(u64) + sizeof(u64); 2002 2003 struct perf_record_event_update *ev; 2003 2004 int max, err; 2004 2005 u16 type; ··· 2015 2016 ev->type = PERF_EVENT_UPDATE__CPUS; 2016 2017 ev->id = evsel->core.id[0]; 2017 2018 2018 - cpu_map_data__synthesize((struct perf_record_cpu_map_data *)ev->data, 2019 - evsel->core.own_cpus, type, max); 2019 + cpu_map_data__synthesize(&ev->cpus.cpus, evsel->core.own_cpus, type, max); 2020 2020 2021 2021 err = process(tool, (union perf_event *)ev, NULL, NULL); 2022 2022 free(ev);