From nobody Sun Jun 28 06:40:44 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 9F5BEC433EF for ; Fri, 11 Feb 2022 10:34:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239505AbiBKKef (ORCPT ); Fri, 11 Feb 2022 05:34:35 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60666 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348908AbiBKKeY (ORCPT ); Fri, 11 Feb 2022 05:34:24 -0500 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6DF92EAC for ; Fri, 11 Feb 2022 02:34:23 -0800 (PST) Received: by mail-pl1-x64a.google.com with SMTP id u4-20020a170902a60400b0014dca32c59eso3069973plq.9 for ; Fri, 11 Feb 2022 02:34: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=1YSpc4YhDXxIYWJh2wErJ5BF47S0XjlsN9o5D+uT5lY=; b=qjOS6ucEdNfpe12GLjFydEh+KaauVgdEMR12xLgo/OfWmDK3MIQExMB9DsIv5BWR6h wqipmB9VfR0BmTqqsSIUxFIrdNX0NzzJAyaTodNiN3bTwGnIHLaB+ptKKr+GHFEGZitm RL6V1nCsqRlggO9hjae2jzEHWU3j7Uh+Bp7ffQdK95NWzxOCBOQI+FIuWtXScaQJ2JjC RXSI8C5nx9WAuUwZTCb8uCleWtfRoq6GPa6QNQ1TkJ3bfCCAVCnOHs6JDhtKHW5sHv3Z 7WuDaMFLfwGTGZhO9kUEyyiFk2/SmjM5ZOf1pwOKB1h63ltAk+nrhEFc/97cz6chTOrZ mG9Q== 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=1YSpc4YhDXxIYWJh2wErJ5BF47S0XjlsN9o5D+uT5lY=; b=SkomXhOnwR1QqtNBJhG4Fon+SyODnuV0K+SZKFuN9uW+8u5ZStRHSM/97O5fRQ8wZS mYJzDxZ7WtG/qdttfJIKyr1+u1dlEodcZGaWglwgAkdEdypulbqo2eNOphl/i+3Xtl+X bHWLlN0vsr+uAlVf3/zTMykwlkv0i5Ja/s6Uxr1notY35hSw8N/iNhYdteVKPkF/WhPH YjDPVOZ8xxG2MsnqJxczdDD7CpIuN2V1eJ1rnMDgoSnXEIPApfmtIshB1JYt7pwA9S5V tfLs6Ukx/fIBpmUJr0Swt51uBZt/k/F67+N2bRQDeODX5D6aKmQLtoKTiaxEmE5x++iU FTQA== X-Gm-Message-State: AOAM5305XuMw7UF+j57S8H8CyRHG4xENaa/Bno0fI+44WDWhTC/y7pnI wrRfPgZQ9bMZTeo1L5C8uLarZvQFaRQg X-Google-Smtp-Source: ABdhPJxTBfqOigPoEX9wGXapHTWuWWdOfcfUfGvkcZ6xKfNyYTb8dRNrdEdRh10mUl2WeAdvVlh3jaavjK6G X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a05:6a00:1682:: with SMTP id k2mr1067116pfc.69.1644575662878; Fri, 11 Feb 2022 02:34:22 -0800 (PST) Date: Fri, 11 Feb 2022 02:33:54 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-2-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 01/22] 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 , Hao Luo 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/perf/tests/cpumap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 84e87e31f119..f94929ebb54b 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -35,10 +35,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,9 +66,9 @@ static int process_event_cpus(struct perf_tool *tool __ma= ybe_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 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(&map->refcnt) =3D=3D 1); perf_cpu_map__put(map); return 0; @@ -130,7 +130,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); --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 0BD5DC433EF for ; Fri, 11 Feb 2022 10:34:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348966AbiBKKej (ORCPT ); Fri, 11 Feb 2022 05:34:39 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348943AbiBKKe1 (ORCPT ); Fri, 11 Feb 2022 05:34:27 -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 381A3EB1 for ; Fri, 11 Feb 2022 02:34:26 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id 2-20020a251302000000b006118f867dadso17901181ybt.12 for ; Fri, 11 Feb 2022 02:34:26 -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=zZqjerFyUzn9J1iLxHpLoHFf7aGVnScfvGTlvzc2WOA=; b=kZbSx2/JG2RC+HrevtaSHlt+chqBCEgACB3vxiIuRd8ty5sIjcAakIpIdDs2A7fZM7 fG9q8IRjuhPtWmnte6QNtaoki3X87mjjo51QAsIFmUW9CAJY+zdB0syIWQ4bxTdLbIrH W5gyqVXceGN+I7V3c4dgPvu5MGDk6/0gSH3mg5eOZcPJ8BLZHWkwMGGnaLeziiw8ZnGi 0hPYMmyZv0XhufzooHJC4L7R7ppAIoLfhBdK47TFJs+N1tOoV7m0I+OVQVODEqF5q0k8 dmyHczuH5c9T3LeGTA4Uh4SlOggn6wf8yXNmuXEGDMM27jEEwuAKMkGyUH63Bp1vjXcM 5eoQ== 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=zZqjerFyUzn9J1iLxHpLoHFf7aGVnScfvGTlvzc2WOA=; b=XennwPy0eg68AjP6GqpEguleK0TFa936vTHBJFvY3xGvijDPm5P3VCfV3ZWA1HsDMW oAjF6de1sC9MlYi0XE6vEsxDkZ4FLoawYkW844sdv3/mTIzbCuOWZzw+mv6k6uIwSf8c A1SlYh6LLxnLxde83dx44jAC3xZerV5kIdn3apVLdKEhfXUbyfw+V7xpF3uBZeZ7im/K OHQbMq+kgDVdNg77ZQZsYn8YT0nIwo3VBbk9Lj0Yxjm8LW4Xm6Ex2Ro8watI3gp+wBha 1IBWAko4C73CG4j2L1CykIxZn2QLgkjM82OTQ7AXJ1MIyhkPGCSWe+uSxmTfZgeDWnxF sCwQ== X-Gm-Message-State: AOAM533sbziWytZyK9fI6+7cBDGsGLQsDJd7U/DlyUSupvI/pKGG8k8W Mo3GVN3zO4u6d0toWOv810f7WyH1rPJw X-Google-Smtp-Source: ABdhPJzVflHjs1qka6WQPmyROhtJTQf9pViBPc/+f9TWgA1LiYueSSAE/42s1WoomHEliWcXiN2OuPqCw/Mt X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a81:a403:: with SMTP id b3mr903675ywh.310.1644575665364; Fri, 11 Feb 2022 02:34:25 -0800 (PST) Date: Fri, 11 Feb 2022 02:33:55 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-3-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 02/22] perf cpumap: Use for each loop 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 , Hao Luo 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" Improve readability in perf_pmu__cpus_match by using perf_cpu_map__for_each_cpu. Signed-off-by: Ian Rogers --- tools/perf/util/pmu.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 8dfbba15aeb8..9a1c7e63e663 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1998,7 +1998,8 @@ int perf_pmu__cpus_match(struct perf_pmu *pmu, struct= perf_cpu_map *cpus, { 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,14 +2011,11 @@ 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)) + unmatched_cpus->map[unmatched_nr++] =3D cpu; else - matched_cpus->map[matched_nr++] =3D cpus->map[i]; + matched_cpus->map[matched_nr++] =3D cpu; } =20 unmatched_cpus->nr =3D unmatched_nr; --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 D0912C43217 for ; Fri, 11 Feb 2022 10:34:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348969AbiBKKem (ORCPT ); Fri, 11 Feb 2022 05:34:42 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348950AbiBKKe3 (ORCPT ); Fri, 11 Feb 2022 05:34:29 -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 B9DF0EB4 for ; Fri, 11 Feb 2022 02:34:28 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id j17-20020a25ec11000000b0061dabf74012so17894373ybh.15 for ; Fri, 11 Feb 2022 02:34:28 -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=+vOkqY9ujgn8jSfYzqg46hBeUg4M5HreQws2W8UcU8Y=; b=tPuuDRE6WJC7bnfBoA28dPv83FT6FoKMQeGtZeMSpWXQALL6+dTtChTvyGeC+iT/Nk +s+ggMScw3vJsOiWa06ibucn2ixK71ZSDjFQrAaJzMLe3tTONDalV2bBy/DIWdT3Bnaz M5HKBclNdOh9ULkPxXrSxPNsAoA+UIDN+61OVLmgIDvHIygcwrzkiDPcSn7qH/fFaaTA p2/VQZ245a7r2mXjA/Nxo2ArOnBvWBD9lYCueIBdFBw7zCcAQO/WODyc3MOoW7LtSTBw SlUqh3YPj3BmD+kyQkqD8k+K1gUWzPSgtwdecN5ucaNcrGsyMbup8x5jMeq4oQcqws11 vQyw== 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=+vOkqY9ujgn8jSfYzqg46hBeUg4M5HreQws2W8UcU8Y=; b=DwVI1/8Po4JmHEjlsAR+Mqv35wm5BHNuEiIxtzfzoz7CQ+x5+7asA6tJNOI3eHu2Dj +6o/LbGsNMkHfGaJ5MTbVanMpnojvp27v9wVLirXqYXZ/BLX0VvpIpraGid71zs1i+Rs 1TeHV+XP93NP6NlRtn4HFKxOMsBX/oD+aFKP5GlbGcmgUc8oVbnn4UOdFRVWC6BIKLl5 RcasUWV/Jtgz3WYFvKNMS2EH9YRLYFoLdQ7AeTQwb1t/u5ZZgJrdVTVc0IxYAvGca5RL YOjGrWTXX6fmzH66GqDQCpFNr1wwjqn05INlH/+BsBULVnB5LK1rQRny/+PM1beagrM9 UZqA== X-Gm-Message-State: AOAM531XZfptnU//EhfuMcMnT8vvlbRafbzh+Xf0e9SrG0EhFJ/6Z8y4 jSkWH11PCu5vyWaKGPL2e66UKDcQciX/ X-Google-Smtp-Source: ABdhPJyonsoIUZQUmjbnltCqHmTteIdPLW9jFfUL6XJGAvW1QrRbXzSVJ1ciNuSiL89/bIjjujvp6zxp+ryV X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:2155:: with SMTP id h82mr645997ybh.606.1644575667809; Fri, 11 Feb 2022 02:34:27 -0800 (PST) Date: Fri, 11 Feb 2022 02:33:56 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-4-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 03/22] perf dso: Make lock error check and add BUG_ONs 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 , Hao Luo 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" Make the pthread mutex on dso use the error check type. This allows deadlock checking via the return type. Assert the returned value from mutex lock is always 0. Signed-off-by: Ian Rogers --- tools/perf/util/dso.c | 12 +++++++++--- tools/perf/util/symbol.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 9cc8a1772b4b..6beccffeef7b 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -784,7 +784,7 @@ dso_cache__free(struct dso *dso) struct rb_root *root =3D &dso->data.cache; struct rb_node *next =3D rb_first(root); =20 - pthread_mutex_lock(&dso->lock); + BUG_ON(pthread_mutex_lock(&dso->lock) !=3D 0); while (next) { struct dso_cache *cache; =20 @@ -830,7 +830,7 @@ dso_cache__insert(struct dso *dso, struct dso_cache *ne= w) struct dso_cache *cache; u64 offset =3D new->offset; =20 - pthread_mutex_lock(&dso->lock); + BUG_ON(pthread_mutex_lock(&dso->lock) !=3D 0); while (*p !=3D NULL) { u64 end; =20 @@ -1259,6 +1259,8 @@ struct dso *dso__new_id(const char *name, struct dso_= id *id) struct dso *dso =3D calloc(1, sizeof(*dso) + strlen(name) + 1); =20 if (dso !=3D NULL) { + pthread_mutexattr_t lock_attr; + strcpy(dso->name, name); if (id) dso->id =3D *id; @@ -1286,8 +1288,12 @@ struct dso *dso__new_id(const char *name, struct dso= _id *id) dso->root =3D NULL; INIT_LIST_HEAD(&dso->node); INIT_LIST_HEAD(&dso->data.open_entry); - pthread_mutex_init(&dso->lock, NULL); + pthread_mutexattr_init(&lock_attr); + pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_ERRORCHECK); + pthread_mutex_init(&dso->lock, &lock_attr); + pthread_mutexattr_destroy(&lock_attr); refcount_set(&dso->refcnt, 1); + } =20 return dso; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b2ed3140a1fa..43f47532696f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1783,7 +1783,7 @@ int dso__load(struct dso *dso, struct map *map) } =20 nsinfo__mountns_enter(dso->nsinfo, &nsc); - pthread_mutex_lock(&dso->lock); + BUG_ON(pthread_mutex_lock(&dso->lock) !=3D 0); =20 /* check again under the dso->lock */ if (dso__loaded(dso)) { --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 50A99C433F5 for ; Fri, 11 Feb 2022 10:34:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348982AbiBKKeq (ORCPT ); Fri, 11 Feb 2022 05:34:46 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348945AbiBKKeb (ORCPT ); Fri, 11 Feb 2022 05:34:31 -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 DA58FEA8 for ; Fri, 11 Feb 2022 02:34:30 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id b12-20020a056902030c00b0061d720e274aso17824428ybs.20 for ; Fri, 11 Feb 2022 02:34:30 -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=wQ52+X1lVqs3NA4HQ0Y5oly0G0KrCZg9YO1xv1PXn5A=; b=a3hvrMFEyL/k2U8ysBuPjJnJ+Ygk9IuzMt5WdmMQmX9koGxdtYxgjRVe1l+4k8Kz+8 13Z3YydDRdSRXaU/sf9MCqpHBy+i9m5aSw/NnjsmXsuL7/HFDACiZf2VX9kCUpttkoVx p+dc3kkdel5pMgKWNy+PwNAXYXubgTfW/Y+VaRnTkocNolWj1Z674DOIAwh0ozl8gt+v c58txNVmQQuMwB7+qt9QpQ7DIeuwdHyolkNvkdmGxK7dVAek5PLOwiiilaE3DRtckn07 79qTmiIkiHJ8AiSApLd/ygFShczSb113Duj1eNT6rLT1hj1z5ebbdzQuzrNDxrmGav9/ EoAw== 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=wQ52+X1lVqs3NA4HQ0Y5oly0G0KrCZg9YO1xv1PXn5A=; b=iXni0WcOd3g836YbkPUDTJxPXDgYpR2g0jlHrFT7XuA/jnDyn0JOWo3iNH7WZV/I8a aF/JeRY81pO5JgIQ6zbJ5ZahoZ0BGr+2o9NarLBbut6h9muqusGAKW6RI9D72OoRrks/ WNttnbAn4X3xGdyZTUlAEw8qu8+A8tg5SHmL+3X3RUq1bHyrXkUi+OGL5iE7J8aTr91S Z+FTkxirThIAkHb4DxBOo6bOVGyaHJTvgFSICNoLqfzm98JAjTFzZ2kfGoRMk47irciC RLAAcdjnpkbTAEdlhbp1IzfC3j1eDwnsqfiCNJJxoYmmNBvWfEKHVyveprm2X71tePT1 Icyw== X-Gm-Message-State: AOAM533EECqzJCbviDYnAzgrXR5qNSpdmCrFP5rg2TNjjG6eeR5Dqo8x TqJRCuuPnai5jmGDG9t3GXzgTD2oXg69 X-Google-Smtp-Source: ABdhPJxL1gJ1wtKPcRX3YXRp7qrePWMozQDDx5tNxxp/EendyW1MtiPytq9GoEJML/jt8+AhT8d3Ej6nzmbl X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:7809:: with SMTP id t9mr606088ybc.577.1644575670099; Fri, 11 Feb 2022 02:34:30 -0800 (PST) Date: Fri, 11 Feb 2022 02:33:57 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-5-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 04/22] perf dso: Hold lock when accessing nsinfo 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 , Hao Luo 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" There may be threads racing to update dso->nsinfo: https://lore.kernel.org/linux-perf-users/CAP-5=3DfWZH20L4kv-BwVtGLwR=3DEm3A= OOT+Q4QGivvQuYn5AsPRg@mail.gmail.com/ Holding the dso->lock avoids use-after-free, memory leaks and other such bugs. Apply the fix in: https://lore.kernel.org/linux-perf-users/20211118193714.2293728-1-irogers@g= oogle.com/ of there being a missing nsinfo__put now that the accesses are data race free. Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 4 ++++ tools/perf/util/dso.c | 5 ++++- tools/perf/util/map.c | 3 +++ tools/perf/util/probe-event.c | 2 ++ tools/perf/util/symbol.c | 2 +- 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index fbf43a454cba..bede332bf0e2 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -363,8 +363,10 @@ static struct dso *findnew_dso(int pid, int tid, const= char *filename, } =20 if (dso) { + BUG_ON(pthread_mutex_lock(&dso->lock) !=3D 0); nsinfo__put(dso->nsinfo); dso->nsinfo =3D nsi; + pthread_mutex_unlock(&dso->lock); } else nsinfo__put(nsi); =20 @@ -547,7 +549,9 @@ static int dso__read_build_id(struct dso *dso) if (dso->has_build_id) return 0; =20 + BUG_ON(pthread_mutex_lock(&dso->lock) !=3D 0); nsinfo__mountns_enter(dso->nsinfo, &nsc); + pthread_mutex_unlock(&dso->lock); if (filename__read_build_id(dso->long_name, &dso->bid) > 0) dso->has_build_id =3D true; nsinfo__mountns_exit(&nsc); diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 6beccffeef7b..b2f570adba35 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -548,8 +548,11 @@ static int open_dso(struct dso *dso, struct machine *m= achine) int fd; struct nscookie nsc; =20 - if (dso->binary_type !=3D DSO_BINARY_TYPE__BUILD_ID_CACHE) + if (dso->binary_type !=3D DSO_BINARY_TYPE__BUILD_ID_CACHE) { + BUG_ON(pthread_mutex_lock(&dso->lock) !=3D 0); nsinfo__mountns_enter(dso->nsinfo, &nsc); + pthread_mutex_unlock(&dso->lock); + } fd =3D __open_dso(dso, machine); if (dso->binary_type !=3D DSO_BINARY_TYPE__BUILD_ID_CACHE) nsinfo__mountns_exit(&nsc); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 8af693d9678c..ae99b52502d5 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -192,7 +192,10 @@ struct map *map__new(struct machine *machine, u64 star= t, u64 len, if (!(prot & PROT_EXEC)) dso__set_loaded(dso); } + BUG_ON(pthread_mutex_lock(&dso->lock) !=3D 0); + nsinfo__put(dso->nsinfo); dso->nsinfo =3D nsi; + pthread_mutex_unlock(&dso->lock); =20 if (build_id__is_defined(bid)) dso__set_build_id(dso, bid); diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a834918a0a0d..7444e689ece7 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -180,8 +180,10 @@ struct map *get_target_map(const char *target, struct = nsinfo *nsi, bool user) =20 map =3D dso__new_map(target); if (map && map->dso) { + BUG_ON(pthread_mutex_lock(&map->dso->lock) !=3D 0); nsinfo__put(map->dso->nsinfo); map->dso->nsinfo =3D nsinfo__get(nsi); + pthread_mutex_unlock(&map->dso->lock); } return map; } else { diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 43f47532696f..a504346feb05 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1774,6 +1774,7 @@ int dso__load(struct dso *dso, struct map *map) char newmapname[PATH_MAX]; const char *map_path =3D dso->long_name; =20 + BUG_ON(pthread_mutex_lock(&dso->lock) !=3D 0); perfmap =3D strncmp(dso->name, "/tmp/perf-", 10) =3D=3D 0; if (perfmap) { if (dso->nsinfo && (dso__find_perf_map(newmapname, @@ -1783,7 +1784,6 @@ int dso__load(struct dso *dso, struct map *map) } =20 nsinfo__mountns_enter(dso->nsinfo, &nsc); - BUG_ON(pthread_mutex_lock(&dso->lock) !=3D 0); =20 /* check again under the dso->lock */ if (dso__loaded(dso)) { --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 131F0C433EF for ; Fri, 11 Feb 2022 10:34:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348988AbiBKKet (ORCPT ); Fri, 11 Feb 2022 05:34:49 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60774 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348962AbiBKKee (ORCPT ); Fri, 11 Feb 2022 05:34:34 -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 9543BEA8 for ; Fri, 11 Feb 2022 02:34:33 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id z15-20020a25bb0f000000b00613388c7d99so17964725ybg.8 for ; Fri, 11 Feb 2022 02:34:33 -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=YeWWX6eij4rjru09a4hqWnNdgpL4pnTfKpwjRF5ZzB0=; b=Kir8UyzLNhSWUOuwK+KEUEu1VPyVi95JRLGpdnZtSylD1Ydjh0jg/e/lQuebj5Yz/Y tjAVAHsNNHCUxyJWZYLC+SJxpY5338YNLYAX0xbS295xLmZ1/95ZYLBlxILWSJZFcnW9 vW3pFczfj8cRVQw8Zvxs88k845NzvZMcdvcdZ3tn3XG7IJjtJEOHi7Rso+1OrIv685Y5 p9c1d3t08pgDRJMVtP0XV45NT5R5FuojhMquFwtMryHmumnYdiWwMsyJPhXEn3wQhwEa f7e5NXyHFjtuBYy4PCqw3v0wtMmb8ezyPKsgtiV52m+Jf8U7PdfoSAduAnaBy2rZdV5z CLJg== 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=YeWWX6eij4rjru09a4hqWnNdgpL4pnTfKpwjRF5ZzB0=; b=ADAzfpP3+jOioszJjwll9eOUDeFVUwD17zXZ1jMrL7x0T6GpH77qa/k+SgJt3GSgIv YtZhI7+taS6MBQiDqeVwQGQBnEx1cC0fXIpBOAPTw8CupsywBMzcdqizr26Jjaiq37f3 6JPwnMn5KQxS3spQ41JX6SMLnLT+CZcoZ2dGG9x80E7kxRdc5OWoI9D0A9So8bS7HjmG OXqdjOOiLvsVcUJdU5aka/qq8A1AAZS88R7d+P+dYjTHKKWjGdWGeIbAb8sq9wx40j/W bFKu+cSXM3qEr+ELJD4xq8H/4qIpXjr/VN1wH1qAEjUCE1liV/P7/V1w+33RwJ7+lwDG TB0w== X-Gm-Message-State: AOAM531p4VQLHPA/ZxTDsxN892bYA8DrqXkRCUMlg1RrmNxyPBDhihqC /msiBHzIVhsXgHRwLtOXeUrWbro46P5o X-Google-Smtp-Source: ABdhPJz5QAOt44oR5/+OEn5kY9Pi2rOdBXMyNYj9Q58PImiI86g+LzMZMfh1NJ7u55qLsmLdjLhwscuuOvYf X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a5b:443:: with SMTP id s3mr675459ybp.117.1644575672806; Fri, 11 Feb 2022 02:34:32 -0800 (PST) Date: Fri, 11 Feb 2022 02:33:58 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-6-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 05/22] perf maps: Use a pointer for kmaps 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 , Hao Luo 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" struct maps is reference counted, using a pointer is more idiomatic. Signed-off-by: Ian Rogers --- tools/perf/arch/x86/util/event.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 4 +-- tools/perf/util/bpf-event.c | 2 +- tools/perf/util/callchain.c | 2 +- tools/perf/util/event.c | 6 ++--- tools/perf/util/machine.c | 38 ++++++++++++++++------------- tools/perf/util/machine.h | 8 +++--- tools/perf/util/probe-event.c | 2 +- 8 files changed, 34 insertions(+), 30 deletions(-) diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/ev= ent.c index 9b31734ee968..e670f3547581 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -18,7 +18,7 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *= tool, { int rc =3D 0; struct map *pos; - struct maps *kmaps =3D &machine->kmaps; + struct maps *kmaps =3D machine__kernel_maps(machine); union perf_event *event =3D zalloc(sizeof(event->mmap) + machine->id_hdr_size); =20 diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index e80df13c0420..84bf5f640065 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -293,7 +293,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused * so use the short name, less descriptive but the same ("[kernel]" in * both cases. */ - pair =3D maps__find_by_name(&kallsyms.kmaps, (map->dso->kernel ? + pair =3D maps__find_by_name(kallsyms.kmaps, (map->dso->kernel ? map->dso->short_name : map->dso->name)); if (pair) { @@ -315,7 +315,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused mem_start =3D vmlinux_map->unmap_ip(vmlinux_map, map->start); mem_end =3D vmlinux_map->unmap_ip(vmlinux_map, map->end); =20 - pair =3D maps__find(&kallsyms.kmaps, mem_start); + pair =3D maps__find(kallsyms.kmaps, mem_start); if (pair =3D=3D NULL || pair->priv) continue; =20 diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index a517eaa51eb3..33257b594a71 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -92,7 +92,7 @@ static int machine__process_bpf_event_load(struct machine= *machine, for (i =3D 0; i < info_linear->info.nr_jited_ksyms; i++) { u64 *addrs =3D (u64 *)(uintptr_t)(info_linear->info.jited_ksyms); u64 addr =3D addrs[i]; - struct map *map =3D maps__find(&machine->kmaps, addr); + struct map *map =3D maps__find(machine__kernel_maps(machine), addr); =20 if (map) { map->dso->binary_type =3D DSO_BINARY_TYPE__BPF_PROG_INFO; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 131207b91d15..5c27a4b2e7a7 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1119,7 +1119,7 @@ int fill_callchain_info(struct addr_location *al, str= uct callchain_cursor_node * goto out; } =20 - if (al->maps =3D=3D &al->maps->machine->kmaps) { + if (al->maps =3D=3D machine__kernel_maps(al->maps->machine)) { if (machine__is_host(al->maps->machine)) { al->cpumode =3D PERF_RECORD_MISC_KERNEL; al->level =3D 'k'; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index fe24801f8e9f..6439c888ae38 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -484,7 +484,7 @@ size_t perf_event__fprintf_text_poke(union perf_event *= event, struct machine *ma if (machine) { struct addr_location al; =20 - al.map =3D maps__find(&machine->kmaps, tp->addr); + al.map =3D maps__find(machine__kernel_maps(machine), tp->addr); if (al.map && map__load(al.map) >=3D 0) { al.addr =3D al.map->map_ip(al.map, tp->addr); al.sym =3D map__find_symbol(al.map, al.addr); @@ -587,13 +587,13 @@ struct map *thread__find_map(struct thread *thread, u= 8 cpumode, u64 addr, =20 if (cpumode =3D=3D PERF_RECORD_MISC_KERNEL && perf_host) { al->level =3D 'k'; - al->maps =3D maps =3D &machine->kmaps; + al->maps =3D maps =3D machine__kernel_maps(machine); load_map =3D true; } else if (cpumode =3D=3D PERF_RECORD_MISC_USER && perf_host) { al->level =3D '.'; } else if (cpumode =3D=3D PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { al->level =3D 'g'; - al->maps =3D maps =3D &machine->kmaps; + al->maps =3D maps =3D machine__kernel_maps(machine); load_map =3D true; } else if (cpumode =3D=3D PERF_RECORD_MISC_GUEST_USER && perf_guest) { al->level =3D 'u'; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index f70ba56912d4..57fbdba66425 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -89,7 +89,10 @@ int machine__init(struct machine *machine, const char *r= oot_dir, pid_t pid) int err =3D -ENOMEM; =20 memset(machine, 0, sizeof(*machine)); - maps__init(&machine->kmaps, machine); + machine->kmaps =3D maps__new(machine); + if (machine->kmaps =3D=3D NULL) + return -ENOMEM; + RB_CLEAR_NODE(&machine->rb_node); dsos__init(&machine->dsos); =20 @@ -108,7 +111,7 @@ int machine__init(struct machine *machine, const char *= root_dir, pid_t pid) =20 machine->root_dir =3D strdup(root_dir); if (machine->root_dir =3D=3D NULL) - return -ENOMEM; + goto out; =20 if (machine__set_mmap_name(machine)) goto out; @@ -131,6 +134,7 @@ int machine__init(struct machine *machine, const char *= root_dir, pid_t pid) =20 out: if (err) { + zfree(&machine->kmaps); zfree(&machine->root_dir); zfree(&machine->mmap_name); } @@ -220,7 +224,7 @@ void machine__exit(struct machine *machine) return; =20 machine__destroy_kernel_maps(machine); - maps__exit(&machine->kmaps); + maps__delete(machine->kmaps); dsos__exit(&machine->dsos); machine__exit_vdso(machine); zfree(&machine->root_dir); @@ -778,7 +782,7 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, struct perf_sample *sample __maybe_unused) { struct symbol *sym; - struct map *map =3D maps__find(&machine->kmaps, event->ksymbol.addr); + struct map *map =3D maps__find(machine__kernel_maps(machine), event->ksym= bol.addr); =20 if (!map) { struct dso *dso =3D dso__new(event->ksymbol.name); @@ -801,7 +805,7 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, =20 map->start =3D event->ksymbol.addr; map->end =3D map->start + event->ksymbol.len; - maps__insert(&machine->kmaps, map); + maps__insert(machine__kernel_maps(machine), map); map__put(map); dso__set_loaded(dso); =20 @@ -827,12 +831,12 @@ static int machine__process_ksymbol_unregister(struct= machine *machine, struct symbol *sym; struct map *map; =20 - map =3D maps__find(&machine->kmaps, event->ksymbol.addr); + map =3D maps__find(machine__kernel_maps(machine), event->ksymbol.addr); if (!map) return 0; =20 if (map !=3D machine->vmlinux_map) - maps__remove(&machine->kmaps, map); + maps__remove(machine__kernel_maps(machine), map); else { sym =3D dso__find_symbol(map->dso, map->map_ip(map, map->start)); if (sym) @@ -858,7 +862,7 @@ int machine__process_ksymbol(struct machine *machine __= maybe_unused, int machine__process_text_poke(struct machine *machine, union perf_event *= event, struct perf_sample *sample __maybe_unused) { - struct map *map =3D maps__find(&machine->kmaps, event->text_poke.addr); + struct map *map =3D maps__find(machine__kernel_maps(machine), event->text= _poke.addr); u8 cpumode =3D event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; =20 if (dump_trace) @@ -914,7 +918,7 @@ static struct map *machine__addnew_module_map(struct ma= chine *machine, u64 start if (map =3D=3D NULL) goto out; =20 - maps__insert(&machine->kmaps, map); + maps__insert(machine__kernel_maps(machine), map); =20 /* Put the map here because maps__insert already got it */ map__put(map); @@ -1100,7 +1104,7 @@ int machine__create_extra_kernel_map(struct machine *= machine, =20 strlcpy(kmap->name, xm->name, KMAP_NAME_LEN); =20 - maps__insert(&machine->kmaps, map); + maps__insert(machine__kernel_maps(machine), map); =20 pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", kmap->name, map->start, map->end); @@ -1145,7 +1149,7 @@ static u64 find_entry_trampoline(struct dso *dso) int machine__map_x86_64_entry_trampolines(struct machine *machine, struct dso *kernel) { - struct maps *kmaps =3D &machine->kmaps; + struct maps *kmaps =3D machine__kernel_maps(machine); int nr_cpus_avail, cpu; bool found =3D false; struct map *map; @@ -1215,7 +1219,7 @@ __machine__create_kernel_maps(struct machine *machine= , struct dso *kernel) return -1; =20 machine->vmlinux_map->map_ip =3D machine->vmlinux_map->unmap_ip =3D ident= ity__map_ip; - maps__insert(&machine->kmaps, machine->vmlinux_map); + maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); return 0; } =20 @@ -1228,7 +1232,7 @@ void machine__destroy_kernel_maps(struct machine *mac= hine) return; =20 kmap =3D map__kmap(map); - maps__remove(&machine->kmaps, map); + maps__remove(machine__kernel_maps(machine), map); if (kmap && kmap->ref_reloc_sym) { zfree((char **)&kmap->ref_reloc_sym->name); zfree(&kmap->ref_reloc_sym); @@ -1323,7 +1327,7 @@ int machine__load_kallsyms(struct machine *machine, c= onst char *filename) * kernel, with modules between them, fixup the end of all * sections. */ - maps__fixup_end(&machine->kmaps); + maps__fixup_end(machine__kernel_maps(machine)); } =20 return ret; @@ -1471,7 +1475,7 @@ static int machine__set_modules_path(struct machine *= machine) machine->root_dir, version); free(version); =20 - return maps__set_modules_path_dir(&machine->kmaps, modules_path, 0); + return maps__set_modules_path_dir(machine__kernel_maps(machine), modules_= path, 0); } int __weak arch__fix_module_text_start(u64 *start __maybe_unused, u64 *size __maybe_unused, @@ -1544,11 +1548,11 @@ static void machine__update_kernel_mmap(struct mach= ine *machine, struct map *map =3D machine__kernel_map(machine); =20 map__get(map); - maps__remove(&machine->kmaps, map); + maps__remove(machine__kernel_maps(machine), map); =20 machine__set_kernel_mmap(machine, start, end); =20 - maps__insert(&machine->kmaps, map); + maps__insert(machine__kernel_maps(machine), map); map__put(map); } =20 diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index c5a45dc8df4c..0023165422aa 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -51,7 +51,7 @@ struct machine { struct vdso_info *vdso_info; struct perf_env *env; struct dsos dsos; - struct maps kmaps; + struct maps *kmaps; struct map *vmlinux_map; u64 kernel_start; pid_t *current_tid; @@ -83,7 +83,7 @@ struct map *machine__kernel_map(struct machine *machine) static inline struct maps *machine__kernel_maps(struct machine *machine) { - return &machine->kmaps; + return machine->kmaps; } =20 int machine__get_kernel_start(struct machine *machine); @@ -223,7 +223,7 @@ static inline struct symbol *machine__find_kernel_symbol(struct machine *machine, u64 ad= dr, struct map **mapp) { - return maps__find_symbol(&machine->kmaps, addr, mapp); + return maps__find_symbol(machine->kmaps, addr, mapp); } =20 static inline @@ -231,7 +231,7 @@ struct symbol *machine__find_kernel_symbol_by_name(stru= ct machine *machine, const char *name, struct map **mapp) { - return maps__find_symbol_by_name(&machine->kmaps, name, mapp); + return maps__find_symbol_by_name(machine->kmaps, name, mapp); } =20 int arch__fix_module_text_start(u64 *start, u64 *size, const char *name); diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 7444e689ece7..bc5ab782ace5 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -334,7 +334,7 @@ static int kernel_get_module_dso(const char *module, st= ruct dso **pdso) char module_name[128]; =20 snprintf(module_name, sizeof(module_name), "[%s]", module); - map =3D maps__find_by_name(&host_machine->kmaps, module_name); + map =3D maps__find_by_name(machine__kernel_maps(host_machine), module_na= me); if (map) { dso =3D map->dso; goto found; --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 A3886C433EF for ; Fri, 11 Feb 2022 10:35:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349008AbiBKKfB (ORCPT ); Fri, 11 Feb 2022 05:35:01 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60822 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348967AbiBKKej (ORCPT ); Fri, 11 Feb 2022 05:34:39 -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 1D0A7EB0 for ; Fri, 11 Feb 2022 02:34:36 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id s73-20020a25aa4f000000b0061d764d3c13so18050029ybi.1 for ; Fri, 11 Feb 2022 02:34:36 -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=adzPZhHgiX/5Q+ijF4WJDVi8pUbKn1ZnOOn3EBB8IqQ=; b=sHWlYTgeRqtGFPCZFhv1M0WLxyKLAO3ES2qCCJpEF61OjOPok7uB9sW8RVSU0nP3xj WXm43G8cz0VWWynvwxeQzY4iL1N3vcTL7Zzq2JJyeoJK1lHio38oJCR2HfMeMMh/27Qv Z5TkIfqn4TS/62scOam0IFaFEs8P08TzVWLV/Tq9yjPZVpINZipSU0fJyLxF/bMlUGCO z0h8WnXikfX1xs0lz6IQAr0ZACywLjM29yvAt03R1OwLVxJnQLab7leWhgBlaxAecs9u r1Pp/lPSu1Ftqily0HkCivJ5C7aI2LLU4szn+WFv2Xykel6kIqZ6Vy7h0nVk6daWw4/v 9QNA== 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=adzPZhHgiX/5Q+ijF4WJDVi8pUbKn1ZnOOn3EBB8IqQ=; b=g1IgM1ghpm04G0Q6Ul2frSdu04KvOLBvBAQAQHHxMUkK2a4KqxBA2c86v70DuJPUXo sM2FLm7f41W1qOeaIPncD/ABiZnhhGNAuYFDWhbYOsuqOLKVMnatclmltEYmCoDd7AXF ygbAbG8hpS+55Dn9iIsTxV01IibBmxwAmPQxXc+MpumAQ2lecL413Ye+IF/TBCCulJLR IIm0fHFPq4i+thyWZAoQ9cEGTRewogrT6OfEeHkXPEbobZP9fXkF7paEY1wgJpVEwA1I 8SriwcYamItsS3wjb4bpbbzXmyQTR86iDKmEo99H/iOjjCLOe1qXK8yu3eNYQVC8AeA2 YQMw== X-Gm-Message-State: AOAM533bAR/j1EDKfD2Fkg6+Qmo27cjY+ErvDgM/PCcx/FDksT6Ht3Vt aAcWSgnhZsk4pz8bJJNOYolE7sXJA+Lp X-Google-Smtp-Source: ABdhPJzAXFkFowKEpkDkpRcUZFxoFSoW7xUtARt67NOfJ1oDepF0lnLRS13c7rx9XshldnFaOqMprYqsAn+i X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:4cd:: with SMTP id 196mr657423ybe.439.1644575675304; Fri, 11 Feb 2022 02:34:35 -0800 (PST) Date: Fri, 11 Feb 2022 02:33:59 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-7-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 06/22] perf test: Use pointer for maps 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 , Hao Luo 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" struct maps is reference counted, using a pointer is more idiomatic. Signed-off-by: Ian Rogers --- tools/perf/tests/maps.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index e308a3296cef..6f53f17f788e 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -35,7 +35,7 @@ static int check_maps(struct map_def *merged, unsigned in= t size, struct maps *ma =20 static int test__maps__merge_in(struct test_suite *t __maybe_unused, int s= ubtest __maybe_unused) { - struct maps maps; + struct maps *maps; unsigned int i; struct map_def bpf_progs[] =3D { { "bpf_prog_1", 200, 300 }, @@ -64,7 +64,7 @@ static int test__maps__merge_in(struct test_suite *t __ma= ybe_unused, int subtest struct map *map_kcore1, *map_kcore2, *map_kcore3; int ret; =20 - maps__init(&maps, NULL); + maps =3D maps__new(NULL); =20 for (i =3D 0; i < ARRAY_SIZE(bpf_progs); i++) { struct map *map; @@ -74,7 +74,7 @@ static int test__maps__merge_in(struct test_suite *t __ma= ybe_unused, int subtest =20 map->start =3D bpf_progs[i].start; map->end =3D bpf_progs[i].end; - maps__insert(&maps, map); + maps__insert(maps, map); map__put(map); } =20 @@ -99,25 +99,25 @@ static int test__maps__merge_in(struct test_suite *t __= maybe_unused, int subtest map_kcore3->start =3D 880; map_kcore3->end =3D 1100; =20 - ret =3D maps__merge_in(&maps, map_kcore1); + ret =3D maps__merge_in(maps, map_kcore1); TEST_ASSERT_VAL("failed to merge map", !ret); =20 - ret =3D check_maps(merged12, ARRAY_SIZE(merged12), &maps); + ret =3D check_maps(merged12, ARRAY_SIZE(merged12), maps); TEST_ASSERT_VAL("merge check failed", !ret); =20 - ret =3D maps__merge_in(&maps, map_kcore2); + ret =3D maps__merge_in(maps, map_kcore2); TEST_ASSERT_VAL("failed to merge map", !ret); =20 - ret =3D check_maps(merged12, ARRAY_SIZE(merged12), &maps); + ret =3D check_maps(merged12, ARRAY_SIZE(merged12), maps); TEST_ASSERT_VAL("merge check failed", !ret); =20 - ret =3D maps__merge_in(&maps, map_kcore3); + ret =3D maps__merge_in(maps, map_kcore3); TEST_ASSERT_VAL("failed to merge map", !ret); =20 - ret =3D check_maps(merged3, ARRAY_SIZE(merged3), &maps); + ret =3D check_maps(merged3, ARRAY_SIZE(merged3), maps); TEST_ASSERT_VAL("merge check failed", !ret); =20 - maps__exit(&maps); + maps__delete(maps); return TEST_OK; } =20 --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 ECF09C433FE for ; Fri, 11 Feb 2022 10:34:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348998AbiBKKe6 (ORCPT ); Fri, 11 Feb 2022 05:34:58 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60826 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348970AbiBKKek (ORCPT ); Fri, 11 Feb 2022 05:34:40 -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 80213EB5 for ; Fri, 11 Feb 2022 02:34:38 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id g205-20020a2552d6000000b0061e1843b8edso16800310ybb.18 for ; Fri, 11 Feb 2022 02:34:38 -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=C+DOP43E99Vgp1ROj45FPpHXIORfM/ghJ3TzgVy+YNU=; b=NLJbtd5YhVa7x/yeTNEjfREFwLmEaOsF4D0AVDKgQdH59TXGtiioclRIC3xmPq2QpF 9474cJJlZEhnjplBaeCQd0En4hEPGeWJbYJh7nTS4soJbzzqXZumTfxSdtKkUVAcU2rj 2+h4glwZrPFB6YwF7f2/OgGlt93moxMoyRR/bfYmYT+CskCpuQpO6FZV6/19d7C5GZ3B OoB7aNU8HueLULQew+tI26evSNTQuRaiKLauae3pYOdGaNZQtsANUXosbAllxa4FVAUR Kwrrp+IBMrKbpSFawC/oyJRM+9IX4ue7MlbfleqIXXV65rDZLtG9WKXwJBy1A4Eh4v4W nNSg== 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=C+DOP43E99Vgp1ROj45FPpHXIORfM/ghJ3TzgVy+YNU=; b=YAPwU4rLlNXnC8/VicWhOrhgC7duqdbItVvmrwxhsPA7Ta9ssgXxroWiktV3wd7WVR UbsydAiNMSxjPdsfAaFE00aw4ih26wbKNH6aUO8h/Vskxfbu5dBYOdosy/WDCmIv7CPe 49Lf8Pn14lDvAnp3K2pwApk8mqFwKAJeRoTSUWV2nsa6vxNvDd9V4ghbA+I+ESBEZOGY MtHTOK3g3Hecq2IvheGpjIdP7+Lx/fbtwuaKknnz01eVtagbfiUgg73UT+EMQfuqQ1FV /wezMVRUHTE6glwzwztbqUtV60qOWy/2YswoBLUXIMr0QpXxpkxvmLh9rjawMVZKLR7y 1jdQ== X-Gm-Message-State: AOAM530oEXBvaE2kQPuP48p8sIJJIYsD6TEhxvsfsAerIZoEBfbIu+Ps p1tqgxOHerUffehmDFQJCy2Pk+age5GY X-Google-Smtp-Source: ABdhPJx37ZV+DBqNto4kqpR7iMyd0RvvVxnoSEdbFJq8X88sRQjetmdRWiYHo8vRcCRMURbz07A1BGEshAli X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:2107:: with SMTP id h7mr650095ybh.513.1644575677752; Fri, 11 Feb 2022 02:34:37 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:00 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-8-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 07/22] perf maps: Reduce scope of init and exit 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 , Hao Luo 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" Now purely accessed through new and delete, so reduce to file scope. Signed-off-by: Ian Rogers --- tools/perf/util/map.c | 4 ++-- tools/perf/util/maps.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index ae99b52502d5..4d1de363c19a 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -527,7 +527,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip) return ip + map->reloc; } =20 -void maps__init(struct maps *maps, struct machine *machine) +static void maps__init(struct maps *maps, struct machine *machine) { maps->entries =3D RB_ROOT; init_rwsem(&maps->lock); @@ -616,7 +616,7 @@ static void __maps__purge(struct maps *maps) } } =20 -void maps__exit(struct maps *maps) +static void maps__exit(struct maps *maps) { down_write(&maps->lock); __maps__purge(maps); diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index 3dd000ddf925..7e729ff42749 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -60,8 +60,6 @@ static inline struct maps *maps__get(struct maps *maps) } =20 void maps__put(struct maps *maps); -void maps__init(struct maps *maps, struct machine *machine); -void maps__exit(struct maps *maps); int maps__clone(struct thread *thread, struct maps *parent); size_t maps__fprintf(struct maps *maps, FILE *fp); =20 --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 7D629C433F5 for ; Fri, 11 Feb 2022 10:35:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349019AbiBKKfG (ORCPT ); Fri, 11 Feb 2022 05:35:06 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348976AbiBKKen (ORCPT ); Fri, 11 Feb 2022 05:34:43 -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 3E8CDEA6 for ; Fri, 11 Feb 2022 02:34:41 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id g205-20020a2552d6000000b0061e1843b8edso16800451ybb.18 for ; Fri, 11 Feb 2022 02:34:41 -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=LrddYWyXaxH+uZEblaokvexEVHXPxvXvKHOPmBC4R1k=; b=gboZ5ClkY6spz9sr4lex4JowKWFRIODa8BnNB+0J/eM53aunePmHbmwrXGa2VVYu0S h44pCJ0owqOQWkdOADb/kkOqjf2XKeOBRnbXRiGutJzhiTcBzZMlyGxX5hhONJ7ppD5Y 3Nis+UtoQLu2yDBDYRWajdMVZIVzz+sCx6QTIXGwJKSKWIjIyx/D6YANxzTzU9NUDBfu bw4iij9DDMk6X+d0y0S9I0mh6kJORZVSRSunVumvfewzfUjwSA9Fsm6NZQQif29qZBjK C9uQ9bfLaAeJDo5l9cW+khyVffjOSD6b/EHz5Jkir3fBJELG3cOg9eoMePBCpXccwiuq uTcQ== 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=LrddYWyXaxH+uZEblaokvexEVHXPxvXvKHOPmBC4R1k=; b=YRRBxO7fg3rtDXKmnJkJe2RSA71aUfWvk8L3jZxbiJLkrm+T2IBAe5UJR1dcYYQ4nZ /alxZspgSClFub449SI78WxiUmbSe0LIAaqWcia24R3UPzs6L3u8ZEjbb0mYCvaGpqvs meyYdDYOgTE4MCDQNlIoTw9YnGfW1Llk2xyRrtWv8vXr3fDegyhGVSYkosXdNBDdTAJx NN2/73iFTEuq+nljBbF1m57qg2MV/+4zs/JvGXr4NWs6jIwFYHHdMVl3A4h3XIPyJRWM IeL7Yxj9LL8j0W7JRKk0UnPkRTEsbEPSfSw4i0+9F3aYQ+t5u0pJVBsNQu58PF5kT5d5 SFSA== X-Gm-Message-State: AOAM5329aGvu745zs/3+hqxA98NO3OAx7SljjO9PtQCVm75RqtBaPCgq 9zqQWdZ3eXyYDmZfg944e1aVG9nLeSG5 X-Google-Smtp-Source: ABdhPJxdLfLRjNuAEEl1K3PMh2J2PCTxrfmMUhlSmFlJyI9dq2vKAbqxWs5bvW44Gz7d6km33wgrZhU4kiAy X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:c644:: with SMTP id k65mr653225ybf.288.1644575680446; Fri, 11 Feb 2022 02:34:40 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:01 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-9-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 08/22] perf maps: Move maps code to own C file 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 , Hao Luo 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" The maps code has its own header, move the corresponding C function definitions to their own C file. In the process tidy and minimize includes. Signed-off-by: Ian Rogers --- tools/perf/util/Build | 1 + tools/perf/util/map.c | 417 +---------------------------------------- tools/perf/util/map.h | 2 + tools/perf/util/maps.c | 403 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 414 insertions(+), 409 deletions(-) create mode 100644 tools/perf/util/maps.c diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 2a403cefcaf2..9a7209a99e16 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -56,6 +56,7 @@ perf-y +=3D debug.o perf-y +=3D fncache.o perf-y +=3D machine.o perf-y +=3D map.o +perf-y +=3D maps.o perf-y +=3D pstack.o perf-y +=3D session.o perf-y +=3D sample-raw.o diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 4d1de363c19a..2cfe5744b86c 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -1,31 +1,20 @@ // SPDX-License-Identifier: GPL-2.0 -#include "symbol.h" -#include -#include #include #include +#include #include #include -#include -#include +#include +#include #include /* To get things like MAP_HUGETLB even on old= er libc headers */ +#include "debug.h" #include "dso.h" #include "map.h" -#include "map_symbol.h" +#include "namespaces.h" +#include "srcline.h" +#include "symbol.h" #include "thread.h" #include "vdso.h" -#include "build-id.h" -#include "debug.h" -#include "machine.h" -#include -#include -#include "srcline.h" -#include "namespaces.h" -#include "unwind.h" -#include "srccode.h" -#include "ui/ui.h" - -static void __maps__insert(struct maps *maps, struct map *map); =20 static inline int is_android_lib(const char *filename) { @@ -527,403 +516,13 @@ u64 map__objdump_2mem(struct map *map, u64 ip) return ip + map->reloc; } =20 -static void maps__init(struct maps *maps, struct machine *machine) -{ - maps->entries =3D RB_ROOT; - init_rwsem(&maps->lock); - maps->machine =3D machine; - maps->last_search_by_name =3D NULL; - maps->nr_maps =3D 0; - maps->maps_by_name =3D NULL; - refcount_set(&maps->refcnt, 1); -} - -static void __maps__free_maps_by_name(struct maps *maps) -{ - /* - * Free everything to try to do it from the rbtree in the next search - */ - zfree(&maps->maps_by_name); - maps->nr_maps_allocated =3D 0; -} - -void maps__insert(struct maps *maps, struct map *map) -{ - down_write(&maps->lock); - __maps__insert(maps, map); - ++maps->nr_maps; - - if (map->dso && map->dso->kernel) { - struct kmap *kmap =3D map__kmap(map); - - if (kmap) - kmap->kmaps =3D maps; - else - pr_err("Internal error: kernel dso with non kernel map\n"); - } - - - /* - * If we already performed some search by name, then we need to add the j= ust - * inserted map and resort. - */ - if (maps->maps_by_name) { - if (maps->nr_maps > maps->nr_maps_allocated) { - int nr_allocate =3D maps->nr_maps * 2; - struct map **maps_by_name =3D realloc(maps->maps_by_name, nr_allocate *= sizeof(map)); - - if (maps_by_name =3D=3D NULL) { - __maps__free_maps_by_name(maps); - up_write(&maps->lock); - return; - } - - maps->maps_by_name =3D maps_by_name; - maps->nr_maps_allocated =3D nr_allocate; - } - maps->maps_by_name[maps->nr_maps - 1] =3D map; - __maps__sort_by_name(maps); - } - up_write(&maps->lock); -} - -static void __maps__remove(struct maps *maps, struct map *map) -{ - rb_erase_init(&map->rb_node, &maps->entries); - map__put(map); -} - -void maps__remove(struct maps *maps, struct map *map) -{ - down_write(&maps->lock); - if (maps->last_search_by_name =3D=3D map) - maps->last_search_by_name =3D NULL; - - __maps__remove(maps, map); - --maps->nr_maps; - if (maps->maps_by_name) - __maps__free_maps_by_name(maps); - up_write(&maps->lock); -} - -static void __maps__purge(struct maps *maps) -{ - struct map *pos, *next; - - maps__for_each_entry_safe(maps, pos, next) { - rb_erase_init(&pos->rb_node, &maps->entries); - map__put(pos); - } -} - -static void maps__exit(struct maps *maps) -{ - down_write(&maps->lock); - __maps__purge(maps); - up_write(&maps->lock); -} - -bool maps__empty(struct maps *maps) -{ - return !maps__first(maps); -} - -struct maps *maps__new(struct machine *machine) -{ - struct maps *maps =3D zalloc(sizeof(*maps)); - - if (maps !=3D NULL) - maps__init(maps, machine); - - return maps; -} - -void maps__delete(struct maps *maps) -{ - maps__exit(maps); - unwind__finish_access(maps); - free(maps); -} - -void maps__put(struct maps *maps) -{ - if (maps && refcount_dec_and_test(&maps->refcnt)) - maps__delete(maps); -} - -struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map *= *mapp) -{ - struct map *map =3D maps__find(maps, addr); - - /* Ensure map is loaded before using map->map_ip */ - if (map !=3D NULL && map__load(map) >=3D 0) { - if (mapp !=3D NULL) - *mapp =3D map; - return map__find_symbol(map, map->map_ip(map, addr)); - } - - return NULL; -} - -static bool map__contains_symbol(struct map *map, struct symbol *sym) +bool map__contains_symbol(struct map *map, struct symbol *sym) { u64 ip =3D map->unmap_ip(map, sym->start); =20 return ip >=3D map->start && ip < map->end; } =20 -struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *na= me, struct map **mapp) -{ - struct symbol *sym; - struct map *pos; - - down_read(&maps->lock); - - maps__for_each_entry(maps, pos) { - sym =3D map__find_symbol_by_name(pos, name); - - if (sym =3D=3D NULL) - continue; - if (!map__contains_symbol(pos, sym)) { - sym =3D NULL; - continue; - } - if (mapp !=3D NULL) - *mapp =3D pos; - goto out; - } - - sym =3D NULL; -out: - up_read(&maps->lock); - return sym; -} - -int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) -{ - if (ams->addr < ams->ms.map->start || ams->addr >=3D ams->ms.map->end) { - if (maps =3D=3D NULL) - return -1; - ams->ms.map =3D maps__find(maps, ams->addr); - if (ams->ms.map =3D=3D NULL) - return -1; - } - - ams->al_addr =3D ams->ms.map->map_ip(ams->ms.map, ams->addr); - ams->ms.sym =3D map__find_symbol(ams->ms.map, ams->al_addr); - - return ams->ms.sym ? 0 : -1; -} - -size_t maps__fprintf(struct maps *maps, FILE *fp) -{ - size_t printed =3D 0; - struct map *pos; - - down_read(&maps->lock); - - maps__for_each_entry(maps, pos) { - printed +=3D fprintf(fp, "Map:"); - printed +=3D map__fprintf(pos, fp); - if (verbose > 2) { - printed +=3D dso__fprintf(pos->dso, fp); - printed +=3D fprintf(fp, "--\n"); - } - } - - up_read(&maps->lock); - - return printed; -} - -int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) -{ - struct rb_root *root; - struct rb_node *next, *first; - int err =3D 0; - - down_write(&maps->lock); - - root =3D &maps->entries; - - /* - * Find first map where end > map->start. - * Same as find_vma() in kernel. - */ - next =3D root->rb_node; - first =3D NULL; - while (next) { - struct map *pos =3D rb_entry(next, struct map, rb_node); - - if (pos->end > map->start) { - first =3D next; - if (pos->start <=3D map->start) - break; - next =3D next->rb_left; - } else - next =3D next->rb_right; - } - - next =3D first; - while (next) { - struct map *pos =3D rb_entry(next, struct map, rb_node); - next =3D rb_next(&pos->rb_node); - - /* - * Stop if current map starts after map->end. - * Maps are ordered by start: next will not overlap for sure. - */ - if (pos->start >=3D map->end) - break; - - if (verbose >=3D 2) { - - if (use_browser) { - pr_debug("overlapping maps in %s (disable tui for more info)\n", - map->dso->name); - } else { - fputs("overlapping maps:\n", fp); - map__fprintf(map, fp); - map__fprintf(pos, fp); - } - } - - rb_erase_init(&pos->rb_node, root); - /* - * Now check if we need to create new maps for areas not - * overlapped by the new map: - */ - if (map->start > pos->start) { - struct map *before =3D map__clone(pos); - - if (before =3D=3D NULL) { - err =3D -ENOMEM; - goto put_map; - } - - before->end =3D map->start; - __maps__insert(maps, before); - if (verbose >=3D 2 && !use_browser) - map__fprintf(before, fp); - map__put(before); - } - - if (map->end < pos->end) { - struct map *after =3D map__clone(pos); - - if (after =3D=3D NULL) { - err =3D -ENOMEM; - goto put_map; - } - - after->start =3D map->end; - after->pgoff +=3D map->end - pos->start; - assert(pos->map_ip(pos, map->end) =3D=3D after->map_ip(after, map->end)= ); - __maps__insert(maps, after); - if (verbose >=3D 2 && !use_browser) - map__fprintf(after, fp); - map__put(after); - } -put_map: - map__put(pos); - - if (err) - goto out; - } - - err =3D 0; -out: - up_write(&maps->lock); - return err; -} - -/* - * XXX This should not really _copy_ te maps, but refcount them. - */ -int maps__clone(struct thread *thread, struct maps *parent) -{ - struct maps *maps =3D thread->maps; - int err; - struct map *map; - - down_read(&parent->lock); - - maps__for_each_entry(parent, map) { - struct map *new =3D map__clone(map); - - if (new =3D=3D NULL) { - err =3D -ENOMEM; - goto out_unlock; - } - - err =3D unwind__prepare_access(maps, new, NULL); - if (err) - goto out_unlock; - - maps__insert(maps, new); - map__put(new); - } - - err =3D 0; -out_unlock: - up_read(&parent->lock); - return err; -} - -static void __maps__insert(struct maps *maps, struct map *map) -{ - struct rb_node **p =3D &maps->entries.rb_node; - struct rb_node *parent =3D NULL; - const u64 ip =3D map->start; - struct map *m; - - while (*p !=3D NULL) { - parent =3D *p; - m =3D rb_entry(parent, struct map, rb_node); - if (ip < m->start) - p =3D &(*p)->rb_left; - else - p =3D &(*p)->rb_right; - } - - rb_link_node(&map->rb_node, parent, p); - rb_insert_color(&map->rb_node, &maps->entries); - map__get(map); -} - -struct map *maps__find(struct maps *maps, u64 ip) -{ - struct rb_node *p; - struct map *m; - - down_read(&maps->lock); - - p =3D maps->entries.rb_node; - while (p !=3D NULL) { - m =3D rb_entry(p, struct map, rb_node); - if (ip < m->start) - p =3D p->rb_left; - else if (ip >=3D m->end) - p =3D p->rb_right; - else - goto out; - } - - m =3D NULL; -out: - up_read(&maps->lock); - return m; -} - -struct map *maps__first(struct maps *maps) -{ - struct rb_node *first =3D rb_first(&maps->entries); - - if (first) - return rb_entry(first, struct map, rb_node); - return NULL; -} - static struct map *__map__next(struct map *map) { struct rb_node *next =3D rb_next(&map->rb_node); diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index d32f5b28c1fb..973dce27b253 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -160,6 +160,8 @@ static inline bool __map__is_kmodule(const struct map *= map) =20 bool map__has_symbols(const struct map *map); =20 +bool map__contains_symbol(struct map *map, struct symbol *sym); + #define ENTRY_TRAMPOLINE_NAME "__entry_SYSCALL_64_trampoline" =20 static inline bool is_entry_trampoline(const char *name) diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c new file mode 100644 index 000000000000..ededabf0a230 --- /dev/null +++ b/tools/perf/util/maps.c @@ -0,0 +1,403 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "debug.h" +#include "dso.h" +#include "map.h" +#include "maps.h" +#include "thread.h" +#include "ui/ui.h" +#include "unwind.h" + +static void __maps__insert(struct maps *maps, struct map *map); + +void maps__init(struct maps *maps, struct machine *machine) +{ + maps->entries =3D RB_ROOT; + init_rwsem(&maps->lock); + maps->machine =3D machine; + maps->last_search_by_name =3D NULL; + maps->nr_maps =3D 0; + maps->maps_by_name =3D NULL; + refcount_set(&maps->refcnt, 1); +} + +static void __maps__free_maps_by_name(struct maps *maps) +{ + /* + * Free everything to try to do it from the rbtree in the next search + */ + zfree(&maps->maps_by_name); + maps->nr_maps_allocated =3D 0; +} + +void maps__insert(struct maps *maps, struct map *map) +{ + down_write(&maps->lock); + __maps__insert(maps, map); + ++maps->nr_maps; + + if (map->dso && map->dso->kernel) { + struct kmap *kmap =3D map__kmap(map); + + if (kmap) + kmap->kmaps =3D maps; + else + pr_err("Internal error: kernel dso with non kernel map\n"); + } + + + /* + * If we already performed some search by name, then we need to add the j= ust + * inserted map and resort. + */ + if (maps->maps_by_name) { + if (maps->nr_maps > maps->nr_maps_allocated) { + int nr_allocate =3D maps->nr_maps * 2; + struct map **maps_by_name =3D realloc(maps->maps_by_name, nr_allocate *= sizeof(map)); + + if (maps_by_name =3D=3D NULL) { + __maps__free_maps_by_name(maps); + up_write(&maps->lock); + return; + } + + maps->maps_by_name =3D maps_by_name; + maps->nr_maps_allocated =3D nr_allocate; + } + maps->maps_by_name[maps->nr_maps - 1] =3D map; + __maps__sort_by_name(maps); + } + up_write(&maps->lock); +} + +static void __maps__remove(struct maps *maps, struct map *map) +{ + rb_erase_init(&map->rb_node, &maps->entries); + map__put(map); +} + +void maps__remove(struct maps *maps, struct map *map) +{ + down_write(&maps->lock); + if (maps->last_search_by_name =3D=3D map) + maps->last_search_by_name =3D NULL; + + __maps__remove(maps, map); + --maps->nr_maps; + if (maps->maps_by_name) + __maps__free_maps_by_name(maps); + up_write(&maps->lock); +} + +static void __maps__purge(struct maps *maps) +{ + struct map *pos, *next; + + maps__for_each_entry_safe(maps, pos, next) { + rb_erase_init(&pos->rb_node, &maps->entries); + map__put(pos); + } +} + +void maps__exit(struct maps *maps) +{ + down_write(&maps->lock); + __maps__purge(maps); + up_write(&maps->lock); +} + +bool maps__empty(struct maps *maps) +{ + return !maps__first(maps); +} + +struct maps *maps__new(struct machine *machine) +{ + struct maps *maps =3D zalloc(sizeof(*maps)); + + if (maps !=3D NULL) + maps__init(maps, machine); + + return maps; +} + +void maps__delete(struct maps *maps) +{ + maps__exit(maps); + unwind__finish_access(maps); + free(maps); +} + +void maps__put(struct maps *maps) +{ + if (maps && refcount_dec_and_test(&maps->refcnt)) + maps__delete(maps); +} + +struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map *= *mapp) +{ + struct map *map =3D maps__find(maps, addr); + + /* Ensure map is loaded before using map->map_ip */ + if (map !=3D NULL && map__load(map) >=3D 0) { + if (mapp !=3D NULL) + *mapp =3D map; + return map__find_symbol(map, map->map_ip(map, addr)); + } + + return NULL; +} + +struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *na= me, struct map **mapp) +{ + struct symbol *sym; + struct map *pos; + + down_read(&maps->lock); + + maps__for_each_entry(maps, pos) { + sym =3D map__find_symbol_by_name(pos, name); + + if (sym =3D=3D NULL) + continue; + if (!map__contains_symbol(pos, sym)) { + sym =3D NULL; + continue; + } + if (mapp !=3D NULL) + *mapp =3D pos; + goto out; + } + + sym =3D NULL; +out: + up_read(&maps->lock); + return sym; +} + +int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) +{ + if (ams->addr < ams->ms.map->start || ams->addr >=3D ams->ms.map->end) { + if (maps =3D=3D NULL) + return -1; + ams->ms.map =3D maps__find(maps, ams->addr); + if (ams->ms.map =3D=3D NULL) + return -1; + } + + ams->al_addr =3D ams->ms.map->map_ip(ams->ms.map, ams->addr); + ams->ms.sym =3D map__find_symbol(ams->ms.map, ams->al_addr); + + return ams->ms.sym ? 0 : -1; +} + +size_t maps__fprintf(struct maps *maps, FILE *fp) +{ + size_t printed =3D 0; + struct map *pos; + + down_read(&maps->lock); + + maps__for_each_entry(maps, pos) { + printed +=3D fprintf(fp, "Map:"); + printed +=3D map__fprintf(pos, fp); + if (verbose > 2) { + printed +=3D dso__fprintf(pos->dso, fp); + printed +=3D fprintf(fp, "--\n"); + } + } + + up_read(&maps->lock); + + return printed; +} + +int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) +{ + struct rb_root *root; + struct rb_node *next, *first; + int err =3D 0; + + down_write(&maps->lock); + + root =3D &maps->entries; + + /* + * Find first map where end > map->start. + * Same as find_vma() in kernel. + */ + next =3D root->rb_node; + first =3D NULL; + while (next) { + struct map *pos =3D rb_entry(next, struct map, rb_node); + + if (pos->end > map->start) { + first =3D next; + if (pos->start <=3D map->start) + break; + next =3D next->rb_left; + } else + next =3D next->rb_right; + } + + next =3D first; + while (next) { + struct map *pos =3D rb_entry(next, struct map, rb_node); + next =3D rb_next(&pos->rb_node); + + /* + * Stop if current map starts after map->end. + * Maps are ordered by start: next will not overlap for sure. + */ + if (pos->start >=3D map->end) + break; + + if (verbose >=3D 2) { + + if (use_browser) { + pr_debug("overlapping maps in %s (disable tui for more info)\n", + map->dso->name); + } else { + fputs("overlapping maps:\n", fp); + map__fprintf(map, fp); + map__fprintf(pos, fp); + } + } + + rb_erase_init(&pos->rb_node, root); + /* + * Now check if we need to create new maps for areas not + * overlapped by the new map: + */ + if (map->start > pos->start) { + struct map *before =3D map__clone(pos); + + if (before =3D=3D NULL) { + err =3D -ENOMEM; + goto put_map; + } + + before->end =3D map->start; + __maps__insert(maps, before); + if (verbose >=3D 2 && !use_browser) + map__fprintf(before, fp); + map__put(before); + } + + if (map->end < pos->end) { + struct map *after =3D map__clone(pos); + + if (after =3D=3D NULL) { + err =3D -ENOMEM; + goto put_map; + } + + after->start =3D map->end; + after->pgoff +=3D map->end - pos->start; + assert(pos->map_ip(pos, map->end) =3D=3D after->map_ip(after, map->end)= ); + __maps__insert(maps, after); + if (verbose >=3D 2 && !use_browser) + map__fprintf(after, fp); + map__put(after); + } +put_map: + map__put(pos); + + if (err) + goto out; + } + + err =3D 0; +out: + up_write(&maps->lock); + return err; +} + +/* + * XXX This should not really _copy_ te maps, but refcount them. + */ +int maps__clone(struct thread *thread, struct maps *parent) +{ + struct maps *maps =3D thread->maps; + int err; + struct map *map; + + down_read(&parent->lock); + + maps__for_each_entry(parent, map) { + struct map *new =3D map__clone(map); + + if (new =3D=3D NULL) { + err =3D -ENOMEM; + goto out_unlock; + } + + err =3D unwind__prepare_access(maps, new, NULL); + if (err) + goto out_unlock; + + maps__insert(maps, new); + map__put(new); + } + + err =3D 0; +out_unlock: + up_read(&parent->lock); + return err; +} + +static void __maps__insert(struct maps *maps, struct map *map) +{ + struct rb_node **p =3D &maps->entries.rb_node; + struct rb_node *parent =3D NULL; + const u64 ip =3D map->start; + struct map *m; + + while (*p !=3D NULL) { + parent =3D *p; + m =3D rb_entry(parent, struct map, rb_node); + if (ip < m->start) + p =3D &(*p)->rb_left; + else + p =3D &(*p)->rb_right; + } + + rb_link_node(&map->rb_node, parent, p); + rb_insert_color(&map->rb_node, &maps->entries); + map__get(map); +} + +struct map *maps__find(struct maps *maps, u64 ip) +{ + struct rb_node *p; + struct map *m; + + down_read(&maps->lock); + + p =3D maps->entries.rb_node; + while (p !=3D NULL) { + m =3D rb_entry(p, struct map, rb_node); + if (ip < m->start) + p =3D p->rb_left; + else if (ip >=3D m->end) + p =3D p->rb_right; + else + goto out; + } + + m =3D NULL; +out: + up_read(&maps->lock); + return m; +} + +struct map *maps__first(struct maps *maps) +{ + struct rb_node *first =3D rb_first(&maps->entries); + + if (first) + return rb_entry(first, struct map, rb_node); + return NULL; +} --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 3740DC43217 for ; Fri, 11 Feb 2022 10:35:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348175AbiBKKfJ (ORCPT ); Fri, 11 Feb 2022 05:35:09 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348978AbiBKKeo (ORCPT ); Fri, 11 Feb 2022 05:34:44 -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 AEEFFEA8 for ; Fri, 11 Feb 2022 02:34:43 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id f32-20020a25b0a0000000b0061dad37dcd6so17757870ybj.16 for ; Fri, 11 Feb 2022 02:34:43 -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=v/iVwWwVZ57NlyJcDZTSYN4OejpmhBwgHB1+GcNUvds=; b=SS4GGPur+8C8MhWOAfUpC++73BZ9x4vvPHZZvzTQ8+TevlAupjKwjyXhJQhlHRfhs5 UPycDJ/IMAzAWlMGtZP9x1VNCODHQIKGk4OqBDTn96LxeDV65HSAk7VupIgcdLF/Af+u vQl22zYp2B44p0i1mrPqULatJPeo+50/U0YmcMNnizTsEAxrFIRx8bLzFp7UFNWPz41V 89ME3ox7joS7WyicJSXOU/CFKuXeZZdknpDWkd8QNhhKzpr05y/kA3+rAep/vmpGwAKY fV+kfLdHQhYDh42Hl0NWrDMRhOxzSHh+3cewa5hBvTO2KazQMP1/tBbJcpFspHorxiMv hDVw== 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=v/iVwWwVZ57NlyJcDZTSYN4OejpmhBwgHB1+GcNUvds=; b=OoCAGdC7KuToFPLw+gD7XVRU53B9bXsm81yg/REFesE555v11QP+IE+L9jnhSjKxac wkXC1ybnFO3hoDwZqRtjMXR9bS8kYWsZrw48kMzVCyhwqkIyZ2bbSxKggSGWH+cNSou6 tqUNgY6MzYIUKmSjtvhqSG2764iyNt/d6jrBnp2aVzCpxDciAMYO4MrSYvqAnUXhXUuv UC0aPyzvHBr2BDunGns6tTVeE085WtIxg2J4TpfoqMmgrxw2mIlTbz4Y2Yl72wYazcKb Lb0rXmkY+IoPXshQQ4laU7vVhqziew4KX5x7dFvuePI8cqPWyhJfVPhdPYs0QCW49Piv Jcyw== X-Gm-Message-State: AOAM533UIgtGlcgbFeRYPfkO375tOe0bCGtXYW2cTOjbzt6qVAujiqpv fkJO/omOxdyxyuQkHv/CJFUAdj5eyE1r X-Google-Smtp-Source: ABdhPJwYNGXn+AssFsFdcI8ZqXlyNvl2Eh8f07LSi+lLqPFZ5RtMlLLP8Jv5Zzv/mrATVgq8k0FuiMjoP50x X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:cb90:: with SMTP id b138mr674042ybg.33.1644575682916; Fri, 11 Feb 2022 02:34:42 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:02 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-10-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 09/22] perf map: Add const to map_ip and unmap_ip 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 , Hao Luo 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" Functions purely determine a value from the map and don't need to modify it. Move functions to C file as they are most commonly used via a function pointer. Signed-off-by: Ian Rogers --- tools/perf/util/map.c | 15 +++++++++++++++ tools/perf/util/map.h | 24 ++++++++---------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 2cfe5744b86c..b98fb000eb5c 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -563,3 +563,18 @@ struct maps *map__kmaps(struct map *map) } return kmap->kmaps; } + +u64 map__map_ip(const struct map *map, u64 ip) +{ + return ip - map->start + map->pgoff; +} + +u64 map__unmap_ip(const struct map *map, u64 ip) +{ + return ip + map->start - map->pgoff; +} + +u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip) +{ + return ip; +} diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 973dce27b253..212a9468d5e1 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -29,9 +29,9 @@ struct map { u64 reloc; =20 /* ip -> dso rip */ - u64 (*map_ip)(struct map *, u64); + u64 (*map_ip)(const struct map *, u64); /* dso rip -> ip */ - u64 (*unmap_ip)(struct map *, u64); + u64 (*unmap_ip)(const struct map *, u64); =20 struct dso *dso; refcount_t refcnt; @@ -44,20 +44,12 @@ struct kmap *__map__kmap(struct map *map); struct kmap *map__kmap(struct map *map); struct maps *map__kmaps(struct map *map); =20 -static inline u64 map__map_ip(struct map *map, u64 ip) -{ - return ip - map->start + map->pgoff; -} - -static inline u64 map__unmap_ip(struct map *map, u64 ip) -{ - return ip + map->start - map->pgoff; -} - -static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip) -{ - return ip; -} +/* ip -> dso rip */ +u64 map__map_ip(const struct map *map, u64 ip); +/* dso rip -> ip */ +u64 map__unmap_ip(const struct map *map, u64 ip); +/* Returns ip */ +u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip); =20 static inline size_t map__size(const struct map *map) { --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 4ADDEC433F5 for ; Fri, 11 Feb 2022 10:35:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348929AbiBKKfM (ORCPT ); Fri, 11 Feb 2022 05:35:12 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32774 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349002AbiBKKe6 (ORCPT ); Fri, 11 Feb 2022 05:34:58 -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 5446EEB0 for ; Fri, 11 Feb 2022 02:34:46 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id h6-20020a253a06000000b0061de83305f2so17835365yba.19 for ; Fri, 11 Feb 2022 02:34:46 -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=S56WfI2GmhqdGh7gnwplme1j2hJlUSzhW1pk4BgzSzk=; b=mBkM8iq3Hm5tOajbE77+PviE5ArQ7pZGE+5Ugb0NOHm0qOpTY+9CzOUeDRPjsBJZa2 XJAyZiH/DGLk/fw3OkYbhHRo3Nx0liPl4cSn3x0QdlwM0c0KpMjrtdDGyGa1EMkpIqME 9Jx1vrj11uenDjxwXLm/INJHnwFHZ5Ia4t5dTqw5hgpfyeERydmin5IUyHNvdxqbhAeK hXvaHL/HrL+JzFLtcVIcGrfojqASbRU9DWQ3sQd3f8jWVZddxTXnYlKGD1w/4b6xqbPS tHkgYuRdz76CtqpUZ3Gn+T3ujyG6QqmtyezxT5mZc4up9glakdspspm5XNcUt3pzDfPL VKjg== 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=S56WfI2GmhqdGh7gnwplme1j2hJlUSzhW1pk4BgzSzk=; b=DFiglBt0VpNU9DQAmQz3xlvY6WM+U54zONhgGpV7DoOepDQlbLY8PWdTgp9R/eU2lb /ZiGyxiIqexcZM7QR941L3jKRVjosXgZuU7BsNC7F6TEfe2MGoSOpEF13dvcD6GI/jVf rXMIrcwMy/xJ+4tVwMBQOQbVwJuuG+ggMX0nECcPFCQtQ3ioXWGy5nx+CPVGc4zpsyII ppHLSzxmHaLozRhW24KMIH52fNtYpVxvZU3SmTVDx+nVTdcbo9YpI0dqlLW8Sy6a5AcG iAQ/jCovHs4nqhtQatckIdpqUVl/SVTagWgmeQBC7Lk/4TYTBOxy7hTiHewTRP80Filv vdbw== X-Gm-Message-State: AOAM532zbsUm3IVnu9kg9KboMofrC+4iJro43wvuJ8Deae5Gy79xdvIL 3402/6WSzuBvVrnFVbT/+NUYiU2t8LVA X-Google-Smtp-Source: ABdhPJwprkLTWbcxJ/B2s7VtdaP+tgOQI2HcM/4+/pcP3Xw9gTr6wdo4zZnOZa29xxTuN1Ogb2EvP4dhCDHL X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a05:6902:49:: with SMTP id m9mr660615ybh.104.1644575685585; Fri, 11 Feb 2022 02:34:45 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:03 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-11-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 10/22] perf map: Make map__contains_symbol args const 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 , Hao Luo 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" Now unmap_ip is const, make contains symbol const. Signed-off-by: Ian Rogers --- tools/perf/util/map.c | 2 +- tools/perf/util/map.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index b98fb000eb5c..8bbf9246a3cf 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -516,7 +516,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip) return ip + map->reloc; } =20 -bool map__contains_symbol(struct map *map, struct symbol *sym) +bool map__contains_symbol(const struct map *map, const struct symbol *sym) { u64 ip =3D map->unmap_ip(map, sym->start); =20 diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 212a9468d5e1..3dcfe06db6b3 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -152,7 +152,7 @@ static inline bool __map__is_kmodule(const struct map *= map) =20 bool map__has_symbols(const struct map *map); =20 -bool map__contains_symbol(struct map *map, struct symbol *sym); +bool map__contains_symbol(const struct map *map, const struct symbol *sym); =20 #define ENTRY_TRAMPOLINE_NAME "__entry_SYSCALL_64_trampoline" =20 --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 C69F4C433F5 for ; Fri, 11 Feb 2022 10:35:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234721AbiBKKfP (ORCPT ); Fri, 11 Feb 2022 05:35:15 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349009AbiBKKfC (ORCPT ); Fri, 11 Feb 2022 05:35:02 -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 BD2ECEB6 for ; Fri, 11 Feb 2022 02:34:48 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id c5-20020a25f305000000b0061dd6123f18so17886874ybs.17 for ; Fri, 11 Feb 2022 02:34:48 -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=R0Dvzg9O7l0PtwThblOaU7REzb8t/7BNSvgMr4EaVqc=; b=KoCSShQIYgFOjacok9goWTjMd1qBAjpQUsnX6E/1F88ONNdP294ova5aZpsd615yXw e9/1Unmo4KsOEjtA1NmkLfYR+4E/0CtjMNc3prqmvMp+9D+bBXfO10nmXlNkumKPet0v QMRsbREBRhULCkhrMVHu1oDd681AuCzoGrVYgs8grKW6QtXInYA2JQ9rDsae17AwumJ8 JNy2hqD+tRhz/gO/icCV5ykmkIJamX82pMkj0B2LMKOyADAvA7SzKNrdmaHuacoTAlnp QrxYllarhfHeApSmgiAs/UrjvIrRP0Rj2PDDA65MPqgz0rEY/poTOPGZH0CkIVEqUlGD /DOg== 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=R0Dvzg9O7l0PtwThblOaU7REzb8t/7BNSvgMr4EaVqc=; b=Po+HD4fNwwPTCGVrdg5YugwMPEv2DNeCu9c7EumkqYV8HoVaDfE8g9f8ed0hpF0JkQ /CHxJRZcSppYcacX6/hxRbANt0OzlQFa1M5dd5qzWfiAFtSMB2tm8c+eqzxBgS5lqd2t Ze50ioSE1GXQqCaRoXBtX88vLe+YufQK2pVuOp1zqm611pVQjsYepk6CEUbJ2K4lNUnG kl0azv1lg4YSlEFSoI85t1/5lbPZtzKponJW5EjHOeNYXuYJohUaJ4owd4JZRKn1V1SQ ZhKWnT5dUMSCsV+R90ZWKVps70yngKbv/ZeNqHXIPqEprIPvj5pSWOJDGDsS2vi+zljP 8bIg== X-Gm-Message-State: AOAM533otvwZ+/zf0z/OYYpR2cCZdU3J28ugcp/atqG0DEGH291HqoLV EWp1cS/vvcVBs1IC6C76x5A2BHJps2sX X-Google-Smtp-Source: ABdhPJwZPREtk69S2uJng/+p/EnTJUYTxGrBBc8C3Ov3BA1WlWObPnq9xK3yKtf5pJDUi/fSzClIBg9ysOdc X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:c70e:: with SMTP id w14mr759216ybe.220.1644575687998; Fri, 11 Feb 2022 02:34:47 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:04 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-12-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 11/22] perf map: Move map list node into symbol 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 , Hao Luo 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" Using a perf map as a list node is only done in symbol. Move the list_node struct into symbol as a single pointer to the map. This makes reference count behavior more obvious and easy to check. Signed-off-by: Ian Rogers --- tools/perf/util/map.h | 5 +-- tools/perf/util/symbol.c | 89 ++++++++++++++++++++++++++-------------- 2 files changed, 60 insertions(+), 34 deletions(-) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 3dcfe06db6b3..2879cae05ee0 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -16,10 +16,7 @@ struct maps; struct machine; =20 struct map { - union { - struct rb_node rb_node; - struct list_head node; - }; + struct rb_node rb_node; u64 start; u64 end; bool erange_warned:1; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a504346feb05..99accae7d3b8 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -48,6 +48,11 @@ static bool symbol__is_idle(const char *name); int vmlinux_path__nr_entries; char **vmlinux_path; =20 +struct map_list_node { + struct list_head node; + struct map *map; +}; + struct symbol_conf symbol_conf =3D { .nanosecs =3D false, .use_modules =3D true, @@ -1193,16 +1198,22 @@ struct kcore_mapfn_data { static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data) { struct kcore_mapfn_data *md =3D data; - struct map *map; + struct map_list_node *list_node; =20 - map =3D map__new2(start, md->dso); - if (map =3D=3D NULL) + list_node =3D malloc(sizeof(*list_node)); + if (list_node =3D=3D NULL) return -ENOMEM; =20 - map->end =3D map->start + len; - map->pgoff =3D pgoff; + list_node->map =3D map__new2(start, md->dso); + if (list_node->map =3D=3D NULL) { + free(list_node); + return -ENOMEM; + } + + list_node->map->end =3D list_node->map->start + len; + list_node->map->pgoff =3D pgoff; =20 - list_add(&map->node, &md->maps); + list_add(&list_node->node, &md->maps); =20 return 0; } @@ -1238,12 +1249,19 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) * |new.............| -> |new..| |new..| * |old....| -> |old....| */ - struct map *m =3D map__clone(new_map); + struct map_list_node *m; =20 + m =3D malloc(sizeof(*m)); if (!m) return -ENOMEM; =20 - m->end =3D old_map->start; + m->map =3D map__clone(new_map); + if (!m->map) { + free(m); + return -ENOMEM; + } + + m->map->end =3D old_map->start; list_add_tail(&m->node, &merged); new_map->pgoff +=3D old_map->end - new_map->start; new_map->start =3D old_map->end; @@ -1273,10 +1291,13 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) } =20 while (!list_empty(&merged)) { - old_map =3D list_entry(merged.next, struct map, node); - list_del_init(&old_map->node); - maps__insert(kmaps, old_map); - map__put(old_map); + struct map_list_node *old_node; + + old_node =3D list_entry(merged.next, struct map_list_node, node); + list_del_init(&old_node->node); + maps__insert(kmaps, old_node->map); + map__put(old_node->map); + free(old_node); } =20 if (new_map) { @@ -1291,7 +1312,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, { struct maps *kmaps =3D map__kmaps(map); struct kcore_mapfn_data md; - struct map *old_map, *new_map, *replacement_map =3D NULL, *next; + struct map *old_map, *replacement_map =3D NULL, *next; struct machine *machine; bool is_64_bit; int err, fd; @@ -1351,42 +1372,47 @@ static int dso__load_kcore(struct dso *dso, struct = map *map, =20 /* Find the kernel map using the '_stext' symbol */ if (!kallsyms__get_function_start(kallsyms_filename, "_stext", &stext)) { - list_for_each_entry(new_map, &md.maps, node) { - if (stext >=3D new_map->start && stext < new_map->end) { - replacement_map =3D new_map; + struct map_list_node *new_node; + + list_for_each_entry(new_node, &md.maps, node) { + if (stext >=3D new_node->map->start && stext < new_node->map->end) { + replacement_map =3D new_node->map; break; } } } =20 if (!replacement_map) - replacement_map =3D list_entry(md.maps.next, struct map, node); + replacement_map =3D list_entry(md.maps.next, struct map_list_node, node)= ->map; =20 /* Add new maps */ while (!list_empty(&md.maps)) { - new_map =3D list_entry(md.maps.next, struct map, node); - list_del_init(&new_map->node); - if (new_map =3D=3D replacement_map) { - map->start =3D new_map->start; - map->end =3D new_map->end; - map->pgoff =3D new_map->pgoff; - map->map_ip =3D new_map->map_ip; - map->unmap_ip =3D new_map->unmap_ip; + struct map_list_node *new_node; + + new_node =3D list_entry(md.maps.next, struct map_list_node, node); + list_del_init(&new_node->node); + if (new_node->map =3D=3D replacement_map) { + map->start =3D new_node->map->start; + map->end =3D new_node->map->end; + map->pgoff =3D new_node->map->pgoff; + map->map_ip =3D new_node->map->map_ip; + map->unmap_ip =3D new_node->map->unmap_ip; /* Ensure maps are correctly ordered */ map__get(map); maps__remove(kmaps, map); maps__insert(kmaps, map); map__put(map); - map__put(new_map); + map__put(new_node->map); } else { /* * Merge kcore map into existing maps, * and ensure that current maps (eBPF) * stay intact. */ - if (maps__merge_in(kmaps, new_map)) + if (maps__merge_in(kmaps, new_node->map)) goto out_err; } + free(new_node); } =20 if (machine__is(machine, "x86_64")) { @@ -1423,9 +1449,12 @@ static int dso__load_kcore(struct dso *dso, struct m= ap *map, =20 out_err: while (!list_empty(&md.maps)) { - map =3D list_entry(md.maps.next, struct map, node); - list_del_init(&map->node); - map__put(map); + struct map_list_node *list_node; + + list_node =3D list_entry(md.maps.next, struct map_list_node, node); + list_del_init(&list_node->node); + map__put(list_node->map); + free(list_node); } close(fd); return -EINVAL; --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 9FF7AC433F5 for ; Fri, 11 Feb 2022 10:35:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245389AbiBKKfS (ORCPT ); Fri, 11 Feb 2022 05:35:18 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349012AbiBKKfC (ORCPT ); Fri, 11 Feb 2022 05:35:02 -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 4C38DEB8 for ; Fri, 11 Feb 2022 02:34:51 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id v10-20020a05690204ca00b0061dd584eb83so17715652ybs.21 for ; Fri, 11 Feb 2022 02:34:51 -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=T6JGdGZNTCjyP+otJD5NTUIMGGuyoHt747zi1J4QsAA=; b=eCPhIKZTqMXDP60Q7y+pcRZZUSgGO++J6Aa5HezZd0qD9BJgPv983xvggi2Ip6bTQl RxE+2Gz4uF8ZCRym6NU6PswR3OAL4ihwLVK4jZTLCKDEjE78BrYPB2noXSu0/Q0uf6aq rW7uPjuvNi9p17MWvXCGaB7F5lW+McFiDeaLjyeiJdh3zG+GC3gIXq9fge70qiiK2qy/ 5WX815bBmepNhC3s4uOmCR5bsK8ty7GzA/1BUmuWvK0jROb15CUEKao3Df0/5UGVHZOO o8vxGDwG3pkfqaAKtsgB6TxnokhlS9q5uY7MoqZJKGWNiyX7J4URcHxMMy+sFAs64tDZ ttsg== 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=T6JGdGZNTCjyP+otJD5NTUIMGGuyoHt747zi1J4QsAA=; b=mXnVH1Tla6eG+DyQ7HfdL1lh+k0FNgWxekpZZOTrqYTA1MvQKNQadbrGNWCHk0TJjB eRwiNEQ1OeHdcb0j/f6SSRtC9evCpWsBfDHjaTz2AQna+z+t9VlGw3XMhzD9FIS6kLH3 otRlIMnP0IutZWitHj4Bij+vvzOCkeUkifQEyLm+9ekeFWSSfq/aqE+KLUQbxea8WLUW noT0BTwEW/0D1HIwgdf2yQJ5ZT0EBsp88OmoMG6qweKiyj2kRfXi6ucMeauAqcJEsMDP EzEdhN6JhFLcp1RrtOCYQXmW26Mjy2oWy7wPsMgddX1d2VMDU31XWSf4IFiFNEftj1m8 okeQ== X-Gm-Message-State: AOAM530+1Zs5b+X42w/R/Gf8JZFEi6pHJMJ+ibsQx/C2jlUEHl2hTzA4 Zq00+knZebgOlHDZEXtxMKR8MputgRWU X-Google-Smtp-Source: ABdhPJyRWBx8o72en74N6m4vWukaGdI1xCuaE2DomITKvjMtP0X71IKua41eeREWnxiYiW8gnOoWWp0RammA X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a05:6902:2cc:: with SMTP id w12mr688464ybh.65.1644575690512; Fri, 11 Feb 2022 02:34:50 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:05 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-13-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 12/22] perf maps: Remove rb_node from struct map 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 , Hao Luo 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" struct map is reference counted, having it also be a node in an red-black tree complicates the reference counting. Switch to having a map_rb_node which is a red-block tree node but points at the reference counted struct map. This reference is responsible for a single reference count. Signed-off-by: Ian Rogers --- tools/perf/arch/x86/util/event.c | 13 +- tools/perf/builtin-report.c | 6 +- tools/perf/tests/maps.c | 8 +- tools/perf/tests/vmlinux-kallsyms.c | 17 +-- tools/perf/util/machine.c | 62 ++++++---- tools/perf/util/map.c | 16 --- tools/perf/util/map.h | 1 - tools/perf/util/maps.c | 182 ++++++++++++++++++---------- tools/perf/util/maps.h | 17 ++- tools/perf/util/probe-event.c | 18 +-- tools/perf/util/symbol-elf.c | 9 +- tools/perf/util/symbol.c | 77 +++++++----- tools/perf/util/synthetic-events.c | 26 ++-- tools/perf/util/thread.c | 10 +- tools/perf/util/vdso.c | 7 +- 15 files changed, 288 insertions(+), 181 deletions(-) diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/ev= ent.c index e670f3547581..7b6b0c98fb36 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -17,7 +17,7 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *= tool, struct machine *machine) { int rc =3D 0; - struct map *pos; + struct map_rb_node *pos; struct maps *kmaps =3D machine__kernel_maps(machine); union perf_event *event =3D zalloc(sizeof(event->mmap) + machine->id_hdr_size); @@ -31,11 +31,12 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool= *tool, maps__for_each_entry(kmaps, pos) { struct kmap *kmap; size_t size; + struct map *map =3D pos->map; =20 - if (!__map__is_extra_kernel_map(pos)) + if (!__map__is_extra_kernel_map(map)) continue; =20 - kmap =3D map__kmap(pos); + kmap =3D map__kmap(map); =20 size =3D sizeof(event->mmap) - sizeof(event->mmap.filename) + PERF_ALIGN(strlen(kmap->name) + 1, sizeof(u64)) + @@ -56,9 +57,9 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *= tool, =20 event->mmap.header.size =3D size; =20 - event->mmap.start =3D pos->start; - event->mmap.len =3D pos->end - pos->start; - event->mmap.pgoff =3D pos->pgoff; + event->mmap.start =3D map->start; + event->mmap.len =3D map->end - map->start; + event->mmap.pgoff =3D map->pgoff; event->mmap.pid =3D machine->pid; =20 strlcpy(event->mmap.filename, kmap->name, PATH_MAX); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1dd92d8c9279..57611ef725c3 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -799,9 +799,11 @@ static struct task *tasks_list(struct task *task, stru= ct machine *machine) static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) { size_t printed =3D 0; - struct map *map; + struct map_rb_node *rb_node; + + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; =20 - maps__for_each_entry(maps, map) { printed +=3D fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRI= x64 " %" PRIu64 " %s\n", indent, "", map->start, map->end, map->prot & PROT_READ ? 'r' : '-', diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index 6f53f17f788e..a58274598587 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -15,10 +15,12 @@ struct map_def { =20 static int check_maps(struct map_def *merged, unsigned int size, struct ma= ps *maps) { - struct map *map; + struct map_rb_node *rb_node; unsigned int i =3D 0; =20 - maps__for_each_entry(maps, map) { + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; + if (i > 0) TEST_ASSERT_VAL("less maps expected", (map && i < size) || (!map && i = =3D=3D size)); =20 @@ -74,7 +76,7 @@ static int test__maps__merge_in(struct test_suite *t __ma= ybe_unused, int subtest =20 map->start =3D bpf_progs[i].start; map->end =3D bpf_progs[i].end; - maps__insert(maps, map); + TEST_ASSERT_VAL("failed to insert map", maps__insert(maps, map) =3D=3D 0= ); map__put(map); } =20 diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index 84bf5f640065..11a230ee5894 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -117,7 +117,8 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused int err =3D -1; struct rb_node *nd; struct symbol *sym; - struct map *kallsyms_map, *vmlinux_map, *map; + struct map *kallsyms_map, *vmlinux_map; + struct map_rb_node *rb_node; struct machine kallsyms, vmlinux; struct maps *maps =3D machine__kernel_maps(&vmlinux); u64 mem_start, mem_end; @@ -285,15 +286,15 @@ static int test__vmlinux_matches_kallsyms(struct test= _suite *test __maybe_unused =20 header_printed =3D false; =20 - maps__for_each_entry(maps, map) { - struct map * + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; /* * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while * the kernel will have the path for the vmlinux file being used, * so use the short name, less descriptive but the same ("[kernel]" in * both cases. */ - pair =3D maps__find_by_name(kallsyms.kmaps, (map->dso->kernel ? + struct map *pair =3D maps__find_by_name(kallsyms.kmaps, (map->dso->kerne= l ? map->dso->short_name : map->dso->name)); if (pair) { @@ -309,8 +310,8 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused =20 header_printed =3D false; =20 - maps__for_each_entry(maps, map) { - struct map *pair; + maps__for_each_entry(maps, rb_node) { + struct map *pair, *map =3D rb_node->map; =20 mem_start =3D vmlinux_map->unmap_ip(vmlinux_map, map->start); mem_end =3D vmlinux_map->unmap_ip(vmlinux_map, map->end); @@ -339,7 +340,9 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused =20 maps =3D machine__kernel_maps(&kallsyms); =20 - maps__for_each_entry(maps, map) { + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; + if (!map->priv) { if (!header_printed) { pr_info("WARN: Maps only in kallsyms:\n"); diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 57fbdba66425..fa25174cabf7 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -786,6 +786,7 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, =20 if (!map) { struct dso *dso =3D dso__new(event->ksymbol.name); + int err; =20 if (dso) { dso->kernel =3D DSO_SPACE__KERNEL; @@ -805,8 +806,11 @@ static int machine__process_ksymbol_register(struct ma= chine *machine, =20 map->start =3D event->ksymbol.addr; map->end =3D map->start + event->ksymbol.len; - maps__insert(machine__kernel_maps(machine), map); + err =3D maps__insert(machine__kernel_maps(machine), map); map__put(map); + if (err) + return err; + dso__set_loaded(dso); =20 if (is_bpf_image(event->ksymbol.name)) { @@ -906,6 +910,7 @@ static struct map *machine__addnew_module_map(struct ma= chine *machine, u64 start struct map *map =3D NULL; struct kmod_path m; struct dso *dso; + int err; =20 if (kmod_path__parse_name(&m, filename)) return NULL; @@ -918,10 +923,14 @@ static struct map *machine__addnew_module_map(struct = machine *machine, u64 start if (map =3D=3D NULL) goto out; =20 - maps__insert(machine__kernel_maps(machine), map); + err =3D maps__insert(machine__kernel_maps(machine), map); =20 /* Put the map here because maps__insert already got it */ map__put(map); + + /* If maps__insert failed, return NULL. */ + if (err) + map =3D NULL; out: /* put the dso here, corresponding to machine__findnew_module_dso */ dso__put(dso); @@ -1092,10 +1101,11 @@ int machine__create_extra_kernel_map(struct machine= *machine, { struct kmap *kmap; struct map *map; + int err; =20 map =3D map__new2(xm->start, kernel); if (!map) - return -1; + return -ENOMEM; =20 map->end =3D xm->end; map->pgoff =3D xm->pgoff; @@ -1104,14 +1114,16 @@ int machine__create_extra_kernel_map(struct machine= *machine, =20 strlcpy(kmap->name, xm->name, KMAP_NAME_LEN); =20 - maps__insert(machine__kernel_maps(machine), map); + err =3D maps__insert(machine__kernel_maps(machine), map); =20 - pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", - kmap->name, map->start, map->end); + if (!err) { + pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", + kmap->name, map->start, map->end); + } =20 map__put(map); =20 - return 0; + return err; } =20 static u64 find_entry_trampoline(struct dso *dso) @@ -1152,16 +1164,16 @@ int machine__map_x86_64_entry_trampolines(struct ma= chine *machine, struct maps *kmaps =3D machine__kernel_maps(machine); int nr_cpus_avail, cpu; bool found =3D false; - struct map *map; + struct map_rb_node *rb_node; u64 pgoff; =20 /* * In the vmlinux case, pgoff is a virtual address which must now be * mapped to a vmlinux offset. */ - maps__for_each_entry(kmaps, map) { + maps__for_each_entry(kmaps, rb_node) { + struct map *dest_map, *map =3D rb_node->map; struct kmap *kmap =3D __map__kmap(map); - struct map *dest_map; =20 if (!kmap || !is_entry_trampoline(kmap->name)) continue; @@ -1216,11 +1228,10 @@ __machine__create_kernel_maps(struct machine *machi= ne, struct dso *kernel) =20 machine->vmlinux_map =3D map__new2(0, kernel); if (machine->vmlinux_map =3D=3D NULL) - return -1; + return -ENOMEM; =20 machine->vmlinux_map->map_ip =3D machine->vmlinux_map->unmap_ip =3D ident= ity__map_ip; - maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); - return 0; + return maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); } =20 void machine__destroy_kernel_maps(struct machine *machine) @@ -1542,25 +1553,26 @@ static void machine__set_kernel_mmap(struct machine= *machine, machine->vmlinux_map->end =3D ~0ULL; } =20 -static void machine__update_kernel_mmap(struct machine *machine, +static int machine__update_kernel_mmap(struct machine *machine, u64 start, u64 end) { struct map *map =3D machine__kernel_map(machine); + int err; =20 map__get(map); maps__remove(machine__kernel_maps(machine), map); =20 machine__set_kernel_mmap(machine, start, end); =20 - maps__insert(machine__kernel_maps(machine), map); + err =3D maps__insert(machine__kernel_maps(machine), map); map__put(map); + return err; } =20 int machine__create_kernel_maps(struct machine *machine) { struct dso *kernel =3D machine__get_kernel(machine); const char *name =3D NULL; - struct map *map; u64 start =3D 0, end =3D ~0ULL; int ret; =20 @@ -1592,7 +1604,9 @@ int machine__create_kernel_maps(struct machine *machi= ne) * we have a real start address now, so re-order the kmaps * assume it's the last in the kmaps */ - machine__update_kernel_mmap(machine, start, end); + ret =3D machine__update_kernel_mmap(machine, start, end); + if (ret < 0) + goto out_put; } =20 if (machine__create_extra_kernel_maps(machine, kernel)) @@ -1600,9 +1614,12 @@ int machine__create_kernel_maps(struct machine *mach= ine) =20 if (end =3D=3D ~0ULL) { /* update end address of the kernel map using adjacent module address */ - map =3D map__next(machine__kernel_map(machine)); - if (map) - machine__set_kernel_mmap(machine, start, map->start); + struct map_rb_node *rb_node =3D maps__find_node(machine__kernel_maps(mac= hine), + machine__kernel_map(machine)); + struct map_rb_node *next =3D map_rb_node__next(rb_node); + + if (next) + machine__set_kernel_mmap(machine, start, next->map->start); } =20 out_put: @@ -1726,7 +1743,10 @@ static int machine__process_kernel_mmap_event(struct= machine *machine, if (strstr(kernel->long_name, "vmlinux")) dso__set_short_name(kernel, "[kernel.vmlinux]", false); =20 - machine__update_kernel_mmap(machine, xm->start, xm->end); + if (machine__update_kernel_mmap(machine, xm->start, xm->end) < 0) { + dso__put(kernel); + goto out_problem; + } =20 if (build_id__is_defined(bid)) dso__set_build_id(kernel, bid); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 8bbf9246a3cf..dfa5f6b7381f 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -111,7 +111,6 @@ void map__init(struct map *map, u64 start, u64 end, u64= pgoff, struct dso *dso) map->dso =3D dso__get(dso); map->map_ip =3D map__map_ip; map->unmap_ip =3D map__unmap_ip; - RB_CLEAR_NODE(&map->rb_node); map->erange_warned =3D false; refcount_set(&map->refcnt, 1); } @@ -383,7 +382,6 @@ struct map *map__clone(struct map *from) map =3D memdup(from, size); if (map !=3D NULL) { refcount_set(&map->refcnt, 1); - RB_CLEAR_NODE(&map->rb_node); dso__get(map->dso); } =20 @@ -523,20 +521,6 @@ bool map__contains_symbol(const struct map *map, const= struct symbol *sym) return ip >=3D map->start && ip < map->end; } =20 -static struct map *__map__next(struct map *map) -{ - struct rb_node *next =3D rb_next(&map->rb_node); - - if (next) - return rb_entry(next, struct map, rb_node); - return NULL; -} - -struct map *map__next(struct map *map) -{ - return map ? __map__next(map) : NULL; -} - struct kmap *__map__kmap(struct map *map) { if (!map->dso || !map->dso->kernel) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 2879cae05ee0..d1a6f85fd31d 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -16,7 +16,6 @@ struct maps; struct machine; =20 struct map { - struct rb_node rb_node; u64 start; u64 end; bool erange_warned:1; diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index ededabf0a230..beb09b9a122c 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -10,9 +10,7 @@ #include "ui/ui.h" #include "unwind.h" =20 -static void __maps__insert(struct maps *maps, struct map *map); - -void maps__init(struct maps *maps, struct machine *machine) +static void maps__init(struct maps *maps, struct machine *machine) { maps->entries =3D RB_ROOT; init_rwsem(&maps->lock); @@ -32,10 +30,44 @@ static void __maps__free_maps_by_name(struct maps *maps) maps->nr_maps_allocated =3D 0; } =20 -void maps__insert(struct maps *maps, struct map *map) +static int __maps__insert(struct maps *maps, struct map *map) +{ + struct rb_node **p =3D &maps->entries.rb_node; + struct rb_node *parent =3D NULL; + const u64 ip =3D map->start; + struct map_rb_node *m, *new_rb_node; + + new_rb_node =3D malloc(sizeof(*new_rb_node)); + if (!new_rb_node) + return -ENOMEM; + + RB_CLEAR_NODE(&new_rb_node->rb_node); + new_rb_node->map =3D map; + + while (*p !=3D NULL) { + parent =3D *p; + m =3D rb_entry(parent, struct map_rb_node, rb_node); + if (ip < m->map->start) + p =3D &(*p)->rb_left; + else + p =3D &(*p)->rb_right; + } + + rb_link_node(&new_rb_node->rb_node, parent, p); + rb_insert_color(&new_rb_node->rb_node, &maps->entries); + map__get(map); + return 0; +} + +int maps__insert(struct maps *maps, struct map *map) { + int err; + down_write(&maps->lock); - __maps__insert(maps, map); + err =3D __maps__insert(maps, map); + if (err) + goto out; + ++maps->nr_maps; =20 if (map->dso && map->dso->kernel) { @@ -59,8 +91,8 @@ void maps__insert(struct maps *maps, struct map *map) =20 if (maps_by_name =3D=3D NULL) { __maps__free_maps_by_name(maps); - up_write(&maps->lock); - return; + err =3D -ENOMEM; + goto out; } =20 maps->maps_by_name =3D maps_by_name; @@ -69,22 +101,29 @@ void maps__insert(struct maps *maps, struct map *map) maps->maps_by_name[maps->nr_maps - 1] =3D map; __maps__sort_by_name(maps); } +out: up_write(&maps->lock); + return err; } =20 -static void __maps__remove(struct maps *maps, struct map *map) +static void __maps__remove(struct maps *maps, struct map_rb_node *rb_node) { - rb_erase_init(&map->rb_node, &maps->entries); - map__put(map); + rb_erase_init(&rb_node->rb_node, &maps->entries); + map__put(rb_node->map); + free(rb_node); } =20 void maps__remove(struct maps *maps, struct map *map) { + struct map_rb_node *rb_node; + down_write(&maps->lock); if (maps->last_search_by_name =3D=3D map) maps->last_search_by_name =3D NULL; =20 - __maps__remove(maps, map); + rb_node =3D maps__find_node(maps, map); + assert(rb_node->map =3D=3D map); + __maps__remove(maps, rb_node); --maps->nr_maps; if (maps->maps_by_name) __maps__free_maps_by_name(maps); @@ -93,15 +132,16 @@ void maps__remove(struct maps *maps, struct map *map) =20 static void __maps__purge(struct maps *maps) { - struct map *pos, *next; + struct map_rb_node *pos, *next; =20 maps__for_each_entry_safe(maps, pos, next) { rb_erase_init(&pos->rb_node, &maps->entries); - map__put(pos); + map__put(pos->map); + free(pos); } } =20 -void maps__exit(struct maps *maps) +static void maps__exit(struct maps *maps) { down_write(&maps->lock); __maps__purge(maps); @@ -153,21 +193,21 @@ struct symbol *maps__find_symbol(struct maps *maps, u= 64 addr, struct map **mapp) struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *na= me, struct map **mapp) { struct symbol *sym; - struct map *pos; + struct map_rb_node *pos; =20 down_read(&maps->lock); =20 maps__for_each_entry(maps, pos) { - sym =3D map__find_symbol_by_name(pos, name); + sym =3D map__find_symbol_by_name(pos->map, name); =20 if (sym =3D=3D NULL) continue; - if (!map__contains_symbol(pos, sym)) { + if (!map__contains_symbol(pos->map, sym)) { sym =3D NULL; continue; } if (mapp !=3D NULL) - *mapp =3D pos; + *mapp =3D pos->map; goto out; } =20 @@ -196,15 +236,15 @@ int maps__find_ams(struct maps *maps, struct addr_map= _symbol *ams) size_t maps__fprintf(struct maps *maps, FILE *fp) { size_t printed =3D 0; - struct map *pos; + struct map_rb_node *pos; =20 down_read(&maps->lock); =20 maps__for_each_entry(maps, pos) { printed +=3D fprintf(fp, "Map:"); - printed +=3D map__fprintf(pos, fp); + printed +=3D map__fprintf(pos->map, fp); if (verbose > 2) { - printed +=3D dso__fprintf(pos->dso, fp); + printed +=3D dso__fprintf(pos->map->dso, fp); printed +=3D fprintf(fp, "--\n"); } } @@ -231,11 +271,11 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) next =3D root->rb_node; first =3D NULL; while (next) { - struct map *pos =3D rb_entry(next, struct map, rb_node); + struct map_rb_node *pos =3D rb_entry(next, struct map_rb_node, rb_node); =20 - if (pos->end > map->start) { + if (pos->map->end > map->start) { first =3D next; - if (pos->start <=3D map->start) + if (pos->map->start <=3D map->start) break; next =3D next->rb_left; } else @@ -244,14 +284,14 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) =20 next =3D first; while (next) { - struct map *pos =3D rb_entry(next, struct map, rb_node); + struct map_rb_node *pos =3D rb_entry(next, struct map_rb_node, rb_node); next =3D rb_next(&pos->rb_node); =20 /* * Stop if current map starts after map->end. * Maps are ordered by start: next will not overlap for sure. */ - if (pos->start >=3D map->end) + if (pos->map->start >=3D map->end) break; =20 if (verbose >=3D 2) { @@ -262,7 +302,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) } else { fputs("overlapping maps:\n", fp); map__fprintf(map, fp); - map__fprintf(pos, fp); + map__fprintf(pos->map, fp); } } =20 @@ -271,8 +311,8 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) * Now check if we need to create new maps for areas not * overlapped by the new map: */ - if (map->start > pos->start) { - struct map *before =3D map__clone(pos); + if (map->start > pos->map->start) { + struct map *before =3D map__clone(pos->map); =20 if (before =3D=3D NULL) { err =3D -ENOMEM; @@ -280,14 +320,17 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) } =20 before->end =3D map->start; - __maps__insert(maps, before); + err =3D __maps__insert(maps, before); + if (err) + goto put_map; + if (verbose >=3D 2 && !use_browser) map__fprintf(before, fp); map__put(before); } =20 - if (map->end < pos->end) { - struct map *after =3D map__clone(pos); + if (map->end < pos->map->end) { + struct map *after =3D map__clone(pos->map); =20 if (after =3D=3D NULL) { err =3D -ENOMEM; @@ -295,15 +338,19 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) } =20 after->start =3D map->end; - after->pgoff +=3D map->end - pos->start; - assert(pos->map_ip(pos, map->end) =3D=3D after->map_ip(after, map->end)= ); - __maps__insert(maps, after); + after->pgoff +=3D map->end - pos->map->start; + assert(pos->map->map_ip(pos->map, map->end) =3D=3D + after->map_ip(after, map->end)); + err =3D __maps__insert(maps, after); + if (err) + goto put_map; + if (verbose >=3D 2 && !use_browser) map__fprintf(after, fp); map__put(after); } put_map: - map__put(pos); + map__put(pos->map); =20 if (err) goto out; @@ -322,12 +369,12 @@ int maps__clone(struct thread *thread, struct maps *p= arent) { struct maps *maps =3D thread->maps; int err; - struct map *map; + struct map_rb_node *rb_node; =20 down_read(&parent->lock); =20 - maps__for_each_entry(parent, map) { - struct map *new =3D map__clone(map); + maps__for_each_entry(parent, rb_node) { + struct map *new =3D map__clone(rb_node->map); =20 if (new =3D=3D NULL) { err =3D -ENOMEM; @@ -338,7 +385,10 @@ int maps__clone(struct thread *thread, struct maps *pa= rent) if (err) goto out_unlock; =20 - maps__insert(maps, new); + err =3D maps__insert(maps, new); + if (err) + goto out_unlock; + map__put(new); } =20 @@ -348,40 +398,30 @@ int maps__clone(struct thread *thread, struct maps *p= arent) return err; } =20 -static void __maps__insert(struct maps *maps, struct map *map) +struct map_rb_node *maps__find_node(struct maps *maps, struct map *map) { - struct rb_node **p =3D &maps->entries.rb_node; - struct rb_node *parent =3D NULL; - const u64 ip =3D map->start; - struct map *m; + struct map_rb_node *rb_node; =20 - while (*p !=3D NULL) { - parent =3D *p; - m =3D rb_entry(parent, struct map, rb_node); - if (ip < m->start) - p =3D &(*p)->rb_left; - else - p =3D &(*p)->rb_right; + maps__for_each_entry(maps, rb_node) { + if (rb_node->map =3D=3D map) + return rb_node; } - - rb_link_node(&map->rb_node, parent, p); - rb_insert_color(&map->rb_node, &maps->entries); - map__get(map); + return NULL; } =20 struct map *maps__find(struct maps *maps, u64 ip) { struct rb_node *p; - struct map *m; + struct map_rb_node *m; =20 down_read(&maps->lock); =20 p =3D maps->entries.rb_node; while (p !=3D NULL) { - m =3D rb_entry(p, struct map, rb_node); - if (ip < m->start) + m =3D rb_entry(p, struct map_rb_node, rb_node); + if (ip < m->map->start) p =3D p->rb_left; - else if (ip >=3D m->end) + else if (ip >=3D m->map->end) p =3D p->rb_right; else goto out; @@ -390,14 +430,30 @@ struct map *maps__find(struct maps *maps, u64 ip) m =3D NULL; out: up_read(&maps->lock); - return m; + + return m ? m->map : NULL; } =20 -struct map *maps__first(struct maps *maps) +struct map_rb_node *maps__first(struct maps *maps) { struct rb_node *first =3D rb_first(&maps->entries); =20 if (first) - return rb_entry(first, struct map, rb_node); + return rb_entry(first, struct map_rb_node, rb_node); return NULL; } + +struct map_rb_node *map_rb_node__next(struct map_rb_node *node) +{ + struct rb_node *next; + + if (!node) + return NULL; + + next =3D rb_next(&node->rb_node); + + if (!next) + return NULL; + + return rb_entry(next, struct map_rb_node, rb_node); +} diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index 7e729ff42749..512746ec0f9a 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -15,15 +15,22 @@ struct map; struct maps; struct thread; =20 +struct map_rb_node { + struct rb_node rb_node; + struct map *map; +}; + +struct map_rb_node *maps__first(struct maps *maps); +struct map_rb_node *map_rb_node__next(struct map_rb_node *node); +struct map_rb_node *maps__find_node(struct maps *maps, struct map *map); struct map *maps__find(struct maps *maps, u64 addr); -struct map *maps__first(struct maps *maps); -struct map *map__next(struct map *map); =20 #define maps__for_each_entry(maps, map) \ - for (map =3D maps__first(maps); map; map =3D map__next(map)) + for (map =3D maps__first(maps); map; map =3D map_rb_node__next(map)) =20 #define maps__for_each_entry_safe(maps, map, next) \ - for (map =3D maps__first(maps), next =3D map__next(map); map; map =3D nex= t, next =3D map__next(map)) + for (map =3D maps__first(maps), next =3D map_rb_node__next(map); map; \ + map =3D next, next =3D map_rb_node__next(map)) =20 struct maps { struct rb_root entries; @@ -63,7 +70,7 @@ void maps__put(struct maps *maps); int maps__clone(struct thread *thread, struct maps *parent); size_t maps__fprintf(struct maps *maps, FILE *fp); =20 -void maps__insert(struct maps *maps, struct map *map); +int maps__insert(struct maps *maps, struct map *map); =20 void maps__remove(struct maps *maps, struct map *map); =20 diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index bc5ab782ace5..f9fbf611f2bf 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -150,23 +150,27 @@ static int kernel_get_symbol_address_by_name(const ch= ar *name, u64 *addr, static struct map *kernel_get_module_map(const char *module) { struct maps *maps =3D machine__kernel_maps(host_machine); - struct map *pos; + struct map_rb_node *pos; =20 /* A file path -- this is an offline module */ if (module && strchr(module, '/')) return dso__new_map(module); =20 if (!module) { - pos =3D machine__kernel_map(host_machine); - return map__get(pos); + struct map *map =3D machine__kernel_map(host_machine); + + return map__get(map); } =20 maps__for_each_entry(maps, pos) { /* short_name is "[module]" */ - if (strncmp(pos->dso->short_name + 1, module, - pos->dso->short_name_len - 2) =3D=3D 0 && - module[pos->dso->short_name_len - 2] =3D=3D '\0') { - return map__get(pos); + const char *short_name =3D pos->map->dso->short_name; + u16 short_name_len =3D pos->map->dso->short_name_len; + + if (strncmp(short_name + 1, module, + short_name_len - 2) =3D=3D 0 && + module[short_name_len - 2] =3D=3D '\0') { + return map__get(pos->map); } } return NULL; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 31cd59a2b66e..4607c9438866 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1000,10 +1000,14 @@ static int dso__process_kernel_symbol(struct dso *d= so, struct map *map, map->unmap_ip =3D map__unmap_ip; /* Ensure maps are correctly ordered */ if (kmaps) { + int err; + map__get(map); maps__remove(kmaps, map); - maps__insert(kmaps, map); + err =3D maps__insert(kmaps, map); map__put(map); + if (err) + return err; } } =20 @@ -1056,7 +1060,8 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, curr_map->map_ip =3D curr_map->unmap_ip =3D identity__map_ip; } curr_dso->symtab_type =3D dso->symtab_type; - maps__insert(kmaps, curr_map); + if (maps__insert(kmaps, curr_map)) + return -1; /* * Add it before we drop the reference to curr_map, i.e. while * we still are sure to have a reference to this DSO via diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 99accae7d3b8..266c65bb8bbb 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -247,13 +247,13 @@ void symbols__fixup_end(struct rb_root_cached *symbol= s) =20 void maps__fixup_end(struct maps *maps) { - struct map *prev =3D NULL, *curr; + struct map_rb_node *prev =3D NULL, *curr; =20 down_write(&maps->lock); =20 maps__for_each_entry(maps, curr) { - if (prev !=3D NULL && !prev->end) - prev->end =3D curr->start; + if (prev !=3D NULL && !prev->map->end) + prev->map->end =3D curr->map->start; =20 prev =3D curr; } @@ -262,8 +262,8 @@ void maps__fixup_end(struct maps *maps) * We still haven't the actual symbols, so guess the * last map final address. */ - if (curr && !curr->end) - curr->end =3D ~0ULL; + if (curr && !curr->map->end) + curr->map->end =3D ~0ULL; =20 up_write(&maps->lock); } @@ -911,7 +911,10 @@ static int maps__split_kallsyms(struct maps *kmaps, st= ruct dso *dso, u64 delta, } =20 curr_map->map_ip =3D curr_map->unmap_ip =3D identity__map_ip; - maps__insert(kmaps, curr_map); + if (maps__insert(kmaps, curr_map)) { + dso__put(ndso); + return -1; + } ++kernel_range; } else if (delta) { /* Kernel was relocated at boot time */ @@ -1099,14 +1102,15 @@ int compare_proc_modules(const char *from, const ch= ar *to) static int do_validate_kcore_modules(const char *filename, struct maps *km= aps) { struct rb_root modules =3D RB_ROOT; - struct map *old_map; + struct map_rb_node *old_node; int err; =20 err =3D read_proc_modules(filename, &modules); if (err) return err; =20 - maps__for_each_entry(kmaps, old_map) { + maps__for_each_entry(kmaps, old_node) { + struct map *old_map =3D old_node->map; struct module_info *mi; =20 if (!__map__is_kmodule(old_map)) { @@ -1224,10 +1228,13 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgof= f, void *data) */ int maps__merge_in(struct maps *kmaps, struct map *new_map) { - struct map *old_map; + struct map_rb_node *rb_node; LIST_HEAD(merged); + int err =3D 0; + + maps__for_each_entry(kmaps, rb_node) { + struct map *old_map =3D rb_node->map; =20 - maps__for_each_entry(kmaps, old_map) { /* no overload with this one */ if (new_map->end < old_map->start || new_map->start >=3D old_map->end) @@ -1252,13 +1259,16 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) struct map_list_node *m; =20 m =3D malloc(sizeof(*m)); - if (!m) - return -ENOMEM; + if (!m) { + err =3D -ENOMEM; + goto out; + } =20 m->map =3D map__clone(new_map); if (!m->map) { free(m); - return -ENOMEM; + err =3D -ENOMEM; + goto out; } =20 m->map->end =3D old_map->start; @@ -1290,21 +1300,24 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) } } =20 +out: while (!list_empty(&merged)) { struct map_list_node *old_node; =20 old_node =3D list_entry(merged.next, struct map_list_node, node); list_del_init(&old_node->node); - maps__insert(kmaps, old_node->map); + if (!err) + err =3D maps__insert(kmaps, old_node->map); map__put(old_node->map); free(old_node); } =20 if (new_map) { - maps__insert(kmaps, new_map); + if (!err) + err =3D maps__insert(kmaps, new_map); map__put(new_map); } - return 0; + return err; } =20 static int dso__load_kcore(struct dso *dso, struct map *map, @@ -1312,7 +1325,8 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, { struct maps *kmaps =3D map__kmaps(map); struct kcore_mapfn_data md; - struct map *old_map, *replacement_map =3D NULL, *next; + struct map *replacement_map =3D NULL; + struct map_rb_node *old_node, *next; struct machine *machine; bool is_64_bit; int err, fd; @@ -1359,7 +1373,9 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, } =20 /* Remove old maps */ - maps__for_each_entry_safe(kmaps, old_map, next) { + maps__for_each_entry_safe(kmaps, old_node, next) { + struct map *old_map =3D old_node->map; + /* * We need to preserve eBPF maps even if they are * covered by kcore, because we need to access @@ -1400,17 +1416,21 @@ static int dso__load_kcore(struct dso *dso, struct = map *map, /* Ensure maps are correctly ordered */ map__get(map); maps__remove(kmaps, map); - maps__insert(kmaps, map); + err =3D maps__insert(kmaps, map); map__put(map); map__put(new_node->map); + if (err) + goto out_err; } else { /* * Merge kcore map into existing maps, * and ensure that current maps (eBPF) * stay intact. */ - if (maps__merge_in(kmaps, new_node->map)) + if (maps__merge_in(kmaps, new_node->map)) { + err =3D -EINVAL; goto out_err; + } } free(new_node); } @@ -1457,7 +1477,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, free(list_node); } close(fd); - return -EINVAL; + return err; } =20 /* @@ -1991,8 +2011,9 @@ void __maps__sort_by_name(struct maps *maps) =20 static int map__groups__sort_by_name_from_rbtree(struct maps *maps) { - struct map *map; - struct map **maps_by_name =3D realloc(maps->maps_by_name, maps->nr_maps *= sizeof(map)); + struct map_rb_node *rb_node; + struct map **maps_by_name =3D realloc(maps->maps_by_name, + maps->nr_maps * sizeof(struct map *)); int i =3D 0; =20 if (maps_by_name =3D=3D NULL) @@ -2001,8 +2022,8 @@ static int map__groups__sort_by_name_from_rbtree(stru= ct maps *maps) maps->maps_by_name =3D maps_by_name; maps->nr_maps_allocated =3D maps->nr_maps; =20 - maps__for_each_entry(maps, map) - maps_by_name[i++] =3D map; + maps__for_each_entry(maps, rb_node) + maps_by_name[i++] =3D rb_node->map; =20 __maps__sort_by_name(maps); return 0; @@ -2024,6 +2045,7 @@ static struct map *__maps__find_by_name(struct maps *= maps, const char *name) =20 struct map *maps__find_by_name(struct maps *maps, const char *name) { + struct map_rb_node *rb_node; struct map *map; =20 down_read(&maps->lock); @@ -2042,12 +2064,13 @@ struct map *maps__find_by_name(struct maps *maps, c= onst char *name) goto out_unlock; =20 /* Fallback to traversing the rbtree... */ - maps__for_each_entry(maps, map) + maps__for_each_entry(maps, rb_node) { + map =3D rb_node->map; if (strcmp(map->dso->short_name, name) =3D=3D 0) { maps->last_search_by_name =3D map; goto out_unlock; } - + } map =3D NULL; =20 out_unlock: diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index 70f095624a0b..ed2d55d224aa 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -639,7 +639,7 @@ int perf_event__synthesize_modules(struct perf_tool *to= ol, perf_event__handler_t struct machine *machine) { int rc =3D 0; - struct map *pos; + struct map_rb_node *pos; struct maps *maps =3D machine__kernel_maps(machine); union perf_event *event; size_t size =3D symbol_conf.buildid_mmap2 ? @@ -662,37 +662,39 @@ int perf_event__synthesize_modules(struct perf_tool *= tool, perf_event__handler_t event->header.misc =3D PERF_RECORD_MISC_GUEST_KERNEL; =20 maps__for_each_entry(maps, pos) { - if (!__map__is_kmodule(pos)) + struct map *map =3D pos->map; + + if (!__map__is_kmodule(map)) continue; =20 if (symbol_conf.buildid_mmap2) { - size =3D PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); + size =3D PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); event->mmap2.header.type =3D PERF_RECORD_MMAP2; event->mmap2.header.size =3D (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size)); memset(event->mmap2.filename + size, 0, machine->id_hdr_size); event->mmap2.header.size +=3D machine->id_hdr_size; - event->mmap2.start =3D pos->start; - event->mmap2.len =3D pos->end - pos->start; + event->mmap2.start =3D map->start; + event->mmap2.len =3D map->end - map->start; event->mmap2.pid =3D machine->pid; =20 - memcpy(event->mmap2.filename, pos->dso->long_name, - pos->dso->long_name_len + 1); + memcpy(event->mmap2.filename, map->dso->long_name, + map->dso->long_name_len + 1); =20 perf_record_mmap2__read_build_id(&event->mmap2, false); } else { - size =3D PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); + size =3D PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); event->mmap.header.type =3D PERF_RECORD_MMAP; event->mmap.header.size =3D (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size)); memset(event->mmap.filename + size, 0, machine->id_hdr_size); event->mmap.header.size +=3D machine->id_hdr_size; - event->mmap.start =3D pos->start; - event->mmap.len =3D pos->end - pos->start; + event->mmap.start =3D map->start; + event->mmap.len =3D map->end - map->start; event->mmap.pid =3D machine->pid; =20 - memcpy(event->mmap.filename, pos->dso->long_name, - pos->dso->long_name_len + 1); + memcpy(event->mmap.filename, map->dso->long_name, + map->dso->long_name_len + 1); } =20 if (perf_tool__process_synth_event(tool, event, machine, process) !=3D 0= ) { diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 665e5c0618ed..4baf4db8af65 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -338,9 +338,7 @@ int thread__insert_map(struct thread *thread, struct ma= p *map) return ret; =20 maps__fixup_overlappings(thread->maps, map, stderr); - maps__insert(thread->maps, map); - - return 0; + return maps__insert(thread->maps, map); } =20 static int __thread__prepare_access(struct thread *thread) @@ -348,12 +346,12 @@ static int __thread__prepare_access(struct thread *th= read) bool initialized =3D false; int err =3D 0; struct maps *maps =3D thread->maps; - struct map *map; + struct map_rb_node *rb_node; =20 down_read(&maps->lock); =20 - maps__for_each_entry(maps, map) { - err =3D unwind__prepare_access(thread->maps, map, &initialized); + maps__for_each_entry(maps, rb_node) { + err =3D unwind__prepare_access(thread->maps, rb_node->map, &initialized); if (err || initialized) break; } diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 43beb169631d..835c39efb80d 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -144,10 +144,11 @@ static enum dso_type machine__thread_dso_type(struct = machine *machine, struct thread *thread) { enum dso_type dso_type =3D DSO__TYPE_UNKNOWN; - struct map *map; + struct map_rb_node *rb_node; + + maps__for_each_entry(thread->maps, rb_node) { + struct dso *dso =3D rb_node->map->dso; =20 - maps__for_each_entry(thread->maps, map) { - struct dso *dso =3D map->dso; if (!dso || dso->long_name[0] !=3D '/') continue; dso_type =3D dso__type(dso, machine); --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 2E596C43217 for ; Fri, 11 Feb 2022 10:35:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238262AbiBKKfZ (ORCPT ); Fri, 11 Feb 2022 05:35:25 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349016AbiBKKfC (ORCPT ); Fri, 11 Feb 2022 05:35:02 -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 A66DAEBD for ; Fri, 11 Feb 2022 02:34:53 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id b64-20020a256743000000b0061e169a5f19so17495041ybc.11 for ; Fri, 11 Feb 2022 02:34:53 -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=Ecm5CSvtzvsHI0TIuBDEh7P+YgW7Azf4QGGIL0a03dA=; b=ce3krB8NWFrMRSeIoRtXFyDqw+VdlqaX8EyuhBwsn7rZFYxmQn47aFdro6MH+a/JTt fDRvncKB/nlulI0bkpNYRUF2OX1ZM96b3gr871zVWEyQf/GchXiN9bLWYfCOGbRasERO M5hTFtzVgtruzkluKQZI8m40A9Z6tD7vFHeQ6L3xV1vDU11uJYQrOFOjKni5QSfzF0Iu 2DByeSUTF44bWN1ZXa+5e/LWGBczxgaDk+V5k2CQ5YnmgWlcJ6XKIOIV9UuAbI0Q4GFB PK8Ai4dkdze5svyyUPmQfyRtbKoNrZGUrRMCV2OdFfg3NYQzOQiTSuvqhnQ1YuS+BEXT cjoA== 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=Ecm5CSvtzvsHI0TIuBDEh7P+YgW7Azf4QGGIL0a03dA=; b=nXHTmWWdn0bJl6uBBjdDtqyDkZb/SSrAPfgEMLUv6TnvfZJIrbftIGLoIO+BgWJDLw IlUsPEYBku70vsN9RKZA2N4ZfgtXeFi9azjUTDrVud3cOqbwLgeeYBZ4FLRy7BaKObp6 wiBMkhJ8VOzLP//11Ze5rCTyGkfK4vGiyFQHZXDd12Sy6sx5D5/IxpnejLcwYuI7CGS3 av7krt03j9mWrX5elB+u0Rniaiw82wvk6ZJqRw65NFiJsUXC+aUS0CLjM9vzhcKN7dzX PdxyewvMM5GixVqYbe454SfFxvxhYsmRBXQ5q2t4P4rR2UpgN9UxBdAInbkgvjrtk7pQ 5oPw== X-Gm-Message-State: AOAM531U/E6wUpO+cMk/HrgxrPzUc2uCjJSCL7iKdUZrKD9r9QvgdsPg Dmc/Ou31w4JCGH2mDVQILMJ8uT8jqA1B X-Google-Smtp-Source: ABdhPJzwDDMxcDGeVt6Ot3wjxv84puS5i6/ff6OWe5GeOpC2qsVX0//v6k7U/o5k7ZQ4HVQhOOqxRkLdBAY2 X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:35c2:: with SMTP id c185mr645352yba.617.1644575692875; Fri, 11 Feb 2022 02:34:52 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:06 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-14-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 13/22] perf namespaces: Add functions to access nsinfo 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 , Hao Luo 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" Having functions to access nsinfo reduces the places where reference counting checking needs to be added. Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-probe.c | 2 +- tools/perf/util/build-id.c | 4 +-- tools/perf/util/jitdump.c | 10 ++++---- tools/perf/util/map.c | 4 +-- tools/perf/util/namespaces.c | 50 ++++++++++++++++++++++++++++-------- tools/perf/util/namespaces.h | 10 ++++++-- tools/perf/util/symbol.c | 8 +++--- 8 files changed, 63 insertions(+), 27 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index bede332bf0e2..f7917c390e96 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -354,7 +354,7 @@ static struct dso *findnew_dso(int pid, int tid, const = char *filename, nnsi =3D nsinfo__copy(nsi); if (nnsi) { nsinfo__put(nsi); - nnsi->need_setns =3D false; + nsinfo__clear_need_setns(nnsi); nsi =3D nnsi; } dso =3D machine__findnew_vdso(machine, thread); diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index c31627af75d4..f62298f5db3b 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -217,7 +217,7 @@ static int opt_set_target_ns(const struct option *opt _= _maybe_unused, return ret; } nsip =3D nsinfo__new(ns_pid); - if (nsip && nsip->need_setns) + if (nsip && nsinfo__need_setns(nsip)) params.nsi =3D nsinfo__get(nsip); nsinfo__put(nsip); =20 diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e32e8f2ff3bd..7a5821c87f94 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -706,7 +706,7 @@ build_id_cache__add(const char *sbuild_id, const char *= name, const char *realnam if (is_kallsyms) { if (copyfile("/proc/kallsyms", filename)) goto out_free; - } else if (nsi && nsi->need_setns) { + } else if (nsi && nsinfo__need_setns(nsi)) { if (copyfile_ns(name, filename, nsi)) goto out_free; } else if (link(realname, filename) && errno !=3D EEXIST && @@ -730,7 +730,7 @@ build_id_cache__add(const char *sbuild_id, const char *= name, const char *realnam goto out_free; } if (access(filename, F_OK)) { - if (nsi && nsi->need_setns) { + if (nsi && nsinfo__need_setns(nsi)) { if (copyfile_ns(debugfile, filename, nsi)) goto out_free; diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 917a9c707371..a23255773c60 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -382,15 +382,15 @@ jit_inject_event(struct jit_buf_desc *jd, union perf_= event *event) =20 static pid_t jr_entry_pid(struct jit_buf_desc *jd, union jr_entry *jr) { - if (jd->nsi && jd->nsi->in_pidns) - return jd->nsi->tgid; + if (jd->nsi && nsinfo__in_pidns(jd->nsi)) + return nsinfo__tgid(jd->nsi); return jr->load.pid; } =20 static pid_t jr_entry_tid(struct jit_buf_desc *jd, union jr_entry *jr) { - if (jd->nsi && jd->nsi->in_pidns) - return jd->nsi->pid; + if (jd->nsi && nsinfo__in_pidns(jd->nsi)) + return nsinfo__pid(jd->nsi); return jr->load.tid; } =20 @@ -779,7 +779,7 @@ jit_detect(char *mmap_name, pid_t pid, struct nsinfo *n= si) * pid does not match mmap pid * pid=3D=3D0 in system-wide mode (synthesized) */ - if (pid && pid2 !=3D nsi->nstgid) + if (pid && pid2 !=3D nsinfo__nstgid(nsi)) return -1; /* * validate suffix diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index dfa5f6b7381f..166c84c829f6 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -139,7 +139,7 @@ struct map *map__new(struct machine *machine, u64 start= , u64 len, =20 if ((anon || no_dso) && nsi && (prot & PROT_EXEC)) { snprintf(newfilename, sizeof(newfilename), - "/tmp/perf-%d.map", nsi->pid); + "/tmp/perf-%d.map", nsinfo__pid(nsi)); filename =3D newfilename; } =20 @@ -156,7 +156,7 @@ struct map *map__new(struct machine *machine, u64 start= , u64 len, nnsi =3D nsinfo__copy(nsi); if (nnsi) { nsinfo__put(nsi); - nnsi->need_setns =3D false; + nsinfo__clear_need_setns(nnsi); nsi =3D nnsi; } pgoff =3D 0; diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index 48aa3217300b..dd536220cdb9 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c @@ -76,7 +76,7 @@ static int nsinfo__get_nspid(struct nsinfo *nsi, const ch= ar *path) if (strstr(statln, "Tgid:") !=3D NULL) { nsi->tgid =3D (pid_t)strtol(strrchr(statln, '\t'), NULL, 10); - nsi->nstgid =3D nsi->tgid; + nsi->nstgid =3D nsinfo__tgid(nsi); } =20 if (strstr(statln, "NStgid:") !=3D NULL) { @@ -108,7 +108,7 @@ int nsinfo__init(struct nsinfo *nsi) if (snprintf(oldns, PATH_MAX, "/proc/self/ns/mnt") >=3D PATH_MAX) return rv; =20 - if (asprintf(&newns, "/proc/%d/ns/mnt", nsi->pid) =3D=3D -1) + if (asprintf(&newns, "/proc/%d/ns/mnt", nsinfo__pid(nsi)) =3D=3D -1) return rv; =20 if (stat(oldns, &old_stat) < 0) @@ -129,7 +129,7 @@ int nsinfo__init(struct nsinfo *nsi) /* If we're dealing with a process that is in a different PID namespace, * attempt to work out the innermost tgid for the process. */ - if (snprintf(spath, PATH_MAX, "/proc/%d/status", nsi->pid) >=3D PATH_MAX) + if (snprintf(spath, PATH_MAX, "/proc/%d/status", nsinfo__pid(nsi)) >=3D P= ATH_MAX) goto out; =20 rv =3D nsinfo__get_nspid(nsi, spath); @@ -166,7 +166,7 @@ struct nsinfo *nsinfo__new(pid_t pid) return nsi; } =20 -struct nsinfo *nsinfo__copy(struct nsinfo *nsi) +struct nsinfo *nsinfo__copy(const struct nsinfo *nsi) { struct nsinfo *nnsi; =20 @@ -175,11 +175,11 @@ struct nsinfo *nsinfo__copy(struct nsinfo *nsi) =20 nnsi =3D calloc(1, sizeof(*nnsi)); if (nnsi !=3D NULL) { - nnsi->pid =3D nsi->pid; - nnsi->tgid =3D nsi->tgid; - nnsi->nstgid =3D nsi->nstgid; - nnsi->need_setns =3D nsi->need_setns; - nnsi->in_pidns =3D nsi->in_pidns; + nnsi->pid =3D nsinfo__pid(nsi); + nnsi->tgid =3D nsinfo__tgid(nsi); + nnsi->nstgid =3D nsinfo__nstgid(nsi); + nnsi->need_setns =3D nsinfo__need_setns(nsi); + nnsi->in_pidns =3D nsinfo__in_pidns(nsi); if (nsi->mntns_path) { nnsi->mntns_path =3D strdup(nsi->mntns_path); if (!nnsi->mntns_path) { @@ -193,7 +193,7 @@ struct nsinfo *nsinfo__copy(struct nsinfo *nsi) return nnsi; } =20 -void nsinfo__delete(struct nsinfo *nsi) +static void nsinfo__delete(struct nsinfo *nsi) { zfree(&nsi->mntns_path); free(nsi); @@ -212,6 +212,36 @@ void nsinfo__put(struct nsinfo *nsi) nsinfo__delete(nsi); } =20 +bool nsinfo__need_setns(const struct nsinfo *nsi) +{ + return nsi->need_setns; +} + +void nsinfo__clear_need_setns(struct nsinfo *nsi) +{ + nsi->need_setns =3D false; +} + +pid_t nsinfo__tgid(const struct nsinfo *nsi) +{ + return nsi->tgid; +} + +pid_t nsinfo__nstgid(const struct nsinfo *nsi) +{ + return nsi->nstgid; +} + +pid_t nsinfo__pid(const struct nsinfo *nsi) +{ + return nsi->pid; +} + +pid_t nsinfo__in_pidns(const struct nsinfo *nsi) +{ + return nsi->in_pidns; +} + void nsinfo__mountns_enter(struct nsinfo *nsi, struct nscookie *nc) { diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 9ceea9643507..567829262c42 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h @@ -47,12 +47,18 @@ struct nscookie { =20 int nsinfo__init(struct nsinfo *nsi); struct nsinfo *nsinfo__new(pid_t pid); -struct nsinfo *nsinfo__copy(struct nsinfo *nsi); -void nsinfo__delete(struct nsinfo *nsi); +struct nsinfo *nsinfo__copy(const struct nsinfo *nsi); =20 struct nsinfo *nsinfo__get(struct nsinfo *nsi); void nsinfo__put(struct nsinfo *nsi); =20 +bool nsinfo__need_setns(const struct nsinfo *nsi); +void nsinfo__clear_need_setns(struct nsinfo *nsi); +pid_t nsinfo__tgid(const struct nsinfo *nsi); +pid_t nsinfo__nstgid(const struct nsinfo *nsi); +pid_t nsinfo__pid(const struct nsinfo *nsi); +pid_t nsinfo__in_pidns(const struct nsinfo *nsi); + void nsinfo__mountns_enter(struct nsinfo *nsi, struct nscookie *nc); void nsinfo__mountns_exit(struct nscookie *nc); =20 diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 266c65bb8bbb..e8045b1c8700 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1784,8 +1784,8 @@ static int dso__find_perf_map(char *filebuf, size_t b= ufsz, =20 nsi =3D *nsip; =20 - if (nsi->need_setns) { - snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nsi->nstgid); + if (nsinfo__need_setns(nsi)) { + snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nsinfo__nstgid(nsi)); nsinfo__mountns_enter(nsi, &nsc); rc =3D access(filebuf, R_OK); nsinfo__mountns_exit(&nsc); @@ -1797,8 +1797,8 @@ static int dso__find_perf_map(char *filebuf, size_t b= ufsz, if (nnsi) { nsinfo__put(nsi); =20 - nnsi->need_setns =3D false; - snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nnsi->tgid); + nsinfo__clear_need_setns(nnsi); + snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nsinfo__tgid(nnsi)); *nsip =3D nnsi; rc =3D 0; } --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 F375EC433FE for ; Fri, 11 Feb 2022 10:35:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231316AbiBKKf1 (ORCPT ); Fri, 11 Feb 2022 05:35:27 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349018AbiBKKfG (ORCPT ); Fri, 11 Feb 2022 05:35:06 -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 60B4CF03 for ; Fri, 11 Feb 2022 02:34:56 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id v134-20020a25618c000000b00620dc86b9d6so10533719ybb.0 for ; Fri, 11 Feb 2022 02:34:56 -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=q8G14SAEa7uvFBFKYlo5q0orDY3ugG7lRFTfspG1Us0=; b=FwigVHlABX1R9xopZ1QIVsESmoMSH6rcpeBlxM37cWyrtfo8Na0UI9actTepeXh0Ae nfo8awP8PtTXMgd92hbHUSnujM/pMAbNuvCT/+UJrNWBi/hSUB7XliUkgGyxYv5nmCBS 1sUBkEWmzzpatEbfWDQL4enX1ikwEJRjKtb5/g9ba+aBBj1i6T/wofaFMxZZcy+Ed2mt DkMG+M26abzPDmKK1zxnlnqCFnfNEVCW4qQHeBl3w/CfeijdPZ6VxYUWoplVrCW+z5jD eSs7vYtD/HdKtc3A5A0W5mMCwPlziwEujBlZx4EmWILDJKQXh9aulbsGcFPlifEYvhfr PFog== 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=q8G14SAEa7uvFBFKYlo5q0orDY3ugG7lRFTfspG1Us0=; b=iO1dvfbLhst6XrCt4yGSyysxGtj1kLG/CGPOmnTWST3bc9tbHP3MA6JmukfzhsOJlg rJY30cPuGqSRjZHs8o8RmL/XajNqS2Eiz7kVR91/EWVRvnQjc0V//gFFRxXXun/m1ix1 /qCh5kd1PEVosC1AD7nyBGX/vMhMZrr3ayi91V6tgyvhORNdEF+Ig9y2l98rJbcwqS5f srX2JB0o1IhjUeyBdDbf1p5LeuCYjntGqx4uB08sW1OjWgPdH5g/rabexsfiSG2taeJB MW9RoZE4T5pxA4pbKgJ9u5jlE/5dKXswHAXffM+YQS0fP2239wgWny6ohb6OKKe5X9or Ig1w== X-Gm-Message-State: AOAM532gRhXMWwd0EBzcUbJrrqMYunCCCUKbRQRp6oyBz+CtDw4ovqyM AjW5JzJlYIbOdO2kOdAlio8uITwSl5+i X-Google-Smtp-Source: ABdhPJz6VWRRigwUwx8Pzmr7Q/qEuaNnd4Q5QLLowxQSdqlEbXhZEZbQyT6q2aT5O8E6vi6g/JZla4Hm8u6+ X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a81:e40a:: with SMTP id r10mr906703ywl.276.1644575695597; Fri, 11 Feb 2022 02:34:55 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:07 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-15-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 14/22] perf maps: Add functions to access maps 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 , Hao Luo 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" Introduce functions to access struct maps. These functions reduce the number of places reference counting is necessary. While tidying APIs do some small const-ification, in particlar to unwind_libunwind_ops. Signed-off-by: Ian Rogers --- .../scripts/python/Perf-Trace-Util/Context.c | 7 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/ui/browsers/hists.c | 3 +- tools/perf/util/callchain.c | 9 +-- tools/perf/util/db-export.c | 12 ++-- tools/perf/util/dlfilter.c | 8 ++- tools/perf/util/event.c | 4 +- tools/perf/util/hist.c | 2 +- tools/perf/util/machine.c | 2 +- tools/perf/util/map.c | 14 ++-- tools/perf/util/maps.c | 69 +++++++++++-------- tools/perf/util/maps.h | 47 ++++++++++--- .../scripting-engines/trace-event-python.c | 2 +- tools/perf/util/sort.c | 2 +- tools/perf/util/symbol-elf.c | 2 +- tools/perf/util/symbol.c | 36 +++++----- tools/perf/util/thread-stack.c | 4 +- tools/perf/util/thread.c | 4 +- tools/perf/util/unwind-libunwind-local.c | 16 +++-- tools/perf/util/unwind-libunwind.c | 30 +++++--- 20 files changed, 170 insertions(+), 105 deletions(-) diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/pe= rf/scripts/python/Perf-Trace-Util/Context.c index 895f5fc23965..b64013a87c54 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c @@ -98,10 +98,11 @@ static PyObject *perf_sample_insn(PyObject *obj, PyObje= ct *args) if (!c) return NULL; =20 - if (c->sample->ip && !c->sample->insn_len && - c->al->thread->maps && c->al->thread->maps->machine) - script_fetch_insn(c->sample, c->al->thread, c->al->thread->maps->machine= ); + if (c->sample->ip && !c->sample->insn_len && c->al->thread->maps) { + struct machine *machine =3D maps__machine(c->al->thread->maps); =20 + script_fetch_insn(c->sample, c->al->thread, machine); + } if (!c->sample->insn_len) Py_RETURN_NONE; /* N.B. This is a return statement */ =20 diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index 5610767b407f..6eafe36a8704 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -268,7 +268,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, len =3D al.map->end - addr; =20 /* Read the object code using perf */ - ret_len =3D dso__data_read_offset(al.map->dso, thread->maps->machine, + ret_len =3D dso__data_read_offset(al.map->dso, maps__machine(thread->maps= ), al.addr, buf1, len); if (ret_len !=3D len) { pr_debug("dso__data_read_offset failed\n"); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index b72ee6822222..572ff38ceb0f 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3139,7 +3139,8 @@ static int evsel__hists_browse(struct evsel *evsel, i= nt nr_events, const char *h continue; case 'k': if (browser->selection !=3D NULL) - hists_browser__zoom_map(browser, browser->selection->maps->machine->vm= linux_map); + hists_browser__zoom_map(browser, + maps__machine(browser->selection->maps)->vmlinux_map); continue; case 'V': verbose =3D (verbose + 1) % 4; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 5c27a4b2e7a7..61bb3fb2107a 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1106,6 +1106,8 @@ int hist_entry__append_callchain(struct hist_entry *h= e, struct perf_sample *samp int fill_callchain_info(struct addr_location *al, struct callchain_cursor_= node *node, bool hide_unresolved) { + struct machine *machine =3D maps__machine(node->ms.maps); + al->maps =3D node->ms.maps; al->map =3D node->ms.map; al->sym =3D node->ms.sym; @@ -1118,9 +1120,8 @@ int fill_callchain_info(struct addr_location *al, str= uct callchain_cursor_node * if (al->map =3D=3D NULL) goto out; } - - if (al->maps =3D=3D machine__kernel_maps(al->maps->machine)) { - if (machine__is_host(al->maps->machine)) { + if (al->maps =3D=3D machine__kernel_maps(machine)) { + if (machine__is_host(machine)) { al->cpumode =3D PERF_RECORD_MISC_KERNEL; al->level =3D 'k'; } else { @@ -1128,7 +1129,7 @@ int fill_callchain_info(struct addr_location *al, str= uct callchain_cursor_node * al->level =3D 'g'; } } else { - if (machine__is_host(al->maps->machine)) { + if (machine__is_host(machine)) { al->cpumode =3D PERF_RECORD_MISC_USER; al->level =3D '.'; } else if (perf_guest) { diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index e0d4f08839fb..1cfcfdd3cf52 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -181,7 +181,7 @@ static int db_ids_from_al(struct db_export *dbe, struct= addr_location *al, if (al->map) { struct dso *dso =3D al->map->dso; =20 - err =3D db_export__dso(dbe, dso, al->maps->machine); + err =3D db_export__dso(dbe, dso, maps__machine(al->maps)); if (err) return err; *dso_db_id =3D dso->db_id; @@ -354,19 +354,21 @@ int db_export__sample(struct db_export *dbe, union pe= rf_event *event, }; struct thread *main_thread; struct comm *comm =3D NULL; + struct machine *machine; int err; =20 err =3D db_export__evsel(dbe, evsel); if (err) return err; =20 - err =3D db_export__machine(dbe, al->maps->machine); + machine =3D maps__machine(al->maps); + err =3D db_export__machine(dbe, machine); if (err) return err; =20 - main_thread =3D thread__main_thread(al->maps->machine, thread); + main_thread =3D thread__main_thread(machine, thread); =20 - err =3D db_export__threads(dbe, thread, main_thread, al->maps->machine, &= comm); + err =3D db_export__threads(dbe, thread, main_thread, machine, &comm); if (err) goto out_put; =20 @@ -380,7 +382,7 @@ int db_export__sample(struct db_export *dbe, union perf= _event *event, goto out_put; =20 if (dbe->cpr) { - struct call_path *cp =3D call_path_from_sample(dbe, al->maps->machine, + struct call_path *cp =3D call_path_from_sample(dbe, machine, thread, sample, evsel); if (cp) { diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index db964d5a52af..d59462af15f1 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -197,8 +197,12 @@ static const __u8 *dlfilter__insn(void *ctx, __u32 *le= n) if (!al->thread && machine__resolve(d->machine, al, d->sample) < 0) return NULL; =20 - if (al->thread->maps && al->thread->maps->machine) - script_fetch_insn(d->sample, al->thread, al->thread->maps->machine); + if (al->thread->maps) { + struct machine *machine =3D maps__machine(al->thread->maps); + + if (machine) + script_fetch_insn(d->sample, al->thread, machine); + } } =20 if (!d->sample->insn_len) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 6439c888ae38..40a3b1a35613 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -571,7 +571,7 @@ struct map *thread__find_map(struct thread *thread, u8 = cpumode, u64 addr, struct addr_location *al) { struct maps *maps =3D thread->maps; - struct machine *machine =3D maps->machine; + struct machine *machine =3D maps__machine(maps); bool load_map =3D false; =20 al->maps =3D maps; @@ -636,7 +636,7 @@ struct map *thread__find_map_fb(struct thread *thread, = u8 cpumode, u64 addr, struct addr_location *al) { struct map *map =3D thread__find_map(thread, cpumode, addr, al); - struct machine *machine =3D thread->maps->machine; + struct machine *machine =3D maps__machine(thread->maps); u8 addr_cpumode =3D machine__addr_cpumode(machine, cpumode, addr); =20 if (map || addr_cpumode =3D=3D cpumode) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0a8033b09e28..78f9fbb925a7 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -237,7 +237,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) =20 if (h->cgroup) { const char *cgrp_name =3D "unknown"; - struct cgroup *cgrp =3D cgroup__find(h->ms.maps->machine->env, + struct cgroup *cgrp =3D cgroup__find(maps__machine(h->ms.maps)->env, h->cgroup); if (cgrp !=3D NULL) cgrp_name =3D cgrp->name; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index fa25174cabf7..88279008e761 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2739,7 +2739,7 @@ static int find_prev_cpumode(struct ip_callchain *cha= in, struct thread *thread, static u64 get_leaf_frame_caller(struct perf_sample *sample, struct thread *thread, int usr_idx) { - if (machine__normalized_is(thread->maps->machine, "arm64")) + if (machine__normalized_is(maps__machine(thread->maps), "arm64")) return get_leaf_frame_caller_aarch64(sample, thread, usr_idx); else return 0; diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 166c84c829f6..57e926ce115f 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -220,7 +220,7 @@ bool __map__is_kernel(const struct map *map) { if (!map->dso->kernel) return false; - return machine__kernel_map(map__kmaps((struct map *)map)->machine) =3D=3D= map; + return machine__kernel_map(maps__machine(map__kmaps((struct map *)map))) = =3D=3D map; } =20 bool __map__is_extra_kernel_map(const struct map *map) @@ -461,11 +461,15 @@ u64 map__rip_2objdump(struct map *map, u64 rip) * kcore may not either. However the trampoline object code is on the * main kernel map, so just use that instead. */ - if (kmap && is_entry_trampoline(kmap->name) && kmap->kmaps && kmap->kmaps= ->machine) { - struct map *kernel_map =3D machine__kernel_map(kmap->kmaps->machine); + if (kmap && is_entry_trampoline(kmap->name) && kmap->kmaps) { + struct machine *machine =3D maps__machine(kmap->kmaps); =20 - if (kernel_map) - map =3D kernel_map; + if (machine) { + struct map *kernel_map =3D machine__kernel_map(machine); + + if (kernel_map) + map =3D kernel_map; + } } =20 if (!map->dso->adjust_symbols) diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index beb09b9a122c..9fc3e7186b8e 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -13,7 +13,7 @@ static void maps__init(struct maps *maps, struct machine *machine) { maps->entries =3D RB_ROOT; - init_rwsem(&maps->lock); + init_rwsem(maps__lock(maps)); maps->machine =3D machine; maps->last_search_by_name =3D NULL; maps->nr_maps =3D 0; @@ -32,7 +32,7 @@ static void __maps__free_maps_by_name(struct maps *maps) =20 static int __maps__insert(struct maps *maps, struct map *map) { - struct rb_node **p =3D &maps->entries.rb_node; + struct rb_node **p =3D &maps__entries(maps)->rb_node; struct rb_node *parent =3D NULL; const u64 ip =3D map->start; struct map_rb_node *m, *new_rb_node; @@ -54,7 +54,7 @@ static int __maps__insert(struct maps *maps, struct map *= map) } =20 rb_link_node(&new_rb_node->rb_node, parent, p); - rb_insert_color(&new_rb_node->rb_node, &maps->entries); + rb_insert_color(&new_rb_node->rb_node, maps__entries(maps)); map__get(map); return 0; } @@ -63,7 +63,7 @@ int maps__insert(struct maps *maps, struct map *map) { int err; =20 - down_write(&maps->lock); + down_write(maps__lock(maps)); err =3D __maps__insert(maps, map); if (err) goto out; @@ -84,10 +84,11 @@ int maps__insert(struct maps *maps, struct map *map) * If we already performed some search by name, then we need to add the j= ust * inserted map and resort. */ - if (maps->maps_by_name) { - if (maps->nr_maps > maps->nr_maps_allocated) { - int nr_allocate =3D maps->nr_maps * 2; - struct map **maps_by_name =3D realloc(maps->maps_by_name, nr_allocate *= sizeof(map)); + if (maps__maps_by_name(maps)) { + if (maps__nr_maps(maps) > maps->nr_maps_allocated) { + int nr_allocate =3D maps__nr_maps(maps) * 2; + struct map **maps_by_name =3D realloc(maps__maps_by_name(maps), + nr_allocate * sizeof(map)); =20 if (maps_by_name =3D=3D NULL) { __maps__free_maps_by_name(maps); @@ -98,17 +99,17 @@ int maps__insert(struct maps *maps, struct map *map) maps->maps_by_name =3D maps_by_name; maps->nr_maps_allocated =3D nr_allocate; } - maps->maps_by_name[maps->nr_maps - 1] =3D map; + maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] =3D map; __maps__sort_by_name(maps); } out: - up_write(&maps->lock); + up_write(maps__lock(maps)); return err; } =20 static void __maps__remove(struct maps *maps, struct map_rb_node *rb_node) { - rb_erase_init(&rb_node->rb_node, &maps->entries); + rb_erase_init(&rb_node->rb_node, maps__entries(maps)); map__put(rb_node->map); free(rb_node); } @@ -117,7 +118,7 @@ void maps__remove(struct maps *maps, struct map *map) { struct map_rb_node *rb_node; =20 - down_write(&maps->lock); + down_write(maps__lock(maps)); if (maps->last_search_by_name =3D=3D map) maps->last_search_by_name =3D NULL; =20 @@ -125,9 +126,9 @@ void maps__remove(struct maps *maps, struct map *map) assert(rb_node->map =3D=3D map); __maps__remove(maps, rb_node); --maps->nr_maps; - if (maps->maps_by_name) + if (maps__maps_by_name(maps)) __maps__free_maps_by_name(maps); - up_write(&maps->lock); + up_write(maps__lock(maps)); } =20 static void __maps__purge(struct maps *maps) @@ -135,7 +136,7 @@ static void __maps__purge(struct maps *maps) struct map_rb_node *pos, *next; =20 maps__for_each_entry_safe(maps, pos, next) { - rb_erase_init(&pos->rb_node, &maps->entries); + rb_erase_init(&pos->rb_node, maps__entries(maps)); map__put(pos->map); free(pos); } @@ -143,9 +144,9 @@ static void __maps__purge(struct maps *maps) =20 static void maps__exit(struct maps *maps) { - down_write(&maps->lock); + down_write(maps__lock(maps)); __maps__purge(maps); - up_write(&maps->lock); + up_write(maps__lock(maps)); } =20 bool maps__empty(struct maps *maps) @@ -170,6 +171,14 @@ void maps__delete(struct maps *maps) free(maps); } =20 +struct maps *maps__get(struct maps *maps) +{ + if (maps) + refcount_inc(&maps->refcnt); + + return maps; +} + void maps__put(struct maps *maps) { if (maps && refcount_dec_and_test(&maps->refcnt)) @@ -195,7 +204,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *m= aps, const char *name, st struct symbol *sym; struct map_rb_node *pos; =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 maps__for_each_entry(maps, pos) { sym =3D map__find_symbol_by_name(pos->map, name); @@ -213,7 +222,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *m= aps, const char *name, st =20 sym =3D NULL; out: - up_read(&maps->lock); + up_read(maps__lock(maps)); return sym; } =20 @@ -238,7 +247,7 @@ size_t maps__fprintf(struct maps *maps, FILE *fp) size_t printed =3D 0; struct map_rb_node *pos; =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 maps__for_each_entry(maps, pos) { printed +=3D fprintf(fp, "Map:"); @@ -249,7 +258,7 @@ size_t maps__fprintf(struct maps *maps, FILE *fp) } } =20 - up_read(&maps->lock); + up_read(maps__lock(maps)); =20 return printed; } @@ -260,9 +269,9 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) struct rb_node *next, *first; int err =3D 0; =20 - down_write(&maps->lock); + down_write(maps__lock(maps)); =20 - root =3D &maps->entries; + root =3D maps__entries(maps); =20 /* * Find first map where end > map->start. @@ -358,7 +367,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) =20 err =3D 0; out: - up_write(&maps->lock); + up_write(maps__lock(maps)); return err; } =20 @@ -371,7 +380,7 @@ int maps__clone(struct thread *thread, struct maps *par= ent) int err; struct map_rb_node *rb_node; =20 - down_read(&parent->lock); + down_read(maps__lock(parent)); =20 maps__for_each_entry(parent, rb_node) { struct map *new =3D map__clone(rb_node->map); @@ -394,7 +403,7 @@ int maps__clone(struct thread *thread, struct maps *par= ent) =20 err =3D 0; out_unlock: - up_read(&parent->lock); + up_read(maps__lock(parent)); return err; } =20 @@ -414,9 +423,9 @@ struct map *maps__find(struct maps *maps, u64 ip) struct rb_node *p; struct map_rb_node *m; =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 - p =3D maps->entries.rb_node; + p =3D maps__entries(maps)->rb_node; while (p !=3D NULL) { m =3D rb_entry(p, struct map_rb_node, rb_node); if (ip < m->map->start) @@ -429,14 +438,14 @@ struct map *maps__find(struct maps *maps, u64 ip) =20 m =3D NULL; out: - up_read(&maps->lock); + up_read(maps__lock(maps)); =20 return m ? m->map : NULL; } =20 struct map_rb_node *maps__first(struct maps *maps) { - struct rb_node *first =3D rb_first(&maps->entries); + struct rb_node *first =3D rb_first(maps__entries(maps)); =20 if (first) return rb_entry(first, struct map_rb_node, rb_node); diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index 512746ec0f9a..bde3390c7096 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -43,7 +43,7 @@ struct maps { unsigned int nr_maps_allocated; #ifdef HAVE_LIBUNWIND_SUPPORT void *addr_space; - struct unwind_libunwind_ops *unwind_libunwind_ops; + const struct unwind_libunwind_ops *unwind_libunwind_ops; #endif }; =20 @@ -58,20 +58,51 @@ struct kmap { struct maps *maps__new(struct machine *machine); void maps__delete(struct maps *maps); bool maps__empty(struct maps *maps); +int maps__clone(struct thread *thread, struct maps *parent); + +struct maps *maps__get(struct maps *maps); +void maps__put(struct maps *maps); =20 -static inline struct maps *maps__get(struct maps *maps) +static inline struct rb_root *maps__entries(struct maps *maps) { - if (maps) - refcount_inc(&maps->refcnt); - return maps; + return &maps->entries; } =20 -void maps__put(struct maps *maps); -int maps__clone(struct thread *thread, struct maps *parent); +static inline struct machine *maps__machine(struct maps *maps) +{ + return maps->machine; +} + +static inline struct rw_semaphore *maps__lock(struct maps *maps) +{ + return &maps->lock; +} + +static inline struct map **maps__maps_by_name(struct maps *maps) +{ + return maps->maps_by_name; +} + +static inline unsigned int maps__nr_maps(const struct maps *maps) +{ + return maps->nr_maps; +} + +#ifdef HAVE_LIBUNWIND_SUPPORT +static inline void *maps__addr_space(struct maps *maps) +{ + return maps->addr_space; +} + +static inline const struct unwind_libunwind_ops *maps__unwind_libunwind_op= s(const struct maps *maps) +{ + return maps->unwind_libunwind_ops; +} +#endif + size_t maps__fprintf(struct maps *maps, FILE *fp); =20 int maps__insert(struct maps *maps, struct map *map); - void maps__remove(struct maps *maps, struct map *map); =20 struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map *= *mapp); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools= /perf/util/scripting-engines/trace-event-python.c index e752e1f4a5f0..0290dc3a6258 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1220,7 +1220,7 @@ static void python_export_sample_table(struct db_expo= rt *dbe, =20 tuple_set_d64(t, 0, es->db_id); tuple_set_d64(t, 1, es->evsel->db_id); - tuple_set_d64(t, 2, es->al->maps->machine->db_id); + tuple_set_d64(t, 2, maps__machine(es->al->maps)->db_id); tuple_set_d64(t, 3, es->al->thread->db_id); tuple_set_d64(t, 4, es->comm_db_id); tuple_set_d64(t, 5, es->dso_db_id); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index cfba8c337783..25686d67ee6f 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -661,7 +661,7 @@ static int hist_entry__cgroup_snprintf(struct hist_entr= y *he, const char *cgrp_name =3D "N/A"; =20 if (he->cgroup) { - struct cgroup *cgrp =3D cgroup__find(he->ms.maps->machine->env, + struct cgroup *cgrp =3D cgroup__find(maps__machine(he->ms.maps)->env, he->cgroup); if (cgrp !=3D NULL) cgrp_name =3D cgrp->name; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 4607c9438866..3ca9a0968345 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1067,7 +1067,7 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, * we still are sure to have a reference to this DSO via * *curr_map->dso. */ - dsos__add(&kmaps->machine->dsos, curr_dso); + dsos__add(&maps__machine(kmaps)->dsos, curr_dso); /* kmaps already got it */ map__put(curr_map); dso__set_loaded(curr_dso); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e8045b1c8700..9b51e669a722 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -249,7 +249,7 @@ void maps__fixup_end(struct maps *maps) { struct map_rb_node *prev =3D NULL, *curr; =20 - down_write(&maps->lock); + down_write(maps__lock(maps)); =20 maps__for_each_entry(maps, curr) { if (prev !=3D NULL && !prev->map->end) @@ -265,7 +265,7 @@ void maps__fixup_end(struct maps *maps) if (curr && !curr->map->end) curr->map->end =3D ~0ULL; =20 - up_write(&maps->lock); + up_write(maps__lock(maps)); } =20 struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const = char *name) @@ -813,7 +813,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, if (!kmaps) return -1; =20 - machine =3D kmaps->machine; + machine =3D maps__machine(kmaps); =20 x86_64 =3D machine__is(machine, "x86_64"); =20 @@ -937,7 +937,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, =20 if (curr_map !=3D initial_map && dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST && - machine__is_default_guest(kmaps->machine)) { + machine__is_default_guest(maps__machine(kmaps))) { dso__set_loaded(curr_map->dso); } =20 @@ -1336,7 +1336,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, if (!kmaps) return -EINVAL; =20 - machine =3D kmaps->machine; + machine =3D maps__machine(kmaps); =20 /* This function requires that the map is the kernel map */ if (!__map__is_kernel(map)) @@ -1851,7 +1851,7 @@ int dso__load(struct dso *dso, struct map *map) else if (dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST) ret =3D dso__load_guest_kernel_sym(dso, map); =20 - machine =3D map__kmaps(map)->machine; + machine =3D maps__machine(map__kmaps(map)); if (machine__is(machine, "x86_64")) machine__map_x86_64_entry_trampolines(machine, dso); goto out; @@ -2006,21 +2006,21 @@ static int map__strcmp_name(const void *name, const= void *b) =20 void __maps__sort_by_name(struct maps *maps) { - qsort(maps->maps_by_name, maps->nr_maps, sizeof(struct map *), map__strcm= p); + qsort(maps__maps_by_name(maps), maps__nr_maps(maps), sizeof(struct map *)= , map__strcmp); } =20 static int map__groups__sort_by_name_from_rbtree(struct maps *maps) { struct map_rb_node *rb_node; - struct map **maps_by_name =3D realloc(maps->maps_by_name, - maps->nr_maps * sizeof(struct map *)); + struct map **maps_by_name =3D realloc(maps__maps_by_name(maps), + maps__nr_maps(maps) * sizeof(struct map *)); int i =3D 0; =20 if (maps_by_name =3D=3D NULL) return -1; =20 maps->maps_by_name =3D maps_by_name; - maps->nr_maps_allocated =3D maps->nr_maps; + maps->nr_maps_allocated =3D maps__nr_maps(maps); =20 maps__for_each_entry(maps, rb_node) maps_by_name[i++] =3D rb_node->map; @@ -2033,11 +2033,12 @@ static struct map *__maps__find_by_name(struct maps= *maps, const char *name) { struct map **mapp; =20 - if (maps->maps_by_name =3D=3D NULL && + if (maps__maps_by_name(maps) =3D=3D NULL && map__groups__sort_by_name_from_rbtree(maps)) return NULL; =20 - mapp =3D bsearch(name, maps->maps_by_name, maps->nr_maps, sizeof(*mapp), = map__strcmp_name); + mapp =3D bsearch(name, maps__maps_by_name(maps), maps__nr_maps(maps), + sizeof(*mapp), map__strcmp_name); if (mapp) return *mapp; return NULL; @@ -2048,9 +2049,10 @@ struct map *maps__find_by_name(struct maps *maps, co= nst char *name) struct map_rb_node *rb_node; struct map *map; =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 - if (maps->last_search_by_name && strcmp(maps->last_search_by_name->dso->s= hort_name, name) =3D=3D 0) { + if (maps->last_search_by_name && + strcmp(maps->last_search_by_name->dso->short_name, name) =3D=3D 0) { map =3D maps->last_search_by_name; goto out_unlock; } @@ -2060,7 +2062,7 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) * made. */ map =3D __maps__find_by_name(maps, name); - if (map || maps->maps_by_name !=3D NULL) + if (map || maps__maps_by_name(maps) !=3D NULL) goto out_unlock; =20 /* Fallback to traversing the rbtree... */ @@ -2074,7 +2076,7 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) map =3D NULL; =20 out_unlock: - up_read(&maps->lock); + up_read(maps__lock(maps)); return map; } =20 @@ -2326,7 +2328,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso= , struct map *map) { int err; const char *kallsyms_filename =3D NULL; - struct machine *machine =3D map__kmaps(map)->machine; + struct machine *machine =3D maps__machine(map__kmaps(map)); char path[PATH_MAX]; =20 if (machine__is_default_guest(machine)) { diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index 1b992bbba4e8..4b85c1728012 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c @@ -155,8 +155,8 @@ static int thread_stack__init(struct thread_stack *ts, = struct thread *thread, ts->br_stack_sz =3D br_stack_sz; } =20 - if (thread->maps && thread->maps->machine) { - struct machine *machine =3D thread->maps->machine; + if (thread->maps && maps__machine(thread->maps)) { + struct machine *machine =3D maps__machine(thread->maps); const char *arch =3D perf_env__arch(machine->env); =20 ts->kernel_start =3D machine__kernel_start(machine); diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 4baf4db8af65..c2256777b813 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -348,7 +348,7 @@ static int __thread__prepare_access(struct thread *thre= ad) struct maps *maps =3D thread->maps; struct map_rb_node *rb_node; =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 maps__for_each_entry(maps, rb_node) { err =3D unwind__prepare_access(thread->maps, rb_node->map, &initialized); @@ -356,7 +356,7 @@ static int __thread__prepare_access(struct thread *thre= ad) break; } =20 - up_read(&maps->lock); + up_read(maps__lock(maps)); =20 return err; } diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unw= ind-libunwind-local.c index 71a353349181..7e6c59811292 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -618,24 +618,26 @@ static unw_accessors_t accessors =3D { =20 static int _unwind__prepare_access(struct maps *maps) { - maps->addr_space =3D unw_create_addr_space(&accessors, 0); - if (!maps->addr_space) { + void *addr_space =3D unw_create_addr_space(&accessors, 0); + + maps->addr_space =3D addr_space; + if (!addr_space) { pr_err("unwind: Can't create unwind address space.\n"); return -ENOMEM; } =20 - unw_set_caching_policy(maps->addr_space, UNW_CACHE_GLOBAL); + unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL); return 0; } =20 static void _unwind__flush_access(struct maps *maps) { - unw_flush_cache(maps->addr_space, 0, 0); + unw_flush_cache(maps__addr_space(maps), 0, 0); } =20 static void _unwind__finish_access(struct maps *maps) { - unw_destroy_addr_space(maps->addr_space); + unw_destroy_addr_space(maps__addr_space(maps)); } =20 static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, @@ -660,7 +662,7 @@ static int get_entries(struct unwind_info *ui, unwind_e= ntry_cb_t cb, */ if (max_stack - 1 > 0) { WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL"); - addr_space =3D ui->thread->maps->addr_space; + addr_space =3D maps__addr_space(ui->thread->maps); =20 if (addr_space =3D=3D NULL) return -1; @@ -709,7 +711,7 @@ static int _unwind__get_entries(unwind_entry_cb_t cb, v= oid *arg, struct unwind_info ui =3D { .sample =3D data, .thread =3D thread, - .machine =3D thread->maps->machine, + .machine =3D maps__machine(thread->maps), }; =20 if (!data->user_regs.regs) diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-li= bunwind.c index e89a5479b361..7b797ffadd19 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -22,12 +22,13 @@ int unwind__prepare_access(struct maps *maps, struct ma= p *map, bool *initialized const char *arch; enum dso_type dso_type; struct unwind_libunwind_ops *ops =3D local_unwind_libunwind_ops; + struct machine *machine; int err; =20 if (!dwarf_callchain_users) return 0; =20 - if (maps->addr_space) { + if (maps__addr_space(maps)) { pr_debug("unwind: thread map already set, dso=3D%s\n", map->dso->name); if (initialized) @@ -35,15 +36,16 @@ int unwind__prepare_access(struct maps *maps, struct ma= p *map, bool *initialized return 0; } =20 + machine =3D maps__machine(maps); /* env->arch is NULL for live-mode (i.e. perf top) */ - if (!maps->machine->env || !maps->machine->env->arch) + if (!machine->env || !machine->env->arch) goto out_register; =20 - dso_type =3D dso__type(map->dso, maps->machine); + dso_type =3D dso__type(map->dso, machine); if (dso_type =3D=3D DSO__TYPE_UNKNOWN) return 0; =20 - arch =3D perf_env__arch(maps->machine->env); + arch =3D perf_env__arch(machine->env); =20 if (!strcmp(arch, "x86")) { if (dso_type !=3D DSO__TYPE_64BIT) @@ -60,7 +62,7 @@ int unwind__prepare_access(struct maps *maps, struct map = *map, bool *initialized out_register: unwind__register_ops(maps, ops); =20 - err =3D maps->unwind_libunwind_ops->prepare_access(maps); + err =3D maps__unwind_libunwind_ops(maps)->prepare_access(maps); if (initialized) *initialized =3D err ? false : true; return err; @@ -68,21 +70,27 @@ int unwind__prepare_access(struct maps *maps, struct ma= p *map, bool *initialized =20 void unwind__flush_access(struct maps *maps) { - if (maps->unwind_libunwind_ops) - maps->unwind_libunwind_ops->flush_access(maps); + const struct unwind_libunwind_ops *ops =3D maps__unwind_libunwind_ops(map= s); + + if (ops) + ops->flush_access(maps); } =20 void unwind__finish_access(struct maps *maps) { - if (maps->unwind_libunwind_ops) - maps->unwind_libunwind_ops->finish_access(maps); + const struct unwind_libunwind_ops *ops =3D maps__unwind_libunwind_ops(map= s); + + if (ops) + ops->finish_access(maps); } =20 int unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct thread *thread, struct perf_sample *data, int max_stack) { - if (thread->maps->unwind_libunwind_ops) - return thread->maps->unwind_libunwind_ops->get_entries(cb, arg, thread, = data, max_stack); + const struct unwind_libunwind_ops *ops =3D maps__unwind_libunwind_ops(thr= ead->maps); + + if (ops) + return ops->get_entries(cb, arg, thread, data, max_stack); return 0; } --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 8E7DBC433F5 for ; Fri, 11 Feb 2022 10:35:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349048AbiBKKfb (ORCPT ); Fri, 11 Feb 2022 05:35:31 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349020AbiBKKfG (ORCPT ); Fri, 11 Feb 2022 05:35:06 -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 05091F06 for ; Fri, 11 Feb 2022 02:34:59 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id t8-20020a259ac8000000b00619a3b5977fso17998848ybo.5 for ; Fri, 11 Feb 2022 02:34:58 -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=FbcuwL3W2wsP1TsIOkKzJAnWKvfNk53YaNpoiTQ+bVg=; b=MlVMGgdPKThtekFIam32DvTXVAKQjGXsYkaY5eFzETZokLkBhSOiAMkirXv8dVf661 W6+QbjBnuIT17rWa+HSVFisUenU0ywBTmlW3WTR1noyW28SCWSq6fXvya3zoF7hkG9Sy bm7F5PcALs+zUemR8B3v/mWziSiCQcrZd6SBDlIbvDaiKNF3LKRccbGUAA7BtC1neojf 86xISO76g4vbA0+wqXJ3uBKEIOTdq3nua69aO5ph7LpjvlQ57Cm3/ViGtJjYLAB72YYs h4INhFYR6aWv3Q49uDba7o75/RGRWIBXusTeh7q+DMTm891DVa5i6OQ7pXrqnS8iodnb aP7Q== 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=FbcuwL3W2wsP1TsIOkKzJAnWKvfNk53YaNpoiTQ+bVg=; b=ITj3jaN3gXYXJ8z8wfCxfTz1q3mnkCwbWYc/rxXbpavWZ6yfo3v0K9DOejCX1mHox2 /4C/wPeUN3yhPiOahIrhLPvTykodzgcobyjIczeWPlXst1aYqOz4pTMxPG8qSaZcSWsu sEcU10o2mm+PxjAyEsR962KnV45BH4+D5PkorxZPMxxbopWSt7kBGXkGow0SEiu8NKWy dF0gonm9l92Mnp/hpy5XBuMAvPzALmrzLLJYoVcWczhzOjEcn5VKGA4truIaD0AvjoPl 3el74rWd6YPskAaWlVZMu1aLqyj5Ukh6pMkG/hJ7klpVwoPCXycAxmfKoUW5wBsOr7DO S87w== X-Gm-Message-State: AOAM531tqrLCkhHZcM2R4egZBsmLiVYrTF/Uax84ypB0PhBqDKqWhABZ 9TVgTWkeEM3QXWU8q4wmByYnLjw1tDQd X-Google-Smtp-Source: ABdhPJzNkM0WjPe0UXFTSPdJfuygwK05rmGK8w2rv7Con/Qg3OM71Q2MoRkKxPQNG0tgU6CiYK+v4fPJgwyX X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:3d81:: with SMTP id k123mr673509yba.740.1644575698179; Fri, 11 Feb 2022 02:34:58 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:08 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-16-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 15/22] perf map: Use functions to access the variables in map 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 , Hao Luo 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" The use of functions enables easier reference count checking. Some minor changes to map_ip and unmap_ip to making the naming a little clearer. __maps_insert is modified to return the inserted map, which simplifies the reference checking wrapping. maps__fixup_overlappings has some minor tweaks so that puts occur on error paths. dso__process_kernel_symbol has the unused curr_mapp argument removed. Signed-off-by: Ian Rogers --- tools/perf/arch/s390/annotate/instructions.c | 4 +- tools/perf/arch/x86/tests/dwarf-unwind.c | 2 +- tools/perf/arch/x86/util/event.c | 6 +- tools/perf/builtin-annotate.c | 8 +- tools/perf/builtin-inject.c | 8 +- tools/perf/builtin-kallsyms.c | 6 +- tools/perf/builtin-kmem.c | 4 +- tools/perf/builtin-mem.c | 4 +- tools/perf/builtin-report.c | 20 +-- tools/perf/builtin-script.c | 26 ++-- tools/perf/builtin-top.c | 12 +- tools/perf/builtin-trace.c | 2 +- .../scripts/python/Perf-Trace-Util/Context.c | 7 +- tools/perf/tests/code-reading.c | 32 ++--- tools/perf/tests/hists_common.c | 4 +- tools/perf/tests/vmlinux-kallsyms.c | 35 +++--- tools/perf/ui/browsers/annotate.c | 7 +- tools/perf/ui/browsers/hists.c | 18 +-- tools/perf/ui/browsers/map.c | 4 +- tools/perf/util/annotate.c | 38 +++--- tools/perf/util/auxtrace.c | 2 +- tools/perf/util/block-info.c | 4 +- tools/perf/util/bpf-event.c | 8 +- tools/perf/util/build-id.c | 2 +- tools/perf/util/callchain.c | 10 +- tools/perf/util/data-convert-json.c | 4 +- tools/perf/util/db-export.c | 4 +- tools/perf/util/dlfilter.c | 21 ++-- tools/perf/util/dso.c | 4 +- tools/perf/util/event.c | 14 +-- tools/perf/util/evsel_fprintf.c | 4 +- tools/perf/util/hist.c | 10 +- tools/perf/util/intel-pt.c | 48 +++---- tools/perf/util/machine.c | 84 +++++++------ tools/perf/util/map.c | 117 +++++++++--------- tools/perf/util/map.h | 58 ++++++++- tools/perf/util/maps.c | 83 +++++++------ tools/perf/util/probe-event.c | 44 +++---- .../util/scripting-engines/trace-event-perl.c | 9 +- .../scripting-engines/trace-event-python.c | 12 +- tools/perf/util/sort.c | 46 +++---- tools/perf/util/symbol-elf.c | 39 +++--- tools/perf/util/symbol.c | 96 +++++++------- tools/perf/util/symbol_fprintf.c | 2 +- tools/perf/util/synthetic-events.c | 28 ++--- tools/perf/util/thread.c | 26 ++-- tools/perf/util/unwind-libunwind-local.c | 34 ++--- tools/perf/util/unwind-libunwind.c | 4 +- tools/perf/util/vdso.c | 2 +- 49 files changed, 577 insertions(+), 489 deletions(-) diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch= /s390/annotate/instructions.c index 0e136630659e..740f1a63bc04 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c @@ -39,7 +39,9 @@ static int s390_call__parse(struct arch *arch, struct ins= _operands *ops, target.addr =3D map__objdump_2mem(map, ops->target.addr); =20 if (maps__find_ams(ms->maps, &target) =3D=3D 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D ops->target.addr) + map__rip_2objdump(target.ms.map, + map->map_ip(target.ms.map, target.addr) + ) =3D=3D ops->target.addr) ops->target.sym =3D target.ms.sym; =20 return 0; diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86= /tests/dwarf-unwind.c index a54dea7c112f..497593be80f2 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -33,7 +33,7 @@ static int sample_ustack(struct perf_sample *sample, return -1; } =20 - stack_size =3D map->end - sp; + stack_size =3D map__end(map) - sp; stack_size =3D stack_size > STACK_SIZE ? STACK_SIZE : stack_size; =20 memcpy(buf, (void *) sp, stack_size); diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/ev= ent.c index 7b6b0c98fb36..c790c682b76e 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -57,9 +57,9 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *= tool, =20 event->mmap.header.size =3D size; =20 - event->mmap.start =3D map->start; - event->mmap.len =3D map->end - map->start; - event->mmap.pgoff =3D map->pgoff; + event->mmap.start =3D map__start(map); + event->mmap.len =3D map__size(map); + event->mmap.pgoff =3D map__pgoff(map); event->mmap.pid =3D machine->pid; =20 strlcpy(event->mmap.filename, kmap->name, PATH_MAX); diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 490bb9b8cf17..49d3ae36fd89 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -199,7 +199,7 @@ static int process_branch_callback(struct evsel *evsel, return 0; =20 if (a.map !=3D NULL) - a.map->dso->hit =3D 1; + map__dso(a.map)->hit =3D 1; =20 hist__account_cycles(sample->branch_stack, al, sample, false, NULL); =20 @@ -231,9 +231,9 @@ static int evsel__add_sample(struct evsel *evsel, struc= t perf_sample *sample, */ if (al->sym !=3D NULL) { rb_erase_cached(&al->sym->rb_node, - &al->map->dso->symbols); + &map__dso(al->map)->symbols); symbol__delete(al->sym); - dso__reset_find_symbol_cache(al->map->dso); + dso__reset_find_symbol_cache(map__dso(al->map)); } return 0; } @@ -315,7 +315,7 @@ static void hists__find_annotations(struct hists *hists, struct hist_entry *he =3D rb_entry(nd, struct hist_entry, rb_node); struct annotation *notes; =20 - if (he->ms.sym =3D=3D NULL || he->ms.map->dso->annotate_warned) + if (he->ms.sym =3D=3D NULL || map__dso(he->ms.map)->annotate_warned) goto find_next; =20 if (ann->sym_hist_filter && diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index f7917c390e96..92a9dbc3d4cd 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -600,10 +600,10 @@ int perf_event__inject_buildid(struct perf_tool *tool= , union perf_event *event, } =20 if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) { - if (!al.map->dso->hit) { - al.map->dso->hit =3D 1; - dso__inject_build_id(al.map->dso, tool, machine, - sample->cpumode, al.map->flags); + if (!map__dso(al.map)->hit) { + map__dso(al.map)->hit =3D 1; + dso__inject_build_id(map__dso(al.map), tool, machine, + sample->cpumode, map__flags(al.map)); } } =20 diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c index c08ee81529e8..d940b60ce812 100644 --- a/tools/perf/builtin-kallsyms.c +++ b/tools/perf/builtin-kallsyms.c @@ -36,8 +36,10 @@ static int __cmd_kallsyms(int argc, const char **argv) } =20 printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n= ", - symbol->name, map->dso->short_name, map->dso->long_name, - map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end), + symbol->name, map__dso(map)->short_name, + map__dso(map)->long_name, + map__unmap_ip(map, symbol->start), + map__unmap_ip(map, symbol->end), symbol->start, symbol->end); } =20 diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 99d7ff9a8eff..d87d9c341a20 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -410,7 +410,7 @@ static u64 find_callsite(struct evsel *evsel, struct pe= rf_sample *sample) if (!caller) { /* found */ if (node->ms.map) - addr =3D map__unmap_ip(node->ms.map, node->ip); + addr =3D map__dso_unmap_ip(node->ms.map, node->ip); else addr =3D node->ip; =20 @@ -1012,7 +1012,7 @@ static void __print_slab_result(struct rb_root *root, =20 if (sym !=3D NULL) snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name, - addr - map->unmap_ip(map, sym->start)); + addr - map__unmap_ip(map, sym->start)); else snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr); printf(" %-34s |", buf); diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index fcf65a59bea2..d18083f57303 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -200,7 +200,7 @@ dump_raw_samples(struct perf_tool *tool, goto out_put; =20 if (al.map !=3D NULL) - al.map->dso->hit =3D 1; + map__dso(al.map)->hit =3D 1; =20 field_sep =3D symbol_conf.field_sep; if (field_sep) { @@ -241,7 +241,7 @@ dump_raw_samples(struct perf_tool *tool, symbol_conf.field_sep, sample->data_src, symbol_conf.field_sep, - al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", + al.map && map__dso(al.map) ? map__dso(al.map)->long_name : "???", al.sym ? al.sym->name : "???"); out_put: addr_location__put(&al); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 57611ef725c3..9b92b2bbd7de 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -304,7 +304,7 @@ static int process_sample_event(struct perf_tool *tool, } =20 if (al.map !=3D NULL) - al.map->dso->hit =3D 1; + map__dso(al.map)->hit =3D 1; =20 if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) { hist__account_cycles(sample->branch_stack, &al, sample, @@ -579,7 +579,7 @@ static void report__warn_kptr_restrict(const struct rep= ort *rep) return; =20 if (kernel_map =3D=3D NULL || - (kernel_map->dso->hit && + (map__dso(kernel_map)->hit && (kernel_kmap->ref_reloc_sym =3D=3D NULL || kernel_kmap->ref_reloc_sym->addr =3D=3D 0))) { const char *desc =3D @@ -805,13 +805,15 @@ static size_t maps__fprintf_task(struct maps *maps, i= nt indent, FILE *fp) struct map *map =3D rb_node->map; =20 printed +=3D fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRI= x64 " %" PRIu64 " %s\n", - indent, "", map->start, map->end, - map->prot & PROT_READ ? 'r' : '-', - map->prot & PROT_WRITE ? 'w' : '-', - map->prot & PROT_EXEC ? 'x' : '-', - map->flags & MAP_SHARED ? 's' : 'p', - map->pgoff, - map->dso->id.ino, map->dso->name); + indent, "", + map__start(map), map__end(map), + map__prot(map) & PROT_READ ? 'r' : '-', + map__prot(map) & PROT_WRITE ? 'w' : '-', + map__prot(map) & PROT_EXEC ? 'x' : '-', + map__flags(map) & MAP_SHARED ? 's' : 'p', + map__pgoff(map), + map__dso(map)->id.ino, + map__dso(map)->name); } =20 return printed; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index abae8184e171..4edfce95e137 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -972,12 +972,12 @@ static int perf_sample__fprintf_brstackoff(struct per= f_sample *sample, to =3D entries[i].to; =20 if (thread__find_map_fb(thread, sample->cpumode, from, &alf) && - !alf.map->dso->adjust_symbols) - from =3D map__map_ip(alf.map, from); + !map__dso(alf.map)->adjust_symbols) + from =3D map__dso_map_ip(alf.map, from); =20 if (thread__find_map_fb(thread, sample->cpumode, to, &alt) && - !alt.map->dso->adjust_symbols) - to =3D map__map_ip(alt.map, to); + !map__dso(alt.map)->adjust_symbols) + to =3D map__dso_map_ip(alt.map, to); =20 printed +=3D fprintf(fp, " 0x%"PRIx64, from); if (PRINT_FIELD(DSO)) { @@ -1039,11 +1039,11 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, return 0; } =20 - if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) { + if (!thread__find_map(thread, *cpumode, start, &al) || !map__dso(al.map))= { pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); return 0; } - if (al.map->dso->data.status =3D=3D DSO_DATA_STATUS_ERROR) { + if (map__dso(al.map)->data.status =3D=3D DSO_DATA_STATUS_ERROR) { pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); return 0; } @@ -1051,11 +1051,11 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, /* Load maps to ensure dso->is_64_bit has been updated */ map__load(al.map); =20 - offset =3D al.map->map_ip(al.map, start); - len =3D dso__data_read_offset(al.map->dso, machine, offset, (u8 *)buffer, - end - start + MAXINSN); + offset =3D map__map_ip(al.map, start); + len =3D dso__data_read_offset(map__dso(al.map), machine, offset, + (u8 *)buffer, end - start + MAXINSN); =20 - *is64bit =3D al.map->dso->is_64_bit; + *is64bit =3D map__dso(al.map)->is_64_bit; if (len <=3D 0) pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n", start, end); @@ -1070,9 +1070,9 @@ static int map__fprintf_srccode(struct map *map, u64 = addr, FILE *fp, struct srcc int len; char *srccode; =20 - if (!map || !map->dso) + if (!map || !map__dso(map)) return 0; - srcfile =3D get_srcline_split(map->dso, + srcfile =3D get_srcline_split(map__dso(map), map__rip_2objdump(map, addr), &line); if (!srcfile) @@ -1164,7 +1164,7 @@ static int ip__fprintf_sym(uint64_t addr, struct thre= ad *thread, if (al.addr < al.sym->end) off =3D al.addr - al.sym->start; else - off =3D al.addr - al.map->start - al.sym->start; + off =3D al.addr - map__start(al.map) - al.sym->start; printed +=3D fprintf(fp, "\t%s", al.sym->name); if (off) printed +=3D fprintf(fp, "%+d", off); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 1fc390f136dd..8db1df7bdabe 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -127,8 +127,8 @@ static int perf_top__parse_source(struct perf_top *top,= struct hist_entry *he) /* * We can't annotate with just /proc/kallsyms */ - if (map->dso->symtab_type =3D=3D DSO_BINARY_TYPE__KALLSYMS && - !dso__is_kcore(map->dso)) { + if (map__dso(map)->symtab_type =3D=3D DSO_BINARY_TYPE__KALLSYMS && + !dso__is_kcore(map__dso(map))) { pr_err("Can't annotate %s: No vmlinux file was found in the " "path\n", sym->name); sleep(1); @@ -180,8 +180,9 @@ static void ui__warn_map_erange(struct map *map, struct= symbol *sym, u64 ip) "Tools: %s\n\n" "Not all samples will be on the annotation output.\n\n" "Please report to linux-kernel@vger.kernel.org\n", - ip, map->dso->long_name, dso__symtab_origin(map->dso), - map->start, map->end, sym->start, sym->end, + ip, map__dso(map)->long_name, + dso__symtab_origin(map__dso(map)), + map__start(map), map__end(map), sym->start, sym->end, sym->binding =3D=3D STB_GLOBAL ? 'g' : sym->binding =3D=3D STB_LOCAL ? 'l' : 'w', sym->name, err ? "[unknown]" : uts.machine, @@ -810,7 +811,8 @@ static void perf_event__process_sample(struct perf_tool= *tool, __map__is_kernel(al.map) && map__has_symbols(al.map)) { if (symbol_conf.vmlinux_name) { char serr[256]; - dso__strerror_load(al.map->dso, serr, sizeof(serr)); + dso__strerror_load(map__dso(al.map), + serr, sizeof(serr)); ui__warning("The %s file can't be used: %s\n%s", symbol_conf.vmlinux_name, serr, msg); } else { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 32844d8a0ea5..0134f24da3e3 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2862,7 +2862,7 @@ static void print_location(FILE *f, struct perf_sampl= e *sample, { =20 if ((verbose > 0 || print_dso) && al->map) - fprintf(f, "%s@", al->map->dso->long_name); + fprintf(f, "%s@", map__dso(al->map)->long_name); =20 if ((verbose > 0 || print_sym) && al->sym) fprintf(f, "%s+0x%" PRIx64, al->sym->name, diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/pe= rf/scripts/python/Perf-Trace-Util/Context.c index b64013a87c54..b83b62d33945 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c @@ -152,9 +152,10 @@ static PyObject *perf_sample_src(PyObject *obj, PyObje= ct *args, bool get_srccode map =3D c->al->map; addr =3D c->al->addr; =20 - if (map && map->dso) - srcfile =3D get_srcline_split(map->dso, map__rip_2objdump(map, addr), &l= ine); - + if (map && map__dso(map)) { + srcfile =3D get_srcline_split(map__dso(map), + map__rip_2objdump(map, addr), &line); + } if (get_srccode) { if (srcfile) srccode =3D find_sourceline(srcfile, line, &len); diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index 6eafe36a8704..9cb7d3f577d7 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -240,7 +240,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, =20 pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); =20 - if (!thread__find_map(thread, cpumode, addr, &al) || !al.map->dso) { + if (!thread__find_map(thread, cpumode, addr, &al) || !map__dso(al.map)) { if (cpumode =3D=3D PERF_RECORD_MISC_HYPERVISOR) { pr_debug("Hypervisor address can not be resolved - skipping\n"); return 0; @@ -250,10 +250,10 @@ static int read_object_code(u64 addr, size_t len, u8 = cpumode, return -1; } =20 - pr_debug("File is: %s\n", al.map->dso->long_name); + pr_debug("File is: %s\n", map__dso(al.map)->long_name); =20 - if (al.map->dso->symtab_type =3D=3D DSO_BINARY_TYPE__KALLSYMS && - !dso__is_kcore(al.map->dso)) { + if (map__dso(al.map)->symtab_type =3D=3D DSO_BINARY_TYPE__KALLSYMS && + !dso__is_kcore(map__dso(al.map))) { pr_debug("Unexpected kernel address - skipping\n"); return 0; } @@ -264,11 +264,11 @@ static int read_object_code(u64 addr, size_t len, u8 = cpumode, len =3D BUFSZ; =20 /* Do not go off the map */ - if (addr + len > al.map->end) - len =3D al.map->end - addr; + if (addr + len > map__end(al.map)) + len =3D map__end(al.map) - addr; =20 /* Read the object code using perf */ - ret_len =3D dso__data_read_offset(al.map->dso, maps__machine(thread->maps= ), + ret_len =3D dso__data_read_offset(map__dso(al.map), maps__machine(thread-= >maps), al.addr, buf1, len); if (ret_len !=3D len) { pr_debug("dso__data_read_offset failed\n"); @@ -283,11 +283,11 @@ static int read_object_code(u64 addr, size_t len, u8 = cpumode, return -1; =20 /* objdump struggles with kcore - try each map only once */ - if (dso__is_kcore(al.map->dso)) { + if (dso__is_kcore(map__dso(al.map))) { size_t d; =20 for (d =3D 0; d < state->done_cnt; d++) { - if (state->done[d] =3D=3D al.map->start) { + if (state->done[d] =3D=3D map__start(al.map)) { pr_debug("kcore map tested already"); pr_debug(" - skipping\n"); return 0; @@ -297,12 +297,12 @@ static int read_object_code(u64 addr, size_t len, u8 = cpumode, pr_debug("Too many kcore maps - skipping\n"); return 0; } - state->done[state->done_cnt++] =3D al.map->start; + state->done[state->done_cnt++] =3D map__start(al.map); } =20 - objdump_name =3D al.map->dso->long_name; - if (dso__needs_decompress(al.map->dso)) { - if (dso__decompress_kmodule_path(al.map->dso, objdump_name, + objdump_name =3D map__dso(al.map)->long_name; + if (dso__needs_decompress(map__dso(al.map))) { + if (dso__decompress_kmodule_path(map__dso(al.map), objdump_name, decomp_name, sizeof(decomp_name)) < 0) { pr_debug("decompression failed\n"); @@ -330,7 +330,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, len -=3D ret; if (len) { pr_debug("Reducing len to %zu\n", len); - } else if (dso__is_kcore(al.map->dso)) { + } else if (dso__is_kcore(map__dso(al.map))) { /* * objdump cannot handle very large segments * that may be found in kcore. @@ -588,8 +588,8 @@ static int do_test_code_reading(bool try_kcore) pr_debug("map__load failed\n"); goto out_err; } - have_vmlinux =3D dso__is_vmlinux(map->dso); - have_kcore =3D dso__is_kcore(map->dso); + have_vmlinux =3D dso__is_vmlinux(map__dso(map)); + have_kcore =3D dso__is_kcore(map__dso(map)); =20 /* 2nd time through we just try kcore */ if (try_kcore && !have_kcore) diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_commo= n.c index 6f34d08b84e5..40eccc659767 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -181,7 +181,7 @@ void print_hists_in(struct hists *hists) if (!he->filtered) { pr_info("%2d: entry: %-8s [%-8s] %20s: period =3D %"PRIu64"\n", i, thread__comm_str(he->thread), - he->ms.map->dso->short_name, + map__dso(he->ms.map)->short_name, he->ms.sym->name, he->stat.period); } =20 @@ -208,7 +208,7 @@ void print_hists_out(struct hists *hists) if (!he->filtered) { pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period =3D %"PRIu64"/%"PRIu64= "\n", i, thread__comm_str(he->thread), he->thread->tid, - he->ms.map->dso->short_name, + map__dso(he->ms.map)->short_name, he->ms.sym->name, he->stat.period, he->stat_acc ? he->stat_acc->period : 0); } diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index 11a230ee5894..5afab21455f1 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -13,7 +13,7 @@ #include "debug.h" #include "machine.h" =20 -#define UM(x) kallsyms_map->unmap_ip(kallsyms_map, (x)) +#define UM(x) map__unmap_ip(kallsyms_map, (x)) =20 static bool is_ignored_symbol(const char *name, char type) { @@ -216,8 +216,8 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused if (sym->start =3D=3D sym->end) continue; =20 - mem_start =3D vmlinux_map->unmap_ip(vmlinux_map, sym->start); - mem_end =3D vmlinux_map->unmap_ip(vmlinux_map, sym->end); + mem_start =3D map__unmap_ip(vmlinux_map, sym->start); + mem_end =3D map__unmap_ip(vmlinux_map, sym->end); =20 first_pair =3D machine__find_kernel_symbol(&kallsyms, mem_start, NULL); pair =3D first_pair; @@ -262,7 +262,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused =20 continue; } - } else if (mem_start =3D=3D kallsyms.vmlinux_map->end) { + } else if (mem_start =3D=3D map__end(kallsyms.vmlinux_map)) { /* * Ignore aliases to _etext, i.e. to the end of the kernel text area, * such as __indirect_thunk_end. @@ -294,9 +294,10 @@ static int test__vmlinux_matches_kallsyms(struct test_= suite *test __maybe_unused * so use the short name, less descriptive but the same ("[kernel]" in * both cases. */ - struct map *pair =3D maps__find_by_name(kallsyms.kmaps, (map->dso->kerne= l ? - map->dso->short_name : - map->dso->name)); + struct map *pair =3D maps__find_by_name(kallsyms.kmaps, + map__dso(map)->kernel + ? map__dso(map)->short_name + : map__dso(map)->name); if (pair) { pair->priv =3D 1; } else { @@ -313,25 +314,27 @@ static int test__vmlinux_matches_kallsyms(struct test= _suite *test __maybe_unused maps__for_each_entry(maps, rb_node) { struct map *pair, *map =3D rb_node->map; =20 - mem_start =3D vmlinux_map->unmap_ip(vmlinux_map, map->start); - mem_end =3D vmlinux_map->unmap_ip(vmlinux_map, map->end); + mem_start =3D map__unmap_ip(vmlinux_map, map__start(map)); + mem_end =3D map__unmap_ip(vmlinux_map, map__end(map)); =20 pair =3D maps__find(kallsyms.kmaps, mem_start); - if (pair =3D=3D NULL || pair->priv) + if (pair =3D=3D NULL || map__priv(pair)) continue; =20 - if (pair->start =3D=3D mem_start) { + if (map__start(pair) =3D=3D mem_start) { if (!header_printed) { pr_info("WARN: Maps in vmlinux with a different name in kallsyms:\n"); header_printed =3D true; } =20 pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", - map->start, map->end, map->pgoff, map->dso->name); - if (mem_end !=3D pair->end) + map__start(map), map__end(map), + map__pgoff(map), map__dso(map)->name); + if (mem_end !=3D map__end(pair)) pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, - pair->start, pair->end, pair->pgoff); - pr_info(" %s\n", pair->dso->name); + map__start(pair), map__end(pair), + map__pgoff(pair)); + pr_info(" %s\n", map__dso(pair)->name); pair->priv =3D 1; } } @@ -343,7 +346,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused maps__for_each_entry(maps, rb_node) { struct map *map =3D rb_node->map; =20 - if (!map->priv) { + if (!map__priv(map)) { if (!header_printed) { pr_info("WARN: Maps only in kallsyms:\n"); header_printed =3D true; diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/ann= otate.c index 44ba900828f6..7d51d92302dc 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -446,7 +446,8 @@ static void ui_browser__init_asm_mode(struct ui_browser= *browser) static int sym_title(struct symbol *sym, struct map *map, char *title, size_t sz, int percent_type) { - return snprintf(title, sz, "%s %s [Percent: %s]", sym->name, map->dso->l= ong_name, + return snprintf(title, sz, "%s %s [Percent: %s]", sym->name, + map__dso(map)->long_name, percent_type_str(percent_type)); } =20 @@ -971,14 +972,14 @@ int symbol__tui_annotate(struct map_symbol *ms, struc= t evsel *evsel, if (sym =3D=3D NULL) return -1; =20 - if (ms->map->dso->annotate_warned) + if (map__dso(ms->map)->annotate_warned) return -1; =20 if (not_annotated) { err =3D symbol__annotate2(ms, evsel, opts, &browser.arch); if (err) { char msg[BUFSIZ]; - ms->map->dso->annotate_warned =3D true; + map__dso(ms->map)->annotate_warned =3D true; symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s:\n%s", sym->name, msg); goto out_free_offsets; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 572ff38ceb0f..2241447e9bfb 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2487,7 +2487,7 @@ static struct symbol *symbol__new_unresolved(u64 addr= , struct map *map) return NULL; } =20 - dso__insert_symbol(map->dso, sym); + dso__insert_symbol(map__dso(map), sym); } =20 return sym; @@ -2499,7 +2499,7 @@ add_annotate_opt(struct hist_browser *browser __maybe= _unused, struct map_symbol *ms, u64 addr) { - if (!ms->map || !ms->map->dso || ms->map->dso->annotate_warned) + if (!ms->map || !map__dso(ms->map) || map__dso(ms->map)->annotate_warned) return 0; =20 if (!ms->sym) @@ -2590,8 +2590,10 @@ static int hists_browser__zoom_map(struct hist_brows= er *browser, struct map *map ui_helpline__pop(); } else { ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DS= O\"", - __map__is_kernel(map) ? "the Kernel" : map->dso->short_name); - browser->hists->dso_filter =3D map->dso; + __map__is_kernel(map) + ? "the Kernel" + : map__dso(map)->short_name); + browser->hists->dso_filter =3D map__dso(map); perf_hpp__set_elide(HISTC_DSO, true); pstack__push(browser->pstack, &browser->hists->dso_filter); } @@ -2616,7 +2618,9 @@ add_dso_opt(struct hist_browser *browser, struct popu= p_action *act, =20 if (asprintf(optstr, "Zoom %s %s DSO (use the 'k' hotkey to zoom directly= into the kernel)", browser->hists->dso_filter ? "out of" : "into", - __map__is_kernel(map) ? "the Kernel" : map->dso->short_name) < 0) + __map__is_kernel(map) + ? "the Kernel" + : map__dso(map)->short_name) < 0) return 0; =20 act->ms.map =3D map; @@ -3091,8 +3095,8 @@ static int evsel__hists_browse(struct evsel *evsel, i= nt nr_events, const char *h =20 if (!browser->selection || !browser->selection->map || - !browser->selection->map->dso || - browser->selection->map->dso->annotate_warned) { + !map__dso(browser->selection->map) || + map__dso(browser->selection->map)->annotate_warned) { continue; } =20 diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 3d49b916c9e4..3d1b958d8832 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -76,7 +76,7 @@ static int map_browser__run(struct map_browser *browser) { int key; =20 - if (ui_browser__show(&browser->b, browser->map->dso->long_name, + if (ui_browser__show(&browser->b, map__dso(browser->map)->long_name, "Press ESC to exit, %s / to search", verbose > 0 ? "" : "restart with -v to use") < 0) return -1; @@ -106,7 +106,7 @@ int map__browse(struct map *map) { struct map_browser mb =3D { .b =3D { - .entries =3D &map->dso->symbols, + .entries =3D &map__dso(map)->symbols, .refresh =3D ui_browser__rb_tree_refresh, .seek =3D ui_browser__rb_tree_seek, .write =3D map_browser__write, diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 01900689dc00..3a7433d3e48a 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -280,7 +280,9 @@ static int call__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s target.addr =3D map__objdump_2mem(map, ops->target.addr); =20 if (maps__find_ams(ms->maps, &target) =3D=3D 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D ops->target.addr) + map__rip_2objdump(target.ms.map, + map->map_ip(target.ms.map, target.addr) + ) =3D=3D ops->target.addr) ops->target.sym =3D target.ms.sym; =20 return 0; @@ -384,8 +386,8 @@ static int jump__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s } =20 target.addr =3D map__objdump_2mem(map, ops->target.addr); - start =3D map->unmap_ip(map, sym->start), - end =3D map->unmap_ip(map, sym->end); + start =3D map__unmap_ip(map, sym->start), + end =3D map__unmap_ip(map, sym->end); =20 ops->target.outside =3D target.addr < start || target.addr > end; =20 @@ -408,7 +410,9 @@ static int jump__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s * the symbol searching and disassembly should be done. */ if (maps__find_ams(ms->maps, &target) =3D=3D 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D ops->target.addr) + map__rip_2objdump(target.ms.map, + map->map_ip(target.ms.map, target.addr) + ) =3D=3D ops->target.addr) ops->target.sym =3D target.ms.sym; =20 if (!ops->target.outside) { @@ -889,7 +893,7 @@ static int __symbol__inc_addr_samples(struct map_symbol= *ms, unsigned offset; struct sym_hist *h; =20 - pr_debug3("%s: addr=3D%#" PRIx64 "\n", __func__, ms->map->unmap_ip(ms->ma= p, addr)); + pr_debug3("%s: addr=3D%#" PRIx64 "\n", __func__, map__unmap_ip(ms->map, a= ddr)); =20 if ((addr < sym->start || addr >=3D sym->end) && (addr !=3D sym->end || sym->start !=3D sym->end)) { @@ -1016,13 +1020,13 @@ int addr_map_symbol__account_cycles(struct addr_map= _symbol *ams, if (start && (start->ms.sym =3D=3D ams->ms.sym || (ams->ms.sym && - start->addr =3D=3D ams->ms.sym->start + ams->ms.map->start))) + start->addr =3D=3D ams->ms.sym->start + map__start(ams->ms.map)))) saddr =3D start->al_addr; if (saddr =3D=3D 0) pr_debug2("BB with bad start: addr %"PRIx64" start %"PRIx64" sym %"PRIx6= 4" saddr %"PRIx64"\n", ams->addr, start ? start->addr : 0, - ams->ms.sym ? ams->ms.sym->start + ams->ms.map->start : 0, + ams->ms.sym ? ams->ms.sym->start + map__start(ams->ms.map) : 0, saddr); err =3D symbol__account_cycles(ams->al_addr, saddr, ams->ms.sym, cycles); if (err) @@ -1593,7 +1597,7 @@ static void delete_last_nop(struct symbol *sym) =20 int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *= buf, size_t buflen) { - struct dso *dso =3D ms->map->dso; + struct dso *dso =3D map__dso(ms->map); =20 BUG_ON(buflen =3D=3D 0); =20 @@ -1723,7 +1727,7 @@ static int symbol__disassemble_bpf(struct symbol *sym, struct map *map =3D args->ms.map; struct perf_bpil *info_linear; struct disassemble_info info; - struct dso *dso =3D map->dso; + struct dso *dso =3D map__dso(map); int pc =3D 0, count, sub_id; struct btf *btf =3D NULL; char tpath[PATH_MAX]; @@ -1946,7 +1950,7 @@ static int symbol__disassemble(struct symbol *sym, st= ruct annotate_args *args) { struct annotation_options *opts =3D args->options; struct map *map =3D args->ms.map; - struct dso *dso =3D map->dso; + struct dso *dso =3D map__dso(map); char *command; FILE *file; char symfs_filename[PATH_MAX]; @@ -1973,8 +1977,8 @@ static int symbol__disassemble(struct symbol *sym, st= ruct annotate_args *args) return err; =20 pr_debug("%s: filename=3D%s, sym=3D%s, start=3D%#" PRIx64 ", end=3D%#" PR= Ix64 "\n", __func__, - symfs_filename, sym->name, map->unmap_ip(map, sym->start), - map->unmap_ip(map, sym->end)); + symfs_filename, sym->name, map__unmap_ip(map, sym->start), + map__unmap_ip(map, sym->end)); =20 pr_debug("annotating [%p] %30s : [%p] %30s\n", dso, dso->long_name, sym, sym->name); @@ -2386,7 +2390,7 @@ int symbol__annotate_printf(struct map_symbol *ms, st= ruct evsel *evsel, { struct map *map =3D ms->map; struct symbol *sym =3D ms->sym; - struct dso *dso =3D map->dso; + struct dso *dso =3D map__dso(map); char *filename; const char *d_filename; const char *evsel_name =3D evsel__name(evsel); @@ -2569,7 +2573,7 @@ int map_symbol__annotation_dump(struct map_symbol *ms= , struct evsel *evsel, } =20 fprintf(fp, "%s() %s\nEvent: %s\n\n", - ms->sym->name, ms->map->dso->long_name, ev_name); + ms->sym->name, map__dso(ms->map)->long_name, ev_name); symbol__annotate_fprintf2(ms->sym, fp, opts); =20 fclose(fp); @@ -2781,7 +2785,7 @@ static void annotation__calc_lines(struct annotation = *notes, struct map *map, if (percent_max <=3D 0.5) continue; =20 - al->path =3D get_srcline(map->dso, notes->start + al->offset, NULL, + al->path =3D get_srcline(map__dso(map), notes->start + al->offset, NULL, false, true, notes->start + al->offset); insert_source_line(&tmp_root, al, opts); } @@ -2800,7 +2804,7 @@ static void symbol__calc_lines(struct map_symbol *ms,= struct rb_root *root, int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts) { - struct dso *dso =3D ms->map->dso; + struct dso *dso =3D map__dso(ms->map); struct symbol *sym =3D ms->sym; struct rb_root source_line =3D RB_ROOT; struct hists *hists =3D evsel__hists(evsel); @@ -2836,7 +2840,7 @@ int symbol__tty_annotate2(struct map_symbol *ms, stru= ct evsel *evsel, int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts) { - struct dso *dso =3D ms->map->dso; + struct dso *dso =3D map__dso(ms->map); struct symbol *sym =3D ms->sym; struct rb_root source_line =3D RB_ROOT; int err; diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 825336304a37..2e864c9bdef3 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -2478,7 +2478,7 @@ static struct dso *load_dso(const char *name) if (map__load(map) < 0) pr_err("File '%s' not found or has no symbols.\n", name); =20 - dso =3D dso__get(map->dso); + dso =3D dso__get(map__dso(map)); =20 map__put(map); =20 diff --git a/tools/perf/util/block-info.c b/tools/perf/util/block-info.c index 5ecd4f401f32..16a7b4adcf18 100644 --- a/tools/perf/util/block-info.c +++ b/tools/perf/util/block-info.c @@ -317,9 +317,9 @@ static int block_dso_entry(struct perf_hpp_fmt *fmt, st= ruct perf_hpp *hpp, struct block_fmt *block_fmt =3D container_of(fmt, struct block_fmt, fmt); struct map *map =3D he->ms.map; =20 - if (map && map->dso) { + if (map && map__dso(map)) { return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, - map->dso->short_name); + map__dso(map)->short_name); } =20 return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 33257b594a71..5717933be116 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -95,10 +95,10 @@ static int machine__process_bpf_event_load(struct machi= ne *machine, struct map *map =3D maps__find(machine__kernel_maps(machine), addr); =20 if (map) { - map->dso->binary_type =3D DSO_BINARY_TYPE__BPF_PROG_INFO; - map->dso->bpf_prog.id =3D id; - map->dso->bpf_prog.sub_id =3D i; - map->dso->bpf_prog.env =3D env; + map__dso(map)->binary_type =3D DSO_BINARY_TYPE__BPF_PROG_INFO; + map__dso(map)->bpf_prog.id =3D id; + map__dso(map)->bpf_prog.sub_id =3D i; + map__dso(map)->bpf_prog.env =3D env; } } return 0; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 7a5821c87f94..274b705dd941 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -59,7 +59,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe= _unused, } =20 if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) - al.map->dso->hit =3D 1; + map__dso(al.map)->hit =3D 1; =20 thread__put(thread); return 0; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 61bb3fb2107a..a8cfd31a3ff0 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -695,8 +695,8 @@ static enum match_result match_chain_strings(const char= *left, static enum match_result match_chain_dso_addresses(struct map *left_map, u= 64 left_ip, struct map *right_map, u64 right_ip) { - struct dso *left_dso =3D left_map ? left_map->dso : NULL; - struct dso *right_dso =3D right_map ? right_map->dso : NULL; + struct dso *left_dso =3D left_map ? map__dso(left_map) : NULL; + struct dso *right_dso =3D right_map ? map__dso(right_map) : NULL; =20 if (left_dso !=3D right_dso) return left_dso < right_dso ? MATCH_LT : MATCH_GT; @@ -1167,9 +1167,9 @@ char *callchain_list__sym_name(struct callchain_list = *cl, =20 if (show_dso) scnprintf(bf + printed, bfsize - printed, " %s", - cl->ms.map ? - cl->ms.map->dso->short_name : - "unknown"); + cl->ms.map + ? map__dso(cl->ms.map)->short_name + : "unknown"); =20 return bf; } diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-con= vert-json.c index f1ab6edba446..9c83228bb9f1 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -127,8 +127,8 @@ static void output_sample_callchain_entry(struct perf_t= ool *tool, fputc(',', out); output_json_key_string(out, false, 5, "symbol", al->sym->name); =20 - if (al->map && al->map->dso) { - const char *dso =3D al->map->dso->short_name; + if (al->map && map__dso(al->map)) { + const char *dso =3D map__dso(al->map)->short_name; =20 if (dso && strlen(dso) > 0) { fputc(',', out); diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index 1cfcfdd3cf52..84c970c11794 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -179,7 +179,7 @@ static int db_ids_from_al(struct db_export *dbe, struct= addr_location *al, int err; =20 if (al->map) { - struct dso *dso =3D al->map->dso; + struct dso *dso =3D map__dso(al->map); =20 err =3D db_export__dso(dbe, dso, maps__machine(al->maps)); if (err) @@ -255,7 +255,7 @@ static struct call_path *call_path_from_sample(struct d= b_export *dbe, al.addr =3D node->ip; =20 if (al.map && !al.sym) - al.sym =3D dso__find_symbol(al.map->dso, al.addr); + al.sym =3D dso__find_symbol(map__dso(al.map), al.addr); =20 db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset); =20 diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index d59462af15f1..f1d9dd7065e6 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -29,7 +29,7 @@ static void al_to_d_al(struct addr_location *al, struct p= erf_dlfilter_al *d_al) =20 d_al->size =3D sizeof(*d_al); if (al->map) { - struct dso *dso =3D al->map->dso; + struct dso *dso =3D map__dso(al->map); =20 if (symbol_conf.show_kernel_path && dso->long_name) d_al->dso =3D dso->long_name; @@ -51,7 +51,7 @@ static void al_to_d_al(struct addr_location *al, struct p= erf_dlfilter_al *d_al) if (al->addr < sym->end) d_al->symoff =3D al->addr - sym->start; else - d_al->symoff =3D al->addr - al->map->start - sym->start; + d_al->symoff =3D al->addr - map__start(al->map) - sym->start; d_al->sym_binding =3D sym->binding; } else { d_al->sym =3D NULL; @@ -232,9 +232,10 @@ static const char *dlfilter__srcline(void *ctx, __u32 = *line_no) map =3D al->map; addr =3D al->addr; =20 - if (map && map->dso) - srcfile =3D get_srcline_split(map->dso, map__rip_2objdump(map, addr), &l= ine); - + if (map && map__dso(map)) { + srcfile =3D get_srcline_split(map__dso(map), + map__rip_2objdump(map, addr), &line); + } *line_no =3D line; return srcfile; } @@ -266,7 +267,7 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip,= void *buf, __u32 len) =20 map =3D al->map; =20 - if (map && ip >=3D map->start && ip < map->end && + if (map && ip >=3D map__start(map) && ip < map__end(map) && machine__kernel_ip(d->machine, ip) =3D=3D machine__kernel_ip(d->machi= ne, d->sample->ip)) goto have_map; =20 @@ -276,10 +277,10 @@ static __s32 dlfilter__object_code(void *ctx, __u64 i= p, void *buf, __u32 len) =20 map =3D a.map; have_map: - offset =3D map->map_ip(map, ip); - if (ip + len >=3D map->end) - len =3D map->end - ip; - return dso__data_read_offset(map->dso, d->machine, offset, buf, len); + offset =3D map__map_ip(map, ip); + if (ip + len >=3D map__end(map)) + len =3D map__end(map) - ip; + return dso__data_read_offset(map__dso(map), d->machine, offset, buf, len); } =20 static const struct perf_dlfilter_fns perf_dlfilter_fns =3D { diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index b2f570adba35..1115bc51a261 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1109,7 +1109,7 @@ ssize_t dso__data_read_addr(struct dso *dso, struct m= ap *map, struct machine *machine, u64 addr, u8 *data, ssize_t size) { - u64 offset =3D map->map_ip(map, addr); + u64 offset =3D map__map_ip(map, addr); return dso__data_read_offset(dso, machine, offset, data, size); } =20 @@ -1149,7 +1149,7 @@ ssize_t dso__data_write_cache_addr(struct dso *dso, s= truct map *map, struct machine *machine, u64 addr, const u8 *data, ssize_t size) { - u64 offset =3D map->map_ip(map, addr); + u64 offset =3D map__map_ip(map, addr); return dso__data_write_cache_offs(dso, machine, offset, data, size); } =20 diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 40a3b1a35613..54a1d4df5f70 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -486,7 +486,7 @@ size_t perf_event__fprintf_text_poke(union perf_event *= event, struct machine *ma =20 al.map =3D maps__find(machine__kernel_maps(machine), tp->addr); if (al.map && map__load(al.map) >=3D 0) { - al.addr =3D al.map->map_ip(al.map, tp->addr); + al.addr =3D map__map_ip(al.map, tp->addr); al.sym =3D map__find_symbol(al.map, al.addr); if (al.sym) ret +=3D symbol__fprintf_symname_offs(al.sym, &al, fp); @@ -621,7 +621,7 @@ struct map *thread__find_map(struct thread *thread, u8 = cpumode, u64 addr, */ if (load_map) map__load(al->map); - al->addr =3D al->map->map_ip(al->map, al->addr); + al->addr =3D map__map_ip(al->map, al->addr); } =20 return al->map; @@ -692,8 +692,8 @@ int machine__resolve(struct machine *machine, struct ad= dr_location *al, dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid= ); thread__find_map(thread, sample->cpumode, sample->ip, al); dump_printf(" ...... dso: %s\n", - al->map ? al->map->dso->long_name : - al->level =3D=3D 'H' ? "[hypervisor]" : ""); + al->map ? map__dso(al->map)->long_name + : al->level =3D=3D 'H' ? "[hypervisor]" : ""); =20 if (thread__is_filtered(thread)) al->filtered |=3D (1 << HIST_FILTER__THREAD); @@ -711,7 +711,7 @@ int machine__resolve(struct machine *machine, struct ad= dr_location *al, } =20 if (al->map) { - struct dso *dso =3D al->map->dso; + struct dso *dso =3D map__dso(al->map); =20 if (symbol_conf.dso_list && (!dso || !(strlist__has_entry(symbol_conf.dso_list, @@ -738,12 +738,12 @@ int machine__resolve(struct machine *machine, struct = addr_location *al, } if (!ret && al->sym) { snprintf(al_addr_str, sz, "0x%"PRIx64, - al->map->unmap_ip(al->map, al->sym->start)); + map__unmap_ip(al->map, al->sym->start)); ret =3D strlist__has_entry(symbol_conf.sym_list, al_addr_str); } if (!ret && symbol_conf.addr_list && al->map) { - unsigned long addr =3D al->map->unmap_ip(al->map, al->addr); + unsigned long addr =3D map__unmap_ip(al->map, al->addr); =20 ret =3D intlist__has_entry(symbol_conf.addr_list, addr); if (!ret && symbol_conf.addr_range) { diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprint= f.c index 8c2ea8001329..ac6fef9d8906 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -146,11 +146,11 @@ int sample__fprintf_callchain(struct perf_sample *sam= ple, int left_alignment, printed +=3D fprintf(fp, " <-"); =20 if (map) - addr =3D map->map_ip(map, node->ip); + addr =3D map__map_ip(map, node->ip); =20 if (print_ip) { /* Show binary offset for userspace addr */ - if (map && !map->dso->kernel) + if (map && !map__dso(map)->kernel) printed +=3D fprintf(fp, "%c%16" PRIx64, s, addr); else printed +=3D fprintf(fp, "%c%16" PRIx64, s, node->ip); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 78f9fbb925a7..f19ac6eb4775 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -105,7 +105,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) hists__set_col_len(hists, HISTC_THREAD, len + 8); =20 if (h->ms.map) { - len =3D dso__name_len(h->ms.map->dso); + len =3D dso__name_len(map__dso(h->ms.map)); hists__new_col_len(hists, HISTC_DSO, len); } =20 @@ -119,7 +119,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) symlen +=3D BITS_PER_LONG / 4 + 2 + 3; hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); =20 - symlen =3D dso__name_len(h->branch_info->from.ms.map->dso); + symlen =3D dso__name_len(map__dso(h->branch_info->from.ms.map)); hists__new_col_len(hists, HISTC_DSO_FROM, symlen); } else { symlen =3D unresolved_col_width + 4 + 2; @@ -133,7 +133,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) symlen +=3D BITS_PER_LONG / 4 + 2 + 3; hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); =20 - symlen =3D dso__name_len(h->branch_info->to.ms.map->dso); + symlen =3D dso__name_len(map__dso(h->branch_info->to.ms.map)); hists__new_col_len(hists, HISTC_DSO_TO, symlen); } else { symlen =3D unresolved_col_width + 4 + 2; @@ -177,7 +177,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) } =20 if (h->mem_info->daddr.ms.map) { - symlen =3D dso__name_len(h->mem_info->daddr.ms.map->dso); + symlen =3D dso__name_len(map__dso(h->mem_info->daddr.ms.map)); hists__new_col_len(hists, HISTC_MEM_DADDR_DSO, symlen); } else { @@ -2096,7 +2096,7 @@ static bool hists__filter_entry_by_dso(struct hists *= hists, struct hist_entry *he) { if (hists->dso_filter !=3D NULL && - (he->ms.map =3D=3D NULL || he->ms.map->dso !=3D hists->dso_filter)) { + (he->ms.map =3D=3D NULL || map__dso(he->ms.map) !=3D hists->dso_filte= r)) { he->filtered |=3D (1 << HIST_FILTER__DSO); return true; } diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index e8613cbda331..c88f112c0a06 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -731,20 +731,20 @@ static int intel_pt_walk_next_insn(struct intel_pt_in= sn *intel_pt_insn, } =20 while (1) { - if (!thread__find_map(thread, cpumode, *ip, &al) || !al.map->dso) + if (!thread__find_map(thread, cpumode, *ip, &al) || !map__dso(al.map)) return -EINVAL; =20 - if (al.map->dso->data.status =3D=3D DSO_DATA_STATUS_ERROR && - dso__data_status_seen(al.map->dso, + if (map__dso(al.map)->data.status =3D=3D DSO_DATA_STATUS_ERROR && + dso__data_status_seen(map__dso(al.map), DSO_DATA_STATUS_SEEN_ITRACE)) return -ENOENT; =20 - offset =3D al.map->map_ip(al.map, *ip); + offset =3D map__map_ip(al.map, *ip); =20 if (!to_ip && one_map) { struct intel_pt_cache_entry *e; =20 - e =3D intel_pt_cache_lookup(al.map->dso, machine, offset); + e =3D intel_pt_cache_lookup(map__dso(al.map), machine, offset); if (e && (!max_insn_cnt || e->insn_cnt <=3D max_insn_cnt)) { *insn_cnt_ptr =3D e->insn_cnt; @@ -766,10 +766,10 @@ static int intel_pt_walk_next_insn(struct intel_pt_in= sn *intel_pt_insn, /* Load maps to ensure dso->is_64_bit has been updated */ map__load(al.map); =20 - x86_64 =3D al.map->dso->is_64_bit; + x86_64 =3D map__dso(al.map)->is_64_bit; =20 while (1) { - len =3D dso__data_read_offset(al.map->dso, machine, + len =3D dso__data_read_offset(map__dso(al.map), machine, offset, buf, INTEL_PT_INSN_BUF_SZ); if (len <=3D 0) @@ -795,7 +795,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn= *intel_pt_insn, goto out_no_cache; } =20 - if (*ip >=3D al.map->end) + if (*ip >=3D map__end(al.map)) break; =20 offset +=3D intel_pt_insn->length; @@ -815,13 +815,13 @@ static int intel_pt_walk_next_insn(struct intel_pt_in= sn *intel_pt_insn, if (to_ip) { struct intel_pt_cache_entry *e; =20 - e =3D intel_pt_cache_lookup(al.map->dso, machine, start_offset); + e =3D intel_pt_cache_lookup(map__dso(al.map), machine, start_offset); if (e) return 0; } =20 /* Ignore cache errors */ - intel_pt_cache_add(al.map->dso, machine, start_offset, insn_cnt, + intel_pt_cache_add(map__dso(al.map), machine, start_offset, insn_cnt, *ip - start_ip, intel_pt_insn); =20 return 0; @@ -892,13 +892,13 @@ static int __intel_pt_pgd_ip(uint64_t ip, void *data) if (!thread) return -EINVAL; =20 - if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso) + if (!thread__find_map(thread, cpumode, ip, &al) || !map__dso(al.map)) return -EINVAL; =20 - offset =3D al.map->map_ip(al.map, ip); + offset =3D map__map_ip(al.map, ip); =20 return intel_pt_match_pgd_ip(ptq->pt, ip, offset, - al.map->dso->long_name); + map__dso(al.map)->long_name); } =20 static bool intel_pt_pgd_ip(uint64_t ip, void *data) @@ -2406,13 +2406,13 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, = u64 *ptss_ip) if (map__load(map)) return 0; =20 - start =3D dso__first_symbol(map->dso); + start =3D dso__first_symbol(map__dso(map)); =20 for (sym =3D start; sym; sym =3D dso__next_symbol(sym)) { if (sym->binding =3D=3D STB_GLOBAL && !strcmp(sym->name, "__switch_to")) { - ip =3D map->unmap_ip(map, sym->start); - if (ip >=3D map->start && ip < map->end) { + ip =3D map__unmap_ip(map, sym->start); + if (ip >=3D map__start(map) && ip < map__end(map)) { switch_ip =3D ip; break; } @@ -2429,8 +2429,8 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u6= 4 *ptss_ip) =20 for (sym =3D start; sym; sym =3D dso__next_symbol(sym)) { if (!strcmp(sym->name, ptss)) { - ip =3D map->unmap_ip(map, sym->start); - if (ip >=3D map->start && ip < map->end) { + ip =3D map__unmap_ip(map, sym->start); + if (ip >=3D map__start(map) && ip < map__end(map)) { *ptss_ip =3D ip; break; } @@ -2965,7 +2965,7 @@ static int intel_pt_process_aux_output_hw_id(struct i= ntel_pt *pt, static int intel_pt_find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al) { - if (!al->map || addr < al->map->start || addr >=3D al->map->end) { + if (!al->map || addr < map__start(al->map) || addr >=3D map__end(al->map)= ) { if (!thread__find_map(thread, cpumode, addr, al)) return -1; } @@ -2996,12 +2996,12 @@ static int intel_pt_text_poke(struct intel_pt *pt, = union perf_event *event) continue; } =20 - if (!al.map->dso || !al.map->dso->auxtrace_cache) + if (!map__dso(al.map) || !map__dso(al.map)->auxtrace_cache) continue; =20 - offset =3D al.map->map_ip(al.map, addr); + offset =3D map__map_ip(al.map, addr); =20 - e =3D intel_pt_cache_lookup(al.map->dso, machine, offset); + e =3D intel_pt_cache_lookup(map__dso(al.map), machine, offset); if (!e) continue; =20 @@ -3014,9 +3014,9 @@ static int intel_pt_text_poke(struct intel_pt *pt, un= ion perf_event *event) if (e->branch !=3D INTEL_PT_BR_NO_BRANCH) return 0; } else { - intel_pt_cache_invalidate(al.map->dso, machine, offset); + intel_pt_cache_invalidate(map__dso(al.map), machine, offset); intel_pt_log("Invalidated instruction cache for %s at %#"PRIx64"\n", - al.map->dso->long_name, addr); + map__dso(al.map)->long_name, addr); } } =20 diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 88279008e761..940fb2a50dfd 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -47,7 +47,7 @@ static void __machine__remove_thread(struct machine *mach= ine, struct thread *th, =20 static struct dso *machine__kernel_dso(struct machine *machine) { - return machine->vmlinux_map->dso; + return map__dso(machine->vmlinux_map); } =20 static void dsos__init(struct dsos *dsos) @@ -842,9 +842,10 @@ static int machine__process_ksymbol_unregister(struct = machine *machine, if (map !=3D machine->vmlinux_map) maps__remove(machine__kernel_maps(machine), map); else { - sym =3D dso__find_symbol(map->dso, map->map_ip(map, map->start)); + sym =3D dso__find_symbol(map__dso(map), + map__map_ip(map, map__start(map))); if (sym) - dso__delete_symbol(map->dso, sym); + dso__delete_symbol(map__dso(map), sym); } =20 return 0; @@ -880,7 +881,7 @@ int machine__process_text_poke(struct machine *machine,= union perf_event *event, return 0; } =20 - if (map && map->dso) { + if (map && map__dso(map)) { u8 *new_bytes =3D event->text_poke.bytes + event->text_poke.old_len; int ret; =20 @@ -889,7 +890,7 @@ int machine__process_text_poke(struct machine *machine,= union perf_event *event, * must be done prior to using kernel maps. */ map__load(map); - ret =3D dso__data_write_cache_addr(map->dso, map, machine, + ret =3D dso__data_write_cache_addr(map__dso(map), map, machine, event->text_poke.addr, new_bytes, event->text_poke.new_len); @@ -931,6 +932,7 @@ static struct map *machine__addnew_module_map(struct ma= chine *machine, u64 start /* If maps__insert failed, return NULL. */ if (err) map =3D NULL; + out: /* put the dso here, corresponding to machine__findnew_module_dso */ dso__put(dso); @@ -1118,7 +1120,7 @@ int machine__create_extra_kernel_map(struct machine *= machine, =20 if (!err) { pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", - kmap->name, map->start, map->end); + kmap->name, map__start(map), map__end(map)); } =20 map__put(map); @@ -1178,9 +1180,9 @@ int machine__map_x86_64_entry_trampolines(struct mach= ine *machine, if (!kmap || !is_entry_trampoline(kmap->name)) continue; =20 - dest_map =3D maps__find(kmaps, map->pgoff); + dest_map =3D maps__find(kmaps, map__pgoff(map)); if (dest_map !=3D map) - map->pgoff =3D dest_map->map_ip(dest_map, map->pgoff); + map->pgoff =3D map__map_ip(dest_map, map__pgoff(map)); found =3D true; } if (found || machine->trampolines_mapped) @@ -1230,7 +1232,8 @@ __machine__create_kernel_maps(struct machine *machine= , struct dso *kernel) if (machine->vmlinux_map =3D=3D NULL) return -ENOMEM; =20 - machine->vmlinux_map->map_ip =3D machine->vmlinux_map->unmap_ip =3D ident= ity__map_ip; + machine->vmlinux_map->map_ip =3D map__identity_ip; + machine->vmlinux_map->unmap_ip =3D map__identity_ip; return maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); } =20 @@ -1329,10 +1332,10 @@ int machines__create_kernel_maps(struct machines *m= achines, pid_t pid) int machine__load_kallsyms(struct machine *machine, const char *filename) { struct map *map =3D machine__kernel_map(machine); - int ret =3D __dso__load_kallsyms(map->dso, filename, map, true); + int ret =3D __dso__load_kallsyms(map__dso(map), filename, map, true); =20 if (ret > 0) { - dso__set_loaded(map->dso); + dso__set_loaded(map__dso(map)); /* * Since /proc/kallsyms will have multiple sessions for the * kernel, with modules between them, fixup the end of all @@ -1347,10 +1350,10 @@ int machine__load_kallsyms(struct machine *machine,= const char *filename) int machine__load_vmlinux_path(struct machine *machine) { struct map *map =3D machine__kernel_map(machine); - int ret =3D dso__load_vmlinux_path(map->dso, map); + int ret =3D dso__load_vmlinux_path(map__dso(map), map); =20 if (ret > 0) - dso__set_loaded(map->dso); + dso__set_loaded(map__dso(map)); =20 return ret; } @@ -1401,16 +1404,16 @@ static int maps__set_module_path(struct maps *maps,= const char *path, struct kmo if (long_name =3D=3D NULL) return -ENOMEM; =20 - dso__set_long_name(map->dso, long_name, true); - dso__kernel_module_get_build_id(map->dso, ""); + dso__set_long_name(map__dso(map), long_name, true); + dso__kernel_module_get_build_id(map__dso(map), ""); =20 /* * Full name could reveal us kmod compression, so * we need to update the symtab_type if needed. */ - if (m->comp && is_kmod_dso(map->dso)) { - map->dso->symtab_type++; - map->dso->comp =3D m->comp; + if (m->comp && is_kmod_dso(map__dso(map))) { + map__dso(map)->symtab_type++; + map__dso(map)->comp =3D m->comp; } =20 return 0; @@ -1509,8 +1512,7 @@ static int machine__create_module(void *arg, const ch= ar *name, u64 start, return -1; map->end =3D start + size; =20 - dso__kernel_module_get_build_id(map->dso, machine->root_dir); - + dso__kernel_module_get_build_id(map__dso(map), machine->root_dir); return 0; } =20 @@ -1619,7 +1621,7 @@ int machine__create_kernel_maps(struct machine *machi= ne) struct map_rb_node *next =3D map_rb_node__next(rb_node); =20 if (next) - machine__set_kernel_mmap(machine, start, next->map->start); + machine__set_kernel_mmap(machine, start, map__start(next->map)); } =20 out_put: @@ -1683,10 +1685,10 @@ static int machine__process_kernel_mmap_event(struc= t machine *machine, if (map =3D=3D NULL) goto out_problem; =20 - map->end =3D map->start + xm->end - xm->start; + map->end =3D map__start(map) + xm->end - xm->start; =20 if (build_id__is_defined(bid)) - dso__set_build_id(map->dso, bid); + dso__set_build_id(map__dso(map), bid); =20 } else if (is_kernel_mmap) { const char *symbol_name =3D (xm->name + strlen(machine->mmap_name)); @@ -2148,14 +2150,14 @@ static char *callchain_srcline(struct map_symbol *m= s, u64 ip) if (!map || callchain_param.key =3D=3D CCKEY_FUNCTION) return srcline; =20 - srcline =3D srcline__tree_find(&map->dso->srclines, ip); + srcline =3D srcline__tree_find(&map__dso(map)->srclines, ip); if (!srcline) { bool show_sym =3D false; bool show_addr =3D callchain_param.key =3D=3D CCKEY_ADDRESS; =20 - srcline =3D get_srcline(map->dso, map__rip_2objdump(map, ip), + srcline =3D get_srcline(map__dso(map), map__rip_2objdump(map, ip), ms->sym, show_sym, show_addr, ip); - srcline__tree_insert(&map->dso->srclines, ip, srcline); + srcline__tree_insert(&map__dso(map)->srclines, ip, srcline); } =20 return srcline; @@ -2179,7 +2181,7 @@ static int add_callchain_ip(struct thread *thread, { struct map_symbol ms; struct addr_location al; - int nr_loop_iter =3D 0; + int nr_loop_iter =3D 0, err; u64 iter_cycles =3D 0; const char *srcline =3D NULL; =20 @@ -2228,9 +2230,10 @@ static int add_callchain_ip(struct thread *thread, } } =20 - if (symbol_conf.hide_unresolved && al.sym =3D=3D NULL) + if (symbol_conf.hide_unresolved && al.sym =3D=3D NULL) { + addr_location__put(&al); return 0; - + } if (iter) { nr_loop_iter =3D iter->nr_loop_iter; iter_cycles =3D iter->cycles; @@ -2240,9 +2243,10 @@ static int add_callchain_ip(struct thread *thread, ms.map =3D al.map; ms.sym =3D al.sym; srcline =3D callchain_srcline(&ms, al.addr); - return callchain_cursor_append(cursor, ip, &ms, - branch, flags, nr_loop_iter, - iter_cycles, branch_from, srcline); + err =3D callchain_cursor_append(cursor, ip, &ms, + branch, flags, nr_loop_iter, + iter_cycles, branch_from, srcline); + return err; } =20 struct branch_info *sample__resolve_bstack(struct perf_sample *sample, @@ -2937,15 +2941,15 @@ static int append_inlines(struct callchain_cursor *= cursor, struct map_symbol *ms if (!symbol_conf.inline_name || !map || !sym) return ret; =20 - addr =3D map__map_ip(map, ip); + addr =3D map__dso_map_ip(map, ip); addr =3D map__rip_2objdump(map, addr); =20 - inline_node =3D inlines__tree_find(&map->dso->inlined_nodes, addr); + inline_node =3D inlines__tree_find(&map__dso(map)->inlined_nodes, addr); if (!inline_node) { - inline_node =3D dso__parse_addr_inlines(map->dso, addr, sym); + inline_node =3D dso__parse_addr_inlines(map__dso(map), addr, sym); if (!inline_node) return ret; - inlines__tree_insert(&map->dso->inlined_nodes, inline_node); + inlines__tree_insert(&map__dso(map)->inlined_nodes, inline_node); } =20 list_for_each_entry(ilist, &inline_node->val, list) { @@ -2981,7 +2985,7 @@ static int unwind_entry(struct unwind_entry *entry, v= oid *arg) * its corresponding binary. */ if (entry->ms.map) - addr =3D map__map_ip(entry->ms.map, entry->ip); + addr =3D map__dso_map_ip(entry->ms.map, entry->ip); =20 srcline =3D callchain_srcline(&entry->ms, addr); return callchain_cursor_append(cursor, entry->ip, &entry->ms, @@ -3183,7 +3187,7 @@ int machine__get_kernel_start(struct machine *machine) * kernel_start =3D 1ULL << 63 for x86_64. */ if (!err && !machine__is(machine, "x86_64")) - machine->kernel_start =3D map->start; + machine->kernel_start =3D map__start(map); } return err; } @@ -3234,8 +3238,8 @@ char *machine__resolve_kernel_addr(void *vmachine, un= signed long long *addrp, ch if (sym =3D=3D NULL) return NULL; =20 - *modp =3D __map__is_kmodule(map) ? (char *)map->dso->short_name : NULL; - *addrp =3D map->unmap_ip(map, sym->start); + *modp =3D __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NU= LL; + *addrp =3D map__unmap_ip(map, sym->start); return sym->name; } =20 diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 57e926ce115f..47d81e361e29 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -109,8 +109,8 @@ void map__init(struct map *map, u64 start, u64 end, u64= pgoff, struct dso *dso) map->pgoff =3D pgoff; map->reloc =3D 0; map->dso =3D dso__get(dso); - map->map_ip =3D map__map_ip; - map->unmap_ip =3D map__unmap_ip; + map->map_ip =3D map__dso_map_ip; + map->unmap_ip =3D map__dso_unmap_ip; map->erange_warned =3D false; refcount_set(&map->refcnt, 1); } @@ -120,10 +120,11 @@ struct map *map__new(struct machine *machine, u64 sta= rt, u64 len, u32 prot, u32 flags, struct build_id *bid, char *filename, struct thread *thread) { - struct map *map =3D malloc(sizeof(*map)); + struct map *map; struct nsinfo *nsi =3D NULL; struct nsinfo *nnsi; =20 + map =3D malloc(sizeof(*map)); if (map !=3D NULL) { char newfilename[PATH_MAX]; struct dso *dso; @@ -170,7 +171,7 @@ struct map *map__new(struct machine *machine, u64 start= , u64 len, map__init(map, start, start + len, pgoff, dso); =20 if (anon || no_dso) { - map->map_ip =3D map->unmap_ip =3D identity__map_ip; + map->map_ip =3D map->unmap_ip =3D map__identity_ip; =20 /* * Set memory without DSO as loaded. All map__find_* @@ -204,8 +205,9 @@ struct map *map__new(struct machine *machine, u64 start= , u64 len, */ struct map *map__new2(u64 start, struct dso *dso) { - struct map *map =3D calloc(1, (sizeof(*map) + - (dso->kernel ? sizeof(struct kmap) : 0))); + struct map *map; + + map =3D calloc(1, sizeof(*map) + (dso->kernel ? sizeof(struct kmap) : 0)); if (map !=3D NULL) { /* * ->end will be filled after we load all the symbols @@ -218,7 +220,7 @@ struct map *map__new2(u64 start, struct dso *dso) =20 bool __map__is_kernel(const struct map *map) { - if (!map->dso->kernel) + if (!map__dso(map)->kernel) return false; return machine__kernel_map(maps__machine(map__kmaps((struct map *)map))) = =3D=3D map; } @@ -234,7 +236,7 @@ bool __map__is_bpf_prog(const struct map *map) { const char *name; =20 - if (map->dso->binary_type =3D=3D DSO_BINARY_TYPE__BPF_PROG_INFO) + if (map__dso(map)->binary_type =3D=3D DSO_BINARY_TYPE__BPF_PROG_INFO) return true; =20 /* @@ -242,7 +244,7 @@ bool __map__is_bpf_prog(const struct map *map) * type of DSO_BINARY_TYPE__BPF_PROG_INFO. In such cases, we can * guess the type based on name. */ - name =3D map->dso->short_name; + name =3D map__dso(map)->short_name; return name && (strstr(name, "bpf_prog_") =3D=3D name); } =20 @@ -250,7 +252,7 @@ bool __map__is_bpf_image(const struct map *map) { const char *name; =20 - if (map->dso->binary_type =3D=3D DSO_BINARY_TYPE__BPF_IMAGE) + if (map__dso(map)->binary_type =3D=3D DSO_BINARY_TYPE__BPF_IMAGE) return true; =20 /* @@ -258,18 +260,19 @@ bool __map__is_bpf_image(const struct map *map) * type of DSO_BINARY_TYPE__BPF_IMAGE. In such cases, we can * guess the type based on name. */ - name =3D map->dso->short_name; + name =3D map__dso(map)->short_name; return name && is_bpf_image(name); } =20 bool __map__is_ool(const struct map *map) { - return map->dso && map->dso->binary_type =3D=3D DSO_BINARY_TYPE__OOL; + return map__dso(map) && + map__dso(map)->binary_type =3D=3D DSO_BINARY_TYPE__OOL; } =20 bool map__has_symbols(const struct map *map) { - return dso__has_symbols(map->dso); + return dso__has_symbols(map__dso(map)); } =20 static void map__exit(struct map *map) @@ -292,7 +295,7 @@ void map__put(struct map *map) =20 void map__fixup_start(struct map *map) { - struct rb_root_cached *symbols =3D &map->dso->symbols; + struct rb_root_cached *symbols =3D &map__dso(map)->symbols; struct rb_node *nd =3D rb_first_cached(symbols); if (nd !=3D NULL) { struct symbol *sym =3D rb_entry(nd, struct symbol, rb_node); @@ -302,7 +305,7 @@ void map__fixup_start(struct map *map) =20 void map__fixup_end(struct map *map) { - struct rb_root_cached *symbols =3D &map->dso->symbols; + struct rb_root_cached *symbols =3D &map__dso(map)->symbols; struct rb_node *nd =3D rb_last(&symbols->rb_root); if (nd !=3D NULL) { struct symbol *sym =3D rb_entry(nd, struct symbol, rb_node); @@ -314,18 +317,18 @@ void map__fixup_end(struct map *map) =20 int map__load(struct map *map) { - const char *name =3D map->dso->long_name; + const char *name =3D map__dso(map)->long_name; int nr; =20 - if (dso__loaded(map->dso)) + if (dso__loaded(map__dso(map))) return 0; =20 - nr =3D dso__load(map->dso, map); + nr =3D dso__load(map__dso(map), map); if (nr < 0) { - if (map->dso->has_build_id) { + if (map__dso(map)->has_build_id) { char sbuild_id[SBUILD_ID_SIZE]; =20 - build_id__sprintf(&map->dso->bid, sbuild_id); + build_id__sprintf(&map__dso(map)->bid, sbuild_id); pr_debug("%s with build id %s not found", name, sbuild_id); } else pr_debug("Failed to open %s", name); @@ -357,7 +360,7 @@ struct symbol *map__find_symbol(struct map *map, u64 ad= dr) if (map__load(map) < 0) return NULL; =20 - return dso__find_symbol(map->dso, addr); + return dso__find_symbol(map__dso(map), addr); } =20 struct symbol *map__find_symbol_by_name(struct map *map, const char *name) @@ -365,24 +368,24 @@ struct symbol *map__find_symbol_by_name(struct map *m= ap, const char *name) if (map__load(map) < 0) return NULL; =20 - if (!dso__sorted_by_name(map->dso)) - dso__sort_by_name(map->dso); + if (!dso__sorted_by_name(map__dso(map))) + dso__sort_by_name(map__dso(map)); =20 - return dso__find_symbol_by_name(map->dso, name); + return dso__find_symbol_by_name(map__dso(map), name); } =20 struct map *map__clone(struct map *from) { - size_t size =3D sizeof(struct map); struct map *map; + size_t size =3D sizeof(struct map); =20 - if (from->dso && from->dso->kernel) + if (map__dso(from) && map__dso(from)->kernel) size +=3D sizeof(struct kmap); =20 map =3D memdup(from, size); if (map !=3D NULL) { refcount_set(&map->refcnt, 1); - dso__get(map->dso); + map->dso =3D dso__get(map->dso); } =20 return map; @@ -391,7 +394,8 @@ struct map *map__clone(struct map *from) size_t map__fprintf(struct map *map, FILE *fp) { return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", - map->start, map->end, map->pgoff, map->dso->name); + map__start(map), map__end(map), + map__pgoff(map), map__dso(map)->name); } =20 size_t map__fprintf_dsoname(struct map *map, FILE *fp) @@ -399,11 +403,11 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp) char buf[symbol_conf.pad_output_len_dso + 1]; const char *dsoname =3D "[unknown]"; =20 - if (map && map->dso) { - if (symbol_conf.show_kernel_path && map->dso->long_name) - dsoname =3D map->dso->long_name; + if (map && map__dso(map)) { + if (symbol_conf.show_kernel_path && map__dso(map)->long_name) + dsoname =3D map__dso(map)->long_name; else - dsoname =3D map->dso->name; + dsoname =3D map__dso(map)->name; } =20 if (symbol_conf.pad_output_len_dso) { @@ -418,7 +422,8 @@ char *map__srcline(struct map *map, u64 addr, struct sy= mbol *sym) { if (map =3D=3D NULL) return SRCLINE_UNKNOWN; - return get_srcline(map->dso, map__rip_2objdump(map, addr), sym, true, tru= e, addr); + return get_srcline(map__dso(map), map__rip_2objdump(map, addr), + sym, true, true, addr); } =20 int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, @@ -426,7 +431,7 @@ int map__fprintf_srcline(struct map *map, u64 addr, con= st char *prefix, { int ret =3D 0; =20 - if (map && map->dso) { + if (map && map__dso(map)) { char *srcline =3D map__srcline(map, addr, NULL); if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) !=3D 0) ret =3D fprintf(fp, "%s%s", prefix, srcline); @@ -472,20 +477,20 @@ u64 map__rip_2objdump(struct map *map, u64 rip) } } =20 - if (!map->dso->adjust_symbols) + if (!map__dso(map)->adjust_symbols) return rip; =20 - if (map->dso->rel) - return rip - map->pgoff; + if (map__dso(map)->rel) + return rip - map__pgoff(map); =20 /* * kernel modules also have DSO_TYPE_USER in dso->kernel, * but all kernel modules are ET_REL, so won't get here. */ - if (map->dso->kernel =3D=3D DSO_SPACE__USER) - return rip + map->dso->text_offset; + if (map__dso(map)->kernel =3D=3D DSO_SPACE__USER) + return rip + map__dso(map)->text_offset; =20 - return map->unmap_ip(map, rip) - map->reloc; + return map__unmap_ip(map, rip) - map__reloc(map); } =20 /** @@ -502,34 +507,34 @@ u64 map__rip_2objdump(struct map *map, u64 rip) */ u64 map__objdump_2mem(struct map *map, u64 ip) { - if (!map->dso->adjust_symbols) - return map->unmap_ip(map, ip); + if (!map__dso(map)->adjust_symbols) + return map__unmap_ip(map, ip); =20 - if (map->dso->rel) - return map->unmap_ip(map, ip + map->pgoff); + if (map__dso(map)->rel) + return map__unmap_ip(map, ip + map__pgoff(map)); =20 /* * kernel modules also have DSO_TYPE_USER in dso->kernel, * but all kernel modules are ET_REL, so won't get here. */ - if (map->dso->kernel =3D=3D DSO_SPACE__USER) - return map->unmap_ip(map, ip - map->dso->text_offset); + if (map__dso(map)->kernel =3D=3D DSO_SPACE__USER) + return map__unmap_ip(map, ip - map__dso(map)->text_offset); =20 - return ip + map->reloc; + return ip + map__reloc(map); } =20 bool map__contains_symbol(const struct map *map, const struct symbol *sym) { - u64 ip =3D map->unmap_ip(map, sym->start); + u64 ip =3D map__unmap_ip(map, sym->start); =20 - return ip >=3D map->start && ip < map->end; + return ip >=3D map__start(map) && ip < map__end(map); } =20 struct kmap *__map__kmap(struct map *map) { - if (!map->dso || !map->dso->kernel) + if (!map__dso(map) || !map__dso(map)->kernel) return NULL; - return (struct kmap *)(map + 1); + return (struct kmap *)(&map[1]); } =20 struct kmap *map__kmap(struct map *map) @@ -552,17 +557,17 @@ struct maps *map__kmaps(struct map *map) return kmap->kmaps; } =20 -u64 map__map_ip(const struct map *map, u64 ip) +u64 map__dso_map_ip(const struct map *map, u64 ip) { - return ip - map->start + map->pgoff; + return ip - map__start(map) + map__pgoff(map); } =20 -u64 map__unmap_ip(const struct map *map, u64 ip) +u64 map__dso_unmap_ip(const struct map *map, u64 ip) { - return ip + map->start - map->pgoff; + return ip + map__start(map) - map__pgoff(map); } =20 -u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip) +u64 map__identity_ip(const struct map *map __maybe_unused, u64 ip) { return ip; } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index d1a6f85fd31d..99ef0464a357 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -41,15 +41,65 @@ struct kmap *map__kmap(struct map *map); struct maps *map__kmaps(struct map *map); =20 /* ip -> dso rip */ -u64 map__map_ip(const struct map *map, u64 ip); +u64 map__dso_map_ip(const struct map *map, u64 ip); /* dso rip -> ip */ -u64 map__unmap_ip(const struct map *map, u64 ip); +u64 map__dso_unmap_ip(const struct map *map, u64 ip); /* Returns ip */ -u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip); +u64 map__identity_ip(const struct map *map __maybe_unused, u64 ip); + +static inline struct dso *map__dso(const struct map *map) +{ + return map->dso; +} + +static inline u64 map__map_ip(const struct map *map, u64 ip) +{ + return map->map_ip(map, ip); +} + +static inline u64 map__unmap_ip(const struct map *map, u64 ip) +{ + return map->unmap_ip(map, ip); +} + +static inline u64 map__start(const struct map *map) +{ + return map->start; +} + +static inline u64 map__end(const struct map *map) +{ + return map->end; +} + +static inline u64 map__pgoff(const struct map *map) +{ + return map->pgoff; +} + +static inline u64 map__reloc(const struct map *map) +{ + return map->reloc; +} + +static inline u32 map__flags(const struct map *map) +{ + return map->flags; +} + +static inline u32 map__prot(const struct map *map) +{ + return map->prot; +} + +static inline bool map__priv(const struct map *map) +{ + return map->priv; +} =20 static inline size_t map__size(const struct map *map) { - return map->end - map->start; + return map__end(map) - map__start(map); } =20 /* rip/ip <-> addr suitable for passing to `objdump --start-address=3D` */ diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 9fc3e7186b8e..6efbcb79131c 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -30,24 +30,24 @@ static void __maps__free_maps_by_name(struct maps *maps) maps->nr_maps_allocated =3D 0; } =20 -static int __maps__insert(struct maps *maps, struct map *map) +static struct map *__maps__insert(struct maps *maps, struct map *map) { struct rb_node **p =3D &maps__entries(maps)->rb_node; struct rb_node *parent =3D NULL; - const u64 ip =3D map->start; + const u64 ip =3D map__start(map); struct map_rb_node *m, *new_rb_node; =20 new_rb_node =3D malloc(sizeof(*new_rb_node)); if (!new_rb_node) - return -ENOMEM; + return NULL; =20 RB_CLEAR_NODE(&new_rb_node->rb_node); - new_rb_node->map =3D map; + new_rb_node->map =3D map__get(map); =20 while (*p !=3D NULL) { parent =3D *p; m =3D rb_entry(parent, struct map_rb_node, rb_node); - if (ip < m->map->start) + if (ip < map__start(m->map)) p =3D &(*p)->rb_left; else p =3D &(*p)->rb_right; @@ -55,22 +55,23 @@ static int __maps__insert(struct maps *maps, struct map= *map) =20 rb_link_node(&new_rb_node->rb_node, parent, p); rb_insert_color(&new_rb_node->rb_node, maps__entries(maps)); - map__get(map); - return 0; + return new_rb_node->map; } =20 int maps__insert(struct maps *maps, struct map *map) { - int err; + int err =3D 0; =20 down_write(maps__lock(maps)); - err =3D __maps__insert(maps, map); - if (err) + map =3D __maps__insert(maps, map); + if (!map) { + err =3D -ENOMEM; goto out; + } =20 ++maps->nr_maps; =20 - if (map->dso && map->dso->kernel) { + if (map__dso(map) && map__dso(map)->kernel) { struct kmap *kmap =3D map__kmap(map); =20 if (kmap) @@ -193,7 +194,7 @@ struct symbol *maps__find_symbol(struct maps *maps, u64= addr, struct map **mapp) if (map !=3D NULL && map__load(map) >=3D 0) { if (mapp !=3D NULL) *mapp =3D map; - return map__find_symbol(map, map->map_ip(map, addr)); + return map__find_symbol(map, map__map_ip(map, addr)); } =20 return NULL; @@ -228,7 +229,8 @@ struct symbol *maps__find_symbol_by_name(struct maps *m= aps, const char *name, st =20 int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) { - if (ams->addr < ams->ms.map->start || ams->addr >=3D ams->ms.map->end) { + if (ams->addr < map__start(ams->ms.map) || + ams->addr >=3D map__end(ams->ms.map)) { if (maps =3D=3D NULL) return -1; ams->ms.map =3D maps__find(maps, ams->addr); @@ -236,7 +238,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_s= ymbol *ams) return -1; } =20 - ams->al_addr =3D ams->ms.map->map_ip(ams->ms.map, ams->addr); + ams->al_addr =3D map__map_ip(ams->ms.map, ams->addr); ams->ms.sym =3D map__find_symbol(ams->ms.map, ams->al_addr); =20 return ams->ms.sym ? 0 : -1; @@ -253,7 +255,7 @@ size_t maps__fprintf(struct maps *maps, FILE *fp) printed +=3D fprintf(fp, "Map:"); printed +=3D map__fprintf(pos->map, fp); if (verbose > 2) { - printed +=3D dso__fprintf(pos->map->dso, fp); + printed +=3D dso__fprintf(map__dso(pos->map), fp); printed +=3D fprintf(fp, "--\n"); } } @@ -282,9 +284,9 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) while (next) { struct map_rb_node *pos =3D rb_entry(next, struct map_rb_node, rb_node); =20 - if (pos->map->end > map->start) { + if (map__end(pos->map) > map__start(map)) { first =3D next; - if (pos->map->start <=3D map->start) + if (map__start(pos->map) <=3D map__start(map)) break; next =3D next->rb_left; } else @@ -300,14 +302,14 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) * Stop if current map starts after map->end. * Maps are ordered by start: next will not overlap for sure. */ - if (pos->map->start >=3D map->end) + if (map__start(pos->map) >=3D map__end(map)) break; =20 if (verbose >=3D 2) { =20 if (use_browser) { pr_debug("overlapping maps in %s (disable tui for more info)\n", - map->dso->name); + map__dso(map)->name); } else { fputs("overlapping maps:\n", fp); map__fprintf(map, fp); @@ -320,7 +322,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) * Now check if we need to create new maps for areas not * overlapped by the new map: */ - if (map->start > pos->map->start) { + if (map__start(map) > map__start(pos->map)) { struct map *before =3D map__clone(pos->map); =20 if (before =3D=3D NULL) { @@ -328,17 +330,19 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) goto put_map; } =20 - before->end =3D map->start; - err =3D __maps__insert(maps, before); - if (err) + before->end =3D map__start(map); + if (!__maps__insert(maps, before)) { + map__put(before); + err =3D -ENOMEM; goto put_map; + } =20 if (verbose >=3D 2 && !use_browser) map__fprintf(before, fp); map__put(before); } =20 - if (map->end < pos->map->end) { + if (map__end(map) < map__end(pos->map)) { struct map *after =3D map__clone(pos->map); =20 if (after =3D=3D NULL) { @@ -346,14 +350,15 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) goto put_map; } =20 - after->start =3D map->end; - after->pgoff +=3D map->end - pos->map->start; - assert(pos->map->map_ip(pos->map, map->end) =3D=3D - after->map_ip(after, map->end)); - err =3D __maps__insert(maps, after); - if (err) + after->start =3D map__end(map); + after->pgoff +=3D map__end(map) - map__start(pos->map); + assert(map__map_ip(pos->map, map__end(map)) =3D=3D + map__map_ip(after, map__end(map))); + if (!__maps__insert(maps, after)) { + map__put(after); + err =3D -ENOMEM; goto put_map; - + } if (verbose >=3D 2 && !use_browser) map__fprintf(after, fp); map__put(after); @@ -377,7 +382,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) int maps__clone(struct thread *thread, struct maps *parent) { struct maps *maps =3D thread->maps; - int err; + int err =3D 0; struct map_rb_node *rb_node; =20 down_read(maps__lock(parent)); @@ -391,17 +396,13 @@ int maps__clone(struct thread *thread, struct maps *p= arent) } =20 err =3D unwind__prepare_access(maps, new, NULL); - if (err) - goto out_unlock; + if (!err) + err =3D maps__insert(maps, new); =20 - err =3D maps__insert(maps, new); + map__put(new); if (err) goto out_unlock; - - map__put(new); } - - err =3D 0; out_unlock: up_read(maps__lock(parent)); return err; @@ -428,9 +429,9 @@ struct map *maps__find(struct maps *maps, u64 ip) p =3D maps__entries(maps)->rb_node; while (p !=3D NULL) { m =3D rb_entry(p, struct map_rb_node, rb_node); - if (ip < m->map->start) + if (ip < map__start(m->map)) p =3D p->rb_left; - else if (ip >=3D m->map->end) + else if (ip >=3D map__end(m->map)) p =3D p->rb_right; else goto out; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index f9fbf611f2bf..1a93dca50a4c 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -134,15 +134,15 @@ static int kernel_get_symbol_address_by_name(const ch= ar *name, u64 *addr, /* ref_reloc_sym is just a label. Need a special fix*/ reloc_sym =3D kernel_get_ref_reloc_sym(&map); if (reloc_sym && strcmp(name, reloc_sym->name) =3D=3D 0) - *addr =3D (!map->reloc || reloc) ? reloc_sym->addr : + *addr =3D (!map__reloc(map) || reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr; else { sym =3D machine__find_kernel_symbol_by_name(host_machine, name, &map); if (!sym) return -ENOENT; - *addr =3D map->unmap_ip(map, sym->start) - - ((reloc) ? 0 : map->reloc) - - ((reladdr) ? map->start : 0); + *addr =3D map__unmap_ip(map, sym->start) - + ((reloc) ? 0 : map__reloc(map)) - + ((reladdr) ? map__start(map) : 0); } return 0; } @@ -164,8 +164,8 @@ static struct map *kernel_get_module_map(const char *mo= dule) =20 maps__for_each_entry(maps, pos) { /* short_name is "[module]" */ - const char *short_name =3D pos->map->dso->short_name; - u16 short_name_len =3D pos->map->dso->short_name_len; + const char *short_name =3D map__dso(pos->map)->short_name; + u16 short_name_len =3D map__dso(pos->map)->short_name_len; =20 if (strncmp(short_name + 1, module, short_name_len - 2) =3D=3D 0 && @@ -183,11 +183,11 @@ struct map *get_target_map(const char *target, struct= nsinfo *nsi, bool user) struct map *map; =20 map =3D dso__new_map(target); - if (map && map->dso) { - BUG_ON(pthread_mutex_lock(&map->dso->lock) !=3D 0); - nsinfo__put(map->dso->nsinfo); - map->dso->nsinfo =3D nsinfo__get(nsi); - pthread_mutex_unlock(&map->dso->lock); + if (map && map__dso(map)) { + BUG_ON(pthread_mutex_lock(&map__dso(map)->lock) !=3D 0); + nsinfo__put(map__dso(map)->nsinfo); + map__dso(map)->nsinfo =3D nsinfo__get(nsi); + pthread_mutex_unlock(&map__dso(map)->lock); } return map; } else { @@ -253,7 +253,7 @@ static bool kprobe_warn_out_range(const char *symbol, u= 64 address) =20 map =3D kernel_get_module_map(NULL); if (map) { - ret =3D address <=3D map->start || map->end < address; + ret =3D address <=3D map__start(map) || map__end(map) < address; if (ret) pr_warning("%s is out of .text, skip it.\n", symbol); map__put(map); @@ -340,7 +340,7 @@ static int kernel_get_module_dso(const char *module, st= ruct dso **pdso) snprintf(module_name, sizeof(module_name), "[%s]", module); map =3D maps__find_by_name(machine__kernel_maps(host_machine), module_na= me); if (map) { - dso =3D map->dso; + dso =3D map__dso(map); goto found; } pr_debug("Failed to find module %s.\n", module); @@ -348,7 +348,7 @@ static int kernel_get_module_dso(const char *module, st= ruct dso **pdso) } =20 map =3D machine__kernel_map(host_machine); - dso =3D map->dso; + dso =3D map__dso(map); if (!dso->has_build_id) dso__read_running_kernel_build_id(dso, host_machine); =20 @@ -396,7 +396,8 @@ static int find_alternative_probe_point(struct debuginf= o *dinfo, "Consider identifying the final function used at run time and set = the probe directly on that.\n", pp->function); } else - address =3D map->unmap_ip(map, sym->start) - map->reloc; + address =3D map__unmap_ip(map, sym->start) - + map__reloc(map); break; } if (!address) { @@ -862,8 +863,7 @@ post_process_kernel_probe_trace_events(struct probe_tra= ce_event *tevs, free(tevs[i].point.symbol); tevs[i].point.symbol =3D tmp; tevs[i].point.offset =3D tevs[i].point.address - - (map->reloc ? reloc_sym->unrelocated_addr : - reloc_sym->addr); + (map__reloc(map) ? reloc_sym->unrelocated_addr : reloc_sym->addr); } return skipped; } @@ -2243,7 +2243,7 @@ static int find_perf_probe_point_from_map(struct prob= e_trace_point *tp, goto out; =20 pp->retprobe =3D tp->retprobe; - pp->offset =3D addr - map->unmap_ip(map, sym->start); + pp->offset =3D addr - map__unmap_ip(map, sym->start); pp->function =3D strdup(sym->name); ret =3D pp->function ? 0 : -ENOMEM; =20 @@ -3117,7 +3117,7 @@ static int find_probe_trace_events_from_map(struct pe= rf_probe_event *pev, goto err_out; } /* Add one probe point */ - tp->address =3D map->unmap_ip(map, sym->start) + pp->offset; + tp->address =3D map__unmap_ip(map, sym->start) + pp->offset; =20 /* Check the kprobe (not in module) is within .text */ if (!pev->uprobes && !pev->target && @@ -3759,13 +3759,13 @@ int show_available_funcs(const char *target, struct= nsinfo *nsi, (target) ? : "kernel"); goto end; } - if (!dso__sorted_by_name(map->dso)) - dso__sort_by_name(map->dso); + if (!dso__sorted_by_name(map__dso(map))) + dso__sort_by_name(map__dso(map)); =20 /* Show all (filtered) symbols */ setup_pager(); =20 - for (nd =3D rb_first_cached(&map->dso->symbol_names); nd; + for (nd =3D rb_first_cached(&map__dso(map)->symbol_names); nd; nd =3D rb_next(nd)) { struct symbol_name_rb_node *pos =3D rb_entry(nd, struct symbol_name_rb_n= ode, rb_node); =20 diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/p= erf/util/scripting-engines/trace-event-perl.c index a5d945415bbc..1282fb9b45e1 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -315,11 +315,12 @@ static SV *perl_process_callchain(struct perf_sample = *sample, if (node->ms.map) { struct map *map =3D node->ms.map; const char *dsoname =3D "[unknown]"; - if (map && map->dso) { - if (symbol_conf.show_kernel_path && map->dso->long_name) - dsoname =3D map->dso->long_name; + if (map && map__dso(map)) { + if (symbol_conf.show_kernel_path && + map__dso(map)->long_name) + dsoname =3D map__dso(map)->long_name; else - dsoname =3D map->dso->name; + dsoname =3D map__dso(map)->name; } if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) { hv_undef(elem); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools= /perf/util/scripting-engines/trace-event-python.c index 0290dc3a6258..559b2ac5cac3 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -382,11 +382,11 @@ static const char *get_dsoname(struct map *map) { const char *dsoname =3D "[unknown]"; =20 - if (map && map->dso) { - if (symbol_conf.show_kernel_path && map->dso->long_name) - dsoname =3D map->dso->long_name; + if (map && map__dso(map)) { + if (symbol_conf.show_kernel_path && map__dso(map)->long_name) + dsoname =3D map__dso(map)->long_name; else - dsoname =3D map->dso->name; + dsoname =3D map__dso(map)->name; } =20 return dsoname; @@ -527,7 +527,7 @@ static unsigned long get_offset(struct symbol *sym, str= uct addr_location *al) if (al->addr < sym->end) offset =3D al->addr - sym->start; else - offset =3D al->addr - al->map->start - sym->start; + offset =3D al->addr - map__start(al->map) - sym->start; =20 return offset; } @@ -741,7 +741,7 @@ static void set_sym_in_dict(PyObject *dict, struct addr= _location *al, { if (al->map) { pydict_set_item_string_decref(dict, dso_field, - _PyUnicode_FromString(al->map->dso->name)); + _PyUnicode_FromString(map__dso(al->map)->name)); } if (al->sym) { pydict_set_item_string_decref(dict, sym_field, diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 25686d67ee6f..6d19bbcd30df 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -173,8 +173,8 @@ struct sort_entry sort_comm =3D { =20 static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r) { - struct dso *dso_l =3D map_l ? map_l->dso : NULL; - struct dso *dso_r =3D map_r ? map_r->dso : NULL; + struct dso *dso_l =3D map_l ? map__dso(map_l) : NULL; + struct dso *dso_r =3D map_r ? map__dso(map_r) : NULL; const char *dso_name_l, *dso_name_r; =20 if (!dso_l || !dso_r) @@ -200,9 +200,9 @@ sort__dso_cmp(struct hist_entry *left, struct hist_entr= y *right) static int _hist_entry__dso_snprintf(struct map *map, char *bf, size_t size, unsigned int width) { - if (map && map->dso) { - const char *dso_name =3D verbose > 0 ? map->dso->long_name : - map->dso->short_name; + if (map && map__dso(map)) { + const char *dso_name =3D verbose > 0 ? map__dso(map)->long_name : + map__dso(map)->short_name; return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); } =20 @@ -222,7 +222,7 @@ static int hist_entry__dso_filter(struct hist_entry *he= , int type, const void *a if (type !=3D HIST_FILTER__DSO) return -1; =20 - return dso && (!he->ms.map || he->ms.map->dso !=3D dso); + return dso && (!he->ms.map || map__dso(he->ms.map) !=3D dso); } =20 struct sort_entry sort_dso =3D { @@ -302,12 +302,12 @@ static int _hist_entry__sym_snprintf(struct map_symbo= l *ms, size_t ret =3D 0; =20 if (verbose > 0) { - char o =3D map ? dso__symtab_origin(map->dso) : '!'; + char o =3D map ? dso__symtab_origin(map__dso(map)) : '!'; u64 rip =3D ip; =20 - if (map && map->dso && map->dso->kernel - && map->dso->adjust_symbols) - rip =3D map->unmap_ip(map, ip); + if (map && map__dso(map) && map__dso(map)->kernel + && map__dso(map)->adjust_symbols) + rip =3D map__unmap_ip(map, ip); =20 ret +=3D repsep_snprintf(bf, size, "%-#*llx %c ", BITS_PER_LONG / 4 + 2, rip, o); @@ -318,7 +318,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol = *ms, if (sym->type =3D=3D STT_OBJECT) { ret +=3D repsep_snprintf(bf + ret, size - ret, "%s", sym->name); ret +=3D repsep_snprintf(bf + ret, size - ret, "+0x%llx", - ip - map->unmap_ip(map, sym->start)); + ip - map__unmap_ip(map, sym->start)); } else { ret +=3D repsep_snprintf(bf + ret, size - ret, "%.*s", width - ret, @@ -517,7 +517,7 @@ static char *hist_entry__get_srcfile(struct hist_entry = *e) if (!map) return no_srcfile; =20 - sf =3D __get_srcline(map->dso, map__rip_2objdump(map, e->ip), + sf =3D __get_srcline(map__dso(map), map__rip_2objdump(map, e->ip), e->ms.sym, false, true, true, e->ip); if (!strcmp(sf, SRCLINE_UNKNOWN)) return no_srcfile; @@ -838,7 +838,7 @@ static int hist_entry__dso_from_filter(struct hist_entr= y *he, int type, return -1; =20 return dso && (!he->branch_info || !he->branch_info->from.ms.map || - he->branch_info->from.ms.map->dso !=3D dso); + map__dso(he->branch_info->from.ms.map) !=3D dso); } =20 static int64_t @@ -870,7 +870,7 @@ static int hist_entry__dso_to_filter(struct hist_entry = *he, int type, return -1; =20 return dso && (!he->branch_info || !he->branch_info->to.ms.map || - he->branch_info->to.ms.map->dso !=3D dso); + map__dso(he->branch_info->to.ms.map) !=3D dso); } =20 static int64_t @@ -1259,7 +1259,7 @@ sort__dcacheline_cmp(struct hist_entry *left, struct = hist_entry *right) if (!l_map) return -1; if (!r_map) return 1; =20 - rc =3D dso__cmp_id(l_map->dso, r_map->dso); + rc =3D dso__cmp_id(map__dso(l_map), map__dso(r_map)); if (rc) return rc; /* @@ -1271,9 +1271,9 @@ sort__dcacheline_cmp(struct hist_entry *left, struct = hist_entry *right) */ =20 if ((left->cpumode !=3D PERF_RECORD_MISC_KERNEL) && - (!(l_map->flags & MAP_SHARED)) && - !l_map->dso->id.maj && !l_map->dso->id.min && - !l_map->dso->id.ino && !l_map->dso->id.ino_generation) { + (!(map__flags(l_map) & MAP_SHARED)) && + !map__dso(l_map)->id.maj && !map__dso(l_map)->id.min && + !map__dso(l_map)->id.ino && !map__dso(l_map)->id.ino_generation) { /* userspace anonymous */ =20 if (left->thread->pid_ > right->thread->pid_) return -1; @@ -1307,10 +1307,10 @@ static int hist_entry__dcacheline_snprintf(struct h= ist_entry *he, char *bf, =20 /* print [s] for shared data mmaps */ if ((he->cpumode !=3D PERF_RECORD_MISC_KERNEL) && - map && !(map->prot & PROT_EXEC) && - (map->flags & MAP_SHARED) && - (map->dso->id.maj || map->dso->id.min || - map->dso->id.ino || map->dso->id.ino_generation)) + map && !(map__prot(map) & PROT_EXEC) && + (map__flags(map) & MAP_SHARED) && + (map__dso(map)->id.maj || map__dso(map)->id.min || + map__dso(map)->id.ino || map__dso(map)->id.ino_generation)) level =3D 's'; else if (!map) level =3D 'X'; @@ -1806,7 +1806,7 @@ sort__dso_size_cmp(struct hist_entry *left, struct hi= st_entry *right) static int _hist_entry__dso_size_snprintf(struct map *map, char *bf, size_t bf_size, unsigned int width) { - if (map && map->dso) + if (map && map__dso(map)) return repsep_snprintf(bf, bf_size, "%*d", width, map__size(map)); =20 diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 3ca9a0968345..056405d3d655 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -970,7 +970,7 @@ void __weak arch__sym_update(struct symbol *s __maybe_u= nused, static int dso__process_kernel_symbol(struct dso *dso, struct map *map, GElf_Sym *sym, GElf_Shdr *shdr, struct maps *kmaps, struct kmap *kmap, - struct dso **curr_dsop, struct map **curr_mapp, + struct dso **curr_dsop, const char *section_name, bool adjust_kernel_syms, bool kmodule, bool *remap_kernel) { @@ -994,18 +994,18 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, if (*remap_kernel && dso->kernel && !kmodule) { *remap_kernel =3D false; map->start =3D shdr->sh_addr + ref_reloc(kmap); - map->end =3D map->start + shdr->sh_size; + map->end =3D map__start(map) + shdr->sh_size; map->pgoff =3D shdr->sh_offset; - map->map_ip =3D map__map_ip; - map->unmap_ip =3D map__unmap_ip; + map->map_ip =3D map__dso_map_ip; + map->unmap_ip =3D map__dso_unmap_ip; /* Ensure maps are correctly ordered */ if (kmaps) { int err; + struct map *updated =3D map__get(map); =20 - map__get(map); maps__remove(kmaps, map); - err =3D maps__insert(kmaps, map); - map__put(map); + err =3D maps__insert(kmaps, updated); + map__put(updated); if (err) return err; } @@ -1021,7 +1021,6 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, map->pgoff =3D shdr->sh_offset; } =20 - *curr_mapp =3D map; *curr_dsop =3D dso; return 0; } @@ -1036,7 +1035,7 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, u64 start =3D sym->st_value; =20 if (kmodule) - start +=3D map->start + shdr->sh_offset; + start +=3D map__start(map) + shdr->sh_offset; =20 curr_dso =3D dso__new(dso_name); if (curr_dso =3D=3D NULL) @@ -1054,10 +1053,11 @@ static int dso__process_kernel_symbol(struct dso *d= so, struct map *map, =20 if (adjust_kernel_syms) { curr_map->start =3D shdr->sh_addr + ref_reloc(kmap); - curr_map->end =3D curr_map->start + shdr->sh_size; - curr_map->pgoff =3D shdr->sh_offset; + curr_map->end =3D map__start(curr_map) + shdr->sh_size; + curr_map->pgoff =3D shdr->sh_offset; } else { - curr_map->map_ip =3D curr_map->unmap_ip =3D identity__map_ip; + curr_map->map_ip =3D map__identity_ip; + curr_map->unmap_ip =3D map__identity_ip; } curr_dso->symtab_type =3D dso->symtab_type; if (maps__insert(kmaps, curr_map)) @@ -1068,13 +1068,11 @@ static int dso__process_kernel_symbol(struct dso *d= so, struct map *map, * *curr_map->dso. */ dsos__add(&maps__machine(kmaps)->dsos, curr_dso); - /* kmaps already got it */ - map__put(curr_map); dso__set_loaded(curr_dso); - *curr_mapp =3D curr_map; *curr_dsop =3D curr_dso; + map__put(curr_map); } else - *curr_dsop =3D curr_map->dso; + *curr_dsop =3D map__dso(curr_map); =20 return 0; } @@ -1085,7 +1083,6 @@ dso__load_sym_internal(struct dso *dso, struct map *m= ap, struct symsrc *syms_ss, { struct kmap *kmap =3D dso->kernel ? map__kmap(map) : NULL; struct maps *kmaps =3D kmap ? map__kmaps(map) : NULL; - struct map *curr_map =3D map; struct dso *curr_dso =3D dso; Elf_Data *symstrs, *secstrs, *secstrs_run, *secstrs_sym; uint32_t nr_syms; @@ -1175,7 +1172,7 @@ dso__load_sym_internal(struct dso *dso, struct map *m= ap, struct symsrc *syms_ss, * attempted to prelink vdso to its virtual address. */ if (dso__is_vdso(dso)) - map->reloc =3D map->start - dso->text_offset; + map->reloc =3D map__start(map) - dso->text_offset; =20 dso->adjust_symbols =3D runtime_ss->adjust_symbols || ref_reloc(kmap); /* @@ -1262,8 +1259,10 @@ dso__load_sym_internal(struct dso *dso, struct map *= map, struct symsrc *syms_ss, --sym.st_value; =20 if (dso->kernel) { - if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &cur= r_dso, &curr_map, - section_name, adjust_kernel_syms, kmodule, &remap_kernel)) + if (dso__process_kernel_symbol(dso, map, &sym, &shdr, + kmaps, kmap, &curr_dso, + section_name, adjust_kernel_syms, + kmodule, &remap_kernel)) goto out_elf_end; } else if ((used_opd && runtime_ss->adjust_symbols) || (!used_opd && syms_ss->adjust_symbols)) { diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 9b51e669a722..6289b3028b91 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -252,8 +252,8 @@ void maps__fixup_end(struct maps *maps) down_write(maps__lock(maps)); =20 maps__for_each_entry(maps, curr) { - if (prev !=3D NULL && !prev->map->end) - prev->map->end =3D curr->map->start; + if (prev !=3D NULL && !map__end(prev->map)) + prev->map->end =3D map__start(curr->map); =20 prev =3D curr; } @@ -262,7 +262,7 @@ void maps__fixup_end(struct maps *maps) * We still haven't the actual symbols, so guess the * last map final address. */ - if (curr && !curr->map->end) + if (curr && !map__end(curr->map)) curr->map->end =3D ~0ULL; =20 up_write(maps__lock(maps)); @@ -778,12 +778,12 @@ static int maps__split_kallsyms_for_kcore(struct maps= *kmaps, struct dso *dso) continue; } =20 - pos->start -=3D curr_map->start - curr_map->pgoff; - if (pos->end > curr_map->end) - pos->end =3D curr_map->end; + pos->start -=3D map__start(curr_map) - map__pgoff(curr_map); + if (pos->end > map__end(curr_map)) + pos->end =3D map__end(curr_map); if (pos->end) - pos->end -=3D curr_map->start - curr_map->pgoff; - symbols__insert(&curr_map->dso->symbols, pos); + pos->end -=3D map__start(curr_map) - map__pgoff(curr_map); + symbols__insert(&map__dso(curr_map)->symbols, pos); ++count; } =20 @@ -830,7 +830,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, =20 *module++ =3D '\0'; =20 - if (strcmp(curr_map->dso->short_name, module)) { + if (strcmp(map__dso(curr_map)->short_name, module)) { if (curr_map !=3D initial_map && dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(machine)) { @@ -841,7 +841,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, * symbols are in its kmap. Mark it as * loaded. */ - dso__set_loaded(curr_map->dso); + dso__set_loaded(map__dso(curr_map)); } =20 curr_map =3D maps__find_by_name(kmaps, module); @@ -854,7 +854,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, goto discard_symbol; } =20 - if (curr_map->dso->loaded && + if (map__dso(curr_map)->loaded && !machine__is_default_guest(machine)) goto discard_symbol; } @@ -862,8 +862,8 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, * So that we look just like we get from .ko files, * i.e. not prelinked, relative to initial_map->start. */ - pos->start =3D curr_map->map_ip(curr_map, pos->start); - pos->end =3D curr_map->map_ip(curr_map, pos->end); + pos->start =3D map__map_ip(curr_map, pos->start); + pos->end =3D map__map_ip(curr_map, pos->end); } else if (x86_64 && is_entry_trampoline(pos->name)) { /* * These symbols are not needed anymore since the @@ -910,7 +910,8 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, return -1; } =20 - curr_map->map_ip =3D curr_map->unmap_ip =3D identity__map_ip; + curr_map->map_ip =3D map__identity_ip; + curr_map->unmap_ip =3D map__identity_ip; if (maps__insert(kmaps, curr_map)) { dso__put(ndso); return -1; @@ -924,7 +925,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, add_symbol: if (curr_map !=3D initial_map) { rb_erase_cached(&pos->rb_node, root); - symbols__insert(&curr_map->dso->symbols, pos); + symbols__insert(&map__dso(curr_map)->symbols, pos); ++moved; } else ++count; @@ -938,7 +939,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, if (curr_map !=3D initial_map && dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(maps__machine(kmaps))) { - dso__set_loaded(curr_map->dso); + dso__set_loaded(map__dso(curr_map)); } =20 return count + moved; @@ -1118,8 +1119,8 @@ static int do_validate_kcore_modules(const char *file= name, struct maps *kmaps) } =20 /* Module must be in memory at the same address */ - mi =3D find_module(old_map->dso->short_name, &modules); - if (!mi || mi->start !=3D old_map->start) { + mi =3D find_module(map__dso(old_map)->short_name, &modules); + if (!mi || mi->start !=3D map__start(old_map)) { err =3D -EINVAL; goto out; } @@ -1214,7 +1215,7 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff,= void *data) return -ENOMEM; } =20 - list_node->map->end =3D list_node->map->start + len; + list_node->map->end =3D map__start(list_node->map) + len; list_node->map->pgoff =3D pgoff; =20 list_add(&list_node->node, &md->maps); @@ -1236,21 +1237,21 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) struct map *old_map =3D rb_node->map; =20 /* no overload with this one */ - if (new_map->end < old_map->start || - new_map->start >=3D old_map->end) + if (map__end(new_map) < map__start(old_map) || + map__start(new_map) >=3D map__end(old_map)) continue; =20 - if (new_map->start < old_map->start) { + if (map__start(new_map) < map__start(old_map)) { /* * |new...... * |old.... */ - if (new_map->end < old_map->end) { + if (map__end(new_map) < map__end(old_map)) { /* * |new......| -> |new..| * |old....| -> |old....| */ - new_map->end =3D old_map->start; + new_map->end =3D map__start(old_map); } else { /* * |new.............| -> |new..| |new..| @@ -1271,17 +1272,18 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) goto out; } =20 - m->map->end =3D old_map->start; + m->map->end =3D map__start(old_map); list_add_tail(&m->node, &merged); - new_map->pgoff +=3D old_map->end - new_map->start; - new_map->start =3D old_map->end; + new_map->pgoff +=3D + map__end(old_map) - map__start(new_map); + new_map->start =3D map__end(old_map); } } else { /* * |new...... * |old.... */ - if (new_map->end < old_map->end) { + if (map__end(new_map) < map__end(old_map)) { /* * |new..| -> x * |old.........| -> |old.........| @@ -1294,8 +1296,9 @@ int maps__merge_in(struct maps *kmaps, struct map *ne= w_map) * |new......| -> |new...| * |old....| -> |old....| */ - new_map->pgoff +=3D old_map->end - new_map->start; - new_map->start =3D old_map->end; + new_map->pgoff +=3D + map__end(old_map) - map__start(new_map); + new_map->start =3D map__end(old_map); } } } @@ -1361,7 +1364,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, } =20 /* Read new maps into temporary lists */ - err =3D file__read_maps(fd, map->prot & PROT_EXEC, kcore_mapfn, &md, + err =3D file__read_maps(fd, map__prot(map) & PROT_EXEC, kcore_mapfn, &md, &is_64_bit); if (err) goto out_err; @@ -1391,7 +1394,8 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, struct map_list_node *new_node; =20 list_for_each_entry(new_node, &md.maps, node) { - if (stext >=3D new_node->map->start && stext < new_node->map->end) { + if (stext >=3D map__start(new_node->map) && + stext < map__end(new_node->map)) { replacement_map =3D new_node->map; break; } @@ -1408,16 +1412,18 @@ static int dso__load_kcore(struct dso *dso, struct = map *map, new_node =3D list_entry(md.maps.next, struct map_list_node, node); list_del_init(&new_node->node); if (new_node->map =3D=3D replacement_map) { - map->start =3D new_node->map->start; - map->end =3D new_node->map->end; - map->pgoff =3D new_node->map->pgoff; - map->map_ip =3D new_node->map->map_ip; - map->unmap_ip =3D new_node->map->unmap_ip; + struct map *updated; + + map->start =3D map__start(new_node->map); + map->end =3D map__end(new_node->map); + map->pgoff =3D map__pgoff(new_node->map); + map->map_ip =3D new_node->map->map_ip; + map->unmap_ip =3D new_node->map->unmap_ip; /* Ensure maps are correctly ordered */ - map__get(map); + updated =3D map__get(map); maps__remove(kmaps, map); - err =3D maps__insert(kmaps, map); - map__put(map); + err =3D maps__insert(kmaps, updated); + map__put(updated); map__put(new_node->map); if (err) goto out_err; @@ -1460,7 +1466,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, =20 close(fd); =20 - if (map->prot & PROT_EXEC) + if (map__prot(map) & PROT_EXEC) pr_debug("Using %s for kernel object code\n", kcore_filename); else pr_debug("Using %s for kernel data\n", kcore_filename); @@ -1995,13 +2001,13 @@ int dso__load(struct dso *dso, struct map *map) static int map__strcmp(const void *a, const void *b) { const struct map *ma =3D *(const struct map **)a, *mb =3D *(const struct = map **)b; - return strcmp(ma->dso->short_name, mb->dso->short_name); + return strcmp(map__dso(ma)->short_name, map__dso(mb)->short_name); } =20 static int map__strcmp_name(const void *name, const void *b) { const struct map *map =3D *(const struct map **)b; - return strcmp(name, map->dso->short_name); + return strcmp(name, map__dso(map)->short_name); } =20 void __maps__sort_by_name(struct maps *maps) @@ -2052,7 +2058,7 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) down_read(maps__lock(maps)); =20 if (maps->last_search_by_name && - strcmp(maps->last_search_by_name->dso->short_name, name) =3D=3D 0) { + strcmp(map__dso(maps->last_search_by_name)->short_name, name) =3D=3D = 0) { map =3D maps->last_search_by_name; goto out_unlock; } @@ -2068,7 +2074,7 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) /* Fallback to traversing the rbtree... */ maps__for_each_entry(maps, rb_node) { map =3D rb_node->map; - if (strcmp(map->dso->short_name, name) =3D=3D 0) { + if (strcmp(map__dso(map)->short_name, name) =3D=3D 0) { maps->last_search_by_name =3D map; goto out_unlock; } diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fpri= ntf.c index 2664fb65e47a..d9e5ad040b6a 100644 --- a/tools/perf/util/symbol_fprintf.c +++ b/tools/perf/util/symbol_fprintf.c @@ -30,7 +30,7 @@ size_t __symbol__fprintf_symname_offs(const struct symbol= *sym, if (al->addr < sym->end) offset =3D al->addr - sym->start; else - offset =3D al->addr - al->map->start - sym->start; + offset =3D al->addr - map__start(al->map) - sym->start; length +=3D fprintf(fp, "+0x%lx", offset); } return length; diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index ed2d55d224aa..437fd57c2084 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -668,33 +668,33 @@ int perf_event__synthesize_modules(struct perf_tool *= tool, perf_event__handler_t continue; =20 if (symbol_conf.buildid_mmap2) { - size =3D PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); + size =3D PERF_ALIGN(map__dso(map)->long_name_len + 1, sizeof(u64)); event->mmap2.header.type =3D PERF_RECORD_MMAP2; event->mmap2.header.size =3D (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size)); memset(event->mmap2.filename + size, 0, machine->id_hdr_size); event->mmap2.header.size +=3D machine->id_hdr_size; - event->mmap2.start =3D map->start; - event->mmap2.len =3D map->end - map->start; + event->mmap2.start =3D map__start(map); + event->mmap2.len =3D map__end(map) - map__start(map); event->mmap2.pid =3D machine->pid; =20 - memcpy(event->mmap2.filename, map->dso->long_name, - map->dso->long_name_len + 1); + memcpy(event->mmap2.filename, map__dso(map)->long_name, + map__dso(map)->long_name_len + 1); =20 perf_record_mmap2__read_build_id(&event->mmap2, false); } else { - size =3D PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); + size =3D PERF_ALIGN(map__dso(map)->long_name_len + 1, sizeof(u64)); event->mmap.header.type =3D PERF_RECORD_MMAP; event->mmap.header.size =3D (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size)); memset(event->mmap.filename + size, 0, machine->id_hdr_size); event->mmap.header.size +=3D machine->id_hdr_size; - event->mmap.start =3D map->start; - event->mmap.len =3D map->end - map->start; + event->mmap.start =3D map__start(map); + event->mmap.len =3D map__end(map) - map__start(map); event->mmap.pid =3D machine->pid; =20 - memcpy(event->mmap.filename, map->dso->long_name, - map->dso->long_name_len + 1); + memcpy(event->mmap.filename, map__dso(map)->long_name, + map__dso(map)->long_name_len + 1); } =20 if (perf_tool__process_synth_event(tool, event, machine, process) !=3D 0= ) { @@ -1112,8 +1112,8 @@ static int __perf_event__synthesize_kernel_mmap(struc= t perf_tool *tool, event->mmap2.header.size =3D (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size) + machine->id_hdr_size); event->mmap2.pgoff =3D kmap->ref_reloc_sym->addr; - event->mmap2.start =3D map->start; - event->mmap2.len =3D map->end - event->mmap.start; + event->mmap2.start =3D map__start(map); + event->mmap2.len =3D map__end(map) - event->mmap.start; event->mmap2.pid =3D machine->pid; =20 perf_record_mmap2__read_build_id(&event->mmap2, true); @@ -1125,8 +1125,8 @@ static int __perf_event__synthesize_kernel_mmap(struc= t perf_tool *tool, event->mmap.header.size =3D (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); event->mmap.pgoff =3D kmap->ref_reloc_sym->addr; - event->mmap.start =3D map->start; - event->mmap.len =3D map->end - event->mmap.start; + event->mmap.start =3D map__start(map); + event->mmap.len =3D map__end(map) - event->mmap.start; event->mmap.pid =3D machine->pid; } =20 diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index c2256777b813..6fbcc115cc6d 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -434,23 +434,23 @@ struct thread *thread__main_thread(struct machine *ma= chine, struct thread *threa int thread__memcpy(struct thread *thread, struct machine *machine, void *buf, u64 ip, int len, bool *is64bit) { - u8 cpumode =3D PERF_RECORD_MISC_USER; - struct addr_location al; - long offset; + u8 cpumode =3D PERF_RECORD_MISC_USER; + struct addr_location al; + long offset; =20 - if (machine__kernel_ip(machine, ip)) - cpumode =3D PERF_RECORD_MISC_KERNEL; + if (machine__kernel_ip(machine, ip)) + cpumode =3D PERF_RECORD_MISC_KERNEL; =20 - if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso || - al.map->dso->data.status =3D=3D DSO_DATA_STATUS_ERROR || - map__load(al.map) < 0) - return -1; + if (!thread__find_map(thread, cpumode, ip, &al) || !map__dso(al.map) || + map__dso(al.map)->data.status =3D=3D DSO_DATA_STATUS_ERROR || + map__load(al.map) < 0) + return -1; =20 - offset =3D al.map->map_ip(al.map, ip); - if (is64bit) - *is64bit =3D al.map->dso->is_64_bit; + offset =3D map__map_ip(al.map, ip); + if (is64bit) + *is64bit =3D map__dso(al.map)->is_64_bit; =20 - return dso__data_read_offset(al.map->dso, machine, offset, buf, len= ); + return dso__data_read_offset(map__dso(al.map), machine, offset, buf, len); } =20 void thread__free_stitch_list(struct thread *thread) diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unw= ind-libunwind-local.c index 7e6c59811292..841ac84a93ab 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -381,20 +381,20 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, un= w_proc_info_t *pi, int ret =3D -EINVAL; =20 map =3D find_map(ip, ui); - if (!map || !map->dso) + if (!map || !map__dso(map)) return -EINVAL; =20 - pr_debug("unwind: find_proc_info dso %s\n", map->dso->name); + pr_debug("unwind: %s dso %s\n", __func__, map__dso(map)->name); =20 /* Check the .eh_frame section for unwinding info */ - if (!read_unwind_spec_eh_frame(map->dso, ui->machine, + if (!read_unwind_spec_eh_frame(map__dso(map), ui->machine, &table_data, &segbase, &fde_count)) { memset(&di, 0, sizeof(di)); di.format =3D UNW_INFO_FORMAT_REMOTE_TABLE; - di.start_ip =3D map->start; - di.end_ip =3D map->end; - di.u.rti.segbase =3D map->start + segbase - map->pgoff; - di.u.rti.table_data =3D map->start + table_data - map->pgoff; + di.start_ip =3D map__start(map); + di.end_ip =3D map__end(map); + di.u.rti.segbase =3D map__start(map) + segbase - map__pgoff(map); + di.u.rti.table_data =3D map__start(map) + table_data - map__pgoff(map); di.u.rti.table_len =3D fde_count * sizeof(struct table_entry) / sizeof(unw_word_t); ret =3D dwarf_search_unwind_table(as, ip, &di, pi, @@ -404,20 +404,20 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, un= w_proc_info_t *pi, #ifndef NO_LIBUNWIND_DEBUG_FRAME /* Check the .debug_frame section for unwinding info */ if (ret < 0 && - !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { - int fd =3D dso__data_get_fd(map->dso, ui->machine); - int is_exec =3D elf_is_exec(fd, map->dso->name); - unw_word_t base =3D is_exec ? 0 : map->start; + !read_unwind_spec_debug_frame(map__dso(map), ui->machine, &segbase)) { + int fd =3D dso__data_get_fd(map__dso(map), ui->machine); + int is_exec =3D elf_is_exec(fd, map__dso(map)->name); + unw_word_t base =3D is_exec ? 0 : map__start(map); const char *symfile; =20 if (fd >=3D 0) - dso__data_put_fd(map->dso); + dso__data_put_fd(map__dso(map)); =20 - symfile =3D map->dso->symsrc_filename ?: map->dso->name; + symfile =3D map__dso(map)->symsrc_filename ?: map__dso(map)->name; =20 memset(&di, 0, sizeof(di)); if (dwarf_find_debug_frame(0, &di, ip, base, symfile, - map->start, map->end)) + map__start(map), map__end(map))) return dwarf_search_unwind_table(as, ip, &di, pi, need_unwind_info, arg); } @@ -473,10 +473,10 @@ static int access_dso_mem(struct unwind_info *ui, unw= _word_t addr, return -1; } =20 - if (!map->dso) + if (!map__dso(map)) return -1; =20 - size =3D dso__data_read_addr(map->dso, map, ui->machine, + size =3D dso__data_read_addr(map__dso(map), map, ui->machine, addr, (u8 *) data, sizeof(*data)); =20 return !(size =3D=3D sizeof(*data)); @@ -583,7 +583,7 @@ static int entry(u64 ip, struct thread *thread, pr_debug("unwind: %s:ip =3D 0x%" PRIx64 " (0x%" PRIx64 ")\n", al.sym ? al.sym->name : "''", ip, - al.map ? al.map->map_ip(al.map, ip) : (u64) 0); + al.map ? map__map_ip(al.map, ip) : (u64) 0); =20 return cb(&e, arg); } diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-li= bunwind.c index 7b797ffadd19..cece1ee89031 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -30,7 +30,7 @@ int unwind__prepare_access(struct maps *maps, struct map = *map, bool *initialized =20 if (maps__addr_space(maps)) { pr_debug("unwind: thread map already set, dso=3D%s\n", - map->dso->name); + map__dso(map)->name); if (initialized) *initialized =3D true; return 0; @@ -41,7 +41,7 @@ int unwind__prepare_access(struct maps *maps, struct map = *map, bool *initialized if (!machine->env || !machine->env->arch) goto out_register; =20 - dso_type =3D dso__type(map->dso, machine); + dso_type =3D dso__type(map__dso(map), machine); if (dso_type =3D=3D DSO__TYPE_UNKNOWN) return 0; =20 diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 835c39efb80d..ec777ee11493 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -147,7 +147,7 @@ static enum dso_type machine__thread_dso_type(struct ma= chine *machine, struct map_rb_node *rb_node; =20 maps__for_each_entry(thread->maps, rb_node) { - struct dso *dso =3D rb_node->map->dso; + struct dso *dso =3D map__dso(rb_node->map); =20 if (!dso || dso->long_name[0] !=3D '/') continue; --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 47564C433EF for ; Fri, 11 Feb 2022 10:35:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349063AbiBKKfn (ORCPT ); Fri, 11 Feb 2022 05:35:43 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32804 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348976AbiBKKfG (ORCPT ); Fri, 11 Feb 2022 05:35:06 -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 A076DF09 for ; Fri, 11 Feb 2022 02:35:01 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id s133-20020a252c8b000000b0062112290d0bso2930924ybs.23 for ; Fri, 11 Feb 2022 02:35:01 -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=G677aq/uRJQFlNf2MOfZhMeeR+Ww2WAIN6eR7wWAbxk=; b=bUSLQ0bmmnsf8LyD0oerPrqmx9F06nj76AZL+2Kohv4lJmWs35/U9aB8laEaprIYcO EFWciz9LYvzUTG6EvUzn0IGrHO9xkmo6R2u/dDtuqpYFdrp+59B0IOR7cV3oeQ319BmO MRaqcnPJuGzeJ33HD+hLT6edOfMx085pat4x7HJRqneh6FmCc678fNssBnmyUAKK5RIj 1KXK9Ef939OQ0PY4yMyCbSkjksRjTLIib92HsYB//+3mcelcrOcNaNVXSoz0Wg4NKkIj Mvzhs2qoZZK0gmuFAyjRW715QTGakOanIKSSS340ZpcLN095CxgrmwiangOqERPdwds1 LkhQ== 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=G677aq/uRJQFlNf2MOfZhMeeR+Ww2WAIN6eR7wWAbxk=; b=zXuTz9mv0c+H2dy4wPjoAmqcex/lPt1IRPCW5GLFJfLeT7/UMW0B4htHdYS+O0o8v/ rKBWk8aO5gy6IVQ6r/2h6V2DXvxbocGyZhJ3QITAhvhVq7DFF+WxtWkIVZzHIPbJYeoz dP/RblJnBpOobj5smZp8LRwoWFkULWIjxb1wPRSvTwNwtCYeLhPnL4VpAjVRdhRz4UOv 5rXdVHIIltBpeWUOyyj1LrI4HGHZ5rfs2x6f5KYxO2py1oT14O8i1QZXSb04jL+2Si31 /aV0EkRR4ggBiMStn7WiZJ+yVs4/PCBImnhT4R4AwNdtdWdum1a6SFzIhXqEuQT4Fe8r GXKg== X-Gm-Message-State: AOAM532l5ZkWPQi55eZfbtqojXjoNo3QK3pCd7ftW7hY2+WOhjknSKM+ kQUiyTV5N8s3byR06fuU0+4WK8P1+dLD X-Google-Smtp-Source: ABdhPJxghSrSMMpEZbAslxqwwvel4CRcbGbXVSy/h5IKRrBTgZcWz+X77CZE8W6GCJva3K6YdMGmuIS7lreQ X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a81:d00d:: with SMTP id v13mr908075ywi.179.1644575700833; Fri, 11 Feb 2022 02:35:00 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:09 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-17-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 16/22] perf test: Add extra diagnostics to maps test 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 , Hao Luo 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" Dump the resultant and comparison maps on failure. Signed-off-by: Ian Rogers --- tools/perf/tests/maps.c | 51 +++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index a58274598587..38c1ec0074d1 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include #include "tests.h" @@ -17,22 +18,42 @@ static int check_maps(struct map_def *merged, unsigned = int size, struct maps *ma { struct map_rb_node *rb_node; unsigned int i =3D 0; - - maps__for_each_entry(maps, rb_node) { - struct map *map =3D rb_node->map; - - if (i > 0) - TEST_ASSERT_VAL("less maps expected", (map && i < size) || (!map && i = =3D=3D size)); - - TEST_ASSERT_VAL("wrong map start", map->start =3D=3D merged[i].start); - TEST_ASSERT_VAL("wrong map end", map->end =3D=3D merged[i].end); - TEST_ASSERT_VAL("wrong map name", !strcmp(map->dso->name, merged[i].nam= e)); - TEST_ASSERT_VAL("wrong map refcnt", refcount_read(&map->refcnt) =3D=3D 1= ); - - i++; + bool failed =3D false; + + if (maps__nr_maps(maps) !=3D size) { + pr_debug("Expected %d maps, got %d", size, maps__nr_maps(maps)); + failed =3D true; + } else { + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; + + if (map__start(map) !=3D merged[i].start || + map__end(map) !=3D merged[i].end || + strcmp(map__dso(map)->name, merged[i].name) || + refcount_read(&map->refcnt) !=3D 1) { + failed =3D true; + } + i++; + } } - - return TEST_OK; + if (failed) { + pr_debug("Expected:\n"); + for (i =3D 0; i < size; i++) { + pr_debug("\tstart: %" PRIu64 " end: %" PRIu64 " name: '%s' refcnt: 1\n", + merged[i].start, merged[i].end, merged[i].name); + } + pr_debug("Got:\n"); + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; + + pr_debug("\tstart: %" PRIu64 " end: %" PRIu64 " name: '%s' refcnt: %d\n= ", + map__start(map), + map__end(map), + map__dso(map)->name, + refcount_read(&map->refcnt)); + } + } + return failed ? TEST_FAIL : TEST_OK; } =20 static int test__maps__merge_in(struct test_suite *t __maybe_unused, int s= ubtest __maybe_unused) --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 CEA56C4332F for ; Fri, 11 Feb 2022 10:35:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245089AbiBKKff (ORCPT ); Fri, 11 Feb 2022 05:35:35 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349025AbiBKKfG (ORCPT ); Fri, 11 Feb 2022 05:35:06 -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 1FCA2EA9 for ; Fri, 11 Feb 2022 02:35:04 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id f32-20020a25b0a0000000b0061dad37dcd6so17759150ybj.16 for ; Fri, 11 Feb 2022 02:35:04 -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=UGsKZnw8VLef09itDvIN0uubt8K78U8H5noB1akwlYQ=; b=qPFa/BmTnJyKCQj1lQy20izhcI5dZGargFOCnI+uAY7B83o2EeSpwpzuAFk675V0Qo 3Z54Lut568TED76lUb08zrruzf054/DvXBr7MF4ScCFfDWIY3KRsVdfdaHajFqZbeUJd HB5JA1EjgjOxhRpdcRtwQydBedorODiwnDwJMYdmI+VTy2WON2yxSGRcyABHsjwN5O3a iJbTmIhZI/WuY+CrT+VzZ/27CfnzjOQVE9kiutiGVFjE2RvnlLsot/UZrFW/45HXC1gD YvdWsISzOZAovUQAFon0Cg6U+ET8QjTQQgipiVDZKpPPKznqia+72sKem2lkyzz6hPhD bM8A== 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=UGsKZnw8VLef09itDvIN0uubt8K78U8H5noB1akwlYQ=; b=V/PvQKa7Qb/cVeWEJELedQ5ofWbVwO7etqBkCshT0EITvodbBXUC1ynCYGd2SFGJLo 5x9U/m20DCet1xe8+8oRGwrf4sU+MYMgZRoj13/uaBaw8lORkEH0bBQsAcXxglq26v7O uIcm7lIKqdGQjKjkMkpHH3fE9EftQZ6MljlE0qH2w6bgWR2TFClik/YR5wS9PI7GmO80 WypxXzTxA/g0ffVZI6eFRscPUPxoVDPHBlTbQC6EOty/2pbq8PcHcAItTPO78Ys4taoC OrJ9VL5j6A8oFZXnMeyiZhyFtpShwVFAEofvb1eeju8E7kpGjyX5gfB3uTHLuM4b2TFS /ynQ== X-Gm-Message-State: AOAM531tuqJjiyPTRfmxJ3TiDJe5doMciCwi2wxAcJ2PjkvD1s8+LSfM icBdGajgR32jgpBbGB6F1b2bG46zX20Y X-Google-Smtp-Source: ABdhPJz/+t+HivuxKtsdEKQzAx6pkU2BsNGvQZMz7j8W6vRH2iunJxeO0aRX/wl86jEF8P75FWf7m/CFCYR5 X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:4943:: with SMTP id w64mr726186yba.619.1644575703290; Fri, 11 Feb 2022 02:35:03 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:10 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-18-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 17/22] perf map: Changes to reference counting 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 , Hao Luo 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" When a pointer to a map exists do a get, when that pointer is overwritten or freed, put the map. This avoids issues with gets and puts being inconsistently used causing, use after puts, etc. Reference count checking and address sanitizer were used to identify issues. Signed-off-by: Ian Rogers --- tools/perf/tests/hists_cumulate.c | 14 ++++- tools/perf/tests/hists_filter.c | 14 ++++- tools/perf/tests/hists_link.c | 18 +++++- tools/perf/tests/hists_output.c | 12 +++- tools/perf/tests/mmap-thread-lookup.c | 3 +- tools/perf/util/callchain.c | 9 +-- tools/perf/util/event.c | 8 ++- tools/perf/util/hist.c | 10 ++-- tools/perf/util/machine.c | 80 ++++++++++++++++----------- 9 files changed, 118 insertions(+), 50 deletions(-) diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cum= ulate.c index 17f4fcd6bdce..28f5eb41eed9 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -112,6 +112,7 @@ static int add_hist_entries(struct hists *hists, struct= machine *machine) } =20 fake_samples[i].thread =3D al.thread; + map__put(fake_samples[i].map); fake_samples[i].map =3D al.map; fake_samples[i].sym =3D al.sym; } @@ -147,15 +148,23 @@ static void del_hist_entries(struct hists *hists) } } =20 +static void put_fake_samples(void) +{ + size_t i; + + for (i =3D 0; i < ARRAY_SIZE(fake_samples); i++) + map__put(fake_samples[i].map); +} + typedef int (*test_fn_t)(struct evsel *, struct machine *); =20 #define COMM(he) (thread__comm_str(he->thread)) -#define DSO(he) (he->ms.map->dso->short_name) +#define DSO(he) (map__dso(he->ms.map)->short_name) #define SYM(he) (he->ms.sym->name) #define CPU(he) (he->cpu) #define PID(he) (he->thread->tid) #define DEPTH(he) (he->callchain->max_depth) -#define CDSO(cl) (cl->ms.map->dso->short_name) +#define CDSO(cl) (map__dso(cl->ms.map)->short_name) #define CSYM(cl) (cl->ms.sym->name) =20 struct result { @@ -733,6 +742,7 @@ static int test__hists_cumulate(struct test_suite *test= __maybe_unused, int subt /* tear down everything */ evlist__delete(evlist); machines__exit(&machines); + put_fake_samples(); =20 return err; } diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filte= r.c index 08cbeb9e39ae..bcd46244182a 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -89,6 +89,7 @@ static int add_hist_entries(struct evlist *evlist, } =20 fake_samples[i].thread =3D al.thread; + map__put(fake_samples[i].map); fake_samples[i].map =3D al.map; fake_samples[i].sym =3D al.sym; } @@ -101,6 +102,14 @@ static int add_hist_entries(struct evlist *evlist, return TEST_FAIL; } =20 +static void put_fake_samples(void) +{ + size_t i; + + for (i =3D 0; i < ARRAY_SIZE(fake_samples); i++) + map__put(fake_samples[i].map); +} + static int test__hists_filter(struct test_suite *test __maybe_unused, int = subtest __maybe_unused) { int err =3D TEST_FAIL; @@ -194,7 +203,7 @@ static int test__hists_filter(struct test_suite *test _= _maybe_unused, int subtes hists__filter_by_thread(hists); =20 /* now applying dso filter for 'kernel' */ - hists->dso_filter =3D fake_samples[0].map->dso; + hists->dso_filter =3D map__dso(fake_samples[0].map); hists__filter_by_dso(hists); =20 if (verbose > 2) { @@ -288,7 +297,7 @@ static int test__hists_filter(struct test_suite *test _= _maybe_unused, int subtes =20 /* now applying all filters at once. */ hists->thread_filter =3D fake_samples[1].thread; - hists->dso_filter =3D fake_samples[1].map->dso; + hists->dso_filter =3D map__dso(fake_samples[1].map); hists__filter_by_thread(hists); hists__filter_by_dso(hists); =20 @@ -322,6 +331,7 @@ static int test__hists_filter(struct test_suite *test _= _maybe_unused, int subtes evlist__delete(evlist); reset_output_field(); machines__exit(&machines); + put_fake_samples(); =20 return err; } diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index c575e13a850d..060e8731feff 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -6,6 +6,7 @@ #include "evsel.h" #include "evlist.h" #include "machine.h" +#include "map.h" #include "parse-events.h" #include "hists_common.h" #include "util/mmap.h" @@ -94,6 +95,7 @@ static int add_hist_entries(struct evlist *evlist, struct= machine *machine) } =20 fake_common_samples[k].thread =3D al.thread; + map__put(fake_common_samples[k].map); fake_common_samples[k].map =3D al.map; fake_common_samples[k].sym =3D al.sym; } @@ -126,11 +128,24 @@ static int add_hist_entries(struct evlist *evlist, st= ruct machine *machine) return -1; } =20 +static void put_fake_samples(void) +{ + size_t i, j; + + for (i =3D 0; i < ARRAY_SIZE(fake_common_samples); i++) + map__put(fake_common_samples[i].map); + for (i =3D 0; i < ARRAY_SIZE(fake_samples); i++) { + for (j =3D 0; j < ARRAY_SIZE(fake_samples[0]); j++) + map__put(fake_samples[i][j].map); + } +} + static int find_sample(struct sample *samples, size_t nr_samples, struct thread *t, struct map *m, struct symbol *s) { while (nr_samples--) { - if (samples->thread =3D=3D t && samples->map =3D=3D m && + if (samples->thread =3D=3D t && + samples->map =3D=3D m && samples->sym =3D=3D s) return 1; samples++; @@ -336,6 +351,7 @@ static int test__hists_link(struct test_suite *test __m= aybe_unused, int subtest evlist__delete(evlist); reset_output_field(); machines__exit(&machines); + put_fake_samples(); =20 return err; } diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_outpu= t.c index 0bde4a768c15..4af6916491e5 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -78,6 +78,7 @@ static int add_hist_entries(struct hists *hists, struct m= achine *machine) } =20 fake_samples[i].thread =3D al.thread; + map__put(fake_samples[i].map); fake_samples[i].map =3D al.map; fake_samples[i].sym =3D al.sym; } @@ -113,10 +114,18 @@ static void del_hist_entries(struct hists *hists) } } =20 +static void put_fake_samples(void) +{ + size_t i; + + for (i =3D 0; i < ARRAY_SIZE(fake_samples); i++) + map__put(fake_samples[i].map); +} + typedef int (*test_fn_t)(struct evsel *, struct machine *); =20 #define COMM(he) (thread__comm_str(he->thread)) -#define DSO(he) (he->ms.map->dso->short_name) +#define DSO(he) (map__dso(he->ms.map)->short_name) #define SYM(he) (he->ms.sym->name) #define CPU(he) (he->cpu) #define PID(he) (he->thread->tid) @@ -620,6 +629,7 @@ static int test__hists_output(struct test_suite *test _= _maybe_unused, int subtes /* tear down everything */ evlist__delete(evlist); machines__exit(&machines); + put_fake_samples(); =20 return err; } diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-= thread-lookup.c index a4301fc7b770..898eda55b7a8 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -202,7 +202,8 @@ static int mmap_events(synth_cb synth) break; } =20 - pr_debug("map %p, addr %" PRIx64 "\n", al.map, al.map->start); + pr_debug("map %p, addr %" PRIx64 "\n", al.map, map__start(al.map)); + map__put(al.map); } =20 machine__delete_threads(machine); diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index a8cfd31a3ff0..ae65b7bc9ab7 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -583,7 +583,7 @@ fill_node(struct callchain_node *node, struct callchain= _cursor *cursor) } call->ip =3D cursor_node->ip; call->ms =3D cursor_node->ms; - map__get(call->ms.map); + call->ms.map =3D map__get(call->ms.map); call->srcline =3D cursor_node->srcline; =20 if (cursor_node->branch) { @@ -1061,7 +1061,7 @@ int callchain_cursor_append(struct callchain_cursor *= cursor, node->ip =3D ip; map__zput(node->ms.map); node->ms =3D *ms; - map__get(node->ms.map); + node->ms.map =3D map__get(node->ms.map); node->branch =3D branch; node->nr_loop_iter =3D nr_loop_iter; node->iter_cycles =3D iter_cycles; @@ -1109,7 +1109,8 @@ int fill_callchain_info(struct addr_location *al, str= uct callchain_cursor_node * struct machine *machine =3D maps__machine(node->ms.maps); =20 al->maps =3D node->ms.maps; - al->map =3D node->ms.map; + map__put(al->map); + al->map =3D map__get(node->ms.map); al->sym =3D node->ms.sym; al->srcline =3D node->srcline; al->addr =3D node->ip; @@ -1530,7 +1531,7 @@ int callchain_node__make_parent_list(struct callchain= _node *node) goto out; *new =3D *chain; new->has_children =3D false; - map__get(new->ms.map); + new->ms.map =3D map__get(new->ms.map); list_add_tail(&new->list, &head); } parent =3D parent->parent; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 54a1d4df5f70..266318d5d006 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -484,13 +484,14 @@ size_t perf_event__fprintf_text_poke(union perf_event= *event, struct machine *ma if (machine) { struct addr_location al; =20 - al.map =3D maps__find(machine__kernel_maps(machine), tp->addr); + al.map =3D map__get(maps__find(machine__kernel_maps(machine), tp->addr)); if (al.map && map__load(al.map) >=3D 0) { al.addr =3D map__map_ip(al.map, tp->addr); al.sym =3D map__find_symbol(al.map, al.addr); if (al.sym) ret +=3D symbol__fprintf_symname_offs(al.sym, &al, fp); } + map__put(al.map); } ret +=3D fprintf(fp, " old len %u new len %u\n", tp->old_len, tp->new_len= ); old =3D true; @@ -581,6 +582,7 @@ struct map *thread__find_map(struct thread *thread, u8 = cpumode, u64 addr, al->filtered =3D 0; =20 if (machine =3D=3D NULL) { + map__put(al->map); al->map =3D NULL; return NULL; } @@ -599,6 +601,7 @@ struct map *thread__find_map(struct thread *thread, u8 = cpumode, u64 addr, al->level =3D 'u'; } else { al->level =3D 'H'; + map__put(al->map); al->map =3D NULL; =20 if ((cpumode =3D=3D PERF_RECORD_MISC_GUEST_USER || @@ -613,7 +616,7 @@ struct map *thread__find_map(struct thread *thread, u8 = cpumode, u64 addr, return NULL; } =20 - al->map =3D maps__find(maps, al->addr); + al->map =3D map__get(maps__find(maps, al->addr)); if (al->map !=3D NULL) { /* * Kernel maps might be changed when loading symbols so loading @@ -768,6 +771,7 @@ int machine__resolve(struct machine *machine, struct ad= dr_location *al, */ void addr_location__put(struct addr_location *al) { + map__zput(al->map); thread__zput(al->thread); } =20 diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index f19ac6eb4775..4dbb1dbf3679 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -446,7 +446,7 @@ static int hist_entry__init(struct hist_entry *he, memset(&he->stat, 0, sizeof(he->stat)); } =20 - map__get(he->ms.map); + he->ms.map =3D map__get(he->ms.map); =20 if (he->branch_info) { /* @@ -461,13 +461,13 @@ static int hist_entry__init(struct hist_entry *he, memcpy(he->branch_info, template->branch_info, sizeof(*he->branch_info)); =20 - map__get(he->branch_info->from.ms.map); - map__get(he->branch_info->to.ms.map); + he->branch_info->from.ms.map =3D map__get(he->branch_info->from.ms.map); + he->branch_info->to.ms.map =3D map__get(he->branch_info->to.ms.map); } =20 if (he->mem_info) { - map__get(he->mem_info->iaddr.ms.map); - map__get(he->mem_info->daddr.ms.map); + he->mem_info->iaddr.ms.map =3D map__get(he->mem_info->iaddr.ms.map); + he->mem_info->daddr.ms.map =3D map__get(he->mem_info->daddr.ms.map); } =20 if (hist_entry__has_callchains(he) && symbol_conf.use_callchain) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 940fb2a50dfd..49e4891e92b7 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -783,33 +783,42 @@ static int machine__process_ksymbol_register(struct m= achine *machine, { struct symbol *sym; struct map *map =3D maps__find(machine__kernel_maps(machine), event->ksym= bol.addr); + bool put_map =3D false; + int err =3D 0; =20 if (!map) { struct dso *dso =3D dso__new(event->ksymbol.name); - int err; =20 - if (dso) { - dso->kernel =3D DSO_SPACE__KERNEL; - map =3D map__new2(0, dso); - dso__put(dso); + if (!dso) { + err =3D -ENOMEM; + goto out; } - - if (!dso || !map) { - return -ENOMEM; + dso->kernel =3D DSO_SPACE__KERNEL; + map =3D map__new2(0, dso); + dso__put(dso); + if (!map) { + err =3D -ENOMEM; + goto out; } - + /* + * The inserted map has a get on it, we need to put to release + * the reference count here, but do it after all accesses are + * done. + */ + put_map =3D true; if (event->ksymbol.ksym_type =3D=3D PERF_RECORD_KSYMBOL_TYPE_OOL) { - map->dso->binary_type =3D DSO_BINARY_TYPE__OOL; - map->dso->data.file_size =3D event->ksymbol.len; - dso__set_loaded(map->dso); + map__dso(map)->binary_type =3D DSO_BINARY_TYPE__OOL; + map__dso(map)->data.file_size =3D event->ksymbol.len; + dso__set_loaded(map__dso(map)); } =20 map->start =3D event->ksymbol.addr; - map->end =3D map->start + event->ksymbol.len; + map->end =3D map__start(map) + event->ksymbol.len; err =3D maps__insert(machine__kernel_maps(machine), map); - map__put(map); - if (err) - return err; + if (err) { + err =3D -ENOMEM; + goto out; + } =20 dso__set_loaded(dso); =20 @@ -819,13 +828,18 @@ static int machine__process_ksymbol_register(struct m= achine *machine, } } =20 - sym =3D symbol__new(map->map_ip(map, map->start), + sym =3D symbol__new(map__map_ip(map, map__start(map)), event->ksymbol.len, 0, 0, event->ksymbol.name); - if (!sym) - return -ENOMEM; - dso__insert_symbol(map->dso, sym); - return 0; + if (!sym) { + err =3D -ENOMEM; + goto out; + } + dso__insert_symbol(map__dso(map), sym); +out: + if (put_map) + map__put(map); + return err; } =20 static int machine__process_ksymbol_unregister(struct machine *machine, @@ -925,14 +939,11 @@ static struct map *machine__addnew_module_map(struct = machine *machine, u64 start goto out; =20 err =3D maps__insert(machine__kernel_maps(machine), map); - - /* Put the map here because maps__insert already got it */ - map__put(map); - /* If maps__insert failed, return NULL. */ - if (err) + if (err) { + map__put(map); map =3D NULL; - + } out: /* put the dso here, corresponding to machine__findnew_module_dso */ dso__put(dso); @@ -1228,6 +1239,7 @@ __machine__create_kernel_maps(struct machine *machine= , struct dso *kernel) /* In case of renewal the kernel map, destroy previous one */ machine__destroy_kernel_maps(machine); =20 + map__put(machine->vmlinux_map); machine->vmlinux_map =3D map__new2(0, kernel); if (machine->vmlinux_map =3D=3D NULL) return -ENOMEM; @@ -1513,6 +1525,7 @@ static int machine__create_module(void *arg, const ch= ar *name, u64 start, map->end =3D start + size; =20 dso__kernel_module_get_build_id(map__dso(map), machine->root_dir); + map__put(map); return 0; } =20 @@ -1558,16 +1571,18 @@ static void machine__set_kernel_mmap(struct machine= *machine, static int machine__update_kernel_mmap(struct machine *machine, u64 start, u64 end) { - struct map *map =3D machine__kernel_map(machine); + struct map *orig, *updated; int err; =20 - map__get(map); - maps__remove(machine__kernel_maps(machine), map); + orig =3D machine->vmlinux_map; + updated =3D map__get(orig); =20 + machine->vmlinux_map =3D updated; machine__set_kernel_mmap(machine, start, end); + maps__remove(machine__kernel_maps(machine), orig); + err =3D maps__insert(machine__kernel_maps(machine), updated); + map__put(orig); =20 - err =3D maps__insert(machine__kernel_maps(machine), map); - map__put(map); return err; } =20 @@ -2246,6 +2261,7 @@ static int add_callchain_ip(struct thread *thread, err =3D callchain_cursor_append(cursor, ip, &ms, branch, flags, nr_loop_iter, iter_cycles, branch_from, srcline); + map__put(al.map); return err; } =20 --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 8EA01C433F5 for ; Fri, 11 Feb 2022 10:35:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349050AbiBKKfu (ORCPT ); Fri, 11 Feb 2022 05:35:50 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349032AbiBKKfH (ORCPT ); Fri, 11 Feb 2022 05:35:07 -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 7961CEB1 for ; Fri, 11 Feb 2022 02:35:06 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id t8-20020a259ac8000000b00619a3b5977fso17999380ybo.5 for ; Fri, 11 Feb 2022 02:35:06 -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=zI7UttEId1m8qD/b8dbgmy1+n+4tYzA6No79RQaEvJg=; b=c95z3s6HerUsvP/6fia6eJdMvptjfAevj7eDXrXgwIk+/Yf1znUfb9oQkMdkukkGxo /NqRN6P/TR/OZgj3LaDZza8AEC1H/0xz/5VKrU72Vfaeze5e9ZGStAeEN7V7WuzLKfU5 WOU5qYZ7Q2y0t3BDkFPJ1BMwqNwqlVaVTolLTpGlPMdSst9KaiBCS5Ls0CGq9NIKrkLD skEflOenO7ka0YxTJqL2cSVyBut2gJDQLX9m7BfEhm+xP4MPnl6Yx+ONFzEsTmdYiRT5 NdgL+/eiQFsuP5u/4IRBw2MLSecRQ8PbLZlhXTmcvRh8w8NIRYAB2aiK+PXuK4zZ+Rc2 zJ6g== 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=zI7UttEId1m8qD/b8dbgmy1+n+4tYzA6No79RQaEvJg=; b=tykJOBTyF8Y9lwa7ma+hCc6T8PlHw9rOkp2cv5xiFZ8ZZ2bzIJEyJ2IgLUquNKzVXi U813UM8cQsXGEQEl2y8lXbZluIVFdtQnNyN7WRgl6H2gDR0/Y0+nOsW2mGmijpeL5cRP GmtoOft1UrC4s2uKtlrMQ0RVkOoaTm0RLlIs0TRdfXQOzDLt17HSeZYD04DbtyoZf/ta iX/9CEs3FG4fIC+N69OY7RVxc+yG3m2iex6Mpq4su264GyJSZcegEnm28e0DJ8WDNA1b DWBVzfLqzObikgSZ9e7QrCS+oROkMahy5rrKY8y7GSVY5pgGS0lMaRx58MwDrgPVupz9 2CZQ== X-Gm-Message-State: AOAM530Qao0YGRmJRC8rsfaDo0PKPfs8RDM1DJYnJxCUyEhgD2Tg7PNG /Ie5oD10mdOLicr/anYmW4DTuSsOsZRC X-Google-Smtp-Source: ABdhPJyR3EAY6q+MUpkB9EnOpbAkDmuicacRDgwQL12qDtgndGv3SRuWrd0G2nqwMG5XhpypEUcVLVx/mWE5 X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a81:3350:: with SMTP id z77mr859862ywz.281.1644575705706; Fri, 11 Feb 2022 02:35:05 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:11 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-19-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 18/22] libperf: Add reference count checking macros. 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 , Hao Luo 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" The macros serve as a way to debug use of a reference counted struct. The macros add a memory allocated pointer that is interposed between the reference counted original struct at a get and freed by a put. The pointer replaces the original struct, so use of the struct name via APIs remains unchanged. Signed-off-by: Ian Rogers --- tools/lib/perf/include/internal/rc_check.h | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 tools/lib/perf/include/internal/rc_check.h diff --git a/tools/lib/perf/include/internal/rc_check.h b/tools/lib/perf/in= clude/internal/rc_check.h new file mode 100644 index 000000000000..30d12f9c7b52 --- /dev/null +++ b/tools/lib/perf/include/internal/rc_check.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LIBPERF_INTERNAL_RC_CHECK_H +#define __LIBPERF_INTERNAL_RC_CHECK_H + +#include +#include + +/* + * Shared reference count checking macros. + * + * Reference count checking is an approach to sanitizing the use of refere= nce + * counted structs. It leverages address and leak sanitizers to make sure = gets + * are paired with a put. Reference count checking adds a malloc-ed layer = of + * indirection on a get, and frees it on a put. A missed put will be repor= ted as + * a memory leak. A double put will be reported as a double free. Accessing + * after a put will cause a use-after-free and/or a segfault. + */ + +#ifndef REFCNT_CHECKING +/* Replaces "struct foo" so that the pointer may be interposed. */ +#define DECLARE_RC_STRUCT(struct_name) \ + struct struct_name + +/* Declare a reference counted struct variable. */ +#define RC_STRUCT(struct_name) struct struct_name + +/* + * Interpose the indirection. Result will hold the indirection and object = is the + * reference counted struct. + */ +#define ADD_RC_CHK(result, object) (result =3D object, object) + +/* Strip the indirection layer. */ +#define RC_CHK_ACCESS(object) object + +/* Frees the object and the indirection layer. */ +#define RC_CHK_FREE(object) free(object) + +/* A get operation adding the indirection layer. */ +#define RC_CHK_GET(result, object) ADD_RC_CHK(result, object) + +/* A put operation removing the indirection layer. */ +#define RC_CHK_PUT(object) {} + +#else + +/* Replaces "struct foo" so that the pointer may be interposed. */ +#define DECLARE_RC_STRUCT(struct_name) \ + struct original_##struct_name; \ + struct struct_name { \ + struct original_##struct_name *orig; \ + }; \ + struct original_##struct_name + +/* Declare a reference counted struct variable. */ +#define RC_STRUCT(struct_name) struct original_##struct_name + +/* + * Interpose the indirection. Result will hold the indirection and object = is the + * reference counted struct. + */ +#define ADD_RC_CHK(result, object) \ + ( \ + object ? (result =3D malloc(sizeof(*result)), \ + result ? (result->orig =3D object, result) \ + : (result =3D NULL, NULL)) \ + : (result =3D NULL, NULL) \ + ) + +/* Strip the indirection layer. */ +#define RC_CHK_ACCESS(object) object->orig + +/* Frees the object and the indirection layer. */ +#define RC_CHK_FREE(object) \ + do { \ + zfree(&object->orig); \ + free(object); \ + } while(0) + +/* A get operation adding the indirection layer. */ +#define RC_CHK_GET(result, object) ADD_RC_CHK(result, (object ? object->or= ig : NULL)) + +/* A put operation removing the indirection layer. */ +#define RC_CHK_PUT(object) \ + do { \ + if (object) { \ + object->orig =3D NULL; \ + free(object); \ + } \ + } while(0) + +#endif + +#endif /* __LIBPERF_INTERNAL_RC_CHECK_H */ --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 6BEDAC433F5 for ; Fri, 11 Feb 2022 10:35:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345029AbiBKKfr (ORCPT ); Fri, 11 Feb 2022 05:35:47 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349037AbiBKKfL (ORCPT ); Fri, 11 Feb 2022 05:35:11 -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 B5650EB7 for ; Fri, 11 Feb 2022 02:35:08 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id b12-20020a056902030c00b0061d720e274aso17826696ybs.20 for ; Fri, 11 Feb 2022 02:35:08 -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=6d1r0MKAfef54H2RZ8ZU6nqFJP/LwK7hjdkyzVqNyNE=; b=adBVbCtuDAkvGvULrIi9dR+76CQ5f0L1d85ql1LgTNYCSJL5iIr1DWLSacUS9S1216 KBNU1mOSYB1wUlU+t8tshnhHoEFiVJphdI08sDeT9G+p9N8YT5L/ZgBhHRD23WxQBnVK 1nvz1E8O2PpRI4OWr7gtuL4+d76T/WPO3y5wn8u6k6tEQITml4g2x5gMX4NgkCzKATKl DQDHBCNNRTOpUu8YuNjjEjjQxp724ELO98i9oVFGAWi2AiUB3igSQVaKqU/Q4TUWCLke ar0JWeHoufoIgZO24ePXZm0PYoGKVG6Zxt3W9Bg8mALWILFAMnBqa2BzhQGmo8/wKEi3 mL5Q== 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=6d1r0MKAfef54H2RZ8ZU6nqFJP/LwK7hjdkyzVqNyNE=; b=iAv7s/4CjQgq8JL+s57Rgbq0fdQEBQcL4B0Saw8t5L1jZUIr6AgjCmMbgB1LD+5N14 bRW5eyuv4wnGvNmEU1NokOWpVwfwy30+LbNRFES/478cLMKMLjLdREfTyGd9PfwaNRzP RpQi1GI3jvPhkJjJi5Joa+aXzoWdB2MWQlQSya9vDpneo2v8f3G0wkmL+eSUPC19LkOi KwmJwIbOqp4nms5jo0U75pPOjUmEbbLJ13zY/M6AcjMiJwxRldVQOMHPAyRbOKbLKR+V VTJG/DX7cnlqROOywTGmO/Ce0LHGHos1qE91k3kwUsA2IILhGwAjYi2OOJ00OwY4J9k7 cNcg== X-Gm-Message-State: AOAM5303m3qVbYUlGMI8WVsjLNmatShJV9HSmfGZ8An552JQfqvnPelE cjl6yrDaY1oNDFQVb5HoQp/NOngNSH2e X-Google-Smtp-Source: ABdhPJx5N2Rhxk1SA+wWm70Cy0hPH0HhHxn80mBgqfJXr5J94aJH5piE7O8/ZWeAb9W9PSa6DvTbdxQJAJ3J X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a81:c644:: with SMTP id q4mr938106ywj.206.1644575707943; Fri, 11 Feb 2022 02:35:07 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:12 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-20-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 19/22] 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 , Hao Luo 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, handled via the RC_CHK_ACCESS 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 | 93 +++++++++++++----------- tools/lib/perf/include/internal/cpumap.h | 4 +- tools/perf/tests/cpumap.c | 2 +- tools/perf/util/cpumap.c | 36 +++++---- tools/perf/util/pmu.c | 8 +- 5 files changed, 75 insertions(+), 68 deletions(-) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index ee66760f1e63..e22cfed7a633 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -10,16 +10,16 @@ #include #include =20 -static struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus) +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) { + struct perf_cpu_map *result; + RC_STRUCT(perf_cpu_map) *cpus =3D + malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus); + if (ADD_RC_CHK(result, cpus)) { cpus->nr =3D nr_cpus; refcount_set(&cpus->refcnt, 1); - } - return cpus; + return result; } =20 struct perf_cpu_map *perf_cpu_map__dummy_new(void) @@ -27,7 +27,7 @@ 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; + RC_CHK_ACCESS(cpus)->map[0].cpu =3D -1; =20 return cpus; } @@ -35,23 +35,30 @@ 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(&RC_CHK_ACCESS(map)->refcnt) !=3D 0, "cpu_map refcnt unbalanced\n"); - free(map); + RC_CHK_FREE(map); } } =20 struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map) { - if (map) - refcount_inc(&map->refcnt); - return map; + struct perf_cpu_map *result; + + if (RC_CHK_GET(result, map)) + refcount_inc(&RC_CHK_ACCESS(map)->refcnt); + + return result; } =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(&RC_CHK_ACCESS(map)->refcnt)) + cpu_map__delete(map); + else + RC_CHK_PUT(map); + } } =20 static struct perf_cpu_map *cpu_map__default_new(void) @@ -68,7 +75,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; + RC_CHK_ACCESS(cpus)->map[i].cpu =3D i; } =20 return cpus; @@ -94,15 +101,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(RC_CHK_ACCESS(cpus)->map, tmp_cpus, payload_size); + qsort(RC_CHK_ACCESS(cpus)->map, nr_cpus, sizeof(struct perf_cpu), cmp_cp= u); /* 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 || + RC_CHK_ACCESS(cpus)->map[i].cpu !=3D RC_CHK_ACCESS(cpus)->map[i - 1= ].cpu) + RC_CHK_ACCESS(cpus)->map[j++].cpu =3D RC_CHK_ACCESS(cpus)->map[i].cpu; } - cpus->nr =3D j; + RC_CHK_ACCESS(cpus)->nr =3D j; assert(j <=3D nr_cpus); } return cpus; @@ -263,20 +271,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 < RC_CHK_ACCESS(cpus)->nr) + return RC_CHK_ACCESS(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 ? RC_CHK_ACCESS(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 ? RC_CHK_ACCESS(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 +295,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 RC_CHK_ACCESS(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 RC_CHK_ACCESS(cpus)->map[idx]; =20 if (cpu_at_idx.cpu =3D=3D cpu.cpu) return idx; @@ -316,7 +324,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 RC_CHK_ACCESS(map)->nr > 0 ? RC_CHK_ACCESS(map)->map[RC_CHK_ACCESS= (map)->nr - 1] : result; } =20 /* @@ -337,37 +345,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 (RC_CHK_ACCESS(orig)->nr =3D=3D RC_CHK_ACCESS(other)->nr && + !memcmp(RC_CHK_ACCESS(orig)->map, RC_CHK_ACCESS(other)->map, + RC_CHK_ACCESS(orig)->nr * sizeof(struct perf_cpu))) return orig; =20 - tmp_len =3D orig->nr + other->nr; + tmp_len =3D RC_CHK_ACCESS(orig)->nr + RC_CHK_ACCESS(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 < RC_CHK_ACCESS(orig)->nr && j < RC_CHK_ACCESS(other)->nr) { + if (RC_CHK_ACCESS(orig)->map[i].cpu <=3D RC_CHK_ACCESS(other)->map[j].cp= u) { + if (RC_CHK_ACCESS(orig)->map[i].cpu =3D=3D RC_CHK_ACCESS(other)->map[j]= .cpu) j++; - tmp_cpus[k++] =3D orig->map[i++]; + tmp_cpus[k++] =3D RC_CHK_ACCESS(orig)->map[i++]; } else - tmp_cpus[k++] =3D other->map[j++]; + tmp_cpus[k++] =3D RC_CHK_ACCESS(other)->map[j++]; } =20 - while (i < orig->nr) - tmp_cpus[k++] =3D orig->map[i++]; + while (i < RC_CHK_ACCESS(orig)->nr) + tmp_cpus[k++] =3D RC_CHK_ACCESS(orig)->map[i++]; =20 - while (j < other->nr) - tmp_cpus[k++] =3D other->map[j++]; + while (j < RC_CHK_ACCESS(other)->nr) + tmp_cpus[k++] =3D RC_CHK_ACCESS(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..1a584d4f125c 100644 --- a/tools/lib/perf/include/internal/cpumap.h +++ b/tools/lib/perf/include/internal/cpumap.h @@ -3,6 +3,7 @@ #define __LIBPERF_INTERNAL_CPUMAP_H =20 #include +#include =20 /** A wrapper around a CPU to avoid confusion with the perf_cpu_map's map'= s indices. */ struct perf_cpu { @@ -16,7 +17,7 @@ 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 { +DECLARE_RC_STRUCT(perf_cpu_map) { refcount_t refcnt; /** Length of the map array. */ int nr; @@ -28,6 +29,7 @@ struct perf_cpu_map { #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 f94929ebb54b..d4a7c289b062 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -69,7 +69,7 @@ static int process_event_cpus(struct perf_tool *tool __ma= ybe_unused, 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(&map->refcnt) =3D=3D 1); + TEST_ASSERT_VAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(map)->refcnt= ) =3D=3D 1); perf_cpu_map__put(map); return 0; } diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 12b2243222b0..d35a849c896a 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -37,9 +37,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; + RC_CHK_ACCESS(map)->map[i].cpu =3D -1; else - map->map[i].cpu =3D (int) cpus->cpu[i]; + RC_CHK_ACCESS(map)->map[i].cpu =3D (int) cpus->cpu[i]; } } =20 @@ -58,7 +58,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; + RC_CHK_ACCESS(map)->map[i++].cpu =3D cpu; } return map; =20 @@ -84,16 +84,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); + RC_CHK_ACCESS(cpus)->map[i].cpu =3D -1; } =20 return cpus; @@ -163,7 +160,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 +184,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 +491,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 +543,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 +554,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 9a1c7e63e663..015aa92100ab 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -2013,13 +2013,13 @@ int perf_pmu__cpus_match(struct perf_pmu *pmu, stru= ct perf_cpu_map *cpus, =20 perf_cpu_map__for_each_cpu(cpu, i, cpus) { if (!perf_cpu_map__has(pmu_cpus, cpu)) - unmatched_cpus->map[unmatched_nr++] =3D cpu; + RC_CHK_ACCESS(unmatched_cpus)->map[unmatched_nr++] =3D cpu; else - matched_cpus->map[matched_nr++] =3D cpu; + RC_CHK_ACCESS(matched_cpus)->map[matched_nr++] =3D cpu; } =20 - unmatched_cpus->nr =3D unmatched_nr; - matched_cpus->nr =3D matched_nr; + RC_CHK_ACCESS(unmatched_cpus)->nr =3D unmatched_nr; + RC_CHK_ACCESS(matched_cpus)->nr =3D matched_nr; *mcpus_ptr =3D matched_cpus; *ucpus_ptr =3D unmatched_cpus; return 0; --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 8298AC433EF for ; Fri, 11 Feb 2022 10:35:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349091AbiBKKf6 (ORCPT ); Fri, 11 Feb 2022 05:35:58 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:33094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348100AbiBKKfW (ORCPT ); Fri, 11 Feb 2022 05:35:22 -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 9880FF0A for ; Fri, 11 Feb 2022 02:35:11 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id b187-20020a251bc4000000b0061e15c5024fso17726590ybb.4 for ; Fri, 11 Feb 2022 02:35:11 -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=zyq69l/QVAkxXrxXDog9O8gGEjbc6SWZFCZOP5MHjmE=; b=nS7Eb2pXZ+ByX3nm9gjhVzC0gTTDAANWrPg5S3lXDlqlm32x02fVCrRZdIs39DzmP8 q1w9sLalMakyPZUblaz/SChaht4TC8IiMZYVy+fvCSf9fojd65aUmfnTK3uSqNQAw3oY YVYf2ly3OreNvru8XjuRIUPrhcgFkeabLeZk3h5UAQzuVrpznKq83GS0q4/1DQ09EJJy RzagEScoYmXozaiwy2p5WZ50kwpjbtIqhPu9z4YbMtDHX3SeqkClkB6XmSI4fHcQ+rwu DHhC3cRhan178Qr+ErZeXET/52OChFNtKML1az0etQLz7HxAQ6yM9+ncVi1K3thhK/10 igxQ== 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=zyq69l/QVAkxXrxXDog9O8gGEjbc6SWZFCZOP5MHjmE=; b=5Vd39QMpG2V7464A4UlT9jFJ6B83qP5mwUx07nxpNG0MXiEHncLaB1hYEx2XD3dXlI 5QOqb0q1WcCHMUfg07EdWHknNqe/ch+WotWdgfgL+N00Ybm+MN+Vk8QM8Qpmjv6wi5vy EEYptU7/lRLPd1DU7Apb+H0XTVLitLMkRn9LvcILokidGcdpeLxfXwCe49bNy9oJvEK6 MnHhY0s/yZ9VV8XMKh79DYKNSqSsJsVSeJZCWwzBIDr3sJn7zfBTxvMd6s2mnRNw47SG RChjCTkVeoP3SOnon4kvoyLDuB6HEUKTSnDVIKR2Je76gbHGkrSgpnzsz48seeoSsKw/ rrEw== X-Gm-Message-State: AOAM531CABLnWrG1dAXzJR5YiIg7o4JtaSjb3NpU9mk+PY+NG+dNVd2T w/k1DQarZigcQJWXAxMwz1q7hY3zijuh X-Google-Smtp-Source: ABdhPJwkCXA3fH2BvEatWT+xS82zXFSx39XwsP47ZQw4Zuz7Z73JI56eq7DF9PbWtZO5TmVGyVYq3pRx70Rx X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a81:ae45:: with SMTP id g5mr952439ywk.90.1644575710554; Fri, 11 Feb 2022 02:35:10 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:13 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-21-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 20/22] perf namespaces: 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 , Hao Luo 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" Add reference count checking controlled by REFCNT_CHECKING ifdef. The reference count checking interposes an allocated pointer between the reference counted struct on a get and frees the pointer on a put. Accesses after a put cause faults and use after free, missed puts are caughts as leaks and double puts are double frees. This checking helped resolve a memory leak and use after free: https://lore.kernel.org/linux-perf-users/CAP-5=3DfWZH20L4kv-BwVtGLwR=3DEm3A= OOT+Q4QGivvQuYn5AsPRg@mail.gmail.com/ Signed-off-by: Ian Rogers --- tools/perf/util/namespaces.c | 132 ++++++++++++++++++++--------------- tools/perf/util/namespaces.h | 3 +- 2 files changed, 78 insertions(+), 57 deletions(-) diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index dd536220cdb9..8a3b7bd27b19 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c @@ -60,7 +60,7 @@ void namespaces__free(struct namespaces *namespaces) free(namespaces); } =20 -static int nsinfo__get_nspid(struct nsinfo *nsi, const char *path) +static int nsinfo__get_nspid(pid_t *tgid, pid_t *nstgid, bool *in_pidns, c= onst char *path) { FILE *f =3D NULL; char *statln =3D NULL; @@ -74,19 +74,18 @@ static int nsinfo__get_nspid(struct nsinfo *nsi, const = char *path) while (getline(&statln, &linesz, f) !=3D -1) { /* Use tgid if CONFIG_PID_NS is not defined. */ if (strstr(statln, "Tgid:") !=3D NULL) { - nsi->tgid =3D (pid_t)strtol(strrchr(statln, '\t'), - NULL, 10); - nsi->nstgid =3D nsinfo__tgid(nsi); + *tgid =3D (pid_t)strtol(strrchr(statln, '\t'), NULL, 10); + *nstgid =3D *tgid; } =20 if (strstr(statln, "NStgid:") !=3D NULL) { nspid =3D strrchr(statln, '\t'); - nsi->nstgid =3D (pid_t)strtol(nspid, NULL, 10); + *nstgid =3D (pid_t)strtol(nspid, NULL, 10); /* * If innermost tgid is not the first, process is in a different * PID namespace. */ - nsi->in_pidns =3D (statln + sizeof("NStgid:") - 1) !=3D nspid; + *in_pidns =3D (statln + sizeof("NStgid:") - 1) !=3D nspid; break; } } @@ -121,8 +120,8 @@ int nsinfo__init(struct nsinfo *nsi) * want to switch as part of looking up dso/map data. */ if (old_stat.st_ino !=3D new_stat.st_ino) { - nsi->need_setns =3D true; - nsi->mntns_path =3D newns; + RC_CHK_ACCESS(nsi)->need_setns =3D true; + RC_CHK_ACCESS(nsi)->mntns_path =3D newns; newns =3D NULL; } =20 @@ -132,13 +131,26 @@ int nsinfo__init(struct nsinfo *nsi) if (snprintf(spath, PATH_MAX, "/proc/%d/status", nsinfo__pid(nsi)) >=3D P= ATH_MAX) goto out; =20 - rv =3D nsinfo__get_nspid(nsi, spath); + rv =3D nsinfo__get_nspid(&RC_CHK_ACCESS(nsi)->tgid, &RC_CHK_ACCESS(nsi)->= nstgid, + &RC_CHK_ACCESS(nsi)->in_pidns, spath); =20 out: free(newns); return rv; } =20 +static struct nsinfo *nsinfo__alloc(void) +{ + struct nsinfo *res; + RC_STRUCT(nsinfo) *nsi; + + nsi =3D calloc(1, sizeof(*nsi)); + if (ADD_RC_CHK(res, nsi)) + refcount_set(&nsi->refcnt, 1); + + return res; +} + struct nsinfo *nsinfo__new(pid_t pid) { struct nsinfo *nsi; @@ -146,22 +158,21 @@ struct nsinfo *nsinfo__new(pid_t pid) if (pid =3D=3D 0) return NULL; =20 - nsi =3D calloc(1, sizeof(*nsi)); - if (nsi !=3D NULL) { - nsi->pid =3D pid; - nsi->tgid =3D pid; - nsi->nstgid =3D pid; - nsi->need_setns =3D false; - nsi->in_pidns =3D false; - /* Init may fail if the process exits while we're trying to look - * at its proc information. In that case, save the pid but - * don't try to enter the namespace. - */ - if (nsinfo__init(nsi) =3D=3D -1) - nsi->need_setns =3D false; + nsi =3D nsinfo__alloc(); + if (!nsi) + return NULL; =20 - refcount_set(&nsi->refcnt, 1); - } + RC_CHK_ACCESS(nsi)->pid =3D pid; + RC_CHK_ACCESS(nsi)->tgid =3D pid; + RC_CHK_ACCESS(nsi)->nstgid =3D pid; + RC_CHK_ACCESS(nsi)->need_setns =3D false; + RC_CHK_ACCESS(nsi)->in_pidns =3D false; + /* Init may fail if the process exits while we're trying to look at its + * proc information. In that case, save the pid but don't try to enter + * the namespace. + */ + if (nsinfo__init(nsi) =3D=3D -1) + RC_CHK_ACCESS(nsi)->need_setns =3D false; =20 return nsi; } @@ -173,21 +184,21 @@ struct nsinfo *nsinfo__copy(const struct nsinfo *nsi) if (nsi =3D=3D NULL) return NULL; =20 - nnsi =3D calloc(1, sizeof(*nnsi)); - if (nnsi !=3D NULL) { - nnsi->pid =3D nsinfo__pid(nsi); - nnsi->tgid =3D nsinfo__tgid(nsi); - nnsi->nstgid =3D nsinfo__nstgid(nsi); - nnsi->need_setns =3D nsinfo__need_setns(nsi); - nnsi->in_pidns =3D nsinfo__in_pidns(nsi); - if (nsi->mntns_path) { - nnsi->mntns_path =3D strdup(nsi->mntns_path); - if (!nnsi->mntns_path) { - free(nnsi); - return NULL; - } + nnsi =3D nsinfo__alloc(); + if (!nnsi) + return NULL; + + RC_CHK_ACCESS(nnsi)->pid =3D nsinfo__pid(nsi); + RC_CHK_ACCESS(nnsi)->tgid =3D nsinfo__tgid(nsi); + RC_CHK_ACCESS(nnsi)->nstgid =3D nsinfo__nstgid(nsi); + RC_CHK_ACCESS(nnsi)->need_setns =3D nsinfo__need_setns(nsi); + RC_CHK_ACCESS(nnsi)->in_pidns =3D nsinfo__in_pidns(nsi); + if (RC_CHK_ACCESS(nsi)->mntns_path) { + RC_CHK_ACCESS(nnsi)->mntns_path =3D strdup(RC_CHK_ACCESS(nsi)->mntns_pat= h); + if (!RC_CHK_ACCESS(nnsi)->mntns_path) { + nsinfo__put(nnsi); + return NULL; } - refcount_set(&nnsi->refcnt, 1); } =20 return nnsi; @@ -195,51 +206,60 @@ struct nsinfo *nsinfo__copy(const struct nsinfo *nsi) =20 static void nsinfo__delete(struct nsinfo *nsi) { - zfree(&nsi->mntns_path); - free(nsi); + if (nsi) { + WARN_ONCE(refcount_read(&RC_CHK_ACCESS(nsi)->refcnt) !=3D 0, + "nsinfo refcnt unbalanced\n"); + zfree(&RC_CHK_ACCESS(nsi)->mntns_path); + RC_CHK_FREE(nsi); + } } =20 struct nsinfo *nsinfo__get(struct nsinfo *nsi) { - if (nsi) - refcount_inc(&nsi->refcnt); - return nsi; + struct nsinfo *result; + + if (RC_CHK_GET(result, nsi)) + refcount_inc(&RC_CHK_ACCESS(nsi)->refcnt); + + return result; } =20 void nsinfo__put(struct nsinfo *nsi) { - if (nsi && refcount_dec_and_test(&nsi->refcnt)) + if (nsi && refcount_dec_and_test(&RC_CHK_ACCESS(nsi)->refcnt)) nsinfo__delete(nsi); + else + RC_CHK_PUT(nsi); } =20 bool nsinfo__need_setns(const struct nsinfo *nsi) { - return nsi->need_setns; + return RC_CHK_ACCESS(nsi)->need_setns; } =20 void nsinfo__clear_need_setns(struct nsinfo *nsi) { - nsi->need_setns =3D false; + RC_CHK_ACCESS(nsi)->need_setns =3D false; } =20 pid_t nsinfo__tgid(const struct nsinfo *nsi) { - return nsi->tgid; + return RC_CHK_ACCESS(nsi)->tgid; } =20 pid_t nsinfo__nstgid(const struct nsinfo *nsi) { - return nsi->nstgid; + return RC_CHK_ACCESS(nsi)->nstgid; } =20 pid_t nsinfo__pid(const struct nsinfo *nsi) { - return nsi->pid; + return RC_CHK_ACCESS(nsi)->pid; } =20 pid_t nsinfo__in_pidns(const struct nsinfo *nsi) { - return nsi->in_pidns; + return RC_CHK_ACCESS(nsi)->in_pidns; } =20 void nsinfo__mountns_enter(struct nsinfo *nsi, @@ -256,7 +276,7 @@ void nsinfo__mountns_enter(struct nsinfo *nsi, nc->oldns =3D -1; nc->newns =3D -1; =20 - if (!nsi || !nsi->need_setns) + if (!nsi || !RC_CHK_ACCESS(nsi)->need_setns) return; =20 if (snprintf(curpath, PATH_MAX, "/proc/self/ns/mnt") >=3D PATH_MAX) @@ -270,7 +290,7 @@ void nsinfo__mountns_enter(struct nsinfo *nsi, if (oldns < 0) goto errout; =20 - newns =3D open(nsi->mntns_path, O_RDONLY); + newns =3D open(RC_CHK_ACCESS(nsi)->mntns_path, O_RDONLY); if (newns < 0) goto errout; =20 @@ -339,9 +359,9 @@ int nsinfo__stat(const char *filename, struct stat *st,= struct nsinfo *nsi) =20 bool nsinfo__is_in_root_namespace(void) { - struct nsinfo nsi; + pid_t tgid =3D 0, nstgid =3D 0; + bool in_pidns =3D false; =20 - memset(&nsi, 0x0, sizeof(nsi)); - nsinfo__get_nspid(&nsi, "/proc/self/status"); - return !nsi.in_pidns; + nsinfo__get_nspid(&tgid, &nstgid, &in_pidns, "/proc/self/status"); + return !in_pidns; } diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 567829262c42..8c0731c6cbb7 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h @@ -13,6 +13,7 @@ #include #include #include +#include =20 #ifndef HAVE_SETNS_SUPPORT int setns(int fd, int nstype); @@ -29,7 +30,7 @@ struct namespaces { struct namespaces *namespaces__new(struct perf_record_namespaces *event); void namespaces__free(struct namespaces *namespaces); =20 -struct nsinfo { +DECLARE_RC_STRUCT(nsinfo) { pid_t pid; pid_t tgid; pid_t nstgid; --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 98E1CC433F5 for ; Fri, 11 Feb 2022 10:35:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349082AbiBKKf4 (ORCPT ); Fri, 11 Feb 2022 05:35:56 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346717AbiBKKfW (ORCPT ); Fri, 11 Feb 2022 05:35:22 -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 9876CEBC for ; Fri, 11 Feb 2022 02:35:13 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id b64-20020a256743000000b0061e169a5f19so17496304ybc.11 for ; Fri, 11 Feb 2022 02:35:13 -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=Oum2Nhoc7NbISccsgG5Jn7Q0d1b5FELJ2y1ISHsilug=; b=SqNd7nr8OnsH2fcSqFE+jD1XVYfw9oiItQEVbt8h2Ej1MxbdnQlpID8Zo7sh4l5QIp l7FRUjL0aJT+2yi0L1w61ooJj3Vq16s4HRL3wKgVOZvr4WxkGxCqh4kx7Hx/EPY5oZ+B CS6PRzyEntI2Rt4g+krkTRIb2yYWKsJ/NBQZ8R65ZrU1vjx1s0MW3lm1GY648jIYVCal 0Tn9Lf64mN1xD1QNO4R/P/yZDHY8ChwRrIOqHtBj7jjlnl7Dj7h7oB6K3vLpqIeUWqVs 0R9QzuJcfDiSiFYSmum8dhyorJKYnOGm38oDKemgtpCFeiXrOy+uC8mHNtBcjkwLVohh HeFw== 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=Oum2Nhoc7NbISccsgG5Jn7Q0d1b5FELJ2y1ISHsilug=; b=gpJ9lyoKCZamC3+Rdl54KQtHYXl/ARHQ0QMow6TAFR+GH/qpl8wm2etXNKgRmZMNvU 8SUElc3TTPDQ+UxqFIfkcXeZi64KZMi0HFGxuNP+rI3JQEVOQbYyQ4wvl76YJlL9fZ/t yxhS+HEm7nSYbjDLIBg8XNGv2Hw6tLZ5nW+FUqE33SU/uDS5rSsVtJTMBMwwJ68POPsX xM+X0teQ+or/GUj+E9XszDiHppsmdNfdlKFZKyJSM9EK2jYCmJsPWeFQVo5gCpNpJeTU cI+I3Pe8OJkYaE2G3H20u52pEUjPRfFS19qX0C2RMA/LXqBaEzR6cUfyy5FLEIyZZ+BH MoRg== X-Gm-Message-State: AOAM5303sR3MjNuY5WyCTWVAjwOHKVWg5y6MwAO9RHMQgU8a3ZcB6K2H YywYIOUQuIcx+zbknut8okmMHdAvdw17 X-Google-Smtp-Source: ABdhPJw45mHHWKIdSKrq1PeFf1JkKXQfDYORTcl8GBaes9P3lVQEtUrG6rPUQgh5wQqXIouuUQUUp08Dm6ty X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:4144:: with SMTP id o65mr650609yba.113.1644575712950; Fri, 11 Feb 2022 02:35:12 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:14 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-22-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 21/22] perf maps: 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 , Hao Luo 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" Add reference count checking to make sure of good use of get and put. Add and use accessors to reduce RC_CHK clutter. The only significant issue was in tests/thread-maps-share.c where reference counts were released in the reverse order to acquisition, leading to a use after put. This was fixed by reversing the put order. Signed-off-by: Ian Rogers --- tools/perf/tests/thread-maps-share.c | 29 ++++++------- tools/perf/util/maps.c | 53 +++++++++++++----------- tools/perf/util/maps.h | 17 ++++---- tools/perf/util/symbol.c | 10 ++--- tools/perf/util/unwind-libunwind-local.c | 2 +- tools/perf/util/unwind-libunwind.c | 2 +- 6 files changed, 60 insertions(+), 53 deletions(-) diff --git a/tools/perf/tests/thread-maps-share.c b/tools/perf/tests/thread= -maps-share.c index 84edd82c519e..dfe51b21bd7d 100644 --- a/tools/perf/tests/thread-maps-share.c +++ b/tools/perf/tests/thread-maps-share.c @@ -43,12 +43,12 @@ static int test__thread_maps_share(struct test_suite *t= est __maybe_unused, int s leader && t1 && t2 && t3 && other); =20 maps =3D leader->maps; - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 4); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->ref= cnt), 4); =20 /* test the maps pointer is shared */ - TEST_ASSERT_VAL("maps don't match", maps =3D=3D t1->maps); - TEST_ASSERT_VAL("maps don't match", maps =3D=3D t2->maps); - TEST_ASSERT_VAL("maps don't match", maps =3D=3D t3->maps); + TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) =3D=3D RC_CHK_ACC= ESS(t1->maps)); + TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) =3D=3D RC_CHK_ACC= ESS(t2->maps)); + TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) =3D=3D RC_CHK_ACC= ESS(t3->maps)); =20 /* * Verify the other leader was created by previous call. @@ -71,25 +71,26 @@ static int test__thread_maps_share(struct test_suite *t= est __maybe_unused, int s machine__remove_thread(machine, other_leader); =20 other_maps =3D other->maps; - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 2); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(other_maps= )->refcnt), 2); =20 - TEST_ASSERT_VAL("maps don't match", other_maps =3D=3D other_leader->maps); + TEST_ASSERT_VAL("maps don't match", + RC_CHK_ACCESS(other_maps) =3D=3D RC_CHK_ACCESS(other_leader->maps)); =20 /* release thread group */ - thread__put(leader); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 3); - - thread__put(t1); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 2); + thread__put(t3); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->ref= cnt), 3); =20 thread__put(t2); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 1); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->ref= cnt), 2); =20 - thread__put(t3); + thread__put(t1); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->ref= cnt), 1); + + thread__put(leader); =20 /* release other group */ thread__put(other_leader); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 1); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(other_maps= )->refcnt), 1); =20 thread__put(other); =20 diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 6efbcb79131c..da59204cb9bb 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -12,13 +12,13 @@ =20 static void maps__init(struct maps *maps, struct machine *machine) { - maps->entries =3D RB_ROOT; + RC_CHK_ACCESS(maps)->entries =3D RB_ROOT; init_rwsem(maps__lock(maps)); - maps->machine =3D machine; - maps->last_search_by_name =3D NULL; - maps->nr_maps =3D 0; - maps->maps_by_name =3D NULL; - refcount_set(&maps->refcnt, 1); + RC_CHK_ACCESS(maps)->machine =3D machine; + RC_CHK_ACCESS(maps)->last_search_by_name =3D NULL; + RC_CHK_ACCESS(maps)->nr_maps =3D 0; + RC_CHK_ACCESS(maps)->maps_by_name =3D NULL; + refcount_set(&RC_CHK_ACCESS(maps)->refcnt, 1); } =20 static void __maps__free_maps_by_name(struct maps *maps) @@ -26,8 +26,8 @@ static void __maps__free_maps_by_name(struct maps *maps) /* * Free everything to try to do it from the rbtree in the next search */ - zfree(&maps->maps_by_name); - maps->nr_maps_allocated =3D 0; + zfree(&RC_CHK_ACCESS(maps)->maps_by_name); + RC_CHK_ACCESS(maps)->nr_maps_allocated =3D 0; } =20 static struct map *__maps__insert(struct maps *maps, struct map *map) @@ -69,7 +69,7 @@ int maps__insert(struct maps *maps, struct map *map) goto out; } =20 - ++maps->nr_maps; + ++RC_CHK_ACCESS(maps)->nr_maps; =20 if (map__dso(map) && map__dso(map)->kernel) { struct kmap *kmap =3D map__kmap(map); @@ -86,7 +86,7 @@ int maps__insert(struct maps *maps, struct map *map) * inserted map and resort. */ if (maps__maps_by_name(maps)) { - if (maps__nr_maps(maps) > maps->nr_maps_allocated) { + if (maps__nr_maps(maps) > RC_CHK_ACCESS(maps)->nr_maps_allocated) { int nr_allocate =3D maps__nr_maps(maps) * 2; struct map **maps_by_name =3D realloc(maps__maps_by_name(maps), nr_allocate * sizeof(map)); @@ -97,8 +97,8 @@ int maps__insert(struct maps *maps, struct map *map) goto out; } =20 - maps->maps_by_name =3D maps_by_name; - maps->nr_maps_allocated =3D nr_allocate; + RC_CHK_ACCESS(maps)->maps_by_name =3D maps_by_name; + RC_CHK_ACCESS(maps)->nr_maps_allocated =3D nr_allocate; } maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] =3D map; __maps__sort_by_name(maps); @@ -120,13 +120,13 @@ void maps__remove(struct maps *maps, struct map *map) struct map_rb_node *rb_node; =20 down_write(maps__lock(maps)); - if (maps->last_search_by_name =3D=3D map) - maps->last_search_by_name =3D NULL; + if (RC_CHK_ACCESS(maps)->last_search_by_name =3D=3D map) + RC_CHK_ACCESS(maps)->last_search_by_name =3D NULL; =20 rb_node =3D maps__find_node(maps, map); assert(rb_node->map =3D=3D map); __maps__remove(maps, rb_node); - --maps->nr_maps; + --RC_CHK_ACCESS(maps)->nr_maps; if (maps__maps_by_name(maps)) __maps__free_maps_by_name(maps); up_write(maps__lock(maps)); @@ -157,33 +157,38 @@ bool maps__empty(struct maps *maps) =20 struct maps *maps__new(struct machine *machine) { - struct maps *maps =3D zalloc(sizeof(*maps)); + struct maps *res; + RC_STRUCT(maps) *maps =3D zalloc(sizeof(*maps)); =20 - if (maps !=3D NULL) - maps__init(maps, machine); + if (ADD_RC_CHK(res, maps)) + maps__init(res, machine); =20 - return maps; + return res; } =20 void maps__delete(struct maps *maps) { maps__exit(maps); unwind__finish_access(maps); - free(maps); + RC_CHK_FREE(maps); } =20 struct maps *maps__get(struct maps *maps) { - if (maps) - refcount_inc(&maps->refcnt); + struct maps *result; =20 - return maps; + if (RC_CHK_GET(result, maps)) + refcount_inc(&RC_CHK_ACCESS(maps)->refcnt); + + return result; } =20 void maps__put(struct maps *maps) { - if (maps && refcount_dec_and_test(&maps->refcnt)) + if (maps && refcount_dec_and_test(&RC_CHK_ACCESS(maps)->refcnt)) maps__delete(maps); + else + RC_CHK_PUT(maps); } =20 struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map *= *mapp) diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index bde3390c7096..0af4b7e42fca 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -8,6 +8,7 @@ #include #include #include "rwsem.h" +#include =20 struct ref_reloc_sym; struct machine; @@ -32,7 +33,7 @@ struct map *maps__find(struct maps *maps, u64 addr); for (map =3D maps__first(maps), next =3D map_rb_node__next(map); map; \ map =3D next, next =3D map_rb_node__next(map)) =20 -struct maps { +DECLARE_RC_STRUCT(maps) { struct rb_root entries; struct rw_semaphore lock; struct machine *machine; @@ -65,38 +66,38 @@ void maps__put(struct maps *maps); =20 static inline struct rb_root *maps__entries(struct maps *maps) { - return &maps->entries; + return &RC_CHK_ACCESS(maps)->entries; } =20 static inline struct machine *maps__machine(struct maps *maps) { - return maps->machine; + return RC_CHK_ACCESS(maps)->machine; } =20 static inline struct rw_semaphore *maps__lock(struct maps *maps) { - return &maps->lock; + return &RC_CHK_ACCESS(maps)->lock; } =20 static inline struct map **maps__maps_by_name(struct maps *maps) { - return maps->maps_by_name; + return RC_CHK_ACCESS(maps)->maps_by_name; } =20 static inline unsigned int maps__nr_maps(const struct maps *maps) { - return maps->nr_maps; + return RC_CHK_ACCESS(maps)->nr_maps; } =20 #ifdef HAVE_LIBUNWIND_SUPPORT static inline void *maps__addr_space(struct maps *maps) { - return maps->addr_space; + return RC_CHK_ACCESS(maps)->addr_space; } =20 static inline const struct unwind_libunwind_ops *maps__unwind_libunwind_op= s(const struct maps *maps) { - return maps->unwind_libunwind_ops; + return RC_CHK_ACCESS(maps)->unwind_libunwind_ops; } #endif =20 diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 6289b3028b91..fdaeeebd6050 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2025,8 +2025,8 @@ static int map__groups__sort_by_name_from_rbtree(stru= ct maps *maps) if (maps_by_name =3D=3D NULL) return -1; =20 - maps->maps_by_name =3D maps_by_name; - maps->nr_maps_allocated =3D maps__nr_maps(maps); + RC_CHK_ACCESS(maps)->maps_by_name =3D maps_by_name; + RC_CHK_ACCESS(maps)->nr_maps_allocated =3D maps__nr_maps(maps); =20 maps__for_each_entry(maps, rb_node) maps_by_name[i++] =3D rb_node->map; @@ -2057,9 +2057,9 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) =20 down_read(maps__lock(maps)); =20 - if (maps->last_search_by_name && + if (RC_CHK_ACCESS(maps)->last_search_by_name && strcmp(map__dso(maps->last_search_by_name)->short_name, name) =3D=3D = 0) { - map =3D maps->last_search_by_name; + map =3D RC_CHK_ACCESS(maps)->last_search_by_name; goto out_unlock; } /* @@ -2075,7 +2075,7 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) maps__for_each_entry(maps, rb_node) { map =3D rb_node->map; if (strcmp(map__dso(map)->short_name, name) =3D=3D 0) { - maps->last_search_by_name =3D map; + RC_CHK_ACCESS(maps)->last_search_by_name =3D map; goto out_unlock; } } diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unw= ind-libunwind-local.c index 841ac84a93ab..e86a6e594017 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -620,7 +620,7 @@ static int _unwind__prepare_access(struct maps *maps) { void *addr_space =3D unw_create_addr_space(&accessors, 0); =20 - maps->addr_space =3D addr_space; + RC_CHK_ACCESS(maps)->addr_space =3D addr_space; if (!addr_space) { pr_err("unwind: Can't create unwind address space.\n"); return -ENOMEM; diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-li= bunwind.c index cece1ee89031..973eaa18ec75 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -14,7 +14,7 @@ struct unwind_libunwind_ops __weak *arm64_unwind_libunwin= d_ops; =20 static void unwind__register_ops(struct maps *maps, struct unwind_libunwin= d_ops *ops) { - maps->unwind_libunwind_ops =3D ops; + RC_CHK_ACCESS(maps)->unwind_libunwind_ops =3D ops; } =20 int unwind__prepare_access(struct maps *maps, struct map *map, bool *initi= alized) --=20 2.35.1.265.g69c8d7142f-goog From nobody Sun Jun 28 06:40:44 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 30CD4C433F5 for ; Fri, 11 Feb 2022 10:36:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349096AbiBKKgB (ORCPT ); Fri, 11 Feb 2022 05:36:01 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:32876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349060AbiBKKfW (ORCPT ); Fri, 11 Feb 2022 05:35:22 -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 5D591F1C for ; Fri, 11 Feb 2022 02:35:16 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id x1-20020a25a001000000b0061c64ee0196so17944574ybh.9 for ; Fri, 11 Feb 2022 02:35:16 -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=bydfP/IeA/FQ2vY0275cM3DwZ6uf7kn04PaBig786tE=; b=PMNrz+LPg3RGnca5ap5Rca9sDX+tMmTq6Jbe+hVD301DmjbsFoKAnYmdeIVDMUn7Ua Hn1uZkTybNVhzmTI/gAfTMynzPPL2nWhUwYT7VoZj/OP8FYFMlYdTaxvb7gcGY3AuVja XdLPqpUO/Wm1oyXdKkCKvXPv566OutelV7krNDUtvZRoA/t3rHtTxLwYZp7ppojc7HBw u+2q4hBzzr+dEaSofHmnnan1YhhaCxacpEhMtylx+xAzLrMhz5Et8e4rXRPD+siu2QD9 JTbwqPVOisjMc7pzrM9f/NMIWkCSYzKKUsTlrvaYU738rrwaVQ9Nwgt1+pJoR4U/khFS eseQ== 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=bydfP/IeA/FQ2vY0275cM3DwZ6uf7kn04PaBig786tE=; b=jSqXPEjzmXGHa91PuWuczpj8a6aLfIM0fhxM+Bbersrf3lBnSVjZb8l5sK9DC4YdFP sdH5XRlAQ3MHzVwggi0jXZ2VOnF/Du6wQ6oCjxDuAxjxAIoTPhGDeukwgAnGacxdh4OZ DXPXApqFneW2rQAdDv+Z9iNy1z0eJcjcUxSB3pSNql/MEWb78zEHSPKIoA/wqT4Exadw yoyTPTx1yhRY3XdHlzcVwRgGwHzQalkW1yQ8rRpbjQG6kdMoe1vBtkln7yZM7IeiarKy rm+/yPYjhJflVCKg62tt20hVQTRJb+Uwkx6N4V57WE4MxLpArc8jt8D0haVAfCWEe3xr 2SWw== X-Gm-Message-State: AOAM531an8jFk4M4/JY+EpF+PfM+sGOE7BSoL4RN/lD7cgkdFMmDNMuo iNBdZqp8MFSj7BJa2bDMp8/AV2kMN2Pn X-Google-Smtp-Source: ABdhPJyIoM4fqJlSodF6pcrAfBiNdbgleVfB2n74Pc95/Y8zMql0yy77CnzTgyQDPi8aaasu7yGIpr/bwQNr X-Received: from irogers.svl.corp.google.com ([2620:15c:2cd:202:2d98:3ad9:1d8a:fb9b]) (user=irogers job=sendgmr) by 2002:a25:6b45:: with SMTP id o5mr681905ybm.704.1644575715542; Fri, 11 Feb 2022 02:35:15 -0800 (PST) Date: Fri, 11 Feb 2022 02:34:15 -0800 In-Reply-To: <20220211103415.2737789-1-irogers@google.com> Message-Id: <20220211103415.2737789-23-irogers@google.com> Mime-Version: 1.0 References: <20220211103415.2737789-1-irogers@google.com> X-Mailer: git-send-email 2.35.1.265.g69c8d7142f-goog Subject: [PATCH v3 22/22] perf map: 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 , Hao Luo 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" There's no strict get/put policy with map that leads to leaks or use after free. Reference count checking identifies correct pairing of gets and puts. Signed-off-by: Ian Rogers --- tools/perf/arch/s390/annotate/instructions.c | 2 +- tools/perf/builtin-top.c | 4 +- tools/perf/tests/hists_link.c | 2 +- tools/perf/tests/maps.c | 20 +++--- tools/perf/tests/vmlinux-kallsyms.c | 4 +- tools/perf/util/annotate.c | 4 +- tools/perf/util/machine.c | 26 ++++---- tools/perf/util/map.c | 65 +++++++++++--------- tools/perf/util/map.h | 34 +++++----- tools/perf/util/maps.c | 11 ++-- tools/perf/util/symbol-elf.c | 27 ++++---- tools/perf/util/symbol.c | 42 +++++++------ 12 files changed, 127 insertions(+), 114 deletions(-) diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch= /s390/annotate/instructions.c index 740f1a63bc04..9953d510f7c1 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c @@ -40,7 +40,7 @@ static int s390_call__parse(struct arch *arch, struct ins= _operands *ops, =20 if (maps__find_ams(ms->maps, &target) =3D=3D 0 && map__rip_2objdump(target.ms.map, - map->map_ip(target.ms.map, target.addr) + RC_CHK_ACCESS(map)->map_ip(target.ms.map, target.addr) ) =3D=3D ops->target.addr) ops->target.sym =3D target.ms.sym; =20 diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 8db1df7bdabe..269d2dc3647c 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -190,7 +190,7 @@ static void ui__warn_map_erange(struct map *map, struct= symbol *sym, u64 ip) if (use_browser <=3D 0) sleep(5); =20 - map->erange_warned =3D true; + RC_CHK_ACCESS(map)->erange_warned =3D true; } =20 static void perf_top__record_precise_ip(struct perf_top *top, @@ -223,7 +223,7 @@ static void perf_top__record_precise_ip(struct perf_top= *top, */ pthread_mutex_unlock(&he->hists->lock); =20 - if (err =3D=3D -ERANGE && !he->ms.map->erange_warned) + if (err =3D=3D -ERANGE && !RC_CHK_ACCESS(he->ms.map)->erange_warned) ui__warn_map_erange(he->ms.map, sym, ip); else if (err =3D=3D -ENOMEM) { pr_err("Not enough memory for annotating '%s' symbol!\n", diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 060e8731feff..6aae97c5c5a8 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -145,7 +145,7 @@ static int find_sample(struct sample *samples, size_t n= r_samples, { while (nr_samples--) { if (samples->thread =3D=3D t && - samples->map =3D=3D m && + RC_CHK_ACCESS(samples->map) =3D=3D RC_CHK_ACCESS(m) && samples->sym =3D=3D s) return 1; samples++; diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index 38c1ec0074d1..9ef13e3316cd 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -30,7 +30,7 @@ static int check_maps(struct map_def *merged, unsigned in= t size, struct maps *ma if (map__start(map) !=3D merged[i].start || map__end(map) !=3D merged[i].end || strcmp(map__dso(map)->name, merged[i].name) || - refcount_read(&map->refcnt) !=3D 1) { + refcount_read(&RC_CHK_ACCESS(map)->refcnt) !=3D 1) { failed =3D true; } i++; @@ -50,7 +50,7 @@ static int check_maps(struct map_def *merged, unsigned in= t size, struct maps *ma map__start(map), map__end(map), map__dso(map)->name, - refcount_read(&map->refcnt)); + refcount_read(&RC_CHK_ACCESS(map)->refcnt)); } } return failed ? TEST_FAIL : TEST_OK; @@ -95,8 +95,8 @@ static int test__maps__merge_in(struct test_suite *t __ma= ybe_unused, int subtest map =3D dso__new_map(bpf_progs[i].name); TEST_ASSERT_VAL("failed to create map", map); =20 - map->start =3D bpf_progs[i].start; - map->end =3D bpf_progs[i].end; + RC_CHK_ACCESS(map)->start =3D bpf_progs[i].start; + RC_CHK_ACCESS(map)->end =3D bpf_progs[i].end; TEST_ASSERT_VAL("failed to insert map", maps__insert(maps, map) =3D=3D 0= ); map__put(map); } @@ -111,16 +111,16 @@ static int test__maps__merge_in(struct test_suite *t = __maybe_unused, int subtest TEST_ASSERT_VAL("failed to create map", map_kcore3); =20 /* kcore1 map overlaps over all bpf maps */ - map_kcore1->start =3D 100; - map_kcore1->end =3D 1000; + RC_CHK_ACCESS(map_kcore1)->start =3D 100; + RC_CHK_ACCESS(map_kcore1)->end =3D 1000; =20 /* kcore2 map hides behind bpf_prog_2 */ - map_kcore2->start =3D 550; - map_kcore2->end =3D 570; + RC_CHK_ACCESS(map_kcore2)->start =3D 550; + RC_CHK_ACCESS(map_kcore2)->end =3D 570; =20 /* kcore3 map hides behind bpf_prog_3, kcore1 and adds new map */ - map_kcore3->start =3D 880; - map_kcore3->end =3D 1100; + RC_CHK_ACCESS(map_kcore3)->start =3D 880; + RC_CHK_ACCESS(map_kcore3)->end =3D 1100; =20 ret =3D maps__merge_in(maps, map_kcore1); TEST_ASSERT_VAL("failed to merge map", !ret); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index 5afab21455f1..be22822f341e 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -299,7 +299,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused ? map__dso(map)->short_name : map__dso(map)->name); if (pair) { - pair->priv =3D 1; + RC_CHK_ACCESS(pair)->priv =3D 1; } else { if (!header_printed) { pr_info("WARN: Maps only in vmlinux:\n"); @@ -335,7 +335,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused map__start(pair), map__end(pair), map__pgoff(pair)); pr_info(" %s\n", map__dso(pair)->name); - pair->priv =3D 1; + RC_CHK_ACCESS(pair)->priv =3D 1; } } =20 diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 3a7433d3e48a..6afe2aa3321c 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -281,7 +281,7 @@ static int call__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s =20 if (maps__find_ams(ms->maps, &target) =3D=3D 0 && map__rip_2objdump(target.ms.map, - map->map_ip(target.ms.map, target.addr) + RC_CHK_ACCESS(map)->map_ip(target.ms.map, target.addr) ) =3D=3D ops->target.addr) ops->target.sym =3D target.ms.sym; =20 @@ -411,7 +411,7 @@ static int jump__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s */ if (maps__find_ams(ms->maps, &target) =3D=3D 0 && map__rip_2objdump(target.ms.map, - map->map_ip(target.ms.map, target.addr) + RC_CHK_ACCESS(map)->map_ip(target.ms.map, target.addr) ) =3D=3D ops->target.addr) ops->target.sym =3D target.ms.sym; =20 diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 49e4891e92b7..d948d365c5a8 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -812,8 +812,8 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, dso__set_loaded(map__dso(map)); } =20 - map->start =3D event->ksymbol.addr; - map->end =3D map__start(map) + event->ksymbol.len; + RC_CHK_ACCESS(map)->start =3D event->ksymbol.addr; + RC_CHK_ACCESS(map)->end =3D map__start(map) + event->ksymbol.len; err =3D maps__insert(machine__kernel_maps(machine), map); if (err) { err =3D -ENOMEM; @@ -853,7 +853,7 @@ static int machine__process_ksymbol_unregister(struct m= achine *machine, if (!map) return 0; =20 - if (map !=3D machine->vmlinux_map) + if (RC_CHK_ACCESS(map) !=3D RC_CHK_ACCESS(machine->vmlinux_map)) maps__remove(machine__kernel_maps(machine), map); else { sym =3D dso__find_symbol(map__dso(map), @@ -1120,8 +1120,8 @@ int machine__create_extra_kernel_map(struct machine *= machine, if (!map) return -ENOMEM; =20 - map->end =3D xm->end; - map->pgoff =3D xm->pgoff; + RC_CHK_ACCESS(map)->end =3D xm->end; + RC_CHK_ACCESS(map)->pgoff =3D xm->pgoff; =20 kmap =3D map__kmap(map); =20 @@ -1193,7 +1193,7 @@ int machine__map_x86_64_entry_trampolines(struct mach= ine *machine, =20 dest_map =3D maps__find(kmaps, map__pgoff(map)); if (dest_map !=3D map) - map->pgoff =3D map__map_ip(dest_map, map__pgoff(map)); + RC_CHK_ACCESS(map)->pgoff =3D map__map_ip(dest_map, map__pgoff(map)); found =3D true; } if (found || machine->trampolines_mapped) @@ -1244,8 +1244,8 @@ __machine__create_kernel_maps(struct machine *machine= , struct dso *kernel) if (machine->vmlinux_map =3D=3D NULL) return -ENOMEM; =20 - machine->vmlinux_map->map_ip =3D map__identity_ip; - machine->vmlinux_map->unmap_ip =3D map__identity_ip; + RC_CHK_ACCESS(machine->vmlinux_map)->map_ip =3D map__identity_ip; + RC_CHK_ACCESS(machine->vmlinux_map)->unmap_ip =3D map__identity_ip; return maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); } =20 @@ -1522,7 +1522,7 @@ static int machine__create_module(void *arg, const ch= ar *name, u64 start, map =3D machine__addnew_module_map(machine, start, name); if (map =3D=3D NULL) return -1; - map->end =3D start + size; + RC_CHK_ACCESS(map)->end =3D start + size; =20 dso__kernel_module_get_build_id(map__dso(map), machine->root_dir); map__put(map); @@ -1558,14 +1558,14 @@ static int machine__create_modules(struct machine *= machine) static void machine__set_kernel_mmap(struct machine *machine, u64 start, u64 end) { - machine->vmlinux_map->start =3D start; - machine->vmlinux_map->end =3D end; + RC_CHK_ACCESS(machine->vmlinux_map)->start =3D start; + RC_CHK_ACCESS(machine->vmlinux_map)->end =3D end; /* * Be a bit paranoid here, some perf.data file came with * a zero sized synthesized MMAP event for the kernel. */ if (start =3D=3D 0 && end =3D=3D 0) - machine->vmlinux_map->end =3D ~0ULL; + RC_CHK_ACCESS(machine->vmlinux_map)->end =3D ~0ULL; } =20 static int machine__update_kernel_mmap(struct machine *machine, @@ -1700,7 +1700,7 @@ static int machine__process_kernel_mmap_event(struct = machine *machine, if (map =3D=3D NULL) goto out_problem; =20 - map->end =3D map__start(map) + xm->end - xm->start; + RC_CHK_ACCESS(map)->end =3D map__start(map) + xm->end - xm->start; =20 if (build_id__is_defined(bid)) dso__set_build_id(map__dso(map), bid); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 47d81e361e29..ad52c763596d 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -104,15 +104,15 @@ static inline bool replace_android_lib(const char *fi= lename, char *newfilename) =20 void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso = *dso) { - map->start =3D start; - map->end =3D end; - map->pgoff =3D pgoff; - map->reloc =3D 0; - map->dso =3D dso__get(dso); - map->map_ip =3D map__dso_map_ip; - map->unmap_ip =3D map__dso_unmap_ip; - map->erange_warned =3D false; - refcount_set(&map->refcnt, 1); + RC_CHK_ACCESS(map)->start =3D start; + RC_CHK_ACCESS(map)->end =3D end; + RC_CHK_ACCESS(map)->pgoff =3D pgoff; + RC_CHK_ACCESS(map)->reloc =3D 0; + RC_CHK_ACCESS(map)->dso =3D dso__get(dso); + RC_CHK_ACCESS(map)->map_ip =3D map__dso_map_ip; + RC_CHK_ACCESS(map)->unmap_ip =3D map__dso_unmap_ip; + RC_CHK_ACCESS(map)->erange_warned =3D false; + refcount_set(&RC_CHK_ACCESS(map)->refcnt, 1); } =20 struct map *map__new(struct machine *machine, u64 start, u64 len, @@ -120,12 +120,13 @@ struct map *map__new(struct machine *machine, u64 sta= rt, u64 len, u32 prot, u32 flags, struct build_id *bid, char *filename, struct thread *thread) { - struct map *map; + struct map *res; + RC_STRUCT(map) *map; struct nsinfo *nsi =3D NULL; struct nsinfo *nnsi; =20 map =3D malloc(sizeof(*map)); - if (map !=3D NULL) { + if (ADD_RC_CHK(res, map)) { char newfilename[PATH_MAX]; struct dso *dso; int anon, no_dso, vdso, android; @@ -168,7 +169,7 @@ struct map *map__new(struct machine *machine, u64 start= , u64 len, if (dso =3D=3D NULL) goto out_delete; =20 - map__init(map, start, start + len, pgoff, dso); + map__init(res, start, start + len, pgoff, dso); =20 if (anon || no_dso) { map->map_ip =3D map->unmap_ip =3D map__identity_ip; @@ -191,10 +192,10 @@ struct map *map__new(struct machine *machine, u64 sta= rt, u64 len, =20 dso__put(dso); } - return map; + return res; out_delete: nsinfo__put(nsi); - free(map); + RC_CHK_FREE(res); return NULL; } =20 @@ -205,17 +206,18 @@ struct map *map__new(struct machine *machine, u64 sta= rt, u64 len, */ struct map *map__new2(u64 start, struct dso *dso) { - struct map *map; + struct map *res; + RC_STRUCT(map) *map; =20 map =3D calloc(1, sizeof(*map) + (dso->kernel ? sizeof(struct kmap) : 0)); - if (map !=3D NULL) { + if (ADD_RC_CHK(res, map)) { /* * ->end will be filled after we load all the symbols */ - map__init(map, start, 0, 0, dso); + map__init(res, start, 0, 0, dso); } =20 - return map; + return res; } =20 bool __map__is_kernel(const struct map *map) @@ -277,20 +279,22 @@ bool map__has_symbols(const struct map *map) =20 static void map__exit(struct map *map) { - BUG_ON(refcount_read(&map->refcnt) !=3D 0); - dso__zput(map->dso); + BUG_ON(refcount_read(&RC_CHK_ACCESS(map)->refcnt) !=3D 0); + dso__zput(RC_CHK_ACCESS(map)->dso); } =20 void map__delete(struct map *map) { map__exit(map); - free(map); + RC_CHK_FREE(map); } =20 void map__put(struct map *map) { - if (map && refcount_dec_and_test(&map->refcnt)) + if (map && refcount_dec_and_test(&RC_CHK_ACCESS(map)->refcnt)) map__delete(map); + else + RC_CHK_PUT(map); } =20 void map__fixup_start(struct map *map) @@ -299,7 +303,7 @@ void map__fixup_start(struct map *map) struct rb_node *nd =3D rb_first_cached(symbols); if (nd !=3D NULL) { struct symbol *sym =3D rb_entry(nd, struct symbol, rb_node); - map->start =3D sym->start; + RC_CHK_ACCESS(map)->start =3D sym->start; } } =20 @@ -309,7 +313,7 @@ void map__fixup_end(struct map *map) struct rb_node *nd =3D rb_last(&symbols->rb_root); if (nd !=3D NULL) { struct symbol *sym =3D rb_entry(nd, struct symbol, rb_node); - map->end =3D sym->end; + RC_CHK_ACCESS(map)->end =3D sym->end; } } =20 @@ -376,19 +380,20 @@ struct symbol *map__find_symbol_by_name(struct map *m= ap, const char *name) =20 struct map *map__clone(struct map *from) { - struct map *map; - size_t size =3D sizeof(struct map); + struct map *res; + RC_STRUCT(map) *map; + size_t size =3D sizeof(RC_STRUCT(map)); =20 if (map__dso(from) && map__dso(from)->kernel) size +=3D sizeof(struct kmap); =20 - map =3D memdup(from, size); - if (map !=3D NULL) { + map =3D memdup(RC_CHK_ACCESS(from), size); + if (ADD_RC_CHK(res, map)) { refcount_set(&map->refcnt, 1); map->dso =3D dso__get(map->dso); } =20 - return map; + return res; } =20 size_t map__fprintf(struct map *map, FILE *fp) @@ -534,7 +539,7 @@ struct kmap *__map__kmap(struct map *map) { if (!map__dso(map) || !map__dso(map)->kernel) return NULL; - return (struct kmap *)(&map[1]); + return (struct kmap *)(&RC_CHK_ACCESS(map)[1]); } =20 struct kmap *map__kmap(struct map *map) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 99ef0464a357..6a6bc7605e75 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -10,12 +10,13 @@ #include #include #include +#include =20 struct dso; struct maps; struct machine; =20 -struct map { +DECLARE_RC_STRUCT(map) { u64 start; u64 end; bool erange_warned:1; @@ -49,52 +50,52 @@ u64 map__identity_ip(const struct map *map __maybe_unus= ed, u64 ip); =20 static inline struct dso *map__dso(const struct map *map) { - return map->dso; + return RC_CHK_ACCESS(map)->dso; } =20 static inline u64 map__map_ip(const struct map *map, u64 ip) { - return map->map_ip(map, ip); + return RC_CHK_ACCESS(map)->map_ip(map, ip); } =20 static inline u64 map__unmap_ip(const struct map *map, u64 ip) { - return map->unmap_ip(map, ip); + return RC_CHK_ACCESS(map)->unmap_ip(map, ip); } =20 static inline u64 map__start(const struct map *map) { - return map->start; + return RC_CHK_ACCESS(map)->start; } =20 static inline u64 map__end(const struct map *map) { - return map->end; + return RC_CHK_ACCESS(map)->end; } =20 static inline u64 map__pgoff(const struct map *map) { - return map->pgoff; + return RC_CHK_ACCESS(map)->pgoff; } =20 static inline u64 map__reloc(const struct map *map) { - return map->reloc; + return RC_CHK_ACCESS(map)->reloc; } =20 static inline u32 map__flags(const struct map *map) { - return map->flags; + return RC_CHK_ACCESS(map)->flags; } =20 static inline u32 map__prot(const struct map *map) { - return map->prot; + return RC_CHK_ACCESS(map)->prot; } =20 static inline bool map__priv(const struct map *map) { - return map->priv; + return RC_CHK_ACCESS(map)->priv; } =20 static inline size_t map__size(const struct map *map) @@ -119,7 +120,7 @@ struct thread; * Note: caller must ensure map->dso is not NULL (map is loaded). */ #define map__for_each_symbol(map, pos, n) \ - dso__for_each_symbol(map->dso, pos, n) + dso__for_each_symbol(map__dso(map), pos, n) =20 /* map__for_each_symbol_with_name - iterate over the symbols in the given = map * that have the given name @@ -153,9 +154,12 @@ struct map *map__clone(struct map *map); =20 static inline struct map *map__get(struct map *map) { - if (map) - refcount_inc(&map->refcnt); - return map; + struct map *result; + + if (RC_CHK_GET(result, map)) + refcount_inc(&RC_CHK_ACCESS(map)->refcnt); + + return result; } =20 void map__put(struct map *map); diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index da59204cb9bb..c579161c12c8 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -124,7 +124,7 @@ void maps__remove(struct maps *maps, struct map *map) RC_CHK_ACCESS(maps)->last_search_by_name =3D NULL; =20 rb_node =3D maps__find_node(maps, map); - assert(rb_node->map =3D=3D map); + assert(rb_node->RC_CHK_ACCESS(map) =3D=3D RC_CHK_ACCESS(map)); __maps__remove(maps, rb_node); --RC_CHK_ACCESS(maps)->nr_maps; if (maps__maps_by_name(maps)) @@ -335,7 +335,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) goto put_map; } =20 - before->end =3D map__start(map); + RC_CHK_ACCESS(before)->end =3D map__start(map); if (!__maps__insert(maps, before)) { map__put(before); err =3D -ENOMEM; @@ -355,8 +355,9 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) goto put_map; } =20 - after->start =3D map__end(map); - after->pgoff +=3D map__end(map) - map__start(pos->map); + RC_CHK_ACCESS(after)->start =3D map__end(map); + RC_CHK_ACCESS(after)->pgoff +=3D + map__end(map) - map__start(pos->map); assert(map__map_ip(pos->map, map__end(map)) =3D=3D map__map_ip(after, map__end(map))); if (!__maps__insert(maps, after)) { @@ -418,7 +419,7 @@ struct map_rb_node *maps__find_node(struct maps *maps, = struct map *map) struct map_rb_node *rb_node; =20 maps__for_each_entry(maps, rb_node) { - if (rb_node->map =3D=3D map) + if (rb_node->RC_CHK_ACCESS(map) =3D=3D RC_CHK_ACCESS(map)) return rb_node; } return NULL; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 056405d3d655..555ac6f5bd75 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -993,11 +993,11 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, */ if (*remap_kernel && dso->kernel && !kmodule) { *remap_kernel =3D false; - map->start =3D shdr->sh_addr + ref_reloc(kmap); - map->end =3D map__start(map) + shdr->sh_size; - map->pgoff =3D shdr->sh_offset; - map->map_ip =3D map__dso_map_ip; - map->unmap_ip =3D map__dso_unmap_ip; + RC_CHK_ACCESS(map)->start =3D shdr->sh_addr + ref_reloc(kmap); + RC_CHK_ACCESS(map)->end =3D map__start(map) + shdr->sh_size; + RC_CHK_ACCESS(map)->pgoff =3D shdr->sh_offset; + RC_CHK_ACCESS(map)->map_ip =3D map__dso_map_ip; + RC_CHK_ACCESS(map)->unmap_ip =3D map__dso_unmap_ip; /* Ensure maps are correctly ordered */ if (kmaps) { int err; @@ -1018,7 +1018,7 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, */ if (*remap_kernel && kmodule) { *remap_kernel =3D false; - map->pgoff =3D shdr->sh_offset; + RC_CHK_ACCESS(map)->pgoff =3D shdr->sh_offset; } =20 *curr_dsop =3D dso; @@ -1052,12 +1052,13 @@ static int dso__process_kernel_symbol(struct dso *d= so, struct map *map, map__kmap(curr_map)->kmaps =3D kmaps; =20 if (adjust_kernel_syms) { - curr_map->start =3D shdr->sh_addr + ref_reloc(kmap); - curr_map->end =3D map__start(curr_map) + shdr->sh_size; - curr_map->pgoff =3D shdr->sh_offset; + RC_CHK_ACCESS(curr_map)->start =3D shdr->sh_addr + ref_reloc(kmap); + RC_CHK_ACCESS(curr_map)->end =3D map__start(curr_map) + + shdr->sh_size; + RC_CHK_ACCESS(curr_map)->pgoff =3D shdr->sh_offset; } else { - curr_map->map_ip =3D map__identity_ip; - curr_map->unmap_ip =3D map__identity_ip; + RC_CHK_ACCESS(curr_map)->map_ip =3D map__identity_ip; + RC_CHK_ACCESS(curr_map)->unmap_ip =3D map__identity_ip; } curr_dso->symtab_type =3D dso->symtab_type; if (maps__insert(kmaps, curr_map)) @@ -1161,7 +1162,7 @@ dso__load_sym_internal(struct dso *dso, struct map *m= ap, struct symsrc *syms_ss, if (strcmp(elf_name, kmap->ref_reloc_sym->name)) continue; kmap->ref_reloc_sym->unrelocated_addr =3D sym.st_value; - map->reloc =3D kmap->ref_reloc_sym->addr - + RC_CHK_ACCESS(map)->reloc =3D kmap->ref_reloc_sym->addr - kmap->ref_reloc_sym->unrelocated_addr; break; } @@ -1172,7 +1173,7 @@ dso__load_sym_internal(struct dso *dso, struct map *m= ap, struct symsrc *syms_ss, * attempted to prelink vdso to its virtual address. */ if (dso__is_vdso(dso)) - map->reloc =3D map__start(map) - dso->text_offset; + RC_CHK_ACCESS(map)->reloc =3D map__start(map) - dso->text_offset; =20 dso->adjust_symbols =3D runtime_ss->adjust_symbols || ref_reloc(kmap); /* diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index fdaeeebd6050..39a650322300 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -253,7 +253,7 @@ void maps__fixup_end(struct maps *maps) =20 maps__for_each_entry(maps, curr) { if (prev !=3D NULL && !map__end(prev->map)) - prev->map->end =3D map__start(curr->map); + RC_CHK_ACCESS(prev->map)->end =3D map__start(curr->map); =20 prev =3D curr; } @@ -263,7 +263,7 @@ void maps__fixup_end(struct maps *maps) * last map final address. */ if (curr && !map__end(curr->map)) - curr->map->end =3D ~0ULL; + RC_CHK_ACCESS(curr->map)->end =3D ~0ULL; =20 up_write(maps__lock(maps)); } @@ -831,7 +831,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, *module++ =3D '\0'; =20 if (strcmp(map__dso(curr_map)->short_name, module)) { - if (curr_map !=3D initial_map && + if (RC_CHK_ACCESS(curr_map) !=3D RC_CHK_ACCESS(initial_map) && dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(machine)) { /* @@ -910,8 +910,8 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, return -1; } =20 - curr_map->map_ip =3D map__identity_ip; - curr_map->unmap_ip =3D map__identity_ip; + RC_CHK_ACCESS(curr_map)->map_ip =3D map__identity_ip; + RC_CHK_ACCESS(curr_map)->unmap_ip =3D map__identity_ip; if (maps__insert(kmaps, curr_map)) { dso__put(ndso); return -1; @@ -1215,8 +1215,8 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff,= void *data) return -ENOMEM; } =20 - list_node->map->end =3D map__start(list_node->map) + len; - list_node->map->pgoff =3D pgoff; + list_node->RC_CHK_ACCESS(map)->end =3D map__start(list_node->map) + len; + list_node->RC_CHK_ACCESS(map)->pgoff =3D pgoff; =20 list_add(&list_node->node, &md->maps); =20 @@ -1251,7 +1251,7 @@ int maps__merge_in(struct maps *kmaps, struct map *ne= w_map) * |new......| -> |new..| * |old....| -> |old....| */ - new_map->end =3D map__start(old_map); + RC_CHK_ACCESS(new_map)->end =3D map__start(old_map); } else { /* * |new.............| -> |new..| |new..| @@ -1272,11 +1272,12 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) goto out; } =20 - m->map->end =3D map__start(old_map); + + RC_CHK_ACCESS(m->map)->end =3D map__start(old_map); list_add_tail(&m->node, &merged); - new_map->pgoff +=3D + RC_CHK_ACCESS(new_map)->pgoff +=3D map__end(old_map) - map__start(new_map); - new_map->start =3D map__end(old_map); + RC_CHK_ACCESS(new_map)->start =3D map__end(old_map); } } else { /* @@ -1296,9 +1297,10 @@ int maps__merge_in(struct maps *kmaps, struct map *n= ew_map) * |new......| -> |new...| * |old....| -> |old....| */ - new_map->pgoff +=3D + + RC_CHK_ACCESS(new_map)->pgoff +=3D map__end(old_map) - map__start(new_map); - new_map->start =3D map__end(old_map); + RC_CHK_ACCESS(new_map)->start =3D map__end(old_map); } } } @@ -1411,14 +1413,14 @@ static int dso__load_kcore(struct dso *dso, struct = map *map, =20 new_node =3D list_entry(md.maps.next, struct map_list_node, node); list_del_init(&new_node->node); - if (new_node->map =3D=3D replacement_map) { + if (RC_CHK_ACCESS(new_node->map) =3D=3D RC_CHK_ACCESS(replacement_map)) { struct map *updated; =20 - map->start =3D map__start(new_node->map); - map->end =3D map__end(new_node->map); - map->pgoff =3D map__pgoff(new_node->map); - map->map_ip =3D new_node->map->map_ip; - map->unmap_ip =3D new_node->map->unmap_ip; + RC_CHK_ACCESS(map)->start =3D map__start(new_node->map); + RC_CHK_ACCESS(map)->end =3D map__end(new_node->map); + RC_CHK_ACCESS(map)->pgoff =3D map__pgoff(new_node->map); + RC_CHK_ACCESS(map)->map_ip =3D RC_CHK_ACCESS(new_node->map)->map_ip; + RC_CHK_ACCESS(map)->unmap_ip =3D RC_CHK_ACCESS(new_node->map)->unmap_ip; /* Ensure maps are correctly ordered */ updated =3D map__get(map); maps__remove(kmaps, map); @@ -2058,7 +2060,7 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) down_read(maps__lock(maps)); =20 if (RC_CHK_ACCESS(maps)->last_search_by_name && - strcmp(map__dso(maps->last_search_by_name)->short_name, name) =3D=3D = 0) { + strcmp(map__dso(RC_CHK_ACCESS(maps)->last_search_by_name)->short_name= , name) =3D=3D 0) { map =3D RC_CHK_ACCESS(maps)->last_search_by_name; goto out_unlock; } --=20 2.35.1.265.g69c8d7142f-goog