From nobody Tue Jun 30 08:09:13 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 CA61EC433EF for ; Sat, 22 Jan 2022 04:58:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232999AbiAVE6Z (ORCPT ); Fri, 21 Jan 2022 23:58:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40902 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232955AbiAVE6V (ORCPT ); Fri, 21 Jan 2022 23:58:21 -0500 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 11B83C061401 for ; Fri, 21 Jan 2022 20:58:21 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id k189-20020a25c6c6000000b0061274ece35eso23233449ybf.22 for ; Fri, 21 Jan 2022 20:58:21 -0800 (PST) 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=aNuBZ0ZpaoD1AkR8uBb0XNwqugpn9QfU7CzwmAlFWuQ=; b=mPEzAeW9MHKoUIiyXGvyAwu+QOQwXqXUloUWAzzKa2I/Tk/zDk6UtdakN5ozYpJNO8 4Orfoc8RkiJjMfB/tiwxo2UV6heXCmAHQIpK+23ucKA+0XmAiV3Mv0Oh8etQyfBfOBBW vzRO1roT/tY2uFITgmZbmNMJFUVLqNtVPfgb9BCo3YnBYXfAt9mvKbrHknZwklmu5E7K qN1EpvfvxIymXukW4t+XVg+k4tk1JijGohqcZsidP1J8TS+X/nhvsQDm69Gi9oN87gYT hBM7+531+CmosJxG7mWrQPRVqfxGfZpP7DEgfpIyNbV8h7kig4SUdZdRhMWMxQGgGvAp WQBA== 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=aNuBZ0ZpaoD1AkR8uBb0XNwqugpn9QfU7CzwmAlFWuQ=; b=31t7Nt9ED8QN3FGQUJmRkutblBkOw9/PcmZnBqQRQDfKLJs5DIGI53AeyOtbmFqDZw pPTOX9WtmosmryHwzUJZN0r0vdliqFQdkO7EbkDxpM16t+S7WRC7qfJuREx7lsrvoA2I GavSwtbsjeRi/r3SX5Qv4JSlGCqIhOz/OxC9Kx9L62OgxO+SOBdCgU9Jssd4lqzYfObH qHdv2OYED24NNDHeqMxt7bXgrgcoETjjAluEsVCH/tnM6s+Ij9SNwLVIoP5u7vAoka5r DvKEgQCbiUrjSxYaA5WXLLGjTZ8yHnnZrFL8HNKjWP/VioZFxJQNMHySV29j8HU91Y2g 0ezw== X-Gm-Message-State: AOAM532eWyZFFU7QKIysbDA8KNYttZRw0FR4AZGcHjvHSfUGLGpMp1eb pvcL6rONLfcTFnjObk5SFfFndIjferuG X-Google-Smtp-Source: ABdhPJw1NzzeJ/QJ8gyxsnNeWJvtCDed/vCdUahcTcTwM0lyHcDWrTca5XzdzlaqbcpcK1zMRjP2VEPJH1Ty X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:6125:f911:aa9a:59ee]) (user=irogers job=sendgmr) by 2002:a25:9c45:: with SMTP id x5mr10714898ybo.91.1642827500208; Fri, 21 Jan 2022 20:58:20 -0800 (PST) Date: Fri, 21 Jan 2022 20:58:09 -0800 In-Reply-To: <20220122045811.3402706-1-irogers@google.com> Message-Id: <20220122045811.3402706-2-irogers@google.com> Mime-Version: 1.0 References: <20220122045811.3402706-1-irogers@google.com> X-Mailer: git-send-email 2.35.0.rc0.227.g00780c9af4-goog Subject: [PATCH 1/3] perf python: Fix cpu_map__item building From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Jin Yao , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov Cc: eranian@google.com, 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" Value should be built as an integer. Switch some uses of perf_cpu_map to use the library API. Fixes: 6d18804b963b ("perf cpumap: Give CPUs their own type") Signed-off-by: Ian Rogers --- tools/perf/util/python.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index f3e5131f183c..52d8995cfd73 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -638,17 +638,17 @@ static Py_ssize_t pyrf_cpu_map__length(PyObject *obj) { struct pyrf_cpu_map *pcpus =3D (void *)obj; =20 - return pcpus->cpus->nr; + return perf_cpu_map__nr(pcpus->cpus); } =20 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i) { struct pyrf_cpu_map *pcpus =3D (void *)obj; =20 - if (i >=3D pcpus->cpus->nr) + if (i >=3D perf_cpu_map__nr(pcpus->cpus)) return NULL; =20 - return Py_BuildValue("i", pcpus->cpus->map[i]); + return Py_BuildValue("i", perf_cpu_map__cpu(pcpus->cpus, i).cpu); } =20 static PySequenceMethods pyrf_cpu_map__sequence_methods =3D { --=20 2.35.0.rc0.227.g00780c9af4-goog From nobody Tue Jun 30 08:09:13 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 55941C433FE for ; Sat, 22 Jan 2022 04:58:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233108AbiAVE6b (ORCPT ); Fri, 21 Jan 2022 23:58:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232964AbiAVE6Y (ORCPT ); Fri, 21 Jan 2022 23:58:24 -0500 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 A76E9C06173B for ; Fri, 21 Jan 2022 20:58:23 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id n196-20020a25d6cd000000b006139bdfade9so21958489ybg.17 for ; Fri, 21 Jan 2022 20:58:23 -0800 (PST) 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=I0Fabc8UfZXyFKtZ3EKl6TervoHXtW5AQxzfTAXziFA=; b=iMpE0HQnCViuBpZGakSHceL3YQOm5OcgMT25ueAMqMGPpih9Vioc6ZrA9w1d3XiILD DpTHob5z9LgVoBh8OvJhLQn4EnFECVPcl+ycsRQgSoffQk0w/BwF/OHmvV66uth4HTm6 5X3xtykzfav1CUIFSzrZNHFLlEVOyE8aS2R94fIvNXXGtg/HXL1XeETcXpWfK0xsOu4n PWM4P4iky/NleuN0J3vOtpNq8KMylxF2x1jfGIOJat/p5ezu17SNh+c+QRAqAZq0m2W4 TOWfm9ixPVMJRwa7x1Ml0+6ezPzU6nImLpVoZWfVzGD/Ciz34V6iBIdVmtEFTpRcjgvR CShQ== 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=I0Fabc8UfZXyFKtZ3EKl6TervoHXtW5AQxzfTAXziFA=; b=zysKdzXZWL+qTJsVjiK1RFCtCL1izM0KDWTMMoYEHh7gOnL6hWQKys5xCLDYfkq5/p h+sT9Dwh2n5nblQfbwG3hVwzsB5tqv++Z3Hl0p1WiDBgBocVFgFfBjAacss9gVpEpemh zt4b4T7ht2sbQlOKTl6Zt3VImv3aqKAZDoXa2+IOQH75v7w6LCJJua9kjXWpOs7YcN/p RdMzJoP3NJ6m7NqYvoAamdsYvEzkmzSoVAhVV8WSGfNYgdWKgL1TTVK6z1PTve3axhK9 wQ+u5KbiDUc018hoUNS3E2WtwsSyakjlZi9lw7PfNg96Knp702UrZ0VgNlyapX+/0xPb 5/+w== X-Gm-Message-State: AOAM532rz1t0BdVjeDnxUlLaeraMXcNn75I7WG3gm2eiu7oaSFntdyQz PNA3+z/8ujvftPaTXczOOZzpCduEOwpq X-Google-Smtp-Source: ABdhPJyujlqViHytgnDmTk41+QjapQziu2K+aYb4G1BOZtFxpBE5xMd9RdMzeAB2uf5RAns0KGw4D3twlXgv X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:6125:f911:aa9a:59ee]) (user=irogers job=sendgmr) by 2002:a25:3f86:: with SMTP id m128mr10794646yba.500.1642827502900; Fri, 21 Jan 2022 20:58:22 -0800 (PST) Date: Fri, 21 Jan 2022 20:58:10 -0800 In-Reply-To: <20220122045811.3402706-1-irogers@google.com> Message-Id: <20220122045811.3402706-3-irogers@google.com> Mime-Version: 1.0 References: <20220122045811.3402706-1-irogers@google.com> X-Mailer: git-send-email 2.35.0.rc0.227.g00780c9af4-goog Subject: [PATCH 2/3] perf cpumap: Migrate to libperf cpumap api From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Jin Yao , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov Cc: eranian@google.com, 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" Switch from directly accessing the perf_cpu_map to using the appropriate libperf API when possible. Using the API simplifies the job of refactoring use of perf_cpu_map. Signed-off-by: Ian Rogers --- tools/lib/perf/evsel.c | 4 +- tools/perf/bench/epoll-ctl.c | 2 +- tools/perf/bench/epoll-wait.c | 2 +- tools/perf/bench/evlist-open-close.c | 4 +- tools/perf/bench/futex-hash.c | 2 +- tools/perf/bench/futex-lock-pi.c | 2 +- tools/perf/bench/futex-requeue.c | 2 +- tools/perf/bench/futex-wake-parallel.c | 2 +- tools/perf/bench/futex-wake.c | 2 +- tools/perf/builtin-ftrace.c | 2 +- tools/perf/builtin-stat.c | 7 ++-- tools/perf/tests/bitmap.c | 4 +- tools/perf/tests/event_update.c | 8 ++-- tools/perf/tests/mem2node.c | 9 +++-- tools/perf/tests/mmap-basic.c | 5 ++- tools/perf/tests/topology.c | 37 +++++++++++-------- tools/perf/util/auxtrace.c | 2 +- tools/perf/util/counts.c | 2 +- tools/perf/util/cpumap.h | 2 +- tools/perf/util/cputopo.c | 4 +- tools/perf/util/evlist-hybrid.c | 11 +++--- tools/perf/util/evsel.c | 20 +++++----- tools/perf/util/evsel.h | 3 +- tools/perf/util/mmap.c | 2 +- tools/perf/util/perf_api_probe.c | 4 +- tools/perf/util/record.c | 6 +-- .../scripting-engines/trace-event-python.c | 4 +- tools/perf/util/session.c | 4 +- tools/perf/util/svghelper.c | 4 +- tools/perf/util/synthetic-events.c | 18 ++++----- tools/perf/util/top.c | 6 +-- 31 files changed, 99 insertions(+), 87 deletions(-) diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c index 7ea86a44eae5..8543a594ea2f 100644 --- a/tools/lib/perf/evsel.c +++ b/tools/lib/perf/evsel.c @@ -141,7 +141,7 @@ int perf_evsel__open(struct perf_evsel *evsel, struct p= erf_cpu_map *cpus, } =20 if (evsel->fd =3D=3D NULL && - perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0) + perf_evsel__alloc_fd(evsel, perf_cpu_map__nr(cpus), threads->nr) < 0) return -ENOMEM; =20 perf_cpu_map__for_each_cpu(cpu, idx, cpus) { @@ -384,7 +384,7 @@ int perf_evsel__apply_filter(struct perf_evsel *evsel, = const char *filter) { int err =3D 0, i; =20 - for (i =3D 0; i < evsel->cpus->nr && !err; i++) + for (i =3D 0; i < perf_cpu_map__nr(evsel->cpus) && !err; i++) err =3D perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_SET_FILTER, (void *)filter, i); diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c index 1a17ec83d3c4..740ae764537e 100644 --- a/tools/perf/bench/epoll-ctl.c +++ b/tools/perf/bench/epoll-ctl.c @@ -333,7 +333,7 @@ int bench_epoll_ctl(int argc, const char **argv) =20 /* default to the number of CPUs */ if (!nthreads) - nthreads =3D cpu->nr; + nthreads =3D perf_cpu_map__nr(cpu); =20 worker =3D calloc(nthreads, sizeof(*worker)); if (!worker) diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c index 0d1dd8879197..37de970c9743 100644 --- a/tools/perf/bench/epoll-wait.c +++ b/tools/perf/bench/epoll-wait.c @@ -452,7 +452,7 @@ int bench_epoll_wait(int argc, const char **argv) =20 /* default to the number of CPUs and leave one for the writer pthread */ if (!nthreads) - nthreads =3D cpu->nr - 1; + nthreads =3D perf_cpu_map__nr(cpu) - 1; =20 worker =3D calloc(nthreads, sizeof(*worker)); if (!worker) { diff --git a/tools/perf/bench/evlist-open-close.c b/tools/perf/bench/evlist= -open-close.c index 482738e9bdad..de56601f69ee 100644 --- a/tools/perf/bench/evlist-open-close.c +++ b/tools/perf/bench/evlist-open-close.c @@ -71,7 +71,7 @@ static int evlist__count_evsel_fds(struct evlist *evlist) int cnt =3D 0; =20 evlist__for_each_entry(evlist, evsel) - cnt +=3D evsel->core.threads->nr * evsel->core.cpus->nr; + cnt +=3D evsel->core.threads->nr * perf_cpu_map__nr(evsel->core.cpus); =20 return cnt; } @@ -151,7 +151,7 @@ static int bench_evlist_open_close__run(char *evstr) =20 init_stats(&time_stats); =20 - printf(" Number of cpus:\t%d\n", evlist->core.cpus->nr); + printf(" Number of cpus:\t%d\n", perf_cpu_map__nr(evlist->core.cpus)); printf(" Number of threads:\t%d\n", evlist->core.threads->nr); printf(" Number of events:\t%d (%d fds)\n", evlist->core.nr_entries, evlist__count_evsel_fds(evlist)); diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index 9627b6ab8670..dbcecec4eeda 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -150,7 +150,7 @@ int bench_futex_hash(int argc, const char **argv) } =20 if (!params.nthreads) /* default to the number of CPUs */ - params.nthreads =3D cpu->nr; + params.nthreads =3D perf_cpu_map__nr(cpu); =20 worker =3D calloc(params.nthreads, sizeof(*worker)); if (!worker) diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock= -pi.c index a512a320df74..6fc9a3d55c1f 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -173,7 +173,7 @@ int bench_futex_lock_pi(int argc, const char **argv) } =20 if (!params.nthreads) - params.nthreads =3D cpu->nr; + params.nthreads =3D perf_cpu_map__nr(cpu); =20 worker =3D calloc(params.nthreads, sizeof(*worker)); if (!worker) diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requ= eue.c index aca47ce8b1e7..2f59d5d1c509 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -175,7 +175,7 @@ int bench_futex_requeue(int argc, const char **argv) } =20 if (!params.nthreads) - params.nthreads =3D cpu->nr; + params.nthreads =3D perf_cpu_map__nr(cpu); =20 worker =3D calloc(params.nthreads, sizeof(*worker)); if (!worker) diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/fute= x-wake-parallel.c index 888ee6037945..861deb934745 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -252,7 +252,7 @@ int bench_futex_wake_parallel(int argc, const char **ar= gv) err(EXIT_FAILURE, "calloc"); =20 if (!params.nthreads) - params.nthreads =3D cpu->nr; + params.nthreads =3D perf_cpu_map__nr(cpu); =20 /* some sanity checks */ if (params.nwakes > params.nthreads || diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index aa82db51c0ab..cfda48bef1d7 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -151,7 +151,7 @@ int bench_futex_wake(int argc, const char **argv) } =20 if (!params.nthreads) - params.nthreads =3D cpu->nr; + params.nthreads =3D perf_cpu_map__nr(cpu); =20 worker =3D calloc(params.nthreads, sizeof(*worker)); if (!worker) diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 71452599f87d..dec24dc0e767 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -281,7 +281,7 @@ static int set_tracing_cpumask(struct perf_cpu_map *cpu= map) int ret; int last_cpu; =20 - last_cpu =3D perf_cpu_map__cpu(cpumap, cpumap->nr - 1).cpu; + last_cpu =3D perf_cpu_map__cpu(cpumap, perf_cpu_map__nr(cpumap) - 1).cpu; mask_size =3D last_cpu / 4 + 2; /* one more byte for EOS */ mask_size +=3D last_cpu / 32; /* ',' is needed for every 32th cpus */ =20 diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 934e992c966f..3f98689dd687 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -230,11 +230,12 @@ static bool cpus_map_matched(struct evsel *a, struct = evsel *b) if (!a->core.cpus || !b->core.cpus) return false; =20 - if (a->core.cpus->nr !=3D b->core.cpus->nr) + if (perf_cpu_map__nr(a->core.cpus) !=3D perf_cpu_map__nr(b->core.cpus)) return false; =20 - for (int i =3D 0; i < a->core.cpus->nr; i++) { - if (a->core.cpus->map[i].cpu !=3D b->core.cpus->map[i].cpu) + for (int i =3D 0; i < perf_cpu_map__nr(a->core.cpus); i++) { + if (perf_cpu_map__cpu(a->core.cpus, i).cpu !=3D + perf_cpu_map__cpu(b->core.cpus, i).cpu) return false; } =20 diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 0bf399c49849..4965dd666956 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -17,8 +17,8 @@ static unsigned long *get_bitmap(const char *str, int nbi= ts) bm =3D bitmap_zalloc(nbits); =20 if (map && bm) { - for (i =3D 0; i < map->nr; i++) - set_bit(map->map[i].cpu, bm); + for (i =3D 0; i < perf_cpu_map__nr(map); i++) + set_bit(perf_cpu_map__cpu(map, i).cpu, bm); } =20 if (map) diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_updat= e.c index 16b6d6f47f38..78db4d704e76 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -75,10 +75,10 @@ static int process_event_cpus(struct perf_tool *tool __= maybe_unused, =20 TEST_ASSERT_VAL("wrong id", ev->id =3D=3D 123); TEST_ASSERT_VAL("wrong type", ev->type =3D=3D PERF_EVENT_UPDATE__CPUS); - TEST_ASSERT_VAL("wrong cpus", map->nr =3D=3D 3); - TEST_ASSERT_VAL("wrong cpus", map->map[0].cpu =3D=3D 1); - TEST_ASSERT_VAL("wrong cpus", map->map[1].cpu =3D=3D 2); - TEST_ASSERT_VAL("wrong cpus", map->map[2].cpu =3D=3D 3); + TEST_ASSERT_VAL("wrong cpus", perf_cpu_map__nr(map) =3D=3D 3); + TEST_ASSERT_VAL("wrong cpus", perf_cpu_map__cpu(map, 0).cpu =3D=3D 1); + TEST_ASSERT_VAL("wrong cpus", perf_cpu_map__cpu(map, 1).cpu =3D=3D 2); + TEST_ASSERT_VAL("wrong cpus", perf_cpu_map__cpu(map, 2).cpu =3D=3D 3); perf_cpu_map__put(map); return 0; } diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index f4a4aba33f76..4c96829510c9 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -25,14 +25,15 @@ static unsigned long *get_bitmap(const char *str, int n= bits) { struct perf_cpu_map *map =3D perf_cpu_map__new(str); unsigned long *bm =3D NULL; - int i; =20 bm =3D bitmap_zalloc(nbits); =20 if (map && bm) { - for (i =3D 0; i < map->nr; i++) { - set_bit(map->map[i].cpu, bm); - } + struct perf_cpu cpu; + int i; + + perf_cpu_map__for_each_cpu(cpu, i, map) + set_bit(cpu.cpu, bm); } =20 if (map) diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 0ad62914b4d7..c3c17600f29c 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -59,11 +59,12 @@ static int test__basic_mmap(struct test_suite *test __m= aybe_unused, int subtest } =20 CPU_ZERO(&cpu_set); - CPU_SET(cpus->map[0].cpu, &cpu_set); + CPU_SET(perf_cpu_map__cpu(cpus, 0).cpu, &cpu_set); sched_setaffinity(0, sizeof(cpu_set), &cpu_set); if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { pr_debug("sched_setaffinity() failed on CPU %d: %s ", - cpus->map[0].cpu, str_error_r(errno, sbuf, sizeof(sbuf))); + perf_cpu_map__cpu(cpus, 0).cpu, + str_error_r(errno, sbuf, sizeof(sbuf))); goto out_free_cpus; } =20 diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index c4ef0c7002f1..ee1e3dcbc0bd 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -122,44 +122,48 @@ static int check_cpu_topology(char *path, struct perf= _cpu_map *map) } =20 // Test that CPU ID contains socket, die, core and CPU - for (i =3D 0; i < map->nr; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map); i++) { id =3D aggr_cpu_id__cpu(perf_cpu_map__cpu(map, i), NULL); - TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match", map->map[i].cpu =3D=3D= id.cpu.cpu); + TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match", + perf_cpu_map__cpu(map, i).cpu =3D=3D id.cpu.cpu); =20 TEST_ASSERT_VAL("Cpu map - Core ID doesn't match", - session->header.env.cpu[map->map[i].cpu].core_id =3D=3D id.core); + session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].core_id =3D=3D i= d.core); TEST_ASSERT_VAL("Cpu map - Socket ID doesn't match", - session->header.env.cpu[map->map[i].cpu].socket_id =3D=3D id.socket); + session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id =3D=3D + id.socket); =20 TEST_ASSERT_VAL("Cpu map - Die ID doesn't match", - session->header.env.cpu[map->map[i].cpu].die_id =3D=3D id.die); + session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id =3D=3D id= .die); TEST_ASSERT_VAL("Cpu map - Node ID is set", id.node =3D=3D -1); TEST_ASSERT_VAL("Cpu map - Thread is set", id.thread =3D=3D -1); } =20 // Test that core ID contains socket, die and core - for (i =3D 0; i < map->nr; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map); i++) { id =3D aggr_cpu_id__core(perf_cpu_map__cpu(map, i), NULL); TEST_ASSERT_VAL("Core map - Core ID doesn't match", - session->header.env.cpu[map->map[i].cpu].core_id =3D=3D id.core); + session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].core_id =3D=3D i= d.core); =20 TEST_ASSERT_VAL("Core map - Socket ID doesn't match", - session->header.env.cpu[map->map[i].cpu].socket_id =3D=3D id.socket); + session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id =3D=3D + id.socket); =20 TEST_ASSERT_VAL("Core map - Die ID doesn't match", - session->header.env.cpu[map->map[i].cpu].die_id =3D=3D id.die); + session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id =3D=3D id= .die); TEST_ASSERT_VAL("Core map - Node ID is set", id.node =3D=3D -1); TEST_ASSERT_VAL("Core map - Thread is set", id.thread =3D=3D -1); } =20 // Test that die ID contains socket and die - for (i =3D 0; i < map->nr; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map); i++) { id =3D aggr_cpu_id__die(perf_cpu_map__cpu(map, i), NULL); TEST_ASSERT_VAL("Die map - Socket ID doesn't match", - session->header.env.cpu[map->map[i].cpu].socket_id =3D=3D id.socket); + session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id =3D=3D + id.socket); =20 TEST_ASSERT_VAL("Die map - Die ID doesn't match", - session->header.env.cpu[map->map[i].cpu].die_id =3D=3D id.die); + session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].die_id =3D=3D id= .die); =20 TEST_ASSERT_VAL("Die map - Node ID is set", id.node =3D=3D -1); TEST_ASSERT_VAL("Die map - Core is set", id.core =3D=3D -1); @@ -168,10 +172,11 @@ static int check_cpu_topology(char *path, struct perf= _cpu_map *map) } =20 // Test that socket ID contains only socket - for (i =3D 0; i < map->nr; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map); i++) { id =3D aggr_cpu_id__socket(perf_cpu_map__cpu(map, i), NULL); TEST_ASSERT_VAL("Socket map - Socket ID doesn't match", - session->header.env.cpu[map->map[i].cpu].socket_id =3D=3D id.socket); + session->header.env.cpu[perf_cpu_map__cpu(map, i).cpu].socket_id =3D=3D + id.socket); =20 TEST_ASSERT_VAL("Socket map - Node ID is set", id.node =3D=3D -1); TEST_ASSERT_VAL("Socket map - Die ID is set", id.die =3D=3D -1); @@ -181,10 +186,10 @@ static int check_cpu_topology(char *path, struct perf= _cpu_map *map) } =20 // Test that node ID contains only node - for (i =3D 0; i < map->nr; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map); i++) { id =3D aggr_cpu_id__node(perf_cpu_map__cpu(map, i), NULL); TEST_ASSERT_VAL("Node map - Node ID doesn't match", - cpu__get_node(map->map[i]) =3D=3D id.node); + cpu__get_node(perf_cpu_map__cpu(map, i)) =3D=3D id.node); TEST_ASSERT_VAL("Node map - Socket is set", id.socket =3D=3D -1); TEST_ASSERT_VAL("Node map - Die ID is set", id.die =3D=3D -1); TEST_ASSERT_VAL("Node map - Core is set", id.core =3D=3D -1); diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 5632efc44738..825336304a37 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -174,7 +174,7 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mmap= _params *mp, mp->idx =3D idx; =20 if (per_cpu) { - mp->cpu =3D evlist->core.cpus->map[idx]; + mp->cpu =3D perf_cpu_map__cpu(evlist->core.cpus, idx); if (evlist->core.threads) mp->tid =3D perf_thread_map__pid(evlist->core.threads, 0); else diff --git a/tools/perf/util/counts.c b/tools/perf/util/counts.c index 2b81707b9dba..7a447d918458 100644 --- a/tools/perf/util/counts.c +++ b/tools/perf/util/counts.c @@ -61,7 +61,7 @@ int evsel__alloc_counts(struct evsel *evsel) struct perf_cpu_map *cpus =3D evsel__cpus(evsel); int nthreads =3D perf_thread_map__nr(evsel->core.threads); =20 - evsel->counts =3D perf_counts__new(cpus ? cpus->nr : 1, nthreads); + evsel->counts =3D perf_counts__new(perf_cpu_map__nr(cpus), nthreads); return evsel->counts !=3D NULL ? 0 : -ENOMEM; } =20 diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 0d3c2006a15d..5c85fbd709b4 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -57,7 +57,7 @@ struct perf_cpu cpu__max_present_cpu(void); */ static inline bool cpu_map__is_dummy(struct perf_cpu_map *cpus) { - return cpus->nr =3D=3D 1 && cpus->map[0].cpu =3D=3D -1; + return perf_cpu_map__nr(cpus) =3D=3D 1 && perf_cpu_map__cpu(cpus, 0).cpu = =3D=3D -1; } =20 /** diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index e20b835a1194..d275d843c155 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c @@ -325,7 +325,7 @@ struct numa_topology *numa_topology__new(void) if (!node_map) goto out; =20 - nr =3D (u32) node_map->nr; + nr =3D (u32) perf_cpu_map__nr(node_map); =20 tp =3D zalloc(sizeof(*tp) + sizeof(tp->nodes[0])*nr); if (!tp) @@ -334,7 +334,7 @@ struct numa_topology *numa_topology__new(void) tp->nr =3D nr; =20 for (i =3D 0; i < nr; i++) { - if (load_numa_node(&tp->nodes[i], node_map->map[i].cpu)) { + if (load_numa_node(&tp->nodes[i], perf_cpu_map__cpu(node_map, i).cpu)) { numa_topology__delete(tp); tp =3D NULL; break; diff --git a/tools/perf/util/evlist-hybrid.c b/tools/perf/util/evlist-hybri= d.c index 7c554234b43d..7f234215147d 100644 --- a/tools/perf/util/evlist-hybrid.c +++ b/tools/perf/util/evlist-hybrid.c @@ -124,22 +124,23 @@ int evlist__fix_hybrid_cpus(struct evlist *evlist, co= nst char *cpu_list) =20 events_nr++; =20 - if (matched_cpus->nr > 0 && (unmatched_cpus->nr > 0 || - matched_cpus->nr < cpus->nr || - matched_cpus->nr < pmu->cpus->nr)) { + if (perf_cpu_map__nr(matched_cpus) > 0 && + (perf_cpu_map__nr(unmatched_cpus) > 0 || + perf_cpu_map__nr(matched_cpus) < perf_cpu_map__nr(cpus) || + perf_cpu_map__nr(matched_cpus) < perf_cpu_map__nr(pmu->cpus))) { perf_cpu_map__put(evsel->core.cpus); perf_cpu_map__put(evsel->core.own_cpus); evsel->core.cpus =3D perf_cpu_map__get(matched_cpus); evsel->core.own_cpus =3D perf_cpu_map__get(matched_cpus); =20 - if (unmatched_cpus->nr > 0) { + if (perf_cpu_map__nr(unmatched_cpus) > 0) { cpu_map__snprint(matched_cpus, buf1, sizeof(buf1)); pr_warning("WARNING: use %s in '%s' for '%s', skip other cpus in list.= \n", buf1, pmu->name, evsel->name); } } =20 - if (matched_cpus->nr =3D=3D 0) { + if (perf_cpu_map__nr(matched_cpus) =3D=3D 0) { evlist__remove(evlist, evsel); evsel__delete(evsel); =20 diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 2f6b18af49e5..fb0a2debf015 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1782,7 +1782,7 @@ static int __evsel__prepare_open(struct evsel *evsel,= struct perf_cpu_map *cpus, nthreads =3D threads->nr; =20 if (evsel->core.fd =3D=3D NULL && - perf_evsel__alloc_fd(&evsel->core, cpus->nr, nthreads) < 0) + perf_evsel__alloc_fd(&evsel->core, perf_cpu_map__nr(cpus), nthreads) = < 0) return -ENOMEM; =20 evsel->open_flags =3D PERF_FLAG_FD_CLOEXEC; @@ -2020,9 +2020,10 @@ static int evsel__open_cpu(struct evsel *evsel, stru= ct perf_cpu_map *cpus, test_attr__ready(); =20 pr_debug2_peo("sys_perf_event_open: pid %d cpu %d group_fd %d flags = %#lx", - pid, cpus->map[idx].cpu, group_fd, evsel->open_flags); + pid, perf_cpu_map__cpu(cpus, idx).cpu, group_fd, evsel->open_flags); =20 - fd =3D sys_perf_event_open(&evsel->core.attr, pid, cpus->map[idx].cpu, + fd =3D sys_perf_event_open(&evsel->core.attr, pid, + perf_cpu_map__cpu(cpus, idx).cpu, group_fd, evsel->open_flags); =20 FD(evsel, idx, thread) =3D fd; @@ -2038,7 +2039,8 @@ static int evsel__open_cpu(struct evsel *evsel, struc= t perf_cpu_map *cpus, bpf_counter__install_pe(evsel, idx, fd); =20 if (unlikely(test_attr__enabled)) { - test_attr__open(&evsel->core.attr, pid, cpus->map[idx], + test_attr__open(&evsel->core.attr, pid, + perf_cpu_map__cpu(cpus, idx), fd, group_fd, evsel->open_flags); } =20 @@ -2079,7 +2081,8 @@ static int evsel__open_cpu(struct evsel *evsel, struc= t perf_cpu_map *cpus, if (evsel__precise_ip_fallback(evsel)) goto retry_open; =20 - if (evsel__ignore_missing_thread(evsel, cpus->nr, idx, threads, thread, e= rr)) { + if (evsel__ignore_missing_thread(evsel, perf_cpu_map__nr(cpus), + idx, threads, thread, err)) { /* We just removed 1 thread, so lower the upper nthreads limit. */ nthreads--; =20 @@ -2119,7 +2122,7 @@ static int evsel__open_cpu(struct evsel *evsel, struc= t perf_cpu_map *cpus, int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus, struct perf_thread_map *threads) { - return evsel__open_cpu(evsel, cpus, threads, 0, cpus ? cpus->nr : 1); + return evsel__open_cpu(evsel, cpus, threads, 0, perf_cpu_map__nr(cpus)); } =20 void evsel__close(struct evsel *evsel) @@ -2131,8 +2134,7 @@ void evsel__close(struct evsel *evsel) int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, in= t cpu_map_idx) { if (cpu_map_idx =3D=3D -1) - return evsel__open_cpu(evsel, cpus, NULL, 0, - cpus ? cpus->nr : 1); + return evsel__open_cpu(evsel, cpus, NULL, 0, perf_cpu_map__nr(cpus)); =20 return evsel__open_cpu(evsel, cpus, NULL, cpu_map_idx, cpu_map_idx + 1); } @@ -2982,7 +2984,7 @@ int evsel__store_ids(struct evsel *evsel, struct evli= st *evlist) struct perf_cpu_map *cpus =3D evsel->core.cpus; struct perf_thread_map *threads =3D evsel->core.threads; =20 - if (perf_evsel__alloc_id(&evsel->core, cpus->nr, threads->nr)) + if (perf_evsel__alloc_id(&evsel->core, perf_cpu_map__nr(cpus), threads->n= r)) return -ENOMEM; =20 return store_evsel_ids(evsel, evlist); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 5720ceebffac..041b42d33bf5 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -11,6 +11,7 @@ #include #include "symbol_conf.h" #include +#include =20 struct bpf_object; struct cgroup; @@ -191,7 +192,7 @@ static inline struct perf_cpu_map *evsel__cpus(struct e= vsel *evsel) =20 static inline int evsel__nr_cpus(struct evsel *evsel) { - return evsel__cpus(evsel)->nr; + return perf_cpu_map__nr(evsel__cpus(evsel)); } =20 void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread, diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 12261ed8c15b..0e8ff8d1e206 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c @@ -250,7 +250,7 @@ static void build_node_mask(int node, struct mmap_cpu_m= ask *mask) =20 nr_cpus =3D perf_cpu_map__nr(cpu_map); for (idx =3D 0; idx < nr_cpus; idx++) { - cpu =3D cpu_map->map[idx]; /* map c index to online cpu index */ + cpu =3D perf_cpu_map__cpu(cpu_map, idx); /* map c index to online cpu in= dex */ if (cpu__get_node(cpu) =3D=3D node) set_bit(cpu.cpu, mask->bits); } diff --git a/tools/perf/util/perf_api_probe.c b/tools/perf/util/perf_api_pr= obe.c index 734d006d9a8c..c28dd50bd571 100644 --- a/tools/perf/util/perf_api_probe.c +++ b/tools/perf/util/perf_api_probe.c @@ -67,7 +67,7 @@ static bool perf_probe_api(setup_probe_fn_t fn) cpus =3D perf_cpu_map__new(NULL); if (!cpus) return false; - cpu =3D cpus->map[0]; + cpu =3D perf_cpu_map__cpu(cpus, 0); perf_cpu_map__put(cpus); =20 do { @@ -144,7 +144,7 @@ bool perf_can_record_cpu_wide(void) if (!cpus) return false; =20 - cpu =3D cpus->map[0]; + cpu =3D perf_cpu_map__cpu(cpus, 0); perf_cpu_map__put(cpus); =20 fd =3D sys_perf_event_open(&attr, -1, cpu.cpu, -1, 0); diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 20461f174991..007a64681416 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -106,7 +106,7 @@ void evlist__config(struct evlist *evlist, struct recor= d_opts *opts, struct call if (opts->group) evlist__set_leader(evlist); =20 - if (evlist->core.cpus->map[0].cpu < 0) + if (perf_cpu_map__cpu(evlist->core.cpus, 0).cpu < 0) opts->no_inherit =3D true; =20 use_comm_exec =3D perf_can_comm_exec(); @@ -248,11 +248,11 @@ bool evlist__can_select_event(struct evlist *evlist, = const char *str) struct perf_cpu_map *cpus =3D perf_cpu_map__new(NULL); =20 if (cpus) - cpu =3D cpus->map[0]; + cpu =3D perf_cpu_map__cpu(cpus, 0); =20 perf_cpu_map__put(cpus); } else { - cpu =3D evlist->core.cpus->map[0]; + cpu =3D perf_cpu_map__cpu(evlist->core.cpus, 0); } =20 while (1) { diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools= /perf/util/scripting-engines/trace-event-python.c index f5ad0e62227a..e752e1f4a5f0 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1607,8 +1607,8 @@ static void python_process_stat(struct perf_stat_conf= ig *config, } =20 for (thread =3D 0; thread < threads->nr; thread++) { - for (cpu =3D 0; cpu < cpus->nr; cpu++) { - process_stat(counter, cpus->map[cpu], + for (cpu =3D 0; cpu < perf_cpu_map__nr(cpus); cpu++) { + process_stat(counter, perf_cpu_map__cpu(cpus, cpu), perf_thread_map__pid(threads, thread), tstamp, perf_counts(counter->counts, cpu, thread)); } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index f19348dddd55..2c0d30f08e78 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -2537,8 +2537,8 @@ int perf_session__cpu_bitmap(struct perf_session *ses= sion, return -1; } =20 - for (i =3D 0; i < map->nr; i++) { - struct perf_cpu cpu =3D map->map[i]; + for (i =3D 0; i < perf_cpu_map__nr(map); i++) { + struct perf_cpu cpu =3D perf_cpu_map__cpu(map, i); =20 if (cpu.cpu >=3D nr_cpus) { pr_err("Requested CPU %d too large. " diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index 4c9f211249db..1e0c731fc539 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c @@ -734,8 +734,8 @@ static int str_to_bitmap(char *s, cpumask_t *b, int nr_= cpus) if (!m) return -1; =20 - for (i =3D 0; i < m->nr; i++) { - c =3D m->map[i]; + for (i =3D 0; i < perf_cpu_map__nr(m); i++) { + c =3D perf_cpu_map__cpu(m, i); if (c.cpu >=3D nr_cpus) { ret =3D -1; break; diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index c9ba8050cc2b..70f095624a0b 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1186,12 +1186,12 @@ int perf_event__synthesize_thread_map2(struct perf_= tool *tool, static void synthesize_cpus(struct cpu_map_entries *cpus, struct perf_cpu_map *map) { - int i; + int i, map_nr =3D perf_cpu_map__nr(map); =20 - cpus->nr =3D map->nr; + cpus->nr =3D map_nr; =20 - for (i =3D 0; i < map->nr; i++) - cpus->cpu[i] =3D map->map[i].cpu; + for (i =3D 0; i < map_nr; i++) + cpus->cpu[i] =3D perf_cpu_map__cpu(map, i).cpu; } =20 static void synthesize_mask(struct perf_record_record_cpu_map *mask, @@ -1202,13 +1202,13 @@ static void synthesize_mask(struct perf_record_reco= rd_cpu_map *mask, mask->nr =3D BITS_TO_LONGS(max); mask->long_size =3D sizeof(long); =20 - for (i =3D 0; i < map->nr; i++) - set_bit(map->map[i].cpu, mask->mask); + for (i =3D 0; i < perf_cpu_map__nr(map); i++) + set_bit(perf_cpu_map__cpu(map, i).cpu, mask->mask); } =20 static size_t cpus_size(struct perf_cpu_map *map) { - return sizeof(struct cpu_map_entries) + map->nr * sizeof(u16); + 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) @@ -1217,9 +1217,9 @@ static size_t mask_size(struct perf_cpu_map *map, int= *max) =20 *max =3D 0; =20 - for (i =3D 0; i < map->nr; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map); i++) { /* bit position of the cpu is + 1 */ - int bit =3D map->map[i].cpu + 1; + int bit =3D perf_cpu_map__cpu(map, i).cpu + 1; =20 if (bit > *max) *max =3D bit; diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index 27945eeb0cb5..c1ebfc5d2e0c 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -95,15 +95,15 @@ size_t perf_top__header_snprintf(struct perf_top *top, = char *bf, size_t size) =20 if (target->cpu_list) ret +=3D SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)", - top->evlist->core.cpus->nr > 1 ? "s" : "", + perf_cpu_map__nr(top->evlist->core.cpus) > 1 ? "s" : "", target->cpu_list); else { if (target->tid) ret +=3D SNPRINTF(bf + ret, size - ret, ")"); else ret +=3D SNPRINTF(bf + ret, size - ret, ", %d CPU%s)", - top->evlist->core.cpus->nr, - top->evlist->core.cpus->nr > 1 ? "s" : ""); + perf_cpu_map__nr(top->evlist->core.cpus), + perf_cpu_map__nr(top->evlist->core.cpus) > 1 ? "s" : ""); } =20 perf_top__reset_sample_counters(top); --=20 2.35.0.rc0.227.g00780c9af4-goog From nobody Tue Jun 30 08:09:13 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 68094C433EF for ; Sat, 22 Jan 2022 04:58:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233132AbiAVE6e (ORCPT ); Fri, 21 Jan 2022 23:58:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233054AbiAVE61 (ORCPT ); Fri, 21 Jan 2022 23:58:27 -0500 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 0DEE2C06173B for ; Fri, 21 Jan 2022 20:58:27 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id g7-20020a25bdc7000000b00611c616bc76so23379396ybk.5 for ; Fri, 21 Jan 2022 20:58:27 -0800 (PST) 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=0TMY5o/dyQ5SuId4r0p3cjinmuagpPVpu9HxaMjlyFs=; b=DeAR0A/54ZEJ8e8t1zmQtC9KB02vVfLnz5iOu0J7GS85FCzaMxZfBZiMXsdb43cy8T uO4SydO4tsqYzItIiZn0LdKoJSm7n485pDJUlZPZMJqLZFYg/LuORMxjecV3YR76BNu3 eXxHUD9plFiCe2cFU2q0NPBI7LTQ7SefNqW2MYgajASwphiJpaWBesGorpN5mg1x316k 4oHlp+TJ+Fj4+ZCdhgEXHksDM5jGaLVAyJWnGurp2PZBGEi7JZmnhcrdL4X1rpqK8Zde rKlO12bO+5mPui7gCX3nJde9HxCuf+7cnufrF6/5Kuu05vVBGkTEIDVrvtkIt/B/HkoW /Q9Q== 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=0TMY5o/dyQ5SuId4r0p3cjinmuagpPVpu9HxaMjlyFs=; b=RKrW+9W3RcbCyIKMJP+I9vBi4BI/KeX6eHyfntd4aXm0qUEUWeiJwCTrWRgVt/BPD/ 6hhMzkv2kWKFCyULg7vlQG4GE5RuAuyneHCn5kq/hniB9hUIGdGRZZnsdkahatpRsEeg td1WIWPLS7Gn/NC3n+sFD6aUdL6etGu81auFvpHEcjKBSlbdoa6DgFth3O+0LsfEged3 wJTeytqCH3rd0wwscb/UT9bQT8gjMQucFXybjPVfRyElHhB1eFatJCWOsXFKhy8kTZSt dfU2inJ50DN4uZvuOCKpLaueX3oSME7rZh+HbsjgJT9XaL/AGWEO1uZ6vhVLFUbeWZ5s xA0w== X-Gm-Message-State: AOAM532Agrwzraayx+JXjY4fP3IerQX2T5Ri+pfCB3jCJvOIQx4jLdAM MRhwQ7ssLK/QjZ1Xivvrbkn/YLoN3+wt X-Google-Smtp-Source: ABdhPJzzXjXtpsFzpd5/4L/6+5gc8B+/RoD+lBkRRnRsman8Nk9iCzfcB3Oj7OgqpYPv5w93UgVuOt357CEZ X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:6125:f911:aa9a:59ee]) (user=irogers job=sendgmr) by 2002:a81:23d4:0:b0:2ca:287c:6c3b with SMTP id 00721157ae682-2ca287c6e87mr07b3.224.1642827505562; Fri, 21 Jan 2022 20:58:25 -0800 (PST) Date: Fri, 21 Jan 2022 20:58:11 -0800 In-Reply-To: <20220122045811.3402706-1-irogers@google.com> Message-Id: <20220122045811.3402706-4-irogers@google.com> Mime-Version: 1.0 References: <20220122045811.3402706-1-irogers@google.com> X-Mailer: git-send-email 2.35.0.rc0.227.g00780c9af4-goog Subject: [PATCH 3/3] perf cpumap: Add reference count checking From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , "=?UTF-8?q?Andr=C3=A9=20Almeida?=" , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Jin Yao , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov Cc: eranian@google.com, 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" Enabled when REFCNT_CHECKING is defined. The change adds a memory allocated pointer that is interposed between the reference counted cpu map at a get and freed by a put. The pointer replaces the original perf_cpu_map struct, so use of the perf_cpu_map via APIs remains unchanged. Any use of the cpu map without the API requires two versions, typically handled via an UNWRAP macro. This change is intended to catch: - use after put: using a cpumap after you have put it will cause a segv. - unbalanced puts: two puts for a get will result in a double free that can be captured and reported by tools like address sanitizer, including with the associated stack traces of allocation and frees. - missing puts: if a put is missing then the get turns into a memory leak that can be reported by leak sanitizer, including the stack trace at the point the get occurs. Signed-off-by: Ian Rogers --- tools/lib/perf/cpumap.c | 120 ++++++++++++++++------- tools/lib/perf/include/internal/cpumap.h | 14 ++- tools/perf/tests/cpumap.c | 20 ++-- tools/perf/util/cpumap.c | 42 ++++---- tools/perf/util/pmu.c | 24 +++-- 5 files changed, 146 insertions(+), 74 deletions(-) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index ee66760f1e63..d401d133f84b 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -10,10 +10,16 @@ #include #include =20 -static struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus) +#ifndef REFCNT_CHECKING +#define UNWRAP_MAP(x) x +#else +#define UNWRAP_MAP(x) x->orig +#endif + +#ifndef REFCNT_CHECKING +struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus) { struct perf_cpu_map *cpus =3D malloc(sizeof(*cpus) + sizeof(struct perf_c= pu) * nr_cpus); - if (cpus !=3D NULL) { cpus->nr =3D nr_cpus; refcount_set(&cpus->refcnt, 1); @@ -21,13 +27,31 @@ static struct perf_cpu_map *perf_cpu_map__alloc(int nr_= cpus) } return cpus; } +#else +struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus) +{ + struct perf_cpu_map *wrapped_cpus =3D NULL; + struct original_perf_cpu_map *cpus =3D + malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus); + if (cpus !=3D NULL) { + cpus->nr =3D nr_cpus; + refcount_set(&cpus->refcnt, 1); + wrapped_cpus =3D malloc(sizeof(*wrapped_cpus)); + if (wrapped_cpus !=3D NULL) + wrapped_cpus->orig =3D cpus; + else + free(cpus); + } + return wrapped_cpus; +} +#endif =20 struct perf_cpu_map *perf_cpu_map__dummy_new(void) { struct perf_cpu_map *cpus =3D perf_cpu_map__alloc(1); =20 if (cpus) - cpus->map[0].cpu =3D -1; + UNWRAP_MAP(cpus)->map[0].cpu =3D -1; =20 return cpus; } @@ -35,23 +59,45 @@ struct perf_cpu_map *perf_cpu_map__dummy_new(void) static void cpu_map__delete(struct perf_cpu_map *map) { if (map) { - WARN_ONCE(refcount_read(&map->refcnt) !=3D 0, + WARN_ONCE(refcount_read(&UNWRAP_MAP(map)->refcnt) !=3D 0, "cpu_map refcnt unbalanced\n"); +#ifdef REFCNT_CHECKING + free(map->orig); + map->orig =3D NULL; +#endif free(map); } } =20 struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map) { - if (map) - refcount_inc(&map->refcnt); + if (map) { +#ifdef REFCNT_CHECKING + struct perf_cpu_map *new_wrapper; +#endif + refcount_inc(&UNWRAP_MAP(map)->refcnt); +#ifdef REFCNT_CHECKING + new_wrapper =3D malloc(sizeof(*new_wrapper)); + new_wrapper->orig =3D map->orig; + map =3D new_wrapper; +#endif + } return map; } =20 void perf_cpu_map__put(struct perf_cpu_map *map) { - if (map && refcount_dec_and_test(&map->refcnt)) - cpu_map__delete(map); + if (map) { + if (refcount_dec_and_test(&UNWRAP_MAP(map)->refcnt)) + cpu_map__delete(map); + else { +#ifdef REFCNT_CHECKING + /* Free the wrapper object but the reference counted object remains. */ + map->orig =3D NULL; + free(map); +#endif + } + } } =20 static struct perf_cpu_map *cpu_map__default_new(void) @@ -68,7 +114,7 @@ static struct perf_cpu_map *cpu_map__default_new(void) int i; =20 for (i =3D 0; i < nr_cpus; ++i) - cpus->map[i].cpu =3D i; + UNWRAP_MAP(cpus)->map[i].cpu =3D i; } =20 return cpus; @@ -94,15 +140,16 @@ static struct perf_cpu_map *cpu_map__trim_new(int nr_c= pus, const struct perf_cpu int i, j; =20 if (cpus !=3D NULL) { - memcpy(cpus->map, tmp_cpus, payload_size); - qsort(cpus->map, nr_cpus, sizeof(struct perf_cpu), cmp_cpu); + memcpy(UNWRAP_MAP(cpus)->map, tmp_cpus, payload_size); + qsort(UNWRAP_MAP(cpus)->map, nr_cpus, sizeof(struct perf_cpu), cmp_cpu); /* Remove dups */ j =3D 0; for (i =3D 0; i < nr_cpus; i++) { - if (i =3D=3D 0 || cpus->map[i].cpu !=3D cpus->map[i - 1].cpu) - cpus->map[j++].cpu =3D cpus->map[i].cpu; + if (i =3D=3D 0 || + UNWRAP_MAP(cpus)->map[i].cpu !=3D UNWRAP_MAP(cpus)->map[i - 1].cpu) + UNWRAP_MAP(cpus)->map[j++].cpu =3D UNWRAP_MAP(cpus)->map[i].cpu; } - cpus->nr =3D j; + UNWRAP_MAP(cpus)->nr =3D j; assert(j <=3D nr_cpus); } return cpus; @@ -263,20 +310,20 @@ struct perf_cpu perf_cpu_map__cpu(const struct perf_c= pu_map *cpus, int idx) .cpu =3D -1 }; =20 - if (cpus && idx < cpus->nr) - return cpus->map[idx]; + if (cpus && idx < UNWRAP_MAP(cpus)->nr) + return UNWRAP_MAP(cpus)->map[idx]; =20 return result; } =20 int perf_cpu_map__nr(const struct perf_cpu_map *cpus) { - return cpus ? cpus->nr : 1; + return cpus ? UNWRAP_MAP(cpus)->nr : 1; } =20 bool perf_cpu_map__empty(const struct perf_cpu_map *map) { - return map ? map->map[0].cpu =3D=3D -1 : true; + return map ? UNWRAP_MAP(map)->map[0].cpu =3D=3D -1 : true; } =20 int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu cpu) @@ -287,10 +334,10 @@ int perf_cpu_map__idx(const struct perf_cpu_map *cpus= , struct perf_cpu cpu) return -1; =20 low =3D 0; - high =3D cpus->nr; + high =3D UNWRAP_MAP(cpus)->nr; while (low < high) { int idx =3D (low + high) / 2; - struct perf_cpu cpu_at_idx =3D cpus->map[idx]; + struct perf_cpu cpu_at_idx =3D UNWRAP_MAP(cpus)->map[idx]; =20 if (cpu_at_idx.cpu =3D=3D cpu.cpu) return idx; @@ -316,7 +363,7 @@ struct perf_cpu perf_cpu_map__max(struct perf_cpu_map *= map) }; =20 // cpu_map__trim_new() qsort()s it, cpu_map__default_new() sorts it as we= ll. - return map->nr > 0 ? map->map[map->nr - 1] : result; + return UNWRAP_MAP(map)->nr > 0 ? UNWRAP_MAP(map)->map[UNWRAP_MAP(map)->nr= - 1] : result; } =20 /* @@ -337,37 +384,36 @@ struct perf_cpu_map *perf_cpu_map__merge(struct perf_= cpu_map *orig, =20 if (!orig && !other) return NULL; - if (!orig) { - perf_cpu_map__get(other); - return other; - } + if (!orig) + return perf_cpu_map__get(other); if (!other) return orig; - if (orig->nr =3D=3D other->nr && - !memcmp(orig->map, other->map, orig->nr * sizeof(struct perf_cpu))) + if (UNWRAP_MAP(orig)->nr =3D=3D UNWRAP_MAP(other)->nr && + !memcmp(UNWRAP_MAP(orig)->map, UNWRAP_MAP(other)->map, + UNWRAP_MAP(orig)->nr * sizeof(struct perf_cpu))) return orig; =20 - tmp_len =3D orig->nr + other->nr; + tmp_len =3D UNWRAP_MAP(orig)->nr + UNWRAP_MAP(other)->nr; tmp_cpus =3D malloc(tmp_len * sizeof(struct perf_cpu)); if (!tmp_cpus) return NULL; =20 /* Standard merge algorithm from wikipedia */ i =3D j =3D k =3D 0; - while (i < orig->nr && j < other->nr) { - if (orig->map[i].cpu <=3D other->map[j].cpu) { - if (orig->map[i].cpu =3D=3D other->map[j].cpu) + while (i < UNWRAP_MAP(orig)->nr && j < UNWRAP_MAP(other)->nr) { + if (UNWRAP_MAP(orig)->map[i].cpu <=3D UNWRAP_MAP(other)->map[j].cpu) { + if (UNWRAP_MAP(orig)->map[i].cpu =3D=3D UNWRAP_MAP(other)->map[j].cpu) j++; - tmp_cpus[k++] =3D orig->map[i++]; + tmp_cpus[k++] =3D UNWRAP_MAP(orig)->map[i++]; } else - tmp_cpus[k++] =3D other->map[j++]; + tmp_cpus[k++] =3D UNWRAP_MAP(other)->map[j++]; } =20 - while (i < orig->nr) - tmp_cpus[k++] =3D orig->map[i++]; + while (i < UNWRAP_MAP(orig)->nr) + tmp_cpus[k++] =3D UNWRAP_MAP(orig)->map[i++]; =20 - while (j < other->nr) - tmp_cpus[k++] =3D other->map[j++]; + while (j < UNWRAP_MAP(other)->nr) + tmp_cpus[k++] =3D UNWRAP_MAP(other)->map[j++]; assert(k <=3D tmp_len); =20 merged =3D cpu_map__trim_new(k, tmp_cpus); diff --git a/tools/lib/perf/include/internal/cpumap.h b/tools/lib/perf/incl= ude/internal/cpumap.h index 581f9ffb4237..64ad56d167a0 100644 --- a/tools/lib/perf/include/internal/cpumap.h +++ b/tools/lib/perf/include/internal/cpumap.h @@ -16,7 +16,12 @@ struct perf_cpu { * gaps if CPU numbers were used. For events associated with a pid, rather= than * a CPU, a single dummy map with an entry of -1 is used. */ -struct perf_cpu_map { +#ifndef REFCNT_CHECKING +struct perf_cpu_map +#else +struct original_perf_cpu_map +#endif +{ refcount_t refcnt; /** Length of the map array. */ int nr; @@ -24,10 +29,17 @@ struct perf_cpu_map { struct perf_cpu map[]; }; =20 +#ifdef REFCNT_CHECKING +struct perf_cpu_map { + struct original_perf_cpu_map *orig; +}; +#endif + #ifndef MAX_NR_CPUS #define MAX_NR_CPUS 2048 #endif =20 +struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus); int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu cpu= ); =20 #endif /* __LIBPERF_INTERNAL_CPUMAP_H */ diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 84e87e31f119..65d9546aec6e 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -11,6 +11,12 @@ =20 struct machine; =20 +#ifndef REFCNT_CHECKING +#define UNWRAP_CPUMAP(x) x +#else +#define UNWRAP_CPUMAP(x) x->orig +#endif + static int process_event_mask(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused, @@ -35,10 +41,10 @@ static int process_event_mask(struct perf_tool *tool __= maybe_unused, } =20 map =3D cpu_map__new_data(data); - TEST_ASSERT_VAL("wrong nr", map->nr =3D=3D 20); + 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", map->map[i].cpu =3D=3D i); + TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, i).cpu =3D=3D i); } =20 perf_cpu_map__put(map); @@ -66,10 +72,10 @@ static int process_event_cpus(struct perf_tool *tool __= maybe_unused, TEST_ASSERT_VAL("wrong cpu", cpus->cpu[1] =3D=3D 256); =20 map =3D cpu_map__new_data(data); - TEST_ASSERT_VAL("wrong nr", map->nr =3D=3D 2); - TEST_ASSERT_VAL("wrong cpu", map->map[0].cpu =3D=3D 1); - TEST_ASSERT_VAL("wrong cpu", map->map[1].cpu =3D=3D 256); - TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) =3D=3D 1); + TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map) =3D=3D 2); + TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 0).cpu =3D=3D 1); + TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 1).cpu =3D=3D 256); + TEST_ASSERT_VAL("wrong refcnt", refcount_read(&UNWRAP_CPUMAP(map)->refcnt= ) =3D=3D 1); perf_cpu_map__put(map); return 0; } @@ -130,7 +136,7 @@ static int test__cpu_map_merge(struct test_suite *test = __maybe_unused, int subte struct perf_cpu_map *c =3D perf_cpu_map__merge(a, b); char buf[100]; =20 - TEST_ASSERT_VAL("failed to merge map: bad nr", c->nr =3D=3D 5); + TEST_ASSERT_VAL("failed to merge map: bad nr", perf_cpu_map__nr(c) =3D=3D= 5); cpu_map__snprint(c, buf, sizeof(buf)); TEST_ASSERT_VAL("failed to merge map: bad result", !strcmp(buf, "1-2,4-5,= 7")); perf_cpu_map__put(b); diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 12b2243222b0..e9976ca238fc 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -22,6 +22,12 @@ static int max_node_num; */ static int *cpunode_map; =20 +#ifndef REFCNT_CHECKING +#define UNWRAP_MAP(x) x +#else +#define UNWRAP_MAP(x) x->orig +#endif + static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *= cpus) { struct perf_cpu_map *map; @@ -37,9 +43,9 @@ static struct perf_cpu_map *cpu_map__from_entries(struct = cpu_map_entries *cpus) * otherwise it would become 65535. */ if (cpus->cpu[i] =3D=3D (u16) -1) - map->map[i].cpu =3D -1; + UNWRAP_MAP(map)->map[i].cpu =3D -1; else - map->map[i].cpu =3D (int) cpus->cpu[i]; + UNWRAP_MAP(map)->map[i].cpu =3D (int) cpus->cpu[i]; } } =20 @@ -58,7 +64,7 @@ static struct perf_cpu_map *cpu_map__from_mask(struct per= f_record_record_cpu_map int cpu, i =3D 0; =20 for_each_set_bit(cpu, mask->mask, nbits) - map->map[i++].cpu =3D cpu; + UNWRAP_MAP(map)->map[i++].cpu =3D cpu; } return map; =20 @@ -84,16 +90,13 @@ size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE = *fp) =20 struct perf_cpu_map *perf_cpu_map__empty_new(int nr) { - struct perf_cpu_map *cpus =3D malloc(sizeof(*cpus) + sizeof(int) * nr); + struct perf_cpu_map *cpus =3D perf_cpu_map__alloc(nr); =20 if (cpus !=3D NULL) { int i; =20 - cpus->nr =3D nr; for (i =3D 0; i < nr; i++) - cpus->map[i].cpu =3D -1; - - refcount_set(&cpus->refcnt, 1); + UNWRAP_MAP(cpus)->map[i].cpu =3D -1; } =20 return cpus; @@ -163,7 +166,7 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct per= f_cpu_map *cpus, { int idx; struct perf_cpu cpu; - struct cpu_aggr_map *c =3D cpu_aggr_map__empty_new(cpus->nr); + struct cpu_aggr_map *c =3D cpu_aggr_map__empty_new(perf_cpu_map__nr(cpus)= ); =20 if (!c) return NULL; @@ -187,7 +190,7 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct per= f_cpu_map *cpus, } } /* Trim. */ - if (c->nr !=3D cpus->nr) { + if (c->nr !=3D perf_cpu_map__nr(cpus)) { struct cpu_aggr_map *trimmed_c =3D realloc(c, sizeof(struct cpu_aggr_map) + sizeof(struct aggr_cpu_id) * c->nr); @@ -494,31 +497,32 @@ size_t cpu_map__snprint(struct perf_cpu_map *map, cha= r *buf, size_t size) =20 #define COMMA first ? "" : "," =20 - for (i =3D 0; i < map->nr + 1; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map) + 1; i++) { struct perf_cpu cpu =3D { .cpu =3D INT_MAX }; - bool last =3D i =3D=3D map->nr; + bool last =3D i =3D=3D perf_cpu_map__nr(map); =20 if (!last) - cpu =3D map->map[i]; + cpu =3D perf_cpu_map__cpu(map, i); =20 if (start =3D=3D -1) { start =3D i; if (last) { ret +=3D snprintf(buf + ret, size - ret, "%s%d", COMMA, - map->map[i].cpu); + perf_cpu_map__cpu(map, i).cpu); } - } else if (((i - start) !=3D (cpu.cpu - map->map[start].cpu)) || last) { + } else if (((i - start) !=3D (cpu.cpu - perf_cpu_map__cpu(map, start).cp= u)) || last) { int end =3D i - 1; =20 if (start =3D=3D end) { ret +=3D snprintf(buf + ret, size - ret, "%s%d", COMMA, - map->map[start].cpu); + perf_cpu_map__cpu(map, start).cpu); } else { ret +=3D snprintf(buf + ret, size - ret, "%s%d-%d", COMMA, - map->map[start].cpu, map->map[end].cpu); + perf_cpu_map__cpu(map, start).cpu, + perf_cpu_map__cpu(map, end).cpu); } first =3D false; start =3D i; @@ -545,7 +549,7 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, = char *buf, size_t size) int i, cpu; char *ptr =3D buf; unsigned char *bitmap; - struct perf_cpu last_cpu =3D perf_cpu_map__cpu(map, map->nr - 1); + struct perf_cpu last_cpu =3D perf_cpu_map__cpu(map, perf_cpu_map__nr(map)= - 1); =20 if (buf =3D=3D NULL) return 0; @@ -556,7 +560,7 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, = char *buf, size_t size) return 0; } =20 - for (i =3D 0; i < map->nr; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map); i++) { cpu =3D perf_cpu_map__cpu(map, i).cpu; bitmap[cpu / 8] |=3D 1 << (cpu % 8); } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 8dfbba15aeb8..1649321fe86f 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1992,13 +1992,20 @@ int perf_pmu__match(char *pattern, char *name, char= *tok) return 0; } =20 +#ifndef REFCNT_CHECKING +#define UNWRAP_CPUMAP(x) x +#else +#define UNWRAP_CPUMAP(x) x->orig +#endif + int perf_pmu__cpus_match(struct perf_pmu *pmu, struct perf_cpu_map *cpus, struct perf_cpu_map **mcpus_ptr, struct perf_cpu_map **ucpus_ptr) { struct perf_cpu_map *pmu_cpus =3D pmu->cpus; struct perf_cpu_map *matched_cpus, *unmatched_cpus; - int matched_nr =3D 0, unmatched_nr =3D 0; + struct perf_cpu cpu; + int i, matched_nr =3D 0, unmatched_nr =3D 0; =20 matched_cpus =3D perf_cpu_map__default_new(); if (!matched_cpus) @@ -2010,18 +2017,15 @@ int perf_pmu__cpus_match(struct perf_pmu *pmu, stru= ct perf_cpu_map *cpus, return -1; } =20 - for (int i =3D 0; i < cpus->nr; i++) { - int cpu; - - cpu =3D perf_cpu_map__idx(pmu_cpus, cpus->map[i]); - if (cpu =3D=3D -1) - unmatched_cpus->map[unmatched_nr++] =3D cpus->map[i]; + perf_cpu_map__for_each_cpu(cpu, i, cpus) { + if (!perf_cpu_map__has(pmu_cpus, cpu)) + UNWRAP_CPUMAP(unmatched_cpus)->map[unmatched_nr++] =3D cpu; else - matched_cpus->map[matched_nr++] =3D cpus->map[i]; + UNWRAP_CPUMAP(matched_cpus)->map[matched_nr++] =3D cpu; } =20 - unmatched_cpus->nr =3D unmatched_nr; - matched_cpus->nr =3D matched_nr; + UNWRAP_CPUMAP(unmatched_cpus)->nr =3D unmatched_nr; + UNWRAP_CPUMAP(matched_cpus)->nr =3D matched_nr; *mcpus_ptr =3D matched_cpus; *ucpus_ptr =3D unmatched_cpus; return 0; --=20 2.35.0.rc0.227.g00780c9af4-goog