From nobody Mon Apr 27 10:05:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D102AC433EF for ; Tue, 14 Jun 2022 14:35:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244011AbiFNOfW (ORCPT ); Tue, 14 Jun 2022 10:35:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354578AbiFNOeE (ORCPT ); Tue, 14 Jun 2022 10:34:04 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E63A73B2B7 for ; Tue, 14 Jun 2022 07:34:02 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-313cfb0c181so26560927b3.20 for ; Tue, 14 Jun 2022 07:34:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=+TZFSQCPo2Ju+GzmGovbnxDwp60NNa1c3IUVi64MUwE=; b=SM8KtAmpm2Ys3z8A/gDTRuvBA26+5U/1BsRykFz7fxva9Fy1jl5Va4R8L6nR/9DN1h ljm7gte7eNCVXnwatRY6PGYjXZWAomXm1T45myPY+P/NjYyQUl+P9MfmbniWzfDgkybs 0uztR1XXCaEa98Y3R3e54joIQ7S4QXneo9AFhkAPuMXZKGTw2sIZ3jjqUbEQ9nKLPtlt H9jOrzAqpEaW6VJJftaIBGw14zJ9kbcgHlLD4Srn/LO0j1PFPElfXbmPo2f7zr5+HHS4 A8P6QJ0fl0/diPiStE7yIz1575/sLY7AnWkRz4ocMtVFRBIpXcXE7m5ZojkvrJ0zZDkw 8JEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=+TZFSQCPo2Ju+GzmGovbnxDwp60NNa1c3IUVi64MUwE=; b=sZE8b6jsBTrLbOVG7KS2PLADLSewl1+z5psJdn28tK3VxGum8YZikRj6z2K67gcWoO 7Qz/PAt/cYGSWGD4rcXCm6WdOk03TB4PJlirgxdIGLXJpNeSpGUC18PPjnPBwH1d5B+e Mz0yKCBzsRyAR0qvGKWV5YoorrFi91i4pALCKb+g+Anf2Dell2gp+5EzqH+LNMHoALHC bUKRC0D1N4vPoxpkDRcQS8oe8RluuvDZMwTJDwt62CxL12DgEGTB/dMYYdeMO9kGx9pm dh8Rx6FXOLMiA8mvSlXePhxXnhmubDxd1/RUzdVVB0XxZT15RSBH9aYsX9+oMmUPNZUx YAKg== X-Gm-Message-State: AJIora/Kw4sPaa4p7Gw048GsgZruYl6ihqBu4K0M9KRLq5HDXlyfX3xh OUP5cQOKOFd11D5gR3epGLMGmMUjb5S3 X-Google-Smtp-Source: AGRyM1upxurQe3D8oHjt7njhWp6P1sk7HMXsEASFWzXkOiyjCYAjTePFki+v0C3+Zjsyt9r1UYqAf4bfCc40 X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:b55a:aaa7:a:1b17]) (user=irogers job=sendgmr) by 2002:a25:dcd1:0:b0:65c:d01c:f730 with SMTP id y200-20020a25dcd1000000b0065cd01cf730mr5738453ybe.372.1655217242022; Tue, 14 Jun 2022 07:34:02 -0700 (PDT) Date: Tue, 14 Jun 2022 07:33:48 -0700 In-Reply-To: <20220614143353.1559597-1-irogers@google.com> Message-Id: <20220614143353.1559597-2-irogers@google.com> Mime-Version: 1.0 References: <20220614143353.1559597-1-irogers@google.com> X-Mailer: git-send-email 2.36.1.476.g0c4daa206d-goog Subject: [PATCH v2 1/6] perf cpumap: Const map for max From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , James Clark , Kees Cook , "Gustavo A. R. Silva" , Adrian Hunter , Riccardo Mancini , German Gomez , Colin Ian King , Song Liu , Dave Marchevsky , Athira Rajeev , Alexey Bayduraev , Leo Yan , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allows max to be used with const perf_cpu_maps. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/lib/perf/cpumap.c | 2 +- tools/lib/perf/include/perf/cpumap.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index 384d5e076ee4..6cd0be7c1bb4 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -309,7 +309,7 @@ bool perf_cpu_map__has(const struct perf_cpu_map *cpus,= struct perf_cpu cpu) return perf_cpu_map__idx(cpus, cpu) !=3D -1; } =20 -struct perf_cpu perf_cpu_map__max(struct perf_cpu_map *map) +struct perf_cpu perf_cpu_map__max(const struct perf_cpu_map *map) { struct perf_cpu result =3D { .cpu =3D -1 diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/include/= perf/cpumap.h index 24de795b09bb..03aceb72a783 100644 --- a/tools/lib/perf/include/perf/cpumap.h +++ b/tools/lib/perf/include/perf/cpumap.h @@ -23,7 +23,7 @@ LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *m= ap); LIBPERF_API struct perf_cpu perf_cpu_map__cpu(const struct perf_cpu_map *c= pus, int idx); LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus); LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map); -LIBPERF_API struct perf_cpu perf_cpu_map__max(struct perf_cpu_map *map); +LIBPERF_API struct perf_cpu perf_cpu_map__max(const struct perf_cpu_map *m= ap); LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct = perf_cpu cpu); =20 #define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \ --=20 2.36.1.476.g0c4daa206d-goog From nobody Mon Apr 27 10:05:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92410C43334 for ; Tue, 14 Jun 2022 14:35:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244418AbiFNOf0 (ORCPT ); Tue, 14 Jun 2022 10:35:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355467AbiFNOeK (ORCPT ); Tue, 14 Jun 2022 10:34:10 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 604D436E24 for ; Tue, 14 Jun 2022 07:34:05 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id v127-20020a256185000000b0065cbe0f6999so7708318ybb.22 for ; Tue, 14 Jun 2022 07:34:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=CO3D4hTzGOfHEmW5/B6ajWEyTv2kPQTJ9KX6c7xDLfk=; b=phffdDdBU4lgb8BoixzP/AC9Kl0ZOB2Uj+TgZCRIxAhkQ6fzCHTWcQEFbTK/aGYTgL +pB57c8L+coHi9FCFrR9DOdMI3W66G8vZVhalCi68PMMVALvh2qput85ncMVrXktD7Xr +qFAjoL0s4ln+eu0cQHhnZzPpPP/NdH6/rVfirDLUI07gc6kFdsZ0E4kIHhlhOD2XfYJ 3p3W8YTRa8hEadLrk9gvu3c0hqNXypHHjeODjmAkPytVfd3lvRkpQLFI0EP4mQPkqbkv yosTQ8Dm9OQfl2eewK/IXZ/8axDUT7hT4H0gfKPBpGaE+Xs66XAkwLCi9LOQjAJFvP8K g9MA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=CO3D4hTzGOfHEmW5/B6ajWEyTv2kPQTJ9KX6c7xDLfk=; b=wNAsadG/ebVy+d5kk+RhVbxJfh4XcelfY2+4qgt8S2DyYICipQ8b+KV7j0pwxK+8j1 pDbyLdA6+AowlEZ+88nUe4vT2XgGW5Llq2wPGD7Ibkr6j592S92zorlp2KuqIwMR4KyX pAq6sFIn+Eo8LXH1gG3xAJRlwIqkkAd80lZtjeon/VMxvul6ik8sMSgyFlRjt5f8jtXI 1TsfgBvK10A+3IWzxQUEVG11WzlOX2Nnc4kX30/TxpTRdZIiZAzNdadVlGiuyh661V7F JJukpvYH7Nhqrb5ikrXvsgNjSU88ZPvcCYsFY3KuZI1I102987DSNuoePnw3DP8gl3zy p0KQ== X-Gm-Message-State: AJIora/EX5J1EKJAwBKmndNyHhg37IrcGPjfy6j4ZOOhloQUxedHgpVg ZucrcqPxira9+CKfXUisYHeBOt5eekc2 X-Google-Smtp-Source: AGRyM1vb+8dVtgkqAvldV+wIVoCPTAtyJliDFVvrwzrOT1wfCpvgGQys+evmTm/OCXAd1QLatlZ1CoO0iRLp X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:b55a:aaa7:a:1b17]) (user=irogers job=sendgmr) by 2002:a05:6902:1006:b0:660:6f21:a210 with SMTP id w6-20020a056902100600b006606f21a210mr5360979ybt.178.1655217244544; Tue, 14 Jun 2022 07:34:04 -0700 (PDT) Date: Tue, 14 Jun 2022 07:33:49 -0700 In-Reply-To: <20220614143353.1559597-1-irogers@google.com> Message-Id: <20220614143353.1559597-3-irogers@google.com> Mime-Version: 1.0 References: <20220614143353.1559597-1-irogers@google.com> X-Mailer: git-send-email 2.36.1.476.g0c4daa206d-goog Subject: [PATCH v2 2/6] perf cpumap: Synthetic events and const/static From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , James Clark , Kees Cook , "Gustavo A. R. Silva" , Adrian Hunter , Riccardo Mancini , German Gomez , Colin Ian King , Song Liu , Dave Marchevsky , Athira Rajeev , Alexey Bayduraev , Leo Yan , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Make the cpumap arguments const to make it clearer they are in rather than out arguments. Make two functions static and remove external declarations. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/perf/util/event.h | 4 ---- tools/perf/util/synthetic-events.c | 20 +++++++++++--------- tools/perf/util/synthetic-events.h | 2 +- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index cdd72e05fd28..2a69e639f6b3 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -461,10 +461,6 @@ size_t perf_event__fprintf(union perf_event *event, st= ruct machine *machine, FIL int kallsyms__get_function_start(const char *kallsyms_filename, const char *symbol_name, u64 *addr); =20 -void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *typ= e, int *max); -void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, stru= ct perf_cpu_map *map, - u16 type, int max); - void event_attr_init(struct perf_event_attr *attr); =20 int perf_event_paranoid(void); diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index 27acdc5e5723..b8a42a096502 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1184,7 +1184,7 @@ int perf_event__synthesize_thread_map2(struct perf_to= ol *tool, } =20 static void synthesize_cpus(struct cpu_map_entries *cpus, - struct perf_cpu_map *map) + const struct perf_cpu_map *map) { int i, map_nr =3D perf_cpu_map__nr(map); =20 @@ -1195,7 +1195,7 @@ static void synthesize_cpus(struct cpu_map_entries *c= pus, } =20 static void synthesize_mask(struct perf_record_record_cpu_map *mask, - struct perf_cpu_map *map, int max) + const struct perf_cpu_map *map, int max) { int i; =20 @@ -1206,12 +1206,12 @@ static void synthesize_mask(struct perf_record_reco= rd_cpu_map *mask, set_bit(perf_cpu_map__cpu(map, i).cpu, mask->mask); } =20 -static size_t cpus_size(struct perf_cpu_map *map) +static size_t cpus_size(const struct perf_cpu_map *map) { return sizeof(struct cpu_map_entries) + perf_cpu_map__nr(map) * sizeof(u1= 6); } =20 -static size_t mask_size(struct perf_cpu_map *map, int *max) +static size_t mask_size(const struct perf_cpu_map *map, int *max) { int i; =20 @@ -1228,7 +1228,8 @@ static size_t mask_size(struct perf_cpu_map *map, int= *max) return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * = sizeof(long); } =20 -void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *typ= e, int *max) +static void *cpu_map_data__alloc(const struct perf_cpu_map *map, size_t *s= ize, + u16 *type, int *max) { size_t size_cpus, size_mask; bool is_dummy =3D perf_cpu_map__empty(map); @@ -1262,8 +1263,9 @@ void *cpu_map_data__alloc(struct perf_cpu_map *map, s= ize_t *size, u16 *type, int return zalloc(*size); } =20 -void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struc= t perf_cpu_map *map, - u16 type, int max) +static void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, + const struct perf_cpu_map *map, + u16 type, int max) { data->type =3D type; =20 @@ -1278,7 +1280,7 @@ void cpu_map_data__synthesize(struct perf_record_cpu_= map_data *data, struct perf } } =20 -static struct perf_record_cpu_map *cpu_map_event__new(struct perf_cpu_map = *map) +static struct perf_record_cpu_map *cpu_map_event__new(const struct perf_cp= u_map *map) { size_t size =3D sizeof(struct perf_record_cpu_map); struct perf_record_cpu_map *event; @@ -1298,7 +1300,7 @@ static struct perf_record_cpu_map *cpu_map_event__new= (struct perf_cpu_map *map) } =20 int perf_event__synthesize_cpu_map(struct perf_tool *tool, - struct perf_cpu_map *map, + const struct perf_cpu_map *map, perf_event__handler_t process, struct machine *machine) { diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic= -events.h index 78a0450db164..44839190234a 100644 --- a/tools/perf/util/synthetic-events.h +++ b/tools/perf/util/synthetic-events.h @@ -46,7 +46,7 @@ typedef int (*perf_event__handler_t)(struct perf_tool *to= ol, union perf_event *e int perf_event__synthesize_attrs(struct perf_tool *tool, struct evlist *ev= list, perf_event__handler_t process); int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_= attr *attr, u32 ids, u64 *id, perf_event__handler_t process); int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *po= s, u16 misc, perf_event__handler_t process, struct machine *machine); -int perf_event__synthesize_cpu_map(struct perf_tool *tool, struct perf_cpu= _map *cpus, perf_event__handler_t process, struct machine *machine); +int perf_event__synthesize_cpu_map(struct perf_tool *tool, const struct pe= rf_cpu_map *cpus, perf_event__handler_t process, struct machine *machine); int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struc= t evsel *evsel, perf_event__handler_t process); int perf_event__synthesize_event_update_name(struct perf_tool *tool, struc= t evsel *evsel, perf_event__handler_t process); int perf_event__synthesize_event_update_scale(struct perf_tool *tool, stru= ct evsel *evsel, perf_event__handler_t process); --=20 2.36.1.476.g0c4daa206d-goog From nobody Mon Apr 27 10:05:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA6BCC433EF for ; Tue, 14 Jun 2022 14:35:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345596AbiFNOfb (ORCPT ); Tue, 14 Jun 2022 10:35:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55466 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355419AbiFNOeJ (ORCPT ); Tue, 14 Jun 2022 10:34:09 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7542136B60 for ; Tue, 14 Jun 2022 07:34:07 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id s23-20020a257717000000b00660719d9f2fso7746394ybc.23 for ; Tue, 14 Jun 2022 07:34:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=jlLUXMLBK64yscSUpLZfKbiaF8vfOQAkVnrzfyvEsEQ=; b=Rq2LH/kH8h16OGkoEDqaZztuc/ZNrRQpln9CWWY2rlmxP6xfWs+uX7GPgsLdw9hhbK iI/w0ywcMZ0+Jcuuu7SGFyOEUki/nvJsuSn+8WNytUMuCbFnMMvBIw+3T8hcj0/raMiP YV2/fFagV5ebYC8CoBSloDp60zD0BcYN03U6nZ9V8VbHO2TYxC4LMNTO6tjrCIWL2NPT l76f05GB8Kp+BKCIPnYqbGTTCEUSKU3VnJT+6nB+nQu8xkcaKfxi39W3k5psa2GNti7w lGxaB9Hw0jiBOFVV0tIL+ZqkV8ZRq6j6pcsVGYg7NOFJZskT+ramiaVCIy0bK5FfOc0v 90lQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=jlLUXMLBK64yscSUpLZfKbiaF8vfOQAkVnrzfyvEsEQ=; b=KYrzLLgIqskUJ4kmPZUnUsiVGEpV9HIThD3tle9+PMyQ1sAc3greDCznfO7EUkQQV3 SSNE2Avsl6iR6nAEgrpN5prEr4bj4aCyDkEXpDMTDW20RLYEivHUR+3bmw/qFFAnYHeW J5XVsdeh79NFSvWboOiu8QLW53N4vhf3F5caqklzq5Wz8qQiF/Al0Gyn3g+iHX8zfVv1 3UibtrRjouwX2mRkr4UhuF0DDLxVzmSvDDFXdbOWwWuRdyM2l4rqD3JqyOlj92JRTxyr O8oC8mPNrrdf9BhQGT+P7UhVz8kZYGeOZn7nBBKNcqYYvncoyqr0bUS0ZDMyNoyrP6eF hN8g== X-Gm-Message-State: AJIora+BAf28EU9n9Fj6p56sxbiE71dV9Hnfi+J0s4w8Umdtdap4oDMk 6jfhkjYTAw6MtWR3+ybnCHF+feFGsrN8 X-Google-Smtp-Source: AGRyM1tFploq+20UVqYMG2V2Ds3SMLs4FHX4Vl/ncalQoNGj9rQow5MxoLBUK3lObTvjj6Lrd91tYger8G4/ X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:b55a:aaa7:a:1b17]) (user=irogers job=sendgmr) by 2002:a25:b884:0:b0:664:7ce8:38f0 with SMTP id w4-20020a25b884000000b006647ce838f0mr5266397ybj.503.1655217246623; Tue, 14 Jun 2022 07:34:06 -0700 (PDT) Date: Tue, 14 Jun 2022 07:33:50 -0700 In-Reply-To: <20220614143353.1559597-1-irogers@google.com> Message-Id: <20220614143353.1559597-4-irogers@google.com> Mime-Version: 1.0 References: <20220614143353.1559597-1-irogers@google.com> X-Mailer: git-send-email 2.36.1.476.g0c4daa206d-goog Subject: [PATCH v2 3/6] perf cpumap: Compute mask size in constant time From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , James Clark , Kees Cook , "Gustavo A. R. Silva" , Adrian Hunter , Riccardo Mancini , German Gomez , Colin Ian King , Song Liu , Dave Marchevsky , Athira Rajeev , Alexey Bayduraev , Leo Yan , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" perf_cpu_map__max computes the cpumap's maximum value, no need to iterate over all values. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/perf/util/synthetic-events.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index b8a42a096502..0d87df20ec44 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1213,18 +1213,7 @@ static size_t cpus_size(const struct perf_cpu_map *m= ap) =20 static size_t mask_size(const struct perf_cpu_map *map, int *max) { - int i; - - *max =3D 0; - - for (i =3D 0; i < perf_cpu_map__nr(map); i++) { - /* bit position of the cpu is + 1 */ - int bit =3D perf_cpu_map__cpu(map, i).cpu + 1; - - if (bit > *max) - *max =3D bit; - } - + *max =3D perf_cpu_map__max(map).cpu; return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * = sizeof(long); } =20 --=20 2.36.1.476.g0c4daa206d-goog From nobody Mon Apr 27 10:05:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03604C433EF for ; Tue, 14 Jun 2022 14:35:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348134AbiFNOfi (ORCPT ); Tue, 14 Jun 2022 10:35:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55450 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355722AbiFNOeL (ORCPT ); Tue, 14 Jun 2022 10:34:11 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D92213701C for ; Tue, 14 Jun 2022 07:34:09 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id j10-20020aa783ca000000b00518265c7cacso3944095pfn.3 for ; Tue, 14 Jun 2022 07:34:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Mij7LDAjsaqpdDbRwp/XiyhZ7u53hLBGMhINXu+GQlg=; b=OaigZg+2L79oFOKR0PVEf7ikBXmS77koR30mTyhh45JMHT6MHl67ssAsnYpm4SIkj4 G2UQyZxlnHKYzjZbmJZGRBOs5B+4xL25tkmxTgntfPXHrvbglDonXCuQsoxK/GlW2jBT lvDFeXrRIxEKoh2/bcR5T6W43oYLLRd6QdY23S18XzAzkyLW2UpnCvUj4OMdKxKQGGEN pEjgq9tNeKHMfgvIgGzovK3V4Zqde7GeMuMGKLIagFjArgt61HdC6xAhBL+j4hTCJHhn ucRLp5k1XKEinVcaBY/el7gENENZZ+su3sTp1FJgNmrK+jsdd96AG6Lv9raby3Csa+8g b25w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Mij7LDAjsaqpdDbRwp/XiyhZ7u53hLBGMhINXu+GQlg=; b=cMAhXrmbuOXUrZLcRXbl8CJ4JUu02zNUI7AS0DJMel4sK1sbuiW+FALyOYXvtBNicg D2aCOrEJRwGAkzl6CopYsbdb2b9LpSHU4vUfQ8B+DX3Qgg8Tx2AjyOIIIemssekBWCQL qAAujzQkNXnOsbzXlUHSXK5MNJnt5hpOAR1i6P4HN6o/ZLaJ6kYuIwtGMIXBTVqgLPfR 4s+Fi7MAOzL9g5xyRh5yXN9/21KmFS37lJKZhvxkPnR+kgroS5RPlFJ4EBZ6is5n4yue CKjLaVgWTLMhFkV4Iw3klPLnWlThKAugu29sTVVueEpwO0vdS8p+zER+8PqtD3mMf9Is 6nTQ== X-Gm-Message-State: AJIora/Brvj1ZO7FFsobjmE8sIhVjSye9/b6A6TP/ZKSbbIVPHCrkbhX RzzB2pzpMpG9FJkBmGqCOP6fzAMRxQ8z X-Google-Smtp-Source: AGRyM1tGuB6H61/UoEjOl9X8VjtVBe2vfu9khpw7qz+ohCUg/Mg1Uc4M8IvfvsJAdmC2S/tEcOCUClmcxa9a X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:b55a:aaa7:a:1b17]) (user=irogers job=sendgmr) by 2002:a17:902:e88e:b0:163:ee82:ffb with SMTP id w14-20020a170902e88e00b00163ee820ffbmr5052335plg.142.1655217249131; Tue, 14 Jun 2022 07:34:09 -0700 (PDT) Date: Tue, 14 Jun 2022 07:33:51 -0700 In-Reply-To: <20220614143353.1559597-1-irogers@google.com> Message-Id: <20220614143353.1559597-5-irogers@google.com> Mime-Version: 1.0 References: <20220614143353.1559597-1-irogers@google.com> X-Mailer: git-send-email 2.36.1.476.g0c4daa206d-goog Subject: [PATCH v2 4/6] perf cpumap: Fix alignment for masks in event encoding From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , James Clark , Kees Cook , "Gustavo A. R. Silva" , Adrian Hunter , Riccardo Mancini , German Gomez , Colin Ian King , Song Liu , Dave Marchevsky , Athira Rajeev , Alexey Bayduraev , Leo Yan , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A mask encoding of a cpu map is laid out as: u16 nr u16 long_size unsigned long mask[]; However, the mask may be 8-byte aligned meaning there is a 4-byte pad after long_size. This means 32-bit and 64-bit builds see the mask as being at different offsets. On top of this the structure is in the byte data[] encoded as: u16 type char data[] This means the mask's struct isn't the required 4 or 8 byte aligned, but is offset by 2. Consequently the long reads and writes are causing undefined behavior as the alignment is broken. Fix the mask struct by creating explicit 32 and 64-bit variants, use a union to avoid data[] and casts; the struct must be packed so the layout matches the existing perf.data layout. Taking an address of a member of a packed struct breaks alignment so pass the packed perf_record_cpu_map_data to functions, so they can access variables with the right alignment. As the 64-bit version has 4 bytes of padding, optimizing writing to only write the 32-bit version. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/lib/perf/include/perf/event.h | 36 +++++++++++-- tools/perf/tests/cpumap.c | 19 ++++--- tools/perf/util/cpumap.c | 80 +++++++++++++++++++++++------ tools/perf/util/cpumap.h | 4 +- tools/perf/util/session.c | 30 +++++------ tools/perf/util/synthetic-events.c | 34 +++++++----- 6 files changed, 143 insertions(+), 60 deletions(-) diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/p= erf/event.h index e7758707cadd..d2d32589758a 100644 --- a/tools/lib/perf/include/perf/event.h +++ b/tools/lib/perf/include/perf/event.h @@ -6,6 +6,7 @@ #include #include #include +#include #include /* pid_t */ =20 #define event_contains(obj, mem) ((obj).header.size > offsetof(typeof(obj)= , mem)) @@ -153,20 +154,47 @@ enum { PERF_CPU_MAP__MASK =3D 1, }; =20 +/* + * Array encoding of a perf_cpu_map where nr is the number of entries in c= pu[] + * and each entry is a value for a CPU in the map. + */ struct cpu_map_entries { __u16 nr; __u16 cpu[]; }; =20 -struct perf_record_record_cpu_map { +/* Bitmap encoding of a perf_cpu_map where bitmap entries are 32-bit. */ +struct perf_record_mask_cpu_map32 { + /* Number of mask values. */ __u16 nr; + /* Constant 4. */ __u16 long_size; - unsigned long mask[]; + /* Bitmap data. */ + __u32 mask[]; }; =20 -struct perf_record_cpu_map_data { +/* Bitmap encoding of a perf_cpu_map where bitmap entries are 64-bit. */ +struct perf_record_mask_cpu_map64 { + /* Number of mask values. */ + __u16 nr; + /* Constant 8. */ + __u16 long_size; + /* Legacy padding. */ + char __pad[4]; + /* Bitmap data. */ + __u64 mask[]; +}; + +struct __packed perf_record_cpu_map_data { __u16 type; - char data[]; + union { + /* Used when type =3D=3D PERF_CPU_MAP__CPUS. */ + struct cpu_map_entries cpus_data; + /* Used when type =3D=3D PERF_CPU_MAP__MASK and long_size =3D=3D 4. */ + struct perf_record_mask_cpu_map32 mask32_data; + /* Used when type =3D=3D PERF_CPU_MAP__MASK and long_size =3D=3D 8. */ + struct perf_record_mask_cpu_map64 mask64_data; + }; }; =20 struct perf_record_cpu_map { diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index f94929ebb54b..7ea150cdc137 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -17,21 +17,23 @@ static int process_event_mask(struct perf_tool *tool __= maybe_unused, struct machine *machine __maybe_unused) { struct perf_record_cpu_map *map_event =3D &event->cpu_map; - struct perf_record_record_cpu_map *mask; struct perf_record_cpu_map_data *data; struct perf_cpu_map *map; int i; + unsigned int long_size; =20 data =3D &map_event->data; =20 TEST_ASSERT_VAL("wrong type", data->type =3D=3D PERF_CPU_MAP__MASK); =20 - mask =3D (struct perf_record_record_cpu_map *)data->data; + long_size =3D data->mask32_data.long_size; =20 - TEST_ASSERT_VAL("wrong nr", mask->nr =3D=3D 1); + TEST_ASSERT_VAL("wrong long_size", long_size =3D=3D 4 || long_size =3D=3D= 8); + + TEST_ASSERT_VAL("wrong nr", data->mask32_data.nr =3D=3D 1); =20 for (i =3D 0; i < 20; i++) { - TEST_ASSERT_VAL("wrong cpu", test_bit(i, mask->mask)); + TEST_ASSERT_VAL("wrong cpu", perf_record_cpu_map_data__test_bit(i, data)= ); } =20 map =3D cpu_map__new_data(data); @@ -51,7 +53,6 @@ static int process_event_cpus(struct perf_tool *tool __ma= ybe_unused, struct machine *machine __maybe_unused) { struct perf_record_cpu_map *map_event =3D &event->cpu_map; - struct cpu_map_entries *cpus; struct perf_record_cpu_map_data *data; struct perf_cpu_map *map; =20 @@ -59,11 +60,9 @@ static int process_event_cpus(struct perf_tool *tool __m= aybe_unused, =20 TEST_ASSERT_VAL("wrong type", data->type =3D=3D PERF_CPU_MAP__CPUS); =20 - cpus =3D (struct cpu_map_entries *)data->data; - - TEST_ASSERT_VAL("wrong nr", cpus->nr =3D=3D 2); - TEST_ASSERT_VAL("wrong cpu", cpus->cpu[0] =3D=3D 1); - TEST_ASSERT_VAL("wrong cpu", cpus->cpu[1] =3D=3D 256); + TEST_ASSERT_VAL("wrong nr", data->cpus_data.nr =3D=3D 2); + TEST_ASSERT_VAL("wrong cpu", data->cpus_data.cpu[0] =3D=3D 1); + TEST_ASSERT_VAL("wrong cpu", data->cpus_data.cpu[1] =3D=3D 256); =20 map =3D cpu_map__new_data(data); TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map) =3D=3D 2); diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 12b2243222b0..ae43fb88f444 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -22,54 +22,102 @@ static int max_node_num; */ static int *cpunode_map; =20 -static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *= cpus) +bool perf_record_cpu_map_data__test_bit(int i, + const struct perf_record_cpu_map_data *data) +{ + int bit_word32 =3D i / 32; + __u32 bit_mask32 =3D 1U << (i & 31); + int bit_word64 =3D i / 64; + __u64 bit_mask64 =3D ((__u64)1) << (i & 63); + + return (data->mask32_data.long_size =3D=3D 4) + ? (bit_word32 < data->mask32_data.nr) && + (data->mask32_data.mask[bit_word32] & bit_mask32) !=3D 0 + : (bit_word64 < data->mask64_data.nr) && + (data->mask64_data.mask[bit_word64] & bit_mask64) !=3D 0; +} + +/* Read ith mask value from data into the given 64-bit sized bitmap */ +static void perf_record_cpu_map_data__read_one_mask(const struct perf_reco= rd_cpu_map_data *data, + int i, unsigned long *bitmap) +{ +#if __SIZEOF_LONG__ =3D=3D 8 + if (data->mask32_data.long_size =3D=3D 4) + bitmap[0] =3D data->mask32_data.mask[i]; + else + bitmap[0] =3D data->mask64_data.mask[i]; +#else + if (data->mask32_data.long_size =3D=3D 4) { + bitmap[0] =3D data->mask32_data.mask[i]; + bitmap[1] =3D 0; + } else { +#if __BYTE_ORDER__ =3D=3D __ORDER_BIG_ENDIAN__ + bitmap[0] =3D (unsigned long)(data->mask64_data.mask[i] >> 32); + bitmap[1] =3D (unsigned long)data->mask64_data.mask[i]; +#else + bitmap[0] =3D (unsigned long)data->mask64_data.mask[i]; + bitmap[1] =3D (unsigned long)(data->mask64_data.mask[i] >> 32); +#endif + } +#endif +} +static struct perf_cpu_map *cpu_map__from_entries(const struct perf_record= _cpu_map_data *data) { struct perf_cpu_map *map; =20 - map =3D perf_cpu_map__empty_new(cpus->nr); + map =3D perf_cpu_map__empty_new(data->cpus_data.nr); if (map) { unsigned i; =20 - for (i =3D 0; i < cpus->nr; i++) { + for (i =3D 0; i < data->cpus_data.nr; i++) { /* * Special treatment for -1, which is not real cpu number, * and we need to use (int) -1 to initialize map[i], * otherwise it would become 65535. */ - if (cpus->cpu[i] =3D=3D (u16) -1) + if (data->cpus_data.cpu[i] =3D=3D (u16) -1) map->map[i].cpu =3D -1; else - map->map[i].cpu =3D (int) cpus->cpu[i]; + map->map[i].cpu =3D (int) data->cpus_data.cpu[i]; } } =20 return map; } =20 -static struct perf_cpu_map *cpu_map__from_mask(struct perf_record_record_c= pu_map *mask) +static struct perf_cpu_map *cpu_map__from_mask(const struct perf_record_cp= u_map_data *data) { + DECLARE_BITMAP(local_copy, 64); + int weight =3D 0, mask_nr =3D data->mask32_data.nr; struct perf_cpu_map *map; - int nr, nbits =3D mask->nr * mask->long_size * BITS_PER_BYTE; =20 - nr =3D bitmap_weight(mask->mask, nbits); + for (int i =3D 0; i < mask_nr; i++) { + perf_record_cpu_map_data__read_one_mask(data, i, local_copy); + weight +=3D bitmap_weight(local_copy, 64); + } + + map =3D perf_cpu_map__empty_new(weight); + if (!map) + return NULL; =20 - map =3D perf_cpu_map__empty_new(nr); - if (map) { - int cpu, i =3D 0; + for (int i =3D 0, j =3D 0; i < mask_nr; i++) { + int cpus_per_i =3D (i * data->mask32_data.long_size * BITS_PER_BYTE); + int cpu; =20 - for_each_set_bit(cpu, mask->mask, nbits) - map->map[i++].cpu =3D cpu; + perf_record_cpu_map_data__read_one_mask(data, i, local_copy); + for_each_set_bit(cpu, local_copy, 64) + map->map[j++].cpu =3D cpu + cpus_per_i; } return map; =20 } =20 -struct perf_cpu_map *cpu_map__new_data(struct perf_record_cpu_map_data *da= ta) +struct perf_cpu_map *cpu_map__new_data(const struct perf_record_cpu_map_da= ta *data) { if (data->type =3D=3D PERF_CPU_MAP__CPUS) - return cpu_map__from_entries((struct cpu_map_entries *)data->data); + return cpu_map__from_entries(data); else - return cpu_map__from_mask((struct perf_record_record_cpu_map *)data->dat= a); + return cpu_map__from_mask(data); } =20 size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp) diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 703ae6d3386e..fa8a5acdcae1 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -37,9 +37,11 @@ struct cpu_aggr_map { =20 struct perf_record_cpu_map_data; =20 +bool perf_record_cpu_map_data__test_bit(int i, const struct perf_record_cp= u_map_data *data); + struct perf_cpu_map *perf_cpu_map__empty_new(int nr); =20 -struct perf_cpu_map *cpu_map__new_data(struct perf_record_cpu_map_data *da= ta); +struct perf_cpu_map *cpu_map__new_data(const struct perf_record_cpu_map_da= ta *data); size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size); size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t s= ize); size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0aa818977d2b..d52a39ba48e3 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -914,30 +914,30 @@ static void perf_event__cpu_map_swap(union perf_event= *event, bool sample_id_all __maybe_unused) { struct perf_record_cpu_map_data *data =3D &event->cpu_map.data; - struct cpu_map_entries *cpus; - struct perf_record_record_cpu_map *mask; - unsigned i; =20 data->type =3D bswap_16(data->type); =20 switch (data->type) { case PERF_CPU_MAP__CPUS: - cpus =3D (struct cpu_map_entries *)data->data; - - cpus->nr =3D bswap_16(cpus->nr); + data->cpus_data.nr =3D bswap_16(data->cpus_data.nr); =20 - for (i =3D 0; i < cpus->nr; i++) - cpus->cpu[i] =3D bswap_16(cpus->cpu[i]); + for (unsigned i =3D 0; i < data->cpus_data.nr; i++) + data->cpus_data.cpu[i] =3D bswap_16(data->cpus_data.cpu[i]); break; case PERF_CPU_MAP__MASK: - mask =3D (struct perf_record_record_cpu_map *)data->data; - - mask->nr =3D bswap_16(mask->nr); - mask->long_size =3D bswap_16(mask->long_size); + data->mask32_data.long_size =3D bswap_16(data->mask32_data.long_size); =20 - switch (mask->long_size) { - case 4: mem_bswap_32(&mask->mask, mask->nr); break; - case 8: mem_bswap_64(&mask->mask, mask->nr); break; + switch (data->mask32_data.long_size) { + case 4: + data->mask32_data.nr =3D bswap_16(data->mask32_data.nr); + for (unsigned i =3D 0; i < data->mask32_data.nr; i++) + data->mask32_data.mask[i] =3D bswap_32(data->mask32_data.mask[i]); + break; + case 8: + data->mask64_data.nr =3D bswap_16(data->mask64_data.nr); + for (unsigned i =3D 0; i < data->mask64_data.nr; i++) + data->mask64_data.mask[i] =3D bswap_64(data->mask64_data.mask[i]); + break; default: pr_err("cpu_map swap: unsupported long size\n"); } diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index 0d87df20ec44..4fa7d0d7dbcf 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1183,27 +1183,33 @@ int perf_event__synthesize_thread_map2(struct perf_= tool *tool, return err; } =20 -static void synthesize_cpus(struct cpu_map_entries *cpus, +static void synthesize_cpus(struct perf_record_cpu_map_data *data, const struct perf_cpu_map *map) { int i, map_nr =3D perf_cpu_map__nr(map); =20 - cpus->nr =3D map_nr; + data->cpus_data.nr =3D map_nr; =20 for (i =3D 0; i < map_nr; i++) - cpus->cpu[i] =3D perf_cpu_map__cpu(map, i).cpu; + data->cpus_data.cpu[i] =3D perf_cpu_map__cpu(map, i).cpu; } =20 -static void synthesize_mask(struct perf_record_record_cpu_map *mask, +static void synthesize_mask(struct perf_record_cpu_map_data *data, const struct perf_cpu_map *map, int max) { - int i; + int idx; + struct perf_cpu cpu; + + /* Due to padding, the 4bytes per entry mask variant is always smaller. */ + data->mask32_data.nr =3D BITS_TO_U32(max); + data->mask32_data.long_size =3D 4; =20 - mask->nr =3D BITS_TO_LONGS(max); - mask->long_size =3D sizeof(long); + perf_cpu_map__for_each_cpu(cpu, idx, map) { + int bit_word =3D cpu.cpu / 32; + __u32 bit_mask =3D 1U << (cpu.cpu & 31); =20 - for (i =3D 0; i < perf_cpu_map__nr(map); i++) - set_bit(perf_cpu_map__cpu(map, i).cpu, mask->mask); + data->mask32_data.mask[bit_word] |=3D bit_mask; + } } =20 static size_t cpus_size(const struct perf_cpu_map *map) @@ -1214,7 +1220,7 @@ static size_t cpus_size(const struct perf_cpu_map *ma= p) static size_t mask_size(const struct perf_cpu_map *map, int *max) { *max =3D perf_cpu_map__max(map).cpu; - return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * = sizeof(long); + return sizeof(struct perf_record_mask_cpu_map32) + BITS_TO_U32(*max) * si= zeof(__u32); } =20 static void *cpu_map_data__alloc(const struct perf_cpu_map *map, size_t *s= ize, @@ -1247,7 +1253,7 @@ static void *cpu_map_data__alloc(const struct perf_cp= u_map *map, size_t *size, *type =3D PERF_CPU_MAP__MASK; } =20 - *size +=3D sizeof(struct perf_record_cpu_map_data); + *size +=3D sizeof(__u16); /* For perf_record_cpu_map_data.type. */ *size =3D PERF_ALIGN(*size, sizeof(u64)); return zalloc(*size); } @@ -1260,10 +1266,10 @@ static void cpu_map_data__synthesize(struct perf_re= cord_cpu_map_data *data, =20 switch (type) { case PERF_CPU_MAP__CPUS: - synthesize_cpus((struct cpu_map_entries *) data->data, map); + synthesize_cpus(data, map); break; case PERF_CPU_MAP__MASK: - synthesize_mask((struct perf_record_record_cpu_map *)data->data, map, ma= x); + synthesize_mask(data, map, max); default: break; } @@ -1271,7 +1277,7 @@ static void cpu_map_data__synthesize(struct perf_reco= rd_cpu_map_data *data, =20 static struct perf_record_cpu_map *cpu_map_event__new(const struct perf_cp= u_map *map) { - size_t size =3D sizeof(struct perf_record_cpu_map); + size_t size =3D sizeof(struct perf_event_header); struct perf_record_cpu_map *event; int max; u16 type; --=20 2.36.1.476.g0c4daa206d-goog From nobody Mon Apr 27 10:05:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F445C433EF for ; Tue, 14 Jun 2022 14:35:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240964AbiFNOfS (ORCPT ); Tue, 14 Jun 2022 10:35:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55524 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355787AbiFNOeO (ORCPT ); Tue, 14 Jun 2022 10:34:14 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C40ED3B3 for ; Tue, 14 Jun 2022 07:34:12 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-30c1d90587dso26705277b3.14 for ; Tue, 14 Jun 2022 07:34:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=RhxA7eRgAfXCkykh9Mqke3rmlCOtyFU0Irt1epvp7hw=; b=GLjcD5Dx33HCbsoWEkqU+neIygwWnlhBDLV2vzAwLmDz8x5q82nfJom16BkE93u/PK hspUdyCTqgVsnGxFdzeO5+D4K6rzB3TOgcohdxOodk2l0hhBFzS3hSKzwR+uRNqflmP+ w7qStg224/xe3rky8A1vFJ2as88HVYqhbgTuIJcGhoTpjcW0rTHT8xVaOLwraPFGxvFW NPJ7yLaBgPfavu3063eucMRS730PQ3OflSLL0j4EZhowwrnC48rqarnfIPxoRPaGoMHf ffxw+WkWbqF/XQXM86FoXasPo2as2buUgyNc2GyL1oUe+IWM36/8TJEw7C3JshxZ+Xu+ i8CQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=RhxA7eRgAfXCkykh9Mqke3rmlCOtyFU0Irt1epvp7hw=; b=AF/KFo7dn0wB/KVEiFisD5q7SUVRsHaZd+tK4poUrMtuvfOVVJ9FJC4pZIrJmHYy0L v2r1QxXl/xd8sOMMpdhryRkWahKjZknugPCTmh7FurWMrUWdzPoTqB/6F4I7Fd7VcktV Vz4cTZQyhIwinYLJ6IxACI+N9rILeWaHmWlTbxST7GQZxu8DyXs9+F8gzI5oikXGViYB BeHuWUwJEFy8GCv6OeLmSS5Fxyk8r37Vh3Zx6sA/7a4XPCFYa133mRZh7fY7O3kNyYgP ecyDZ/BHxl9iHN1RUUn1DM3OTHsFlKDp5NvyYSD/b6m1E/i8xCbWoWcsniy04+zZdlbM LPPw== X-Gm-Message-State: AJIora+F6oZn3CcPl/hXeRitxYe+xaK3HDAf1s4atD04zqs3yfUrMr05 IbjEy8POVJ9GAcO8zxEFUydaq/hCNMSL X-Google-Smtp-Source: AGRyM1t1Ygr0jc8VIJfd7IOc2+oMNdhp6qPa2VuDhBtAwkK9kLSXnT7iPkQCmX1L3JPff2GK64cCWAczPWx4 X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:b55a:aaa7:a:1b17]) (user=irogers job=sendgmr) by 2002:a81:2d0b:0:b0:313:34ae:77b9 with SMTP id t11-20020a812d0b000000b0031334ae77b9mr6077081ywt.233.1655217251575; Tue, 14 Jun 2022 07:34:11 -0700 (PDT) Date: Tue, 14 Jun 2022 07:33:52 -0700 In-Reply-To: <20220614143353.1559597-1-irogers@google.com> Message-Id: <20220614143353.1559597-6-irogers@google.com> Mime-Version: 1.0 References: <20220614143353.1559597-1-irogers@google.com> X-Mailer: git-send-email 2.36.1.476.g0c4daa206d-goog Subject: [PATCH v2 5/6] perf events: Prefer union over variable length array From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , James Clark , Kees Cook , "Gustavo A. R. Silva" , Adrian Hunter , Riccardo Mancini , German Gomez , Colin Ian King , Song Liu , Dave Marchevsky , Athira Rajeev , Alexey Bayduraev , Leo Yan , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" It is possible for casts to introduce alignment issues, prefer a union for perf_record_event_update. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/lib/perf/include/perf/event.h | 11 ++++++++++- tools/perf/tests/event_update.c | 14 ++++---------- tools/perf/util/header.c | 24 ++++++++---------------- tools/perf/util/synthetic-events.c | 12 +++++------- 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/p= erf/event.h index d2d32589758a..21170f5afb61 100644 --- a/tools/lib/perf/include/perf/event.h +++ b/tools/lib/perf/include/perf/event.h @@ -221,7 +221,16 @@ struct perf_record_event_update { struct perf_event_header header; __u64 type; __u64 id; - char data[]; + union { + /* Used when type =3D=3D PERF_EVENT_UPDATE__SCALE. */ + struct perf_record_event_update_scale scale; + /* Used when type =3D=3D PERF_EVENT_UPDATE__UNIT. */ + char unit[0]; + /* Used when type =3D=3D PERF_EVENT_UPDATE__NAME. */ + char name[0]; + /* Used when type =3D=3D PERF_EVENT_UPDATE__CPUS. */ + struct perf_record_event_update_cpus cpus; + }; }; =20 #define MAX_EVENT_NAME 64 diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_updat= e.c index 78db4d704e76..d093a9b878d1 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -21,7 +21,7 @@ static int process_event_unit(struct perf_tool *tool __ma= ybe_unused, =20 TEST_ASSERT_VAL("wrong id", ev->id =3D=3D 123); TEST_ASSERT_VAL("wrong id", ev->type =3D=3D PERF_EVENT_UPDATE__UNIT); - TEST_ASSERT_VAL("wrong unit", !strcmp(ev->data, "KRAVA")); + TEST_ASSERT_VAL("wrong unit", !strcmp(ev->unit, "KRAVA")); return 0; } =20 @@ -31,13 +31,10 @@ static int process_event_scale(struct perf_tool *tool _= _maybe_unused, struct machine *machine __maybe_unused) { struct perf_record_event_update *ev =3D (struct perf_record_event_update = *)event; - struct perf_record_event_update_scale *ev_data; - - ev_data =3D (struct perf_record_event_update_scale *)ev->data; =20 TEST_ASSERT_VAL("wrong id", ev->id =3D=3D 123); TEST_ASSERT_VAL("wrong id", ev->type =3D=3D PERF_EVENT_UPDATE__SCALE); - TEST_ASSERT_VAL("wrong scale", ev_data->scale =3D=3D 0.123); + TEST_ASSERT_VAL("wrong scale", ev->scale.scale =3D=3D 0.123); return 0; } =20 @@ -56,7 +53,7 @@ static int process_event_name(struct perf_tool *tool, =20 TEST_ASSERT_VAL("wrong id", ev->id =3D=3D 123); TEST_ASSERT_VAL("wrong id", ev->type =3D=3D PERF_EVENT_UPDATE__NAME); - TEST_ASSERT_VAL("wrong name", !strcmp(ev->data, tmp->name)); + TEST_ASSERT_VAL("wrong name", !strcmp(ev->name, tmp->name)); return 0; } =20 @@ -66,12 +63,9 @@ static int process_event_cpus(struct perf_tool *tool __m= aybe_unused, struct machine *machine __maybe_unused) { struct perf_record_event_update *ev =3D (struct perf_record_event_update = *)event; - struct perf_record_event_update_cpus *ev_data; struct perf_cpu_map *map; =20 - ev_data =3D (struct perf_record_event_update_cpus *) ev->data; - - map =3D cpu_map__new_data(&ev_data->cpus); + map =3D cpu_map__new_data(&ev->cpus.cpus); =20 TEST_ASSERT_VAL("wrong id", ev->id =3D=3D 123); TEST_ASSERT_VAL("wrong type", ev->type =3D=3D PERF_EVENT_UPDATE__CPUS); diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 53332da100e8..108c8da5d2e3 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -4264,8 +4264,6 @@ int perf_event__process_feature(struct perf_session *= session, size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp) { struct perf_record_event_update *ev =3D &event->event_update; - struct perf_record_event_update_scale *ev_scale; - struct perf_record_event_update_cpus *ev_cpus; struct perf_cpu_map *map; size_t ret; =20 @@ -4273,20 +4271,18 @@ size_t perf_event__fprintf_event_update(union perf_= event *event, FILE *fp) =20 switch (ev->type) { case PERF_EVENT_UPDATE__SCALE: - ev_scale =3D (struct perf_record_event_update_scale *)ev->data; - ret +=3D fprintf(fp, "... scale: %f\n", ev_scale->scale); + ret +=3D fprintf(fp, "... scale: %f\n", ev->scale.scale); break; case PERF_EVENT_UPDATE__UNIT: - ret +=3D fprintf(fp, "... unit: %s\n", ev->data); + ret +=3D fprintf(fp, "... unit: %s\n", ev->unit); break; case PERF_EVENT_UPDATE__NAME: - ret +=3D fprintf(fp, "... name: %s\n", ev->data); + ret +=3D fprintf(fp, "... name: %s\n", ev->name); break; case PERF_EVENT_UPDATE__CPUS: - ev_cpus =3D (struct perf_record_event_update_cpus *)ev->data; ret +=3D fprintf(fp, "... "); =20 - map =3D cpu_map__new_data(&ev_cpus->cpus); + map =3D cpu_map__new_data(&ev->cpus.cpus); if (map) ret +=3D cpu_map__fprintf(map, fp); else @@ -4343,8 +4339,6 @@ int perf_event__process_event_update(struct perf_tool= *tool __maybe_unused, struct evlist **pevlist) { struct perf_record_event_update *ev =3D &event->event_update; - struct perf_record_event_update_scale *ev_scale; - struct perf_record_event_update_cpus *ev_cpus; struct evlist *evlist; struct evsel *evsel; struct perf_cpu_map *map; @@ -4361,19 +4355,17 @@ int perf_event__process_event_update(struct perf_to= ol *tool __maybe_unused, switch (ev->type) { case PERF_EVENT_UPDATE__UNIT: free((char *)evsel->unit); - evsel->unit =3D strdup(ev->data); + evsel->unit =3D strdup(ev->unit); break; case PERF_EVENT_UPDATE__NAME: free(evsel->name); - evsel->name =3D strdup(ev->data); + evsel->name =3D strdup(ev->name); break; case PERF_EVENT_UPDATE__SCALE: - ev_scale =3D (struct perf_record_event_update_scale *)ev->data; - evsel->scale =3D ev_scale->scale; + evsel->scale =3D ev->scale.scale; break; case PERF_EVENT_UPDATE__CPUS: - ev_cpus =3D (struct perf_record_event_update_cpus *)ev->data; - map =3D cpu_map__new_data(&ev_cpus->cpus); + map =3D cpu_map__new_data(&ev->cpus.cpus); if (map) { perf_cpu_map__put(evsel->core.own_cpus); evsel->core.own_cpus =3D map; diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index 4fa7d0d7dbcf..ec54ac1ed96f 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1848,7 +1848,7 @@ int perf_event__synthesize_event_update_unit(struct p= erf_tool *tool, struct evse if (ev =3D=3D NULL) return -ENOMEM; =20 - strlcpy(ev->data, evsel->unit, size + 1); + strlcpy(ev->unit, evsel->unit, size + 1); err =3D process(tool, (union perf_event *)ev, NULL, NULL); free(ev); return err; @@ -1865,8 +1865,7 @@ int perf_event__synthesize_event_update_scale(struct = perf_tool *tool, struct evs if (ev =3D=3D NULL) return -ENOMEM; =20 - ev_data =3D (struct perf_record_event_update_scale *)ev->data; - ev_data->scale =3D evsel->scale; + ev->scale.scale =3D evsel->scale; err =3D process(tool, (union perf_event *)ev, NULL, NULL); free(ev); return err; @@ -1883,7 +1882,7 @@ int perf_event__synthesize_event_update_name(struct p= erf_tool *tool, struct evse if (ev =3D=3D NULL) return -ENOMEM; =20 - strlcpy(ev->data, evsel->name, len + 1); + strlcpy(ev->name, evsel->name, len + 1); err =3D process(tool, (union perf_event *)ev, NULL, NULL); free(ev); return err; @@ -1892,7 +1891,7 @@ int perf_event__synthesize_event_update_name(struct p= erf_tool *tool, struct evse int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struc= t evsel *evsel, perf_event__handler_t process) { - size_t size =3D sizeof(struct perf_record_event_update); + size_t size =3D sizeof(struct perf_event_header) + sizeof(u64) + sizeof(u= 64); struct perf_record_event_update *ev; int max, err; u16 type; @@ -1909,8 +1908,7 @@ int perf_event__synthesize_event_update_cpus(struct p= erf_tool *tool, struct evse ev->type =3D PERF_EVENT_UPDATE__CPUS; ev->id =3D evsel->core.id[0]; =20 - cpu_map_data__synthesize((struct perf_record_cpu_map_data *)ev->data, - evsel->core.own_cpus, type, max); + cpu_map_data__synthesize(&ev->cpus.cpus, evsel->core.own_cpus, type, max); =20 err =3D process(tool, (union perf_event *)ev, NULL, NULL); free(ev); --=20 2.36.1.476.g0c4daa206d-goog From nobody Mon Apr 27 10:05:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0CCC6C433EF for ; Tue, 14 Jun 2022 14:34:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243680AbiFNOeT (ORCPT ); Tue, 14 Jun 2022 10:34:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355895AbiFNOeQ (ORCPT ); Tue, 14 Jun 2022 10:34:16 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BD7C236177 for ; Tue, 14 Jun 2022 07:34:14 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id z5-20020aa79f85000000b0051baa4e9fb8so3943446pfr.7 for ; Tue, 14 Jun 2022 07:34:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=UewJqU8rUQMKPeVGAP0/Y/t8r5J/Omui5wNwxJu+AJ0=; b=MHBjuQC8yYtGQgPYRH4HfWCGi7dvDrRXxmA8jRHk0s4tq354dmzBvJELeMaYKEkd0B gnJ6j6yCk4T1aLE+hl1U0NT9g3IKeFeDYgU8GF1IFwPFmJKaVejgTGynlmUc0iwvReN5 knmNW2rh0sgIq4c+/aGjxNEbz0mKA196dp3jPrz3lPT06Wt+DszYLVtxNnReCQFknys7 44zmaDqJX9NNwXk4ofLh5HS45sYm2EzktB985D9O5f9Flz6EO8i0C9mahvWY8GMbofpL V32zP4P4icyjMmNSPHBFxR4McF+uf6jC9KFLVjK5ahKMPNDFI6a3/bzBKJl1Xo49JAdU B7kA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=UewJqU8rUQMKPeVGAP0/Y/t8r5J/Omui5wNwxJu+AJ0=; b=7nx0AJjmWg0f6qDoi1TsyplzrsGfaaL3Fkj7Vob0gy+U6uDQPfQlTQPreKDNOwu3iY dsOJQEwLw0eGFgGSorqM+2Tq+cy60uzIRr65jdADTHb6y2ChURdUfeRsOYZnfqYolXgO wGm1lkyomkvg2OwPIDlURTeyYfj/BkjNWd5D4wSvh9ZG10flDC4UnTaFGe0geXwU9uGl PJbSoWqVmofWKjNJV8lr3m5vxuS19e7qV9sehtBcMCdypKzNKQN8dHyfjpnnjbch9ZB0 PM74nwJtVUOfZMzcwX+7+VisXWbI/KZ8Fe97mY5bp7tA1GyTX228o/noc7LLFDBWUVDT Rtsg== X-Gm-Message-State: AJIora+ZlLvD3MAHfoFtWRL8rmUYeGrW+4CcvD3/nkp10jJ8GeinikL6 EFRtblSXpyqK/Po1iImKuGcy7gcFHoqJ X-Google-Smtp-Source: AGRyM1t1btBv8VGktDGMGfE+C/8S7YLYrzj4B9G7ynAKfNrVdsjHz4AXbO/xZ9XYWTj52/mE/S8IJS4wUEgT X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:b55a:aaa7:a:1b17]) (user=irogers job=sendgmr) by 2002:a17:902:ea08:b0:163:ec68:ae08 with SMTP id s8-20020a170902ea0800b00163ec68ae08mr4588980plg.52.1655217254238; Tue, 14 Jun 2022 07:34:14 -0700 (PDT) Date: Tue, 14 Jun 2022 07:33:53 -0700 In-Reply-To: <20220614143353.1559597-1-irogers@google.com> Message-Id: <20220614143353.1559597-7-irogers@google.com> Mime-Version: 1.0 References: <20220614143353.1559597-1-irogers@google.com> X-Mailer: git-send-email 2.36.1.476.g0c4daa206d-goog Subject: [PATCH v2 6/6] perf cpumap: Add range data encoding From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , James Clark , Kees Cook , "Gustavo A. R. Silva" , Adrian Hunter , Riccardo Mancini , German Gomez , Colin Ian King , Song Liu , Dave Marchevsky , Athira Rajeev , Alexey Bayduraev , Leo Yan , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Often cpumaps encode a range of all CPUs, add a compact encoding that doesn't require a bit mask or list of all CPUs. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/lib/perf/include/perf/event.h | 14 +++ tools/perf/tests/cpumap.c | 52 ++++++++-- tools/perf/util/cpumap.c | 31 +++++- tools/perf/util/session.c | 5 + tools/perf/util/synthetic-events.c | 151 ++++++++++++++-------------- 5 files changed, 166 insertions(+), 87 deletions(-) diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/p= erf/event.h index 21170f5afb61..43f990b8c58b 100644 --- a/tools/lib/perf/include/perf/event.h +++ b/tools/lib/perf/include/perf/event.h @@ -152,6 +152,7 @@ struct perf_record_header_attr { enum { PERF_CPU_MAP__CPUS =3D 0, PERF_CPU_MAP__MASK =3D 1, + PERF_CPU_MAP__RANGE_CPUS =3D 2, }; =20 /* @@ -185,6 +186,17 @@ struct perf_record_mask_cpu_map64 { __u64 mask[]; }; =20 +/* + * An encoding of a CPU map for a range starting at start_cpu through to + * end_cpu. If any_cpu is 1, an any CPU (-1) value (aka dummy value) is pr= esent. + */ +struct perf_record_range_cpu_map { + __u8 any_cpu; + __u8 __pad; + __u16 start_cpu; + __u16 end_cpu; +}; + struct __packed perf_record_cpu_map_data { __u16 type; union { @@ -194,6 +206,8 @@ struct __packed perf_record_cpu_map_data { struct perf_record_mask_cpu_map32 mask32_data; /* Used when type =3D=3D PERF_CPU_MAP__MASK and long_size =3D=3D 8. */ struct perf_record_mask_cpu_map64 mask64_data; + /* Used when type =3D=3D PERF_CPU_MAP__RANGE_CPUS. */ + struct perf_record_range_cpu_map range_cpu_data; }; }; =20 diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 7ea150cdc137..7c873c6ae3eb 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -19,7 +19,6 @@ static int process_event_mask(struct perf_tool *tool __ma= ybe_unused, struct perf_record_cpu_map *map_event =3D &event->cpu_map; struct perf_record_cpu_map_data *data; struct perf_cpu_map *map; - int i; unsigned int long_size; =20 data =3D &map_event->data; @@ -32,16 +31,17 @@ static int process_event_mask(struct perf_tool *tool __= maybe_unused, =20 TEST_ASSERT_VAL("wrong nr", data->mask32_data.nr =3D=3D 1); =20 - for (i =3D 0; i < 20; i++) { + TEST_ASSERT_VAL("wrong cpu", perf_record_cpu_map_data__test_bit(0, data)); + TEST_ASSERT_VAL("wrong cpu", !perf_record_cpu_map_data__test_bit(1, data)= ); + for (int i =3D 2; i <=3D 20; i++) TEST_ASSERT_VAL("wrong cpu", perf_record_cpu_map_data__test_bit(i, data)= ); - } =20 map =3D cpu_map__new_data(data); TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map) =3D=3D 20); =20 - for (i =3D 0; i < 20; i++) { - TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, i).cpu =3D=3D i); - } + TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 0).cpu =3D=3D 0); + for (int i =3D 2; i <=3D 20; i++) + TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, i - 1).cpu =3D=3D i); =20 perf_cpu_map__put(map); return 0; @@ -73,25 +73,59 @@ static int process_event_cpus(struct perf_tool *tool __= maybe_unused, return 0; } =20 +static int process_event_range_cpus(struct perf_tool *tool __maybe_unused, + union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine __maybe_unused) +{ + struct perf_record_cpu_map *map_event =3D &event->cpu_map; + struct perf_record_cpu_map_data *data; + struct perf_cpu_map *map; + + data =3D &map_event->data; + + TEST_ASSERT_VAL("wrong type", data->type =3D=3D PERF_CPU_MAP__RANGE_CPUS); + + TEST_ASSERT_VAL("wrong any_cpu", data->range_cpu_data.any_cpu =3D=3D 0); + TEST_ASSERT_VAL("wrong start_cpu", data->range_cpu_data.start_cpu =3D=3D = 1); + TEST_ASSERT_VAL("wrong end_cpu", data->range_cpu_data.end_cpu =3D=3D 25= 6); + + map =3D cpu_map__new_data(data); + TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map) =3D=3D 256); + TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 0).cpu =3D=3D 1); + TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__max(map).cpu =3D=3D 256); + TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) =3D=3D 1); + perf_cpu_map__put(map); + return 0; +} + =20 static int test__cpu_map_synthesize(struct test_suite *test __maybe_unused= , int subtest __maybe_unused) { struct perf_cpu_map *cpus; =20 - /* This one is better stores in mask. */ - cpus =3D perf_cpu_map__new("0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,1= 8,19"); + /* This one is better stored in a mask. */ + cpus =3D perf_cpu_map__new("0,2-20"); =20 TEST_ASSERT_VAL("failed to synthesize map", !perf_event__synthesize_cpu_map(NULL, cpus, process_event_mask, NULL)); =20 perf_cpu_map__put(cpus); =20 - /* This one is better stores in cpu values. */ + /* This one is better stored in cpu values. */ cpus =3D perf_cpu_map__new("1,256"); =20 TEST_ASSERT_VAL("failed to synthesize map", !perf_event__synthesize_cpu_map(NULL, cpus, process_event_cpus, NULL)); =20 + perf_cpu_map__put(cpus); + + /* This one is better stored as a range. */ + cpus =3D perf_cpu_map__new("1-256"); + + TEST_ASSERT_VAL("failed to synthesize map", + !perf_event__synthesize_cpu_map(NULL, cpus, process_event_range_cpus, NU= LL)); + perf_cpu_map__put(cpus); return 0; } diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index ae43fb88f444..2389bd3e19b8 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -112,12 +112,39 @@ static struct perf_cpu_map *cpu_map__from_mask(const = struct perf_record_cpu_map_ =20 } =20 +static struct perf_cpu_map *cpu_map__from_range(const struct perf_record_c= pu_map_data *data) +{ + struct perf_cpu_map *map; + unsigned int i =3D 0; + + map =3D perf_cpu_map__empty_new(data->range_cpu_data.end_cpu - + data->range_cpu_data.start_cpu + 1 + data->range_cpu_data.any_cpu); + if (!map) + return NULL; + + if (data->range_cpu_data.any_cpu) + map->map[i++].cpu =3D -1; + + for (int cpu =3D data->range_cpu_data.start_cpu; cpu <=3D data->range_cpu= _data.end_cpu; + i++, cpu++) + map->map[i].cpu =3D cpu; + + return map; +} + struct perf_cpu_map *cpu_map__new_data(const struct perf_record_cpu_map_da= ta *data) { - if (data->type =3D=3D PERF_CPU_MAP__CPUS) + switch (data->type) { + case PERF_CPU_MAP__CPUS: return cpu_map__from_entries(data); - else + case PERF_CPU_MAP__MASK: return cpu_map__from_mask(data); + case PERF_CPU_MAP__RANGE_CPUS: + return cpu_map__from_range(data); + default: + pr_err("cpu_map__new_data unknown type %d\n", data->type); + return NULL; + } } =20 size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index d52a39ba48e3..0acb9de54b06 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -941,6 +941,11 @@ static void perf_event__cpu_map_swap(union perf_event = *event, default: pr_err("cpu_map swap: unsupported long size\n"); } + break; + case PERF_CPU_MAP__RANGE_CPUS: + data->range_cpu_data.start_cpu =3D bswap_16(data->range_cpu_data.start_c= pu); + data->range_cpu_data.end_cpu =3D bswap_16(data->range_cpu_data.end_cpu); + break; default: break; } diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index ec54ac1ed96f..76beda3e1a10 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1183,93 +1183,97 @@ int perf_event__synthesize_thread_map2(struct perf_= tool *tool, return err; } =20 -static void synthesize_cpus(struct perf_record_cpu_map_data *data, - const struct perf_cpu_map *map) -{ - int i, map_nr =3D perf_cpu_map__nr(map); - - data->cpus_data.nr =3D map_nr; +struct synthesize_cpu_map_data { + const struct perf_cpu_map *map; + int nr; + int min_cpu; + int max_cpu; + int has_any_cpu; + int type; + size_t size; + struct perf_record_cpu_map_data *data; +}; =20 - for (i =3D 0; i < map_nr; i++) - data->cpus_data.cpu[i] =3D perf_cpu_map__cpu(map, i).cpu; +static void synthesize_cpus(struct synthesize_cpu_map_data *data) +{ + data->data->type =3D PERF_CPU_MAP__CPUS; + data->data->cpus_data.nr =3D data->nr; + for (int i =3D 0; i < data->nr; i++) + data->data->cpus_data.cpu[i] =3D perf_cpu_map__cpu(data->map, i).cpu; } =20 -static void synthesize_mask(struct perf_record_cpu_map_data *data, - const struct perf_cpu_map *map, int max) +static void synthesize_mask(struct synthesize_cpu_map_data *data) { int idx; struct perf_cpu cpu; =20 /* Due to padding, the 4bytes per entry mask variant is always smaller. */ - data->mask32_data.nr =3D BITS_TO_U32(max); - data->mask32_data.long_size =3D 4; + data->data->type =3D PERF_CPU_MAP__MASK; + data->data->mask32_data.nr =3D BITS_TO_U32(data->max_cpu); + data->data->mask32_data.long_size =3D 4; =20 - perf_cpu_map__for_each_cpu(cpu, idx, map) { + perf_cpu_map__for_each_cpu(cpu, idx, data->map) { int bit_word =3D cpu.cpu / 32; - __u32 bit_mask =3D 1U << (cpu.cpu & 31); + u32 bit_mask =3D 1U << (cpu.cpu & 31); =20 - data->mask32_data.mask[bit_word] |=3D bit_mask; + data->data->mask32_data.mask[bit_word] |=3D bit_mask; } } =20 -static size_t cpus_size(const struct perf_cpu_map *map) +static void synthesize_range_cpus(struct synthesize_cpu_map_data *data) { - return sizeof(struct cpu_map_entries) + perf_cpu_map__nr(map) * sizeof(u1= 6); + data->data->type =3D PERF_CPU_MAP__RANGE_CPUS; + data->data->range_cpu_data.any_cpu =3D data->has_any_cpu; + data->data->range_cpu_data.start_cpu =3D data->min_cpu; + data->data->range_cpu_data.end_cpu =3D data->max_cpu; } =20 -static size_t mask_size(const struct perf_cpu_map *map, int *max) -{ - *max =3D perf_cpu_map__max(map).cpu; - return sizeof(struct perf_record_mask_cpu_map32) + BITS_TO_U32(*max) * si= zeof(__u32); -} - -static void *cpu_map_data__alloc(const struct perf_cpu_map *map, size_t *s= ize, - u16 *type, int *max) +static void *cpu_map_data__alloc(struct synthesize_cpu_map_data *syn_data, + size_t header_size) { size_t size_cpus, size_mask; - bool is_dummy =3D perf_cpu_map__empty(map); =20 - /* - * Both array and mask data have variable size based - * on the number of cpus and their actual values. - * The size of the 'struct perf_record_cpu_map_data' is: - * - * array =3D size of 'struct cpu_map_entries' + - * number of cpus * sizeof(u64) - * - * mask =3D size of 'struct perf_record_record_cpu_map' + - * maximum cpu bit converted to size of longs - * - * and finally + the size of 'struct perf_record_cpu_map_data'. - */ - size_cpus =3D cpus_size(map); - size_mask =3D mask_size(map, max); + syn_data->nr =3D perf_cpu_map__nr(syn_data->map); + syn_data->has_any_cpu =3D (perf_cpu_map__cpu(syn_data->map, 0).cpu =3D=3D= -1) ? 1 : 0; =20 - if (is_dummy || (size_cpus < size_mask)) { - *size +=3D size_cpus; - *type =3D PERF_CPU_MAP__CPUS; - } else { - *size +=3D size_mask; - *type =3D PERF_CPU_MAP__MASK; + syn_data->min_cpu =3D perf_cpu_map__cpu(syn_data->map, syn_data->has_any_= cpu).cpu; + syn_data->max_cpu =3D perf_cpu_map__max(syn_data->map).cpu; + if (syn_data->max_cpu - syn_data->min_cpu + 1 =3D=3D syn_data->nr - syn_d= ata->has_any_cpu) { + /* A consecutive range of CPUs can be encoded using a range. */ + assert(sizeof(u16) + sizeof(struct perf_record_range_cpu_map) =3D=3D siz= eof(u64)); + syn_data->type =3D PERF_CPU_MAP__RANGE_CPUS; + syn_data->size =3D header_size + sizeof(u64); + return zalloc(syn_data->size); } =20 - *size +=3D sizeof(__u16); /* For perf_record_cpu_map_data.type. */ - *size =3D PERF_ALIGN(*size, sizeof(u64)); - return zalloc(*size); + size_cpus =3D sizeof(u16) + sizeof(struct cpu_map_entries) + syn_data->nr= * sizeof(u16); + /* Due to padding, the 4bytes per entry mask variant is always smaller. */ + size_mask =3D sizeof(u16) + sizeof(struct perf_record_mask_cpu_map32) + + BITS_TO_U32(syn_data->max_cpu) * sizeof(__u32); + if (syn_data->has_any_cpu || size_cpus < size_mask) { + /* Follow the CPU map encoding. */ + syn_data->type =3D PERF_CPU_MAP__CPUS; + syn_data->size =3D header_size + PERF_ALIGN(size_cpus, sizeof(u64)); + return zalloc(syn_data->size); + } + /* Encode using a bitmask. */ + syn_data->type =3D PERF_CPU_MAP__MASK; + syn_data->size =3D header_size + PERF_ALIGN(size_mask, sizeof(u64)); + return zalloc(syn_data->size); } =20 -static void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, - const struct perf_cpu_map *map, - u16 type, int max) +static void cpu_map_data__synthesize(struct synthesize_cpu_map_data *data) { - data->type =3D type; - - switch (type) { + switch (data->type) { case PERF_CPU_MAP__CPUS: - synthesize_cpus(data, map); + synthesize_cpus(data); break; case PERF_CPU_MAP__MASK: - synthesize_mask(data, map, max); + synthesize_mask(data); + break; + case PERF_CPU_MAP__RANGE_CPUS: + synthesize_range_cpus(data); + break; default: break; } @@ -1277,23 +1281,22 @@ static void cpu_map_data__synthesize(struct perf_re= cord_cpu_map_data *data, =20 static struct perf_record_cpu_map *cpu_map_event__new(const struct perf_cp= u_map *map) { - size_t size =3D sizeof(struct perf_event_header); + struct synthesize_cpu_map_data syn_data =3D { .map =3D map }; struct perf_record_cpu_map *event; - int max; - u16 type; =20 - event =3D cpu_map_data__alloc(map, &size, &type, &max); + + event =3D cpu_map_data__alloc(&syn_data, sizeof(struct perf_event_header)= ); if (!event) return NULL; =20 + syn_data.data =3D &event->data; event->header.type =3D PERF_RECORD_CPU_MAP; - event->header.size =3D size; - event->data.type =3D type; - - cpu_map_data__synthesize(&event->data, map, type, max); + event->header.size =3D syn_data.size; + cpu_map_data__synthesize(&syn_data); return event; } =20 + int perf_event__synthesize_cpu_map(struct perf_tool *tool, const struct perf_cpu_map *map, perf_event__handler_t process, @@ -1891,24 +1894,20 @@ int perf_event__synthesize_event_update_name(struct= perf_tool *tool, struct evse int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struc= t evsel *evsel, perf_event__handler_t process) { - size_t size =3D sizeof(struct perf_event_header) + sizeof(u64) + sizeof(u= 64); + struct synthesize_cpu_map_data syn_data =3D { .map =3D evsel->core.own_cp= us }; struct perf_record_event_update *ev; - int max, err; - u16 type; - - if (!evsel->core.own_cpus) - return 0; + int err; =20 - ev =3D cpu_map_data__alloc(evsel->core.own_cpus, &size, &type, &max); + ev =3D cpu_map_data__alloc(&syn_data, sizeof(struct perf_event_header) + = 2 * sizeof(u64)); if (!ev) return -ENOMEM; =20 + syn_data.data =3D &ev->cpus.cpus; ev->header.type =3D PERF_RECORD_EVENT_UPDATE; - ev->header.size =3D (u16)size; + ev->header.size =3D (u16)syn_data.size; ev->type =3D PERF_EVENT_UPDATE__CPUS; ev->id =3D evsel->core.id[0]; - - cpu_map_data__synthesize(&ev->cpus.cpus, evsel->core.own_cpus, type, max); + cpu_map_data__synthesize(&syn_data); =20 err =3D process(tool, (union perf_event *)ev, NULL, NULL); free(ev); --=20 2.36.1.476.g0c4daa206d-goog