From nobody Sat Apr 11 02:17:41 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 2D832C25B08 for ; Wed, 17 Aug 2022 05:39:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238447AbiHQFjn (ORCPT ); Wed, 17 Aug 2022 01:39:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58396 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238433AbiHQFjj (ORCPT ); Wed, 17 Aug 2022 01:39:39 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 15A835208E for ; Tue, 16 Aug 2022 22:39:38 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-334228502a8so46272127b3.20 for ; Tue, 16 Aug 2022 22:39:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=nFjjywYL+BVjt5EDUuhdhFDZkG96RDHku4lEiPwRqSM=; b=DY963OWNxbUetRHL/zVLldA9FoKtyoCuJj5av8/bni8HuabvoELzPFFmjhpQlDSZdm OSOeUg615k9F4HcUcvzSKEM05MsmcIqWYixSKqrzPQvZbtajf8wwkbZCbXUhwJqr3fND TgMkiwHIUn61iXvBYj/h08fm0qtwu35t/7AopPODtQCqszGMUvsegiIYG6mdBEN8kwbl mZyXAf5EghM28D8MJaot1nIAmoUOXJFk9VM+gKpLuLanNhiyq8VCr3eqtuInW8ncXzb8 7ThAyVLtqSbedCRujaH6y/B9jG+RJlkbinII3b88rj1/oanhaMJlYioHzQgRUFKpBHaQ VzIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=nFjjywYL+BVjt5EDUuhdhFDZkG96RDHku4lEiPwRqSM=; b=bU0/xYJuRmROx3JA8b2JLXXrrrl9s+8HzRxK29MMGcxFfdu4N778H9jIIlGTUGqXuC Wa9x5PYe5JYvBnU9Rx5+DbPeLddSW3Gml9nDJt5rKS2iZ5T1td3wH2o0/LHgFXmE6VSf ZTa/7bqg+kvorGC0HBj1UzYNwNe5ozEEGeZQdko2go50GYS+G5jlWFPU7aGPUTwVRBCW SpdIdx3hr+5VeGB9yiVgfJ3+l6s22m0faIfAqi6FhcLnhRqQLQIe5ZzawizI2u1vcwK9 HM2WurwVeLsDcfOq6CnohHjZwOrpgX9Ia2RIUsTUSYp9TythdNsSXquIIVGxZlP3O+vF JSyw== X-Gm-Message-State: ACgBeo3jHN3w03MIdPZl1QvBFO1FEqxxGl7x+xfUJOyBhHLeHPZnqvue a+Yn3PeHkfg0ugAYCy7hWVtbKbgCUXlD X-Google-Smtp-Source: AA6agR6uvHiEAD8FKpS5Zq1mVo2EGqf4MDZxVAHCk2jlM44oEFgnPYVVKCVce46t56k7uUnIbgXr3gRUTs5f X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:3bec:858f:9a6d:63de]) (user=irogers job=sendgmr) by 2002:a25:b5c9:0:b0:67b:a397:5e24 with SMTP id d9-20020a25b5c9000000b0067ba3975e24mr17396936ybg.108.1660714777306; Tue, 16 Aug 2022 22:39:37 -0700 (PDT) Date: Tue, 16 Aug 2022 22:39:25 -0700 In-Reply-To: <20220817053930.769840-1-irogers@google.com> Message-Id: <20220817053930.769840-2-irogers@google.com> Mime-Version: 1.0 References: <20220817053930.769840-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v1 1/6] perf mutex: Wrapped usage of mutex and cond 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?=" , Nathan Chancellor , Nick Desaulniers , Tom Rix , Athira Rajeev , Weiguo Li , Pavithra Gurushankar , Thomas Richter , Ravi Bangoria , Dario Petrillo , Wenyu Liu , Hewenliang , yaowenbin , Dave Marchevsky , Andrii Nakryiko , Alexandre Truong , Kim Phillips , Leo Yan , Quentin Monnet , William Cohen , Andres Freund , Song Liu , Adrian Hunter , "=?UTF-8?q?Martin=20Li=C5=A1ka?=" , Colin Ian King , James Clark , Fangrui Song , Stephane Eranian , Kajol Jain , Andi Kleen , Alexey Bayduraev , Riccardo Mancini , Masami Hiramatsu , Christophe JAILLET , Zechuan Chen , Jason Wang , Lexi Shao , Remi Bernon , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Cc: 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" From: Pavithra Gurushankar Added a new header file mutex.h that wraps the usage of pthread_mutex_t and pthread_cond_t. By abstracting these it is possible to introduce error checking. Signed-off-by: Pavithra Gurushankar Signed-off-by: Ian Rogers --- tools/perf/util/Build | 1 + tools/perf/util/mutex.c | 97 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/mutex.h | 43 ++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 tools/perf/util/mutex.c create mode 100644 tools/perf/util/mutex.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 9dfae1bda9cc..8fd6dc8de521 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -143,6 +143,7 @@ perf-y +=3D branch.o perf-y +=3D mem2node.o perf-y +=3D clockid.o perf-y +=3D list_sort.o +perf-y +=3D mutex.o =20 perf-$(CONFIG_LIBBPF) +=3D bpf-loader.o perf-$(CONFIG_LIBBPF) +=3D bpf_map.o diff --git a/tools/perf/util/mutex.c b/tools/perf/util/mutex.c new file mode 100644 index 000000000000..d12cf0714268 --- /dev/null +++ b/tools/perf/util/mutex.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "mutex.h" + +#include "debug.h" +#include +#include + +static void check_err(const char *fn, int err) +{ + char sbuf[STRERR_BUFSIZE]; + + if (err =3D=3D 0) + return; + + pr_err("%s error: '%s'", fn, str_error_r(err, sbuf, sizeof(sbuf))); +} + +#define CHECK_ERR(err) check_err(__func__, err) + +void mutex_init(struct mutex *mtx, bool pshared) +{ + pthread_mutexattr_t attr; + + CHECK_ERR(pthread_mutexattr_init(&attr)); + +#ifndef NDEBUG + /* In normal builds enable error checking, such as recursive usage. */ + CHECK_ERR(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)); +#endif + if (pshared) + pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + + CHECK_ERR(pthread_mutex_init(&mtx->lock, &attr)); + CHECK_ERR(pthread_mutexattr_destroy(&attr)); +} + +void mutex_destroy(struct mutex *mtx) +{ + CHECK_ERR(pthread_mutex_destroy(&mtx->lock)); +} + +void mutex_lock(struct mutex *mtx) +{ + CHECK_ERR(pthread_mutex_lock(&mtx->lock)); +} + +void mutex_unlock(struct mutex *mtx) +{ + CHECK_ERR(pthread_mutex_unlock(&mtx->lock)); +} + +bool mutex_trylock(struct mutex *mtx) +{ + int ret =3D pthread_mutex_trylock(&mtx->lock); + + if (ret =3D=3D 0) + return true; /* Lock acquired. */ + + if (ret =3D=3D EBUSY) + return false; /* Lock busy. */ + + /* Print error. */ + CHECK_ERR(ret); + return false; +} + +void cond_init(struct cond *cnd, bool pshared) +{ + pthread_condattr_t attr; + + CHECK_ERR(pthread_condattr_init(&attr)); + if (pshared) + CHECK_ERR(pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)); + + CHECK_ERR(pthread_cond_init(&cnd->cond, &attr)); + CHECK_ERR(pthread_condattr_destroy(&attr)); +} + +void cond_destroy(struct cond *cnd) +{ + CHECK_ERR(pthread_cond_destroy(&cnd->cond)); +} + +void cond_wait(struct cond *cnd, struct mutex *mtx) +{ + CHECK_ERR(pthread_cond_wait(&cnd->cond, &mtx->lock)); +} + +void cond_signal(struct cond *cnd) +{ + CHECK_ERR(pthread_cond_signal(&cnd->cond)); +} + +void cond_broadcast(struct cond *cnd) +{ + CHECK_ERR(pthread_cond_broadcast(&cnd->cond)); +} diff --git a/tools/perf/util/mutex.h b/tools/perf/util/mutex.h new file mode 100644 index 000000000000..952276ad83bd --- /dev/null +++ b/tools/perf/util/mutex.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_MUTEX_H +#define __PERF_MUTEX_H + +#include +#include + +/* + * A wrapper around the mutex implementation that allows perf to error che= ck + * usage, etc. + */ +struct mutex { + pthread_mutex_t lock; +}; + +/* A wrapper around the condition variable implementation. */ +struct cond { + pthread_cond_t cond; +}; + +/* + * Initialize the mtx struct, if pshared is set then specify the process-s= hared + * rather than default process-private attribute. + */ +void mutex_init(struct mutex *mtx, bool pshared); +void mutex_destroy(struct mutex *mtx); + +void mutex_lock(struct mutex *mtx); +void mutex_unlock(struct mutex *mtx); +bool mutex_trylock(struct mutex *mtx); + +/* + * Initialize the cond struct, if pshared is set then specify the process-= shared + * rather than default process-private attribute. + */ +void cond_init(struct cond *cnd, bool pshared); +void cond_destroy(struct cond *cnd); + +void cond_wait(struct cond *cnd, struct mutex *mtx); +void cond_signal(struct cond *cnd); +void cond_broadcast(struct cond *cnd); + +#endif /* __PERF_MUTEX_H */ --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 02:17:41 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 21E7AC32789 for ; Wed, 17 Aug 2022 05:40:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238511AbiHQFj7 (ORCPT ); Wed, 17 Aug 2022 01:39:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58494 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238433AbiHQFjp (ORCPT ); Wed, 17 Aug 2022 01:39:45 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F7E05283D for ; Tue, 16 Aug 2022 22:39:41 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-32a115757b6so139686057b3.13 for ; Tue, 16 Aug 2022 22:39:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=QvlPD26rc1/ez9TK6XVR+aAU4WfudIohtAURVoM42AY=; b=oyGzJr1a9wSJ05iJdCn/kk9g+hzlMPzE/aDBspUMLFnT9ghiGfpSP+xGQ/Kuw+WNQp L3rkVWYehwGF/UgvRkqLB7tloY4hdr7IhSsX6n2xSA0vnaoA3I0ZcvqjQYvvfvVRRHA2 hC7+iuYwrq7FEAkJ+nVUqJCnY2KoUNoLqkzMGAaL6oOBvoOkSFbZ3QmOjy0SfcQ5SRRU KP0OQAy3DrSOrOLd5J3PQWli4hVtG1J2ggur+iznf1vjIzlHWwf+naD4+77s7DuIZpi8 5wjxejxkT55DFyixFf6vwCLT9JVIAnQsco63LOlwSz4gtLY3HF8RrFe4jyGVIJ9YWEor 5ycg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=QvlPD26rc1/ez9TK6XVR+aAU4WfudIohtAURVoM42AY=; b=lChUjALaiFOpMOyfW47HoQbNbzOQOU9YbCRFX0yUD6sjUWkaN7PYSTVpFRioDqgpuG eBVaAUjFERgSx5diYw6b4rMhkdPRyes5RGt7eiN8xohEdKFZJU0ptfKXWzB9NdRXbYcc 6O0ervlSSVjViyhaV0lcZq4711q+Nz5p4IRTvbu4A4fwUtaHSXldL0SIpLQMW5UiUFUn aG0joWAGiQ670eV9YtT3aY8FOrfw8nO07tjlVEdpXpl5P9/7flaZaqvgKvkZYzb1CcHU gP0HTbPFLr8pIbz7f+WJALGyTQwZ9kDtoyOFzHNr2Nk7uIPXpLaV8Mj/UpUhfxekefw1 pMUQ== X-Gm-Message-State: ACgBeo2aM/6qvzV2M8LiDcVa8SrdyHi7tC+ZOxEGXw3IoKepFUam03sy isq0bMzoxNdc7beg7eVr/MBhLBcF3FuT X-Google-Smtp-Source: AA6agR5xSiQ5hXNj619DTu0KSJJb1Di6CDQ+3Qe0PWWdx0Bk8cs8NtUJGoPlzksK6JTTWK1DlsQYgJTl4Rh5 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:3bec:858f:9a6d:63de]) (user=irogers job=sendgmr) by 2002:a25:b986:0:b0:671:a73:1ea6 with SMTP id r6-20020a25b986000000b006710a731ea6mr17925638ybg.405.1660714780300; Tue, 16 Aug 2022 22:39:40 -0700 (PDT) Date: Tue, 16 Aug 2022 22:39:26 -0700 In-Reply-To: <20220817053930.769840-1-irogers@google.com> Message-Id: <20220817053930.769840-3-irogers@google.com> Mime-Version: 1.0 References: <20220817053930.769840-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v1 2/6] perf mutex: Update use of pthread mutex/cond 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?=" , Nathan Chancellor , Nick Desaulniers , Tom Rix , Athira Rajeev , Weiguo Li , Pavithra Gurushankar , Thomas Richter , Ravi Bangoria , Dario Petrillo , Wenyu Liu , Hewenliang , yaowenbin , Dave Marchevsky , Andrii Nakryiko , Alexandre Truong , Kim Phillips , Leo Yan , Quentin Monnet , William Cohen , Andres Freund , Song Liu , Adrian Hunter , "=?UTF-8?q?Martin=20Li=C5=A1ka?=" , Colin Ian King , James Clark , Fangrui Song , Stephane Eranian , Kajol Jain , Andi Kleen , Alexey Bayduraev , Riccardo Mancini , Masami Hiramatsu , Christophe JAILLET , Zechuan Chen , Jason Wang , Lexi Shao , Remi Bernon , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Cc: 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" From: Pavithra Gurushankar pthread_mutex_t and pthread_cond_t were replaced with the new wrapped struct/functions. To avoid default initialization values, use of PTHREAD_MUTEX_INITIALIZER was replaced with mutex_init/destroy. This wasn't done for dso__data_open_lock due to no clear early initialization code. Signed-off-by: Pavithra Gurushankar Signed-off-by: Ian Rogers --- tools/perf/bench/epoll-ctl.c | 33 ++++---- tools/perf/bench/epoll-wait.c | 33 ++++---- tools/perf/bench/futex-hash.c | 33 ++++---- tools/perf/bench/futex-lock-pi.c | 33 ++++---- tools/perf/bench/futex-requeue.c | 33 ++++---- tools/perf/bench/futex-wake-parallel.c | 33 ++++---- tools/perf/bench/futex-wake.c | 33 ++++---- tools/perf/bench/numa.c | 93 ++++++++-------------- tools/perf/builtin-lock.c | 1 - tools/perf/builtin-record.c | 13 ++- tools/perf/builtin-sched.c | 67 ++++++++-------- tools/perf/builtin-top.c | 40 +++++----- tools/perf/tests/mmap-basic.c | 2 - tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/perf-record.c | 2 - tools/perf/ui/browser.c | 20 ++--- tools/perf/ui/browsers/annotate.c | 12 +-- tools/perf/ui/setup.c | 5 +- tools/perf/ui/tui/helpline.c | 5 +- tools/perf/ui/tui/progress.c | 8 +- tools/perf/ui/tui/setup.c | 8 +- tools/perf/ui/tui/util.c | 18 ++--- tools/perf/ui/ui.h | 4 +- tools/perf/util/annotate.c | 13 ++- tools/perf/util/annotate.h | 4 +- tools/perf/util/bpf-event.h | 1 - tools/perf/util/dso.c | 12 +-- tools/perf/util/dso.h | 4 +- tools/perf/util/hist.c | 6 +- tools/perf/util/hist.h | 4 +- tools/perf/util/mmap.h | 1 - tools/perf/util/symbol.c | 4 +- tools/perf/util/top.h | 5 +- 33 files changed, 281 insertions(+), 304 deletions(-) diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c index 4256dc5d6236..82309add47d1 100644 --- a/tools/perf/bench/epoll-ctl.c +++ b/tools/perf/bench/epoll-ctl.c @@ -23,6 +23,7 @@ #include #include =20 +#include "../util/mutex.h" #include "../util/stat.h" #include #include "bench.h" @@ -58,10 +59,10 @@ static unsigned int nested =3D 0; /* amount of fds to monitor, per thread */ static unsigned int nfds =3D 64; =20 -static pthread_mutex_t thread_lock; +static struct mutex thread_lock; static unsigned int threads_starting; static struct stats all_stats[EPOLL_NR_OPS]; -static pthread_cond_t thread_parent, thread_worker; +static struct cond thread_parent, thread_worker; =20 struct worker { int tid; @@ -174,12 +175,12 @@ static void *workerfn(void *arg) struct timespec ts =3D { .tv_sec =3D 0, .tv_nsec =3D 250 }; =20 - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); threads_starting--; if (!threads_starting) - pthread_cond_signal(&thread_parent); - pthread_cond_wait(&thread_worker, &thread_lock); - pthread_mutex_unlock(&thread_lock); + cond_signal(&thread_parent); + cond_wait(&thread_worker, &thread_lock); + mutex_unlock(&thread_lock); =20 /* Let 'em loose */ do { @@ -367,9 +368,9 @@ int bench_epoll_ctl(int argc, const char **argv) for (i =3D 0; i < EPOLL_NR_OPS; i++) init_stats(&all_stats[i]); =20 - pthread_mutex_init(&thread_lock, NULL); - pthread_cond_init(&thread_parent, NULL); - pthread_cond_init(&thread_worker, NULL); + mutex_init(&thread_lock, /*pshared=3D*/false); + cond_init(&thread_parent, /*pshared=3D*/false); + cond_init(&thread_worker, /*pshared=3D*/false); =20 threads_starting =3D nthreads; =20 @@ -377,11 +378,11 @@ int bench_epoll_ctl(int argc, const char **argv) =20 do_threads(worker, cpu); =20 - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); while (threads_starting) - pthread_cond_wait(&thread_parent, &thread_lock); - pthread_cond_broadcast(&thread_worker); - pthread_mutex_unlock(&thread_lock); + cond_wait(&thread_parent, &thread_lock); + cond_broadcast(&thread_worker); + mutex_unlock(&thread_lock); =20 sleep(nsecs); toggle_done(0, NULL, NULL); @@ -394,9 +395,9 @@ int bench_epoll_ctl(int argc, const char **argv) } =20 /* cleanup & report results */ - pthread_cond_destroy(&thread_parent); - pthread_cond_destroy(&thread_worker); - pthread_mutex_destroy(&thread_lock); + cond_destroy(&thread_parent); + cond_destroy(&thread_worker); + mutex_destroy(&thread_lock); =20 for (i =3D 0; i < nthreads; i++) { unsigned long t[EPOLL_NR_OPS]; diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c index 2728b0140853..2ed20c55105d 100644 --- a/tools/perf/bench/epoll-wait.c +++ b/tools/perf/bench/epoll-wait.c @@ -79,6 +79,7 @@ #include =20 #include "../util/stat.h" +#include "../util/mutex.h" #include #include "bench.h" =20 @@ -109,10 +110,10 @@ static bool multiq; /* use an epoll instance per thre= ad */ /* amount of fds to monitor, per thread */ static unsigned int nfds =3D 64; =20 -static pthread_mutex_t thread_lock; +static struct mutex thread_lock; static unsigned int threads_starting; static struct stats throughput_stats; -static pthread_cond_t thread_parent, thread_worker; +static struct cond thread_parent, thread_worker; =20 struct worker { int tid; @@ -189,12 +190,12 @@ static void *workerfn(void *arg) int to =3D nonblocking? 0 : -1; int efd =3D multiq ? w->epollfd : epollfd; =20 - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); threads_starting--; if (!threads_starting) - pthread_cond_signal(&thread_parent); - pthread_cond_wait(&thread_worker, &thread_lock); - pthread_mutex_unlock(&thread_lock); + cond_signal(&thread_parent); + cond_wait(&thread_worker, &thread_lock); + mutex_unlock(&thread_lock); =20 do { /* @@ -485,9 +486,9 @@ int bench_epoll_wait(int argc, const char **argv) getpid(), nthreads, oneshot ? " (EPOLLONESHOT semantics)": "", nfd= s, nsecs); =20 init_stats(&throughput_stats); - pthread_mutex_init(&thread_lock, NULL); - pthread_cond_init(&thread_parent, NULL); - pthread_cond_init(&thread_worker, NULL); + mutex_init(&thread_lock, /*pshared=3D*/false); + cond_init(&thread_parent, /*pshared=3D*/false); + cond_init(&thread_worker, /*pshared=3D*/false); =20 threads_starting =3D nthreads; =20 @@ -495,11 +496,11 @@ int bench_epoll_wait(int argc, const char **argv) =20 do_threads(worker, cpu); =20 - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); while (threads_starting) - pthread_cond_wait(&thread_parent, &thread_lock); - pthread_cond_broadcast(&thread_worker); - pthread_mutex_unlock(&thread_lock); + cond_wait(&thread_parent, &thread_lock); + cond_broadcast(&thread_worker); + mutex_unlock(&thread_lock); =20 /* * At this point the workers should be blocked waiting for read events @@ -522,9 +523,9 @@ int bench_epoll_wait(int argc, const char **argv) err(EXIT_FAILURE, "pthread_join"); =20 /* cleanup & report results */ - pthread_cond_destroy(&thread_parent); - pthread_cond_destroy(&thread_worker); - pthread_mutex_destroy(&thread_lock); + cond_destroy(&thread_parent); + cond_destroy(&thread_worker); + mutex_destroy(&thread_lock); =20 /* sort the array back before reporting */ if (randomize) diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index f05db4cf983d..b564ff7ba9a0 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -23,6 +23,7 @@ #include #include =20 +#include "../util/mutex.h" #include "../util/stat.h" #include #include "bench.h" @@ -34,10 +35,10 @@ static bool done =3D false; static int futex_flag =3D 0; =20 struct timeval bench__start, bench__end, bench__runtime; -static pthread_mutex_t thread_lock; +static struct mutex thread_lock; static unsigned int threads_starting; static struct stats throughput_stats; -static pthread_cond_t thread_parent, thread_worker; +static struct cond thread_parent, thread_worker; =20 struct worker { int tid; @@ -73,12 +74,12 @@ static void *workerfn(void *arg) unsigned int i; unsigned long ops =3D w->ops; /* avoid cacheline bouncing */ =20 - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); threads_starting--; if (!threads_starting) - pthread_cond_signal(&thread_parent); - pthread_cond_wait(&thread_worker, &thread_lock); - pthread_mutex_unlock(&thread_lock); + cond_signal(&thread_parent); + cond_wait(&thread_worker, &thread_lock); + mutex_unlock(&thread_lock); =20 do { for (i =3D 0; i < params.nfutexes; i++, ops++) { @@ -165,9 +166,9 @@ int bench_futex_hash(int argc, const char **argv) getpid(), params.nthreads, params.nfutexes, params.fshared ? "shar= ed":"private", params.runtime); =20 init_stats(&throughput_stats); - pthread_mutex_init(&thread_lock, NULL); - pthread_cond_init(&thread_parent, NULL); - pthread_cond_init(&thread_worker, NULL); + mutex_init(&thread_lock, /*pshared=3D*/false); + cond_init(&thread_parent, /*pshared=3D*/false); + cond_init(&thread_worker, /*pshared=3D*/false); =20 threads_starting =3D params.nthreads; pthread_attr_init(&thread_attr); @@ -203,11 +204,11 @@ int bench_futex_hash(int argc, const char **argv) CPU_FREE(cpuset); pthread_attr_destroy(&thread_attr); =20 - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); while (threads_starting) - pthread_cond_wait(&thread_parent, &thread_lock); - pthread_cond_broadcast(&thread_worker); - pthread_mutex_unlock(&thread_lock); + cond_wait(&thread_parent, &thread_lock); + cond_broadcast(&thread_worker); + mutex_unlock(&thread_lock); =20 sleep(params.runtime); toggle_done(0, NULL, NULL); @@ -219,9 +220,9 @@ int bench_futex_hash(int argc, const char **argv) } =20 /* cleanup & report results */ - pthread_cond_destroy(&thread_parent); - pthread_cond_destroy(&thread_worker); - pthread_mutex_destroy(&thread_lock); + cond_destroy(&thread_parent); + cond_destroy(&thread_worker); + mutex_destroy(&thread_lock); =20 for (i =3D 0; i < params.nthreads; i++) { unsigned long t =3D bench__runtime.tv_sec > 0 ? diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock= -pi.c index 0abb3f7ee24f..106b5554030f 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -8,6 +8,7 @@ #include =20 #include +#include "../util/mutex.h" #include "../util/stat.h" #include #include @@ -34,10 +35,10 @@ static u_int32_t global_futex =3D 0; static struct worker *worker; static bool done =3D false; static int futex_flag =3D 0; -static pthread_mutex_t thread_lock; +static struct mutex thread_lock; static unsigned int threads_starting; static struct stats throughput_stats; -static pthread_cond_t thread_parent, thread_worker; +static struct cond thread_parent, thread_worker; =20 static struct bench_futex_parameters params =3D { .runtime =3D 10, @@ -83,12 +84,12 @@ static void *workerfn(void *arg) struct worker *w =3D (struct worker *) arg; unsigned long ops =3D w->ops; =20 - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); threads_starting--; if (!threads_starting) - pthread_cond_signal(&thread_parent); - pthread_cond_wait(&thread_worker, &thread_lock); - pthread_mutex_unlock(&thread_lock); + cond_signal(&thread_parent); + cond_wait(&thread_worker, &thread_lock); + mutex_unlock(&thread_lock); =20 do { int ret; @@ -197,9 +198,9 @@ int bench_futex_lock_pi(int argc, const char **argv) getpid(), params.nthreads, params.runtime); =20 init_stats(&throughput_stats); - pthread_mutex_init(&thread_lock, NULL); - pthread_cond_init(&thread_parent, NULL); - pthread_cond_init(&thread_worker, NULL); + mutex_init(&thread_lock, /*pshared=3D*/false); + cond_init(&thread_parent, /*pshared=3D*/false); + cond_init(&thread_worker, /*pshared=3D*/false); =20 threads_starting =3D params.nthreads; pthread_attr_init(&thread_attr); @@ -208,11 +209,11 @@ int bench_futex_lock_pi(int argc, const char **argv) create_threads(worker, thread_attr, cpu); pthread_attr_destroy(&thread_attr); =20 - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); while (threads_starting) - pthread_cond_wait(&thread_parent, &thread_lock); - pthread_cond_broadcast(&thread_worker); - pthread_mutex_unlock(&thread_lock); + cond_wait(&thread_parent, &thread_lock); + cond_broadcast(&thread_worker); + mutex_unlock(&thread_lock); =20 sleep(params.runtime); toggle_done(0, NULL, NULL); @@ -224,9 +225,9 @@ int bench_futex_lock_pi(int argc, const char **argv) } =20 /* cleanup & report results */ - pthread_cond_destroy(&thread_parent); - pthread_cond_destroy(&thread_worker); - pthread_mutex_destroy(&thread_lock); + cond_destroy(&thread_parent); + cond_destroy(&thread_worker); + mutex_destroy(&thread_lock); =20 for (i =3D 0; i < params.nthreads; i++) { unsigned long t =3D bench__runtime.tv_sec > 0 ? diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requ= eue.c index b6faabfafb8e..d09509289f1d 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -15,6 +15,7 @@ #include =20 #include +#include "../util/mutex.h" #include "../util/stat.h" #include #include @@ -34,8 +35,8 @@ static u_int32_t futex1 =3D 0, futex2 =3D 0; =20 static pthread_t *worker; static bool done =3D false; -static pthread_mutex_t thread_lock; -static pthread_cond_t thread_parent, thread_worker; +static struct mutex thread_lock; +static struct cond thread_parent, thread_worker; static struct stats requeuetime_stats, requeued_stats; static unsigned int threads_starting; static int futex_flag =3D 0; @@ -82,12 +83,12 @@ static void *workerfn(void *arg __maybe_unused) { int ret; =20 - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); threads_starting--; if (!threads_starting) - pthread_cond_signal(&thread_parent); - pthread_cond_wait(&thread_worker, &thread_lock); - pthread_mutex_unlock(&thread_lock); + cond_signal(&thread_parent); + cond_wait(&thread_worker, &thread_lock); + mutex_unlock(&thread_lock); =20 while (1) { if (!params.pi) { @@ -209,9 +210,9 @@ int bench_futex_requeue(int argc, const char **argv) init_stats(&requeued_stats); init_stats(&requeuetime_stats); pthread_attr_init(&thread_attr); - pthread_mutex_init(&thread_lock, NULL); - pthread_cond_init(&thread_parent, NULL); - pthread_cond_init(&thread_worker, NULL); + mutex_init(&thread_lock, /*pshared=3D*/false); + cond_init(&thread_parent, /*pshared=3D*/false); + cond_init(&thread_worker, /*pshared=3D*/false); =20 for (j =3D 0; j < bench_repeat && !done; j++) { unsigned int nrequeued =3D 0, wakeups =3D 0; @@ -221,11 +222,11 @@ int bench_futex_requeue(int argc, const char **argv) block_threads(worker, thread_attr, cpu); =20 /* make sure all threads are already blocked */ - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); while (threads_starting) - pthread_cond_wait(&thread_parent, &thread_lock); - pthread_cond_broadcast(&thread_worker); - pthread_mutex_unlock(&thread_lock); + cond_wait(&thread_parent, &thread_lock); + cond_broadcast(&thread_worker); + mutex_unlock(&thread_lock); =20 usleep(100000); =20 @@ -297,9 +298,9 @@ int bench_futex_requeue(int argc, const char **argv) } =20 /* cleanup & report results */ - pthread_cond_destroy(&thread_parent); - pthread_cond_destroy(&thread_worker); - pthread_mutex_destroy(&thread_lock); + cond_destroy(&thread_parent); + cond_destroy(&thread_worker); + mutex_destroy(&thread_lock); pthread_attr_destroy(&thread_attr); =20 print_summary(); diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/fute= x-wake-parallel.c index e47f46a3a47e..5eb2e5a2a813 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -10,6 +10,7 @@ #include "bench.h" #include #include "../util/debug.h" +#include "../util/mutex.h" =20 #ifndef HAVE_PTHREAD_BARRIER int bench_futex_wake_parallel(int argc __maybe_unused, const char **argv _= _maybe_unused) @@ -49,8 +50,8 @@ static u_int32_t futex =3D 0; =20 static pthread_t *blocked_worker; static bool done =3D false; -static pthread_mutex_t thread_lock; -static pthread_cond_t thread_parent, thread_worker; +static struct mutex thread_lock; +static struct cond thread_parent, thread_worker; static pthread_barrier_t barrier; static struct stats waketime_stats, wakeup_stats; static unsigned int threads_starting; @@ -125,12 +126,12 @@ static void wakeup_threads(struct thread_data *td, pt= hread_attr_t thread_attr) =20 static void *blocked_workerfn(void *arg __maybe_unused) { - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); threads_starting--; if (!threads_starting) - pthread_cond_signal(&thread_parent); - pthread_cond_wait(&thread_worker, &thread_lock); - pthread_mutex_unlock(&thread_lock); + cond_signal(&thread_parent); + cond_wait(&thread_worker, &thread_lock); + mutex_unlock(&thread_lock); =20 while (1) { /* handle spurious wakeups */ if (futex_wait(&futex, 0, NULL, futex_flag) !=3D EINTR) @@ -294,9 +295,9 @@ int bench_futex_wake_parallel(int argc, const char **ar= gv) init_stats(&waketime_stats); =20 pthread_attr_init(&thread_attr); - pthread_mutex_init(&thread_lock, NULL); - pthread_cond_init(&thread_parent, NULL); - pthread_cond_init(&thread_worker, NULL); + mutex_init(&thread_lock, /*pshared=3D*/false); + cond_init(&thread_parent, /*pshared=3D*/false); + cond_init(&thread_worker, /*pshared=3D*/false); =20 for (j =3D 0; j < bench_repeat && !done; j++) { waking_worker =3D calloc(params.nwakes, sizeof(*waking_worker)); @@ -307,11 +308,11 @@ int bench_futex_wake_parallel(int argc, const char **= argv) block_threads(blocked_worker, thread_attr, cpu); =20 /* make sure all threads are already blocked */ - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); while (threads_starting) - pthread_cond_wait(&thread_parent, &thread_lock); - pthread_cond_broadcast(&thread_worker); - pthread_mutex_unlock(&thread_lock); + cond_wait(&thread_parent, &thread_lock); + cond_broadcast(&thread_worker); + mutex_unlock(&thread_lock); =20 usleep(100000); =20 @@ -332,9 +333,9 @@ int bench_futex_wake_parallel(int argc, const char **ar= gv) } =20 /* cleanup & report results */ - pthread_cond_destroy(&thread_parent); - pthread_cond_destroy(&thread_worker); - pthread_mutex_destroy(&thread_lock); + cond_destroy(&thread_parent); + cond_destroy(&thread_worker); + mutex_destroy(&thread_lock); pthread_attr_destroy(&thread_attr); =20 print_summary(); diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 201a3555f09a..eb161a755197 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -14,6 +14,7 @@ #include =20 #include +#include "../util/mutex.h" #include "../util/stat.h" #include #include @@ -34,8 +35,8 @@ static u_int32_t futex1 =3D 0; =20 static pthread_t *worker; static bool done =3D false; -static pthread_mutex_t thread_lock; -static pthread_cond_t thread_parent, thread_worker; +static struct mutex thread_lock; +static struct cond thread_parent, thread_worker; static struct stats waketime_stats, wakeup_stats; static unsigned int threads_starting; static int futex_flag =3D 0; @@ -65,12 +66,12 @@ static const char * const bench_futex_wake_usage[] =3D { =20 static void *workerfn(void *arg __maybe_unused) { - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); threads_starting--; if (!threads_starting) - pthread_cond_signal(&thread_parent); - pthread_cond_wait(&thread_worker, &thread_lock); - pthread_mutex_unlock(&thread_lock); + cond_signal(&thread_parent); + cond_wait(&thread_worker, &thread_lock); + mutex_unlock(&thread_lock); =20 while (1) { if (futex_wait(&futex1, 0, NULL, futex_flag) !=3D EINTR) @@ -178,9 +179,9 @@ int bench_futex_wake(int argc, const char **argv) init_stats(&wakeup_stats); init_stats(&waketime_stats); pthread_attr_init(&thread_attr); - pthread_mutex_init(&thread_lock, NULL); - pthread_cond_init(&thread_parent, NULL); - pthread_cond_init(&thread_worker, NULL); + mutex_init(&thread_lock, /*pshared=3D*/false); + cond_init(&thread_parent, /*pshared=3D*/false); + cond_init(&thread_worker, /*pshared=3D*/false); =20 for (j =3D 0; j < bench_repeat && !done; j++) { unsigned int nwoken =3D 0; @@ -190,11 +191,11 @@ int bench_futex_wake(int argc, const char **argv) block_threads(worker, thread_attr, cpu); =20 /* make sure all threads are already blocked */ - pthread_mutex_lock(&thread_lock); + mutex_lock(&thread_lock); while (threads_starting) - pthread_cond_wait(&thread_parent, &thread_lock); - pthread_cond_broadcast(&thread_worker); - pthread_mutex_unlock(&thread_lock); + cond_wait(&thread_parent, &thread_lock); + cond_broadcast(&thread_worker); + mutex_unlock(&thread_lock); =20 usleep(100000); =20 @@ -224,9 +225,9 @@ int bench_futex_wake(int argc, const char **argv) } =20 /* cleanup & report results */ - pthread_cond_destroy(&thread_parent); - pthread_cond_destroy(&thread_worker); - pthread_mutex_destroy(&thread_lock); + cond_destroy(&thread_parent); + cond_destroy(&thread_worker); + mutex_destroy(&thread_lock); pthread_attr_destroy(&thread_attr); =20 print_summary(); diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 20eed1e53f80..934f1fb2d723 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c @@ -6,8 +6,6 @@ */ =20 #include -/* For the CLR_() macros */ -#include =20 #include #include "../util/cloexec.h" @@ -35,6 +33,7 @@ #include =20 #include "../util/header.h" +#include "../util/mutex.h" #include #include =20 @@ -67,7 +66,7 @@ struct thread_data { u64 system_time_ns; u64 user_time_ns; double speed_gbs; - pthread_mutex_t *process_lock; + struct mutex *process_lock; }; =20 /* Parameters set by options: */ @@ -137,16 +136,16 @@ struct params { struct global_info { u8 *data; =20 - pthread_mutex_t startup_mutex; - pthread_cond_t startup_cond; + struct mutex startup_mutex; + struct cond startup_cond; int nr_tasks_started; =20 - pthread_mutex_t start_work_mutex; - pthread_cond_t start_work_cond; + struct mutex start_work_mutex; + struct cond start_work_cond; int nr_tasks_working; bool start_work; =20 - pthread_mutex_t stop_work_mutex; + struct mutex stop_work_mutex; u64 bytes_done; =20 struct thread_data *threads; @@ -524,30 +523,6 @@ static void * setup_private_data(ssize_t bytes) return alloc_data(bytes, MAP_PRIVATE, 0, g->p.init_cpu0, g->p.thp, g->p.= init_random); } =20 -/* - * Return a process-shared (global) mutex: - */ -static void init_global_mutex(pthread_mutex_t *mutex) -{ - pthread_mutexattr_t attr; - - pthread_mutexattr_init(&attr); - pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_mutex_init(mutex, &attr); -} - -/* - * Return a process-shared (global) condition variable: - */ -static void init_global_cond(pthread_cond_t *cond) -{ - pthread_condattr_t attr; - - pthread_condattr_init(&attr); - pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); - pthread_cond_init(cond, &attr); -} - static int parse_cpu_list(const char *arg) { p0.cpu_list_str =3D strdup(arg); @@ -1220,22 +1195,22 @@ static void *worker_thread(void *__tdata) } =20 if (g->p.serialize_startup) { - pthread_mutex_lock(&g->startup_mutex); + mutex_lock(&g->startup_mutex); g->nr_tasks_started++; /* The last thread wakes the main process. */ if (g->nr_tasks_started =3D=3D g->p.nr_tasks) - pthread_cond_signal(&g->startup_cond); + cond_signal(&g->startup_cond); =20 - pthread_mutex_unlock(&g->startup_mutex); + mutex_unlock(&g->startup_mutex); =20 /* Here we will wait for the main process to start us all at once: */ - pthread_mutex_lock(&g->start_work_mutex); + mutex_lock(&g->start_work_mutex); g->start_work =3D false; g->nr_tasks_working++; while (!g->start_work) - pthread_cond_wait(&g->start_work_cond, &g->start_work_mutex); + cond_wait(&g->start_work_cond, &g->start_work_mutex); =20 - pthread_mutex_unlock(&g->start_work_mutex); + mutex_unlock(&g->start_work_mutex); } =20 gettimeofday(&start0, NULL); @@ -1254,17 +1229,17 @@ static void *worker_thread(void *__tdata) val +=3D do_work(thread_data, g->p.bytes_thread, 0, 1, l, va= l); =20 if (g->p.sleep_usecs) { - pthread_mutex_lock(td->process_lock); + mutex_lock(td->process_lock); usleep(g->p.sleep_usecs); - pthread_mutex_unlock(td->process_lock); + mutex_unlock(td->process_lock); } /* * Amount of work to be done under a process-global lock: */ if (g->p.bytes_process_locked) { - pthread_mutex_lock(td->process_lock); + mutex_lock(td->process_lock); val +=3D do_work(process_data, g->p.bytes_process_locked, thread_nr, g= ->p.nr_threads, l, val); - pthread_mutex_unlock(td->process_lock); + mutex_unlock(td->process_lock); } =20 work_done =3D g->p.bytes_global + g->p.bytes_process + @@ -1361,9 +1336,9 @@ static void *worker_thread(void *__tdata) =20 free_data(thread_data, g->p.bytes_thread); =20 - pthread_mutex_lock(&g->stop_work_mutex); + mutex_lock(&g->stop_work_mutex); g->bytes_done +=3D bytes_done; - pthread_mutex_unlock(&g->stop_work_mutex); + mutex_unlock(&g->stop_work_mutex); =20 return NULL; } @@ -1373,7 +1348,7 @@ static void *worker_thread(void *__tdata) */ static void worker_process(int process_nr) { - pthread_mutex_t process_lock; + struct mutex process_lock; struct thread_data *td; pthread_t *pthreads; u8 *process_data; @@ -1381,7 +1356,7 @@ static void worker_process(int process_nr) int ret; int t; =20 - pthread_mutex_init(&process_lock, NULL); + mutex_init(&process_lock, /*pshared=3D*/false); set_taskname("process %d", process_nr); =20 /* @@ -1540,11 +1515,11 @@ static int init(void) g->data =3D setup_shared_data(g->p.bytes_global); =20 /* Startup serialization: */ - init_global_mutex(&g->start_work_mutex); - init_global_cond(&g->start_work_cond); - init_global_mutex(&g->startup_mutex); - init_global_cond(&g->startup_cond); - init_global_mutex(&g->stop_work_mutex); + mutex_init(&g->start_work_mutex, /*pshared=3D*/true); + cond_init(&g->start_work_cond, /*pshared=3D*/true); + mutex_init(&g->startup_mutex, /*pshared=3D*/true); + cond_init(&g->startup_cond, /*pshared=3D*/true); + mutex_init(&g->stop_work_mutex, /*pshared=3D*/true); =20 init_thread_data(); =20 @@ -1633,17 +1608,17 @@ static int __bench_numa(const char *name) * Wait for all the threads to start up. The last thread will * signal this process. */ - pthread_mutex_lock(&g->startup_mutex); + mutex_lock(&g->startup_mutex); while (g->nr_tasks_started !=3D g->p.nr_tasks) - pthread_cond_wait(&g->startup_cond, &g->startup_mutex); + cond_wait(&g->startup_cond, &g->startup_mutex); =20 - pthread_mutex_unlock(&g->startup_mutex); + mutex_unlock(&g->startup_mutex); =20 /* Wait for all threads to be at the start_work_cond. */ while (!threads_ready) { - pthread_mutex_lock(&g->start_work_mutex); + mutex_lock(&g->start_work_mutex); threads_ready =3D (g->nr_tasks_working =3D=3D g->p.nr_tasks); - pthread_mutex_unlock(&g->start_work_mutex); + mutex_unlock(&g->start_work_mutex); if (!threads_ready) usleep(1); } @@ -1661,10 +1636,10 @@ static int __bench_numa(const char *name) =20 start =3D stop; /* Start all threads running. */ - pthread_mutex_lock(&g->start_work_mutex); + mutex_lock(&g->start_work_mutex); g->start_work =3D true; - pthread_mutex_unlock(&g->start_work_mutex); - pthread_cond_broadcast(&g->start_work_cond); + mutex_unlock(&g->start_work_mutex); + cond_broadcast(&g->start_work_cond); } else { gettimeofday(&start, NULL); } diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index dd11d3471baf..70197c0593b1 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include =20 diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4713f0f3a6cf..02eb85677e99 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -21,6 +21,7 @@ #include "util/evsel.h" #include "util/debug.h" #include "util/mmap.h" +#include "util/mutex.h" #include "util/target.h" #include "util/session.h" #include "util/tool.h" @@ -608,17 +609,18 @@ static int process_synthesized_event(struct perf_tool= *tool, return record__write(rec, NULL, event, event->header.size); } =20 +static struct mutex synth_lock; + static int process_locked_synthesized_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - static pthread_mutex_t synth_lock =3D PTHREAD_MUTEX_INITIALIZER; int ret; =20 - pthread_mutex_lock(&synth_lock); + mutex_lock(&synth_lock); ret =3D process_synthesized_event(tool, event, sample, machine); - pthread_mutex_unlock(&synth_lock); + mutex_unlock(&synth_lock); return ret; } =20 @@ -1917,6 +1919,7 @@ static int record__synthesize(struct record *rec, boo= l tail) } =20 if (rec->opts.nr_threads_synthesize > 1) { + mutex_init(&synth_lock, /*pshared=3D*/false); perf_set_multithreaded(); f =3D process_locked_synthesized_event; } @@ -1930,8 +1933,10 @@ static int record__synthesize(struct record *rec, bo= ol tail) rec->opts.nr_threads_synthesize); } =20 - if (rec->opts.nr_threads_synthesize > 1) + if (rec->opts.nr_threads_synthesize > 1) { perf_set_singlethreaded(); + mutex_destroy(&synth_lock); + } =20 out: return err; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 2f6cd1b8b662..0f52f73be896 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -7,6 +7,7 @@ #include "util/evlist.h" #include "util/evsel.h" #include "util/evsel_fprintf.h" +#include "util/mutex.h" #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" @@ -184,8 +185,8 @@ struct perf_sched { struct task_desc **pid_to_task; struct task_desc **tasks; const struct trace_sched_handler *tp_handler; - pthread_mutex_t start_work_mutex; - pthread_mutex_t work_done_wait_mutex; + struct mutex start_work_mutex; + struct mutex work_done_wait_mutex; int profile_cpu; /* * Track the current task - that way we can know whether there's any @@ -635,10 +636,8 @@ static void *thread_func(void *ctx) again: ret =3D sem_post(&this_task->ready_for_work); BUG_ON(ret); - ret =3D pthread_mutex_lock(&sched->start_work_mutex); - BUG_ON(ret); - ret =3D pthread_mutex_unlock(&sched->start_work_mutex); - BUG_ON(ret); + mutex_lock(&sched->start_work_mutex); + mutex_unlock(&sched->start_work_mutex); =20 cpu_usage_0 =3D get_cpu_usage_nsec_self(fd); =20 @@ -652,10 +651,8 @@ static void *thread_func(void *ctx) ret =3D sem_post(&this_task->work_done_sem); BUG_ON(ret); =20 - ret =3D pthread_mutex_lock(&sched->work_done_wait_mutex); - BUG_ON(ret); - ret =3D pthread_mutex_unlock(&sched->work_done_wait_mutex); - BUG_ON(ret); + mutex_lock(&sched->work_done_wait_mutex); + mutex_unlock(&sched->work_done_wait_mutex); =20 goto again; } @@ -672,10 +669,8 @@ static void create_tasks(struct perf_sched *sched) err =3D pthread_attr_setstacksize(&attr, (size_t) max(16 * 1024, (int)PTHREAD_STACK_MIN)); BUG_ON(err); - err =3D pthread_mutex_lock(&sched->start_work_mutex); - BUG_ON(err); - err =3D pthread_mutex_lock(&sched->work_done_wait_mutex); - BUG_ON(err); + mutex_lock(&sched->start_work_mutex); + mutex_lock(&sched->work_done_wait_mutex); for (i =3D 0; i < sched->nr_tasks; i++) { struct sched_thread_parms *parms =3D malloc(sizeof(*parms)); BUG_ON(parms =3D=3D NULL); @@ -699,7 +694,7 @@ static void wait_for_tasks(struct perf_sched *sched) =20 sched->start_time =3D get_nsecs(); sched->cpu_usage =3D 0; - pthread_mutex_unlock(&sched->work_done_wait_mutex); + mutex_unlock(&sched->work_done_wait_mutex); =20 for (i =3D 0; i < sched->nr_tasks; i++) { task =3D sched->tasks[i]; @@ -707,12 +702,11 @@ static void wait_for_tasks(struct perf_sched *sched) BUG_ON(ret); sem_init(&task->ready_for_work, 0, 0); } - ret =3D pthread_mutex_lock(&sched->work_done_wait_mutex); - BUG_ON(ret); + mutex_lock(&sched->work_done_wait_mutex); =20 cpu_usage_0 =3D get_cpu_usage_nsec_parent(); =20 - pthread_mutex_unlock(&sched->start_work_mutex); + mutex_unlock(&sched->start_work_mutex); =20 for (i =3D 0; i < sched->nr_tasks; i++) { task =3D sched->tasks[i]; @@ -734,8 +728,7 @@ static void wait_for_tasks(struct perf_sched *sched) sched->runavg_parent_cpu_usage =3D (sched->runavg_parent_cpu_usage * (sch= ed->replay_repeat - 1) + sched->parent_cpu_usage)/sched->replay_repeat; =20 - ret =3D pthread_mutex_lock(&sched->start_work_mutex); - BUG_ON(ret); + mutex_lock(&sched->start_work_mutex); =20 for (i =3D 0; i < sched->nr_tasks; i++) { task =3D sched->tasks[i]; @@ -3430,8 +3423,6 @@ int cmd_sched(int argc, const char **argv) }, .cmp_pid =3D LIST_HEAD_INIT(sched.cmp_pid), .sort_list =3D LIST_HEAD_INIT(sched.sort_list), - .start_work_mutex =3D PTHREAD_MUTEX_INITIALIZER, - .work_done_wait_mutex =3D PTHREAD_MUTEX_INITIALIZER, .sort_order =3D default_sort_order, .replay_repeat =3D 10, .profile_cpu =3D -1, @@ -3545,8 +3536,10 @@ int cmd_sched(int argc, const char **argv) .fork_event =3D replay_fork_event, }; unsigned int i; - int ret; + int ret =3D 0; =20 + mutex_init(&sched.start_work_mutex, /*pshared=3D*/false); + mutex_init(&sched.work_done_wait_mutex, /*pshared=3D*/false); for (i =3D 0; i < ARRAY_SIZE(sched.curr_pid); i++) sched.curr_pid[i] =3D -1; =20 @@ -3558,11 +3551,10 @@ int cmd_sched(int argc, const char **argv) /* * Aliased to 'perf script' for now: */ - if (!strcmp(argv[0], "script")) - return cmd_script(argc, argv); - - if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) { - return __cmd_record(argc, argv); + if (!strcmp(argv[0], "script")) { + ret =3D cmd_script(argc, argv); + } else if (strlen(argv[0]) > 2 && strstarts("record", argv[0])) { + ret =3D __cmd_record(argc, argv); } else if (strlen(argv[0]) > 2 && strstarts("latency", argv[0])) { sched.tp_handler =3D &lat_ops; if (argc > 1) { @@ -3571,7 +3563,7 @@ int cmd_sched(int argc, const char **argv) usage_with_options(latency_usage, latency_options); } setup_sorting(&sched, latency_options, latency_usage); - return perf_sched__lat(&sched); + ret =3D perf_sched__lat(&sched); } else if (!strcmp(argv[0], "map")) { if (argc) { argc =3D parse_options(argc, argv, map_options, map_usage, 0); @@ -3580,7 +3572,7 @@ int cmd_sched(int argc, const char **argv) } sched.tp_handler =3D &map_ops; setup_sorting(&sched, latency_options, latency_usage); - return perf_sched__map(&sched); + ret =3D perf_sched__map(&sched); } else if (strlen(argv[0]) > 2 && strstarts("replay", argv[0])) { sched.tp_handler =3D &replay_ops; if (argc) { @@ -3588,7 +3580,7 @@ int cmd_sched(int argc, const char **argv) if (argc) usage_with_options(replay_usage, replay_options); } - return perf_sched__replay(&sched); + ret =3D perf_sched__replay(&sched); } else if (!strcmp(argv[0], "timehist")) { if (argc) { argc =3D parse_options(argc, argv, timehist_options, @@ -3604,16 +3596,21 @@ int cmd_sched(int argc, const char **argv) parse_options_usage(NULL, timehist_options, "w", true); if (sched.show_next) parse_options_usage(NULL, timehist_options, "n", true); - return -EINVAL; + ret =3D -EINVAL; + goto out; } ret =3D symbol__validate_sym_arguments(); if (ret) - return ret; + goto out; =20 - return perf_sched__timehist(&sched); + ret =3D perf_sched__timehist(&sched); } else { usage_with_options(sched_usage, sched_options); } =20 - return 0; +out: + mutex_destroy(&sched.start_work_mutex); + mutex_destroy(&sched.work_done_wait_mutex); + + return ret; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index fd8fd913c533..3757292bfe86 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -136,10 +136,10 @@ static int perf_top__parse_source(struct perf_top *to= p, struct hist_entry *he) } =20 notes =3D symbol__annotation(sym); - pthread_mutex_lock(¬es->lock); + mutex_lock(¬es->lock); =20 if (!symbol__hists(sym, top->evlist->core.nr_entries)) { - pthread_mutex_unlock(¬es->lock); + mutex_unlock(¬es->lock); pr_err("Not enough memory for annotating '%s' symbol!\n", sym->name); sleep(1); @@ -155,7 +155,7 @@ static int perf_top__parse_source(struct perf_top *top,= struct hist_entry *he) pr_err("Couldn't annotate %s: %s\n", sym->name, msg); } =20 - pthread_mutex_unlock(¬es->lock); + mutex_unlock(¬es->lock); return err; } =20 @@ -208,19 +208,19 @@ static void perf_top__record_precise_ip(struct perf_t= op *top, =20 notes =3D symbol__annotation(sym); =20 - if (pthread_mutex_trylock(¬es->lock)) + if (!mutex_trylock(¬es->lock)) return; =20 err =3D hist_entry__inc_addr_samples(he, sample, evsel, ip); =20 - pthread_mutex_unlock(¬es->lock); + mutex_unlock(¬es->lock); =20 if (unlikely(err)) { /* * This function is now called with he->hists->lock held. * Release it before going to sleep. */ - pthread_mutex_unlock(&he->hists->lock); + mutex_unlock(&he->hists->lock); =20 if (err =3D=3D -ERANGE && !he->ms.map->erange_warned) ui__warn_map_erange(he->ms.map, sym, ip); @@ -230,7 +230,7 @@ static void perf_top__record_precise_ip(struct perf_top= *top, sleep(1); } =20 - pthread_mutex_lock(&he->hists->lock); + mutex_lock(&he->hists->lock); } } =20 @@ -250,7 +250,7 @@ static void perf_top__show_details(struct perf_top *top) symbol =3D he->ms.sym; notes =3D symbol__annotation(symbol); =20 - pthread_mutex_lock(¬es->lock); + mutex_lock(¬es->lock); =20 symbol__calc_percent(symbol, evsel); =20 @@ -271,7 +271,7 @@ static void perf_top__show_details(struct perf_top *top) if (more !=3D 0) printf("%d lines not displayed, maybe increase display entries [e]\n", m= ore); out_unlock: - pthread_mutex_unlock(¬es->lock); + mutex_unlock(¬es->lock); } =20 static void perf_top__resort_hists(struct perf_top *t) @@ -836,12 +836,12 @@ static void perf_event__process_sample(struct perf_to= ol *tool, else iter.ops =3D &hist_iter_normal; =20 - pthread_mutex_lock(&hists->lock); + mutex_lock(&hists->lock); =20 if (hist_entry_iter__add(&iter, &al, top->max_stack, top) < 0) pr_err("Problem incrementing symbol period, skipping event\n"); =20 - pthread_mutex_unlock(&hists->lock); + mutex_unlock(&hists->lock); } =20 addr_location__put(&al); @@ -893,10 +893,10 @@ static void perf_top__mmap_read_idx(struct perf_top *= top, int idx) perf_mmap__consume(&md->core); =20 if (top->qe.rotate) { - pthread_mutex_lock(&top->qe.mutex); + mutex_lock(&top->qe.mutex); top->qe.rotate =3D false; - pthread_cond_signal(&top->qe.cond); - pthread_mutex_unlock(&top->qe.mutex); + cond_signal(&top->qe.cond); + mutex_unlock(&top->qe.mutex); } } =20 @@ -1100,10 +1100,10 @@ static void *process_thread(void *arg) =20 out =3D rotate_queues(top); =20 - pthread_mutex_lock(&top->qe.mutex); + mutex_lock(&top->qe.mutex); top->qe.rotate =3D true; - pthread_cond_wait(&top->qe.cond, &top->qe.mutex); - pthread_mutex_unlock(&top->qe.mutex); + cond_wait(&top->qe.cond, &top->qe.mutex); + mutex_unlock(&top->qe.mutex); =20 if (ordered_events__flush(out, OE_FLUSH__TOP)) pr_err("failed to process events\n"); @@ -1217,8 +1217,8 @@ static void init_process_thread(struct perf_top *top) ordered_events__set_copy_on_queue(&top->qe.data[0], true); ordered_events__set_copy_on_queue(&top->qe.data[1], true); top->qe.in =3D &top->qe.data[0]; - pthread_mutex_init(&top->qe.mutex, NULL); - pthread_cond_init(&top->qe.cond, NULL); + mutex_init(&top->qe.mutex, /*pshared=3D*/false); + cond_init(&top->qe.cond, /*pshared=3D*/false); } =20 static int __cmd_top(struct perf_top *top) @@ -1349,7 +1349,7 @@ static int __cmd_top(struct perf_top *top) out_join: pthread_join(thread, NULL); out_join_thread: - pthread_cond_signal(&top->qe.cond); + cond_signal(&top->qe.cond); pthread_join(thread_process, NULL); return ret; } diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index dfb6173b2a82..21b5e68179d7 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -1,8 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -/* For the CLR_() macros */ -#include #include #include =20 diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/= openat-syscall-all-cpus.c index 90828ae03ef5..f3275be83a33 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -2,7 +2,7 @@ #include #include /* For the CPU_* macros */ -#include +#include =20 #include #include diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 6a001fcfed68..b386ade9ed06 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -2,8 +2,6 @@ #include #include #include -/* For the CLR_() macros */ -#include =20 #include #include diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index fa5bd5c20e96..78fb01d6ad63 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -268,9 +268,9 @@ void __ui_browser__show_title(struct ui_browser *browse= r, const char *title) =20 void ui_browser__show_title(struct ui_browser *browser, const char *title) { - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); __ui_browser__show_title(browser, title); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); } =20 int ui_browser__show(struct ui_browser *browser, const char *title, @@ -284,7 +284,7 @@ int ui_browser__show(struct ui_browser *browser, const = char *title, =20 browser->refresh_dimensions(browser); =20 - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); __ui_browser__show_title(browser, title); =20 browser->title =3D title; @@ -295,16 +295,16 @@ int ui_browser__show(struct ui_browser *browser, cons= t char *title, va_end(ap); if (err > 0) ui_helpline__push(browser->helpline); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); return err ? 0 : -1; } =20 void ui_browser__hide(struct ui_browser *browser) { - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); ui_helpline__pop(); zfree(&browser->helpline); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); } =20 static void ui_browser__scrollbar_set(struct ui_browser *browser) @@ -352,9 +352,9 @@ static int __ui_browser__refresh(struct ui_browser *bro= wser) =20 int ui_browser__refresh(struct ui_browser *browser) { - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); __ui_browser__refresh(browser); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); =20 return 0; } @@ -390,10 +390,10 @@ int ui_browser__run(struct ui_browser *browser, int d= elay_secs) while (1) { off_t offset; =20 - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); err =3D __ui_browser__refresh(browser); SLsmg_refresh(); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); if (err < 0) break; =20 diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/ann= otate.c index 44ba900828f6..9bc1076374ff 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -8,11 +8,11 @@ #include "../../util/hist.h" #include "../../util/sort.h" #include "../../util/map.h" +#include "../../util/mutex.h" #include "../../util/symbol.h" #include "../../util/evsel.h" #include "../../util/evlist.h" #include -#include #include #include #include @@ -319,7 +319,7 @@ static void annotate_browser__calc_percent(struct annot= ate_browser *browser, =20 browser->entries =3D RB_ROOT; =20 - pthread_mutex_lock(¬es->lock); + mutex_lock(¬es->lock); =20 symbol__calc_percent(sym, evsel); =20 @@ -348,7 +348,7 @@ static void annotate_browser__calc_percent(struct annot= ate_browser *browser, } disasm_rb_tree__insert(browser, &pos->al); } - pthread_mutex_unlock(¬es->lock); + mutex_unlock(¬es->lock); =20 browser->curr_hot =3D rb_last(&browser->entries); } @@ -474,10 +474,10 @@ static bool annotate_browser__callq(struct annotate_b= rowser *browser, } =20 notes =3D symbol__annotation(dl->ops.target.sym); - pthread_mutex_lock(¬es->lock); + mutex_lock(¬es->lock); =20 if (!symbol__hists(dl->ops.target.sym, evsel->evlist->core.nr_entries)) { - pthread_mutex_unlock(¬es->lock); + mutex_unlock(¬es->lock); ui__warning("Not enough memory for annotating '%s' symbol!\n", dl->ops.target.sym->name); return true; @@ -486,7 +486,7 @@ static bool annotate_browser__callq(struct annotate_bro= wser *browser, target_ms.maps =3D ms->maps; target_ms.map =3D ms->map; target_ms.sym =3D dl->ops.target.sym; - pthread_mutex_unlock(¬es->lock); + mutex_unlock(¬es->lock); symbol__tui_annotate(&target_ms, evsel, hbt, browser->opts); sym_title(ms->sym, ms->map, title, sizeof(title), browser->opts->percent_= type); ui_browser__show_title(&browser->b, title); diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index 700335cde618..fd10dc6baf07 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c @@ -1,5 +1,4 @@ // SPDX-License-Identifier: GPL-2.0 -#include #include #include =20 @@ -8,7 +7,7 @@ #include "../util/hist.h" #include "ui.h" =20 -pthread_mutex_t ui__lock =3D PTHREAD_MUTEX_INITIALIZER; +struct mutex ui__lock; void *perf_gtk_handle; int use_browser =3D -1; =20 @@ -76,6 +75,7 @@ int stdio__config_color(const struct option *opt __maybe_= unused, =20 void setup_browser(bool fallback_to_pager) { + mutex_init(&ui__lock, /*pshared=3D*/false); if (use_browser < 2 && (!isatty(1) || dump_trace)) use_browser =3D 0; =20 @@ -118,4 +118,5 @@ void exit_browser(bool wait_for_ok) default: break; } + mutex_destroy(&ui__lock); } diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c index 298d6af82fdd..db4952f5990b 100644 --- a/tools/perf/ui/tui/helpline.c +++ b/tools/perf/ui/tui/helpline.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include =20 @@ -33,7 +32,7 @@ static int tui_helpline__show(const char *format, va_list= ap) int ret; static int backlog; =20 - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); ret =3D vscnprintf(ui_helpline__last_msg + backlog, sizeof(ui_helpline__last_msg) - backlog, format, ap); backlog +=3D ret; @@ -45,7 +44,7 @@ static int tui_helpline__show(const char *format, va_list= ap) SLsmg_refresh(); backlog =3D 0; } - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); =20 return ret; } diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c index 3d74af5a7ece..71b6c8d9474f 100644 --- a/tools/perf/ui/tui/progress.c +++ b/tools/perf/ui/tui/progress.c @@ -45,7 +45,7 @@ static void tui_progress__update(struct ui_progress *p) } =20 ui__refresh_dimensions(false); - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); y =3D SLtt_Screen_Rows / 2 - 2; SLsmg_set_color(0); SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols); @@ -56,7 +56,7 @@ static void tui_progress__update(struct ui_progress *p) bar =3D ((SLtt_Screen_Cols - 2) * p->curr) / p->total; SLsmg_fill_region(y, 1, 1, bar, ' '); SLsmg_refresh(); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); } =20 static void tui_progress__finish(void) @@ -67,12 +67,12 @@ static void tui_progress__finish(void) return; =20 ui__refresh_dimensions(false); - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); y =3D SLtt_Screen_Rows / 2 - 2; SLsmg_set_color(0); SLsmg_fill_region(y, 0, 3, SLtt_Screen_Cols, ' '); SLsmg_refresh(); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); } =20 static struct ui_progress_ops tui_progress__ops =3D { diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index b1be59b4e2a4..a3b8c397c24d 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -29,10 +29,10 @@ void ui__refresh_dimensions(bool force) { if (force || ui__need_resize) { ui__need_resize =3D 0; - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); SLtt_get_screen_size(); SLsmg_reinit_smg(); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); } } =20 @@ -170,10 +170,10 @@ void ui__exit(bool wait_for_ok) "Press any key...", 0); =20 SLtt_set_cursor_visibility(1); - if (!pthread_mutex_trylock(&ui__lock)) { + if (mutex_trylock(&ui__lock)) { SLsmg_refresh(); SLsmg_reset_smg(); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); } SLang_reset_tty(); perf_error__unregister(&perf_tui_eops); diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index 0f562e2cb1e8..3c5174854ac8 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c @@ -95,7 +95,7 @@ int ui_browser__input_window(const char *title, const cha= r *text, char *input, t =3D sep + 1; } =20 - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); =20 max_len +=3D 2; nr_lines +=3D 8; @@ -125,17 +125,17 @@ int ui_browser__input_window(const char *title, const= char *text, char *input, SLsmg_write_nstring((char *)exit_msg, max_len); SLsmg_refresh(); =20 - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); =20 x +=3D 2; len =3D 0; key =3D ui__getch(delay_secs); while (key !=3D K_TIMER && key !=3D K_ENTER && key !=3D K_ESC) { - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); =20 if (key =3D=3D K_BKSPC) { if (len =3D=3D 0) { - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); goto next_key; } SLsmg_gotorc(y, x + --len); @@ -147,7 +147,7 @@ int ui_browser__input_window(const char *title, const c= har *text, char *input, } SLsmg_refresh(); =20 - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); =20 /* XXX more graceful overflow handling needed */ if (len =3D=3D sizeof(buf) - 1) { @@ -215,19 +215,19 @@ void __ui__info_window(const char *title, const char = *text, const char *exit_msg =20 void ui__info_window(const char *title, const char *text) { - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); __ui__info_window(title, text, NULL); SLsmg_refresh(); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); } =20 int ui__question_window(const char *title, const char *text, const char *exit_msg, int delay_secs) { - pthread_mutex_lock(&ui__lock); + mutex_lock(&ui__lock); __ui__info_window(title, text, exit_msg); SLsmg_refresh(); - pthread_mutex_unlock(&ui__lock); + mutex_unlock(&ui__lock); return ui__getch(delay_secs); } =20 diff --git a/tools/perf/ui/ui.h b/tools/perf/ui/ui.h index 9b6fdf06e1d2..99f8d2fe9bc5 100644 --- a/tools/perf/ui/ui.h +++ b/tools/perf/ui/ui.h @@ -2,11 +2,11 @@ #ifndef _PERF_UI_H_ #define _PERF_UI_H_ 1 =20 -#include +#include "../util/mutex.h" #include #include =20 -extern pthread_mutex_t ui__lock; +extern struct mutex ui__lock; extern void *perf_gtk_handle; =20 extern int use_browser; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 2c6a485c3de5..29d804d76145 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -35,7 +35,6 @@ #include "arch/common.h" #include "namespaces.h" #include -#include #include #include #include @@ -821,7 +820,7 @@ void symbol__annotate_zero_histograms(struct symbol *sy= m) { struct annotation *notes =3D symbol__annotation(sym); =20 - pthread_mutex_lock(¬es->lock); + mutex_lock(¬es->lock); if (notes->src !=3D NULL) { memset(notes->src->histograms, 0, notes->src->nr_histograms * notes->src->sizeof_sym_hist); @@ -829,7 +828,7 @@ void symbol__annotate_zero_histograms(struct symbol *sy= m) memset(notes->src->cycles_hist, 0, symbol__size(sym) * sizeof(struct cyc_hist)); } - pthread_mutex_unlock(¬es->lock); + mutex_unlock(¬es->lock); } =20 static int __symbol__account_cycles(struct cyc_hist *ch, @@ -1086,7 +1085,7 @@ void annotation__compute_ipc(struct annotation *notes= , size_t size) notes->hit_insn =3D 0; notes->cover_insn =3D 0; =20 - pthread_mutex_lock(¬es->lock); + mutex_lock(¬es->lock); for (offset =3D size - 1; offset >=3D 0; --offset) { struct cyc_hist *ch; =20 @@ -1105,7 +1104,7 @@ void annotation__compute_ipc(struct annotation *notes= , size_t size) notes->have_cycles =3D true; } } - pthread_mutex_unlock(¬es->lock); + mutex_unlock(¬es->lock); } =20 int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_= sample *sample, @@ -1258,13 +1257,13 @@ int disasm_line__scnprintf(struct disasm_line *dl, = char *bf, size_t size, bool r =20 void annotation__init(struct annotation *notes) { - pthread_mutex_init(¬es->lock, NULL); + mutex_init(¬es->lock, /*pshared=3D*/false); } =20 void annotation__exit(struct annotation *notes) { annotated_source__delete(notes->src); - pthread_mutex_destroy(¬es->lock); + mutex_destroy(¬es->lock); } =20 static void annotation_line__add(struct annotation_line *al, struct list_h= ead *head) diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 986f2bbe4870..3cbd883e4d7a 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -8,9 +8,9 @@ #include #include #include -#include #include #include "symbol_conf.h" +#include "mutex.h" #include "spark.h" =20 struct hist_browser_timer; @@ -273,7 +273,7 @@ struct annotated_source { }; =20 struct annotation { - pthread_mutex_t lock; + struct mutex lock; u64 max_coverage; u64 start; u64 hit_cycles; diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h index 144a8a24cc69..1bcbd4fb6c66 100644 --- a/tools/perf/util/bpf-event.h +++ b/tools/perf/util/bpf-event.h @@ -4,7 +4,6 @@ =20 #include #include -#include #include #include =20 diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 5ac13958d1bd..c7a5b42d1311 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -795,7 +795,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); + mutex_lock(&dso->lock); while (next) { struct dso_cache *cache; =20 @@ -804,7 +804,7 @@ dso_cache__free(struct dso *dso) rb_erase(&cache->rb_node, root); free(cache); } - pthread_mutex_unlock(&dso->lock); + mutex_unlock(&dso->lock); } =20 static struct dso_cache *__dso_cache__find(struct dso *dso, u64 offset) @@ -841,7 +841,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); + mutex_lock(&dso->lock); while (*p !=3D NULL) { u64 end; =20 @@ -862,7 +862,7 @@ dso_cache__insert(struct dso *dso, struct dso_cache *ne= w) =20 cache =3D NULL; out: - pthread_mutex_unlock(&dso->lock); + mutex_unlock(&dso->lock); return cache; } =20 @@ -1297,7 +1297,7 @@ 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); + mutex_init(&dso->lock, /*pshared=3D*/false); refcount_set(&dso->refcnt, 1); } =20 @@ -1336,7 +1336,7 @@ void dso__delete(struct dso *dso) dso__free_a2l(dso); zfree(&dso->symsrc_filename); nsinfo__zput(dso->nsinfo); - pthread_mutex_destroy(&dso->lock); + mutex_destroy(&dso->lock); free(dso); } =20 diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 66981c7a9a18..58d94175e714 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -2,7 +2,6 @@ #ifndef __PERF_DSO #define __PERF_DSO =20 -#include #include #include #include @@ -11,6 +10,7 @@ #include #include #include "build-id.h" +#include "mutex.h" =20 struct machine; struct map; @@ -145,7 +145,7 @@ struct dso_cache { struct auxtrace_cache; =20 struct dso { - pthread_mutex_t lock; + struct mutex lock; struct list_head node; struct rb_node rb_node; /* rbtree node sorted by long name */ struct rb_root *root; /* root of rbtree that rb_node is in */ diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 1c085ab56534..bfce88e5eb0d 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1622,13 +1622,13 @@ struct rb_root_cached *hists__get_rotate_entries_in= (struct hists *hists) { struct rb_root_cached *root; =20 - pthread_mutex_lock(&hists->lock); + mutex_lock(&hists->lock); =20 root =3D hists->entries_in; if (++hists->entries_in > &hists->entries_in_array[1]) hists->entries_in =3D &hists->entries_in_array[0]; =20 - pthread_mutex_unlock(&hists->lock); + mutex_unlock(&hists->lock); =20 return root; } @@ -2805,7 +2805,7 @@ int __hists__init(struct hists *hists, struct perf_hp= p_list *hpp_list) hists->entries_in =3D &hists->entries_in_array[0]; hists->entries_collapsed =3D RB_ROOT_CACHED; hists->entries =3D RB_ROOT_CACHED; - pthread_mutex_init(&hists->lock, NULL); + mutex_init(&hists->lock, /*pshared=3D*/false); hists->socket_filter =3D -1; hists->hpp_list =3D hpp_list; INIT_LIST_HEAD(&hists->hpp_formats); diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 7ed4648d2fc2..508428b2c1b2 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -4,10 +4,10 @@ =20 #include #include -#include #include "evsel.h" #include "color.h" #include "events_stats.h" +#include "mutex.h" =20 struct hist_entry; struct hist_entry_ops; @@ -98,7 +98,7 @@ struct hists { const struct dso *dso_filter; const char *uid_filter_str; const char *symbol_filter_str; - pthread_mutex_t lock; + struct mutex lock; struct hists_stats stats; u64 event_stream; u16 col_len[HISTC_NR_COLS]; diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h index cd8b0777473b..cd4ccec7f361 100644 --- a/tools/perf/util/mmap.h +++ b/tools/perf/util/mmap.h @@ -9,7 +9,6 @@ #include #include #include -#include // for cpu_set_t #ifdef HAVE_AIO_SUPPORT #include #endif diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a4b22caa7c24..656d9b4dd456 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1800,7 +1800,7 @@ int dso__load(struct dso *dso, struct map *map) } =20 nsinfo__mountns_enter(dso->nsinfo, &nsc); - pthread_mutex_lock(&dso->lock); + mutex_lock(&dso->lock); =20 /* check again under the dso->lock */ if (dso__loaded(dso)) { @@ -1964,7 +1964,7 @@ int dso__load(struct dso *dso, struct map *map) ret =3D 0; out: dso__set_loaded(dso); - pthread_mutex_unlock(&dso->lock); + mutex_unlock(&dso->lock); nsinfo__mountns_exit(&nsc); =20 return ret; diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 1c2c0a838430..a8b0d79bd96c 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h @@ -5,6 +5,7 @@ #include "tool.h" #include "evswitch.h" #include "annotate.h" +#include "mutex.h" #include "ordered-events.h" #include "record.h" #include @@ -53,8 +54,8 @@ struct perf_top { struct ordered_events *in; struct ordered_events data[2]; bool rotate; - pthread_mutex_t mutex; - pthread_cond_t cond; + struct mutex mutex; + struct cond cond; } qe; }; =20 --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 02:17:41 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 8865DC25B08 for ; Wed, 17 Aug 2022 05:39:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238064AbiHQFjt (ORCPT ); Wed, 17 Aug 2022 01:39:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231222AbiHQFjp (ORCPT ); Wed, 17 Aug 2022 01:39:45 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3CA34F667 for ; Tue, 16 Aug 2022 22:39:43 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f3959ba41so138317077b3.2 for ; Tue, 16 Aug 2022 22:39:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=VkM79uf89xeQ9qFc9A5bUuDYRz5EWRncjylJ1j1cl8Q=; b=TpKExb6K4/FgBtiARrFl0maFT5kacEGjgS13MSq4nMcb1rY/NAKYdSkRUwo0cZvGLQ nVmt7R31EYgz8/3OAbL/ej5r/YQy+vbbQ6kjOsaUzYPArAa2dFFY4foFNiWT5n3cPk9A NDqGoimWlp50Opxx8m8Rhf/aIFa198L6t4kahaGBaTun4jXhqe6cwhcY/onJk4rJ+DPJ 1HRk7em27jJVRLf+BdFSwreL315IRrhsN5jZSwTqlrCamOVYzmuYJFMVVvXeImlf1ZSi 70IZroSyCeR/FpxI6y3nivSmmi+sdeaJ4VaJR5hDErG6o8tfe2jn0b24UVz4gd0WM2GC 1/Xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=VkM79uf89xeQ9qFc9A5bUuDYRz5EWRncjylJ1j1cl8Q=; b=pfWD4zbSbeRLsq8BOvfl7/6sXfAgRCE0jw2cn4zfiSx4NOYp8Gf6GNA0H/F+1cgq/m J5EbJrg8skqGbq7EFVUvTJChXMpmWazrjAb+WmVHKp0Gbr7hhGorI0CDiBKlQ3uAy2+D gKCRsW2FPDDzH3B1YXm6yh4kLCJpDG8sd6h0Glb2PHOra/Qk4zCjJFuER51xP9hBUyEC 3svO3D7gjhJjb3xnyMbu9nG/prnZEArptgz5hp2uTi9IVwQZnzWprbyX1XTittAgmXY2 puSj6aPMkKwfT//+zQnpN33jQ+B68jQGTHmGxuhWdHLNDUNRY8kQoPrLBrXyN8C9MfTk 5OPA== X-Gm-Message-State: ACgBeo0d9fjaNDQqICrEJOJqnGVrXE0Dp1HzyrbV+okJPebXYn/AsUUV svzOrvMkNrkIhGMYHY9GI+23aiB2D/dj X-Google-Smtp-Source: AA6agR49j963T7BConaaXi/0oWf0mWkxrSWi84UR5nMJIfrNEkbIwlSm4ueLbVQzRCuSzrdrZ2GnzGWrHeoX X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:3bec:858f:9a6d:63de]) (user=irogers job=sendgmr) by 2002:a25:6002:0:b0:684:da54:e35 with SMTP id u2-20020a256002000000b00684da540e35mr15600368ybb.552.1660714782806; Tue, 16 Aug 2022 22:39:42 -0700 (PDT) Date: Tue, 16 Aug 2022 22:39:27 -0700 In-Reply-To: <20220817053930.769840-1-irogers@google.com> Message-Id: <20220817053930.769840-4-irogers@google.com> Mime-Version: 1.0 References: <20220817053930.769840-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v1 3/6] 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?=" , Nathan Chancellor , Nick Desaulniers , Tom Rix , Athira Rajeev , Weiguo Li , Pavithra Gurushankar , Thomas Richter , Ravi Bangoria , Dario Petrillo , Wenyu Liu , Hewenliang , yaowenbin , Dave Marchevsky , Andrii Nakryiko , Alexandre Truong , Kim Phillips , Leo Yan , Quentin Monnet , William Cohen , Andres Freund , Song Liu , Adrian Hunter , "=?UTF-8?q?Martin=20Li=C5=A1ka?=" , Colin Ian King , James Clark , Fangrui Song , Stephane Eranian , Kajol Jain , Andi Kleen , Alexey Bayduraev , Riccardo Mancini , Masami Hiramatsu , Christophe JAILLET , Zechuan Chen , Jason Wang , Lexi Shao , Remi Bernon , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Cc: 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. Fixes test "Lookup mmap thread" when compiled with address sanitizer. Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 4 ++++ tools/perf/util/annotate.c | 2 ++ tools/perf/util/build-id.c | 12 +++++++++--- tools/perf/util/dso.c | 7 ++++++- tools/perf/util/map.c | 3 +++ tools/perf/util/probe-event.c | 3 +++ tools/perf/util/symbol.c | 2 +- 7 files changed, 28 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 2a0f992ca0be..2a914eaf6425 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -433,8 +433,10 @@ static struct dso *findnew_dso(int pid, int tid, const= char *filename, } =20 if (dso) { + mutex_lock(&dso->lock); nsinfo__put(dso->nsinfo); dso->nsinfo =3D nsi; + mutex_unlock(&dso->lock); } else nsinfo__put(nsi); =20 @@ -617,6 +619,7 @@ static int dso__read_build_id(struct dso *dso) if (dso->has_build_id) return 0; =20 + mutex_lock(&dso->lock); nsinfo__mountns_enter(dso->nsinfo, &nsc); if (filename__read_build_id(dso->long_name, &dso->bid) > 0) dso->has_build_id =3D true; @@ -630,6 +633,7 @@ static int dso__read_build_id(struct dso *dso) free(new_name); } nsinfo__mountns_exit(&nsc); + mutex_unlock(&dso->lock); =20 return dso->has_build_id ? 0 : -1; } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 29d804d76145..1bbfbc8e1554 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1697,6 +1697,7 @@ static int dso__disassemble_filename(struct dso *dso,= char *filename, size_t fil */ __symbol__join_symfs(filename, filename_size, dso->long_name); =20 + mutex_lock(&dso->lock); if (access(filename, R_OK) && errno =3D=3D ENOENT && dso->nsinfo) { char *new_name =3D filename_with_chroot(dso->nsinfo->pid, filename); @@ -1705,6 +1706,7 @@ static int dso__disassemble_filename(struct dso *dso,= char *filename, size_t fil free(new_name); } } + mutex_unlock(&dso->lock); } =20 free(build_id_path); diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index ec18ed5caf3e..a839b30c981b 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -898,11 +898,15 @@ static int filename__read_build_id_ns(const char *fil= ename, static bool dso__build_id_mismatch(struct dso *dso, const char *name) { struct build_id bid; + bool ret =3D false; =20 - if (filename__read_build_id_ns(name, &bid, dso->nsinfo) < 0) - return false; + mutex_lock(&dso->lock); + if (filename__read_build_id_ns(name, &bid, dso->nsinfo) >=3D 0) + ret =3D !dso__build_id_equal(dso, &bid); =20 - return !dso__build_id_equal(dso, &bid); + mutex_unlock(&dso->lock); + + return ret; } =20 static int dso__cache_build_id(struct dso *dso, struct machine *machine, @@ -941,8 +945,10 @@ static int dso__cache_build_id(struct dso *dso, struct= machine *machine, if (!is_kallsyms && dso__build_id_mismatch(dso, name)) goto out_free; =20 + mutex_lock(&dso->lock); ret =3D build_id_cache__add_b(&dso->bid, name, dso->nsinfo, is_kallsyms, is_vdso, proper_name, root_dir); + mutex_unlock(&dso->lock); out_free: free(allocated_name); return ret; diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index c7a5b42d1311..89e1b93cb874 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -501,6 +501,7 @@ static int __open_dso(struct dso *dso, struct machine *= machine) if (!name) return -ENOMEM; =20 + mutex_lock(&dso->lock); if (machine) root_dir =3D machine->root_dir; =20 @@ -541,6 +542,7 @@ static int __open_dso(struct dso *dso, struct machine *= machine) unlink(name); =20 out: + mutex_unlock(&dso->lock); free(name); return fd; } @@ -559,8 +561,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) { + mutex_lock(&dso->lock); nsinfo__mountns_enter(dso->nsinfo, &nsc); + 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 e0aa4a254583..f3a3d9b3a40d 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -181,7 +181,10 @@ struct map *map__new(struct machine *machine, u64 star= t, u64 len, if (!(prot & PROT_EXEC)) dso__set_loaded(dso); } + mutex_lock(&dso->lock); + nsinfo__put(dso->nsinfo); dso->nsinfo =3D nsi; + 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 785246ff4179..0c24bc7afbca 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -29,6 +29,7 @@ #include "color.h" #include "map.h" #include "maps.h" +#include "mutex.h" #include "symbol.h" #include #include "trace-event.h" /* For __maybe_unused */ @@ -180,8 +181,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) { + mutex_lock(&map->dso->lock); nsinfo__put(map->dso->nsinfo); map->dso->nsinfo =3D nsinfo__get(nsi); + mutex_unlock(&map->dso->lock); } return map; } else { diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 656d9b4dd456..a3a165ae933a 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1791,6 +1791,7 @@ int dso__load(struct dso *dso, struct map *map) char newmapname[PATH_MAX]; const char *map_path =3D dso->long_name; =20 + mutex_lock(&dso->lock); perfmap =3D strncmp(dso->name, "/tmp/perf-", 10) =3D=3D 0; if (perfmap) { if (dso->nsinfo && (dso__find_perf_map(newmapname, @@ -1800,7 +1801,6 @@ int dso__load(struct dso *dso, struct map *map) } =20 nsinfo__mountns_enter(dso->nsinfo, &nsc); - mutex_lock(&dso->lock); =20 /* check again under the dso->lock */ if (dso__loaded(dso)) { --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 02:17:41 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 74937C25B08 for ; Wed, 17 Aug 2022 05:40:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238535AbiHQFkC (ORCPT ); Wed, 17 Aug 2022 01:40:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58616 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231222AbiHQFj4 (ORCPT ); Wed, 17 Aug 2022 01:39:56 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D67C67CA3 for ; Tue, 16 Aug 2022 22:39:46 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f3959ba41so138318347b3.2 for ; Tue, 16 Aug 2022 22:39:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=dvXHlanNSMpb8+NK6h6mlaZdJjvFNZm2U3e/25BiLG8=; b=mYp9/Sr/BzctNpEaunppnamILdm+vQXkxgyXNAS6a0QaWmaKLlm25oxAnyn2IJgmtz hagzDnnPKhwIAXUv2ZJRYc6IVqAhuRHaPODwh3Q563t+oe1lRL+ErStXbEi+tYxHBYVm nOYkDy4xuwbYmK786oVtKub1xhTwScQLqC/olf/AcIja9xAmoFNAO1qun/tLqpY88wfx jGc+cEZ5xN7ZWQenIRMnd3rNV0LkdxZXhZuN1mi8DVDhGzh6BkGnKSIbVeO/KfclhoWe T2vm6MQAyKt5N0pAEKl2X9GH+ZjBDy2ZaFbCvk15+KpKHTWUJBzLv0Mc4IJ2lKsVojKz h4eQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=dvXHlanNSMpb8+NK6h6mlaZdJjvFNZm2U3e/25BiLG8=; b=lTzk/ncrWpjkuKj8/nDT4Z76+yqhu21sUmc4lHYPObKj5QeGVQJqBPgYNebqiJ6U51 LBkHgz8cSPPcFvHhK5V5wtxTD1GUQaHzSFKZCt1+uDwpZ5kCNjScs/mXofQzsOU68RuI HCPl+aLKIVTRF28EVNnon3P7u6B2zi4hjMOO24Il87ntMQ8Cs716+RP6ZAo+NuIJzK3k RK5YVEmyENoNEwnekchG9LLyhNPPInWpixI8BBzyxlpAHausKbax8/cVx/o44Ay91KbY X66Zane1maTjbWKTJ0XvjNFLClkjgTJh6VutBBN8ZdQHajFmIUCWTYLx3zuJrJY1fBd6 953Q== X-Gm-Message-State: ACgBeo1a65NOfQZm9EWKs0JD4R+iRTT2gRUkbA8McfWDekK17o6QPrEJ nXcSx4YDPBuox7YR3KBXec/4+qE+EBYX X-Google-Smtp-Source: AA6agR6zSnCmpG7kuPNJMbVm7HIrXY4YLPDkRXnjRDSwn6ZhR4GqOHvFVK+oQ64A8/6nWhOOENcY693gBv1U X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:3bec:858f:9a6d:63de]) (user=irogers job=sendgmr) by 2002:a5b:83:0:b0:689:7b36:5307 with SMTP id b3-20020a5b0083000000b006897b365307mr10169676ybp.328.1660714785978; Tue, 16 Aug 2022 22:39:45 -0700 (PDT) Date: Tue, 16 Aug 2022 22:39:28 -0700 In-Reply-To: <20220817053930.769840-1-irogers@google.com> Message-Id: <20220817053930.769840-5-irogers@google.com> Mime-Version: 1.0 References: <20220817053930.769840-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v1 4/6] perf mutex: Add thread safety annotations 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?=" , Nathan Chancellor , Nick Desaulniers , Tom Rix , Athira Rajeev , Weiguo Li , Pavithra Gurushankar , Thomas Richter , Ravi Bangoria , Dario Petrillo , Wenyu Liu , Hewenliang , yaowenbin , Dave Marchevsky , Andrii Nakryiko , Alexandre Truong , Kim Phillips , Leo Yan , Quentin Monnet , William Cohen , Andres Freund , Song Liu , Adrian Hunter , "=?UTF-8?q?Martin=20Li=C5=A1ka?=" , Colin Ian King , James Clark , Fangrui Song , Stephane Eranian , Kajol Jain , Andi Kleen , Alexey Bayduraev , Riccardo Mancini , Masami Hiramatsu , Christophe JAILLET , Zechuan Chen , Jason Wang , Lexi Shao , Remi Bernon , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Cc: 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 thread safety annotations to struct mutex so that when compiled with clang's -Wthread-safety warnings are generated for erroneous lock patterns. NO_THREAD_SAFETY_ANALYSIS is needed for mutex_lock/mutex_unlock as the analysis doesn't under pthread calls. Signed-off-by: Ian Rogers --- tools/perf/util/mutex.c | 2 ++ tools/perf/util/mutex.h | 72 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/mutex.c b/tools/perf/util/mutex.c index d12cf0714268..c936557d8bbb 100644 --- a/tools/perf/util/mutex.c +++ b/tools/perf/util/mutex.c @@ -40,11 +40,13 @@ void mutex_destroy(struct mutex *mtx) } =20 void mutex_lock(struct mutex *mtx) + NO_THREAD_SAFETY_ANALYSIS { CHECK_ERR(pthread_mutex_lock(&mtx->lock)); } =20 void mutex_unlock(struct mutex *mtx) + NO_THREAD_SAFETY_ANALYSIS { CHECK_ERR(pthread_mutex_unlock(&mtx->lock)); } diff --git a/tools/perf/util/mutex.h b/tools/perf/util/mutex.h index 952276ad83bd..6c2062d41a4e 100644 --- a/tools/perf/util/mutex.h +++ b/tools/perf/util/mutex.h @@ -5,11 +5,73 @@ #include #include =20 +/* + * A function-like feature checking macro that is a wrapper around + * `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates t= o a + * nonzero constant integer if the attribute is supported or 0 if not. + */ +#ifdef __has_attribute +#define HAVE_ATTRIBUTE(x) __has_attribute(x) +#else +#define HAVE_ATTRIBUTE(x) 0 +#endif + + +#if HAVE_ATTRIBUTE(guarded_by) && HAVE_ATTRIBUTE(pt_guarded_by) && \ + HAVE_ATTRIBUTE(lockable) && HAVE_ATTRIBUTE(exclusive_lock_function) && \ + HAVE_ATTRIBUTE(exclusive_trylock_function) && HAVE_ATTRIBUTE(exclusive_lo= cks_required) && \ + HAVE_ATTRIBUTE(no_thread_safety_analysis) + +/* Documents if a shared field or global variable needs to be protected by= a mutex. */ +#define GUARDED_BY(x) __attribute__((guarded_by(x))) + +/* + * Documents if the memory location pointed to by a pointer should be guar= ded by + * a mutex when dereferencing the pointer. + */ +#define PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x))) + +/* Documents if a type is a lockable type. */ +#define LOCKABLE __attribute__((capability("lockable"))) + +/* Documents functions that acquire a lock in the body of a function, and = do not release it. */ +#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__((exclusive_lock_functi= on(__VA_ARGS__))) + +/* + * Documents functions that expect a lock to be held on entry to the funct= ion, + * and release it in the body of the function. + */ +#define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) + +/* Documents functions that try to acquire a lock, and return success or f= ailure. */ +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \ + __attribute__((exclusive_trylock_function(__VA_ARGS__))) + + +/* Documents a function that expects a mutex to be held prior to entry. */ +#define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__((exclusive_locks_requi= red(__VA_ARGS__))) + +/* Turns off thread safety checking within the body of a particular functi= on. */ +#define NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis= )) + +#else + +#define GUARDED_BY(x) +#define PT_GUARDED_BY(x) +#define LOCKABLE +#define EXCLUSIVE_LOCK_FUNCTION(...) +#define UNLOCK_FUNCTION(...) +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) +#define EXCLUSIVE_LOCKS_REQUIRED(...) +#define NO_THREAD_SAFETY_ANALYSIS + +#endif + /* * A wrapper around the mutex implementation that allows perf to error che= ck * usage, etc. */ -struct mutex { +struct LOCKABLE mutex { pthread_mutex_t lock; }; =20 @@ -25,9 +87,9 @@ struct cond { void mutex_init(struct mutex *mtx, bool pshared); void mutex_destroy(struct mutex *mtx); =20 -void mutex_lock(struct mutex *mtx); -void mutex_unlock(struct mutex *mtx); -bool mutex_trylock(struct mutex *mtx); +void mutex_lock(struct mutex *mtx) EXCLUSIVE_LOCK_FUNCTION(*mtx); +void mutex_unlock(struct mutex *mtx) UNLOCK_FUNCTION(*mtx); +bool mutex_trylock(struct mutex *mtx) EXCLUSIVE_TRYLOCK_FUNCTION(true, *mt= x); =20 /* * Initialize the cond struct, if pshared is set then specify the process-= shared @@ -36,7 +98,7 @@ bool mutex_trylock(struct mutex *mtx); void cond_init(struct cond *cnd, bool pshared); void cond_destroy(struct cond *cnd); =20 -void cond_wait(struct cond *cnd, struct mutex *mtx); +void cond_wait(struct cond *cnd, struct mutex *mtx) EXCLUSIVE_LOCKS_REQUIR= ED(mtx); void cond_signal(struct cond *cnd); void cond_broadcast(struct cond *cnd); =20 --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 02:17:41 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 647F5C25B08 for ; Wed, 17 Aug 2022 05:40:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238544AbiHQFkJ (ORCPT ); Wed, 17 Aug 2022 01:40:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58618 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238506AbiHQFj4 (ORCPT ); Wed, 17 Aug 2022 01:39:56 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2EC4153D15 for ; Tue, 16 Aug 2022 22:39:49 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-3328a211611so87240857b3.5 for ; Tue, 16 Aug 2022 22:39:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=iLN5+FLnhYIWqoDWLTWymRmT3HSuCKQDMghp6cr49+4=; b=RmO9zVA/7Wz8b9GtpWsugHokUFgVDsG4vXhQNbDdnCDmm9BYfj+EyK6z57xrOuwSr5 xEHy7nRGZdtn7j0pVRnsb79os9hz8xZ8L3I3H/+5RGvGbmAaY1KTeppz5YckCGTdlKFi WMmnxqPfR29q93koEqVqKV0oQyX6zZAGkY0X+m7nC1ZDpearMsBP/fqcS/s4uAbh7N4k VL5kJWQpBFQf16lVQU3Hz3d7rLu9p44+5RFbWVEZKnl4dC6PjnAHJBEy0jRaUu8zH2r1 brJNcJN3Lg6IsHi6eP1cNqo9Kcsv7W71EYHmTabd6r3Bc8KeGw+RTkqsFBciOOgkRjzC qIBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=iLN5+FLnhYIWqoDWLTWymRmT3HSuCKQDMghp6cr49+4=; b=49Eh2zHXQosNCiRBAQ26YOHa3MKRsV1nuOY4ebwKtF9PPL6JNp8uJj88zoGR2ysg0J 6YC6Ru/hIDkjagR6SmU8+oqDF+WM9hOn3v9gkYSX5BcgmdT5FV802n270ixcKhX8RXK0 h8Bt/Y1fVmTrAzA2fVkB7+uyrvIAHp9NsYXxrZPSTiwaDYgi980HxAhTukURf009d+ZY r/5N9LTZv7Ci960WzLJ6a6A4jTtF2sw5eTgSsV+uuYeDGVRHH5sbpNw/SFs2USTRt5Pj bFhAzxpcFMr5t/2bucTJ7LKICazCF0+g9yNzkvM7Xp0JCe/T7PShkVfxKX4mmwQQlo/9 Suew== X-Gm-Message-State: ACgBeo2pifAtlAOpzbOnbS9jr9HPnE01bUTFSs6yL65MAoB/oEs/P6zR 51CUCgj5D5dNL0aZgaa4rtJAoqtp0NtV X-Google-Smtp-Source: AA6agR5Ztfm8DnME40MFJ+L3pOkrk/LLHs6fSAOR1/U1JeP8TP+phIUcP0v3cVdGvdWh8ubaYa9KQriPDx3N X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:3bec:858f:9a6d:63de]) (user=irogers job=sendgmr) by 2002:a05:6902:920:b0:68f:a286:2a2b with SMTP id bu32-20020a056902092000b0068fa2862a2bmr3041696ybb.612.1660714788460; Tue, 16 Aug 2022 22:39:48 -0700 (PDT) Date: Tue, 16 Aug 2022 22:39:29 -0700 In-Reply-To: <20220817053930.769840-1-irogers@google.com> Message-Id: <20220817053930.769840-6-irogers@google.com> Mime-Version: 1.0 References: <20220817053930.769840-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v1 5/6] perf mutex: Fix thread safety analysis 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?=" , Nathan Chancellor , Nick Desaulniers , Tom Rix , Athira Rajeev , Weiguo Li , Pavithra Gurushankar , Thomas Richter , Ravi Bangoria , Dario Petrillo , Wenyu Liu , Hewenliang , yaowenbin , Dave Marchevsky , Andrii Nakryiko , Alexandre Truong , Kim Phillips , Leo Yan , Quentin Monnet , William Cohen , Andres Freund , Song Liu , Adrian Hunter , "=?UTF-8?q?Martin=20Li=C5=A1ka?=" , Colin Ian King , James Clark , Fangrui Song , Stephane Eranian , Kajol Jain , Andi Kleen , Alexey Bayduraev , Riccardo Mancini , Masami Hiramatsu , Christophe JAILLET , Zechuan Chen , Jason Wang , Lexi Shao , Remi Bernon , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Cc: 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 annotations to describe lock behavior. Add missing unlocks to perf_sched__replay. Alter hist_iter__top_callback as the thread-safety analysis cannot follow pointers through local variables. Signed-off-by: Ian Rogers --- tools/perf/builtin-sched.c | 8 ++++++++ tools/perf/builtin-top.c | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 0f52f73be896..a8a765ed28ce 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -658,6 +658,8 @@ static void *thread_func(void *ctx) } =20 static void create_tasks(struct perf_sched *sched) + EXCLUSIVE_LOCK_FUNCTION(sched->start_work_mutex) + EXCLUSIVE_LOCK_FUNCTION(sched->work_done_wait_mutex) { struct task_desc *task; pthread_attr_t attr; @@ -687,6 +689,8 @@ static void create_tasks(struct perf_sched *sched) } =20 static void wait_for_tasks(struct perf_sched *sched) + EXCLUSIVE_LOCKS_REQUIRED(sched->work_done_wait_mutex) + EXCLUSIVE_LOCKS_REQUIRED(sched->start_work_mutex) { u64 cpu_usage_0, cpu_usage_1; struct task_desc *task; @@ -738,6 +742,8 @@ static void wait_for_tasks(struct perf_sched *sched) } =20 static void run_one_test(struct perf_sched *sched) + EXCLUSIVE_LOCKS_REQUIRED(sched->work_done_wait_mutex) + EXCLUSIVE_LOCKS_REQUIRED(sched->start_work_mutex) { u64 T0, T1, delta, avg_delta, fluct; =20 @@ -3314,6 +3320,8 @@ static int perf_sched__replay(struct perf_sched *sche= d) for (i =3D 0; i < sched->replay_repeat; i++) run_one_test(sched); =20 + mutex_unlock(&sched->start_work_mutex); + mutex_unlock(&sched->work_done_wait_mutex); return 0; } =20 diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 3757292bfe86..e832f04e3076 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -196,6 +196,7 @@ static void perf_top__record_precise_ip(struct perf_top= *top, struct hist_entry *he, struct perf_sample *sample, struct evsel *evsel, u64 ip) + EXCLUSIVE_LOCKS_REQUIRED(he->hists->lock) { struct annotation *notes; struct symbol *sym =3D he->ms.sym; @@ -724,13 +725,13 @@ static void *display_thread(void *arg) static int hist_iter__top_callback(struct hist_entry_iter *iter, struct addr_location *al, bool single, void *arg) + EXCLUSIVE_LOCKS_REQUIRED(iter->he->hists->lock) { struct perf_top *top =3D arg; - struct hist_entry *he =3D iter->he; struct evsel *evsel =3D iter->evsel; =20 if (perf_hpp_list.sym && single) - perf_top__record_precise_ip(top, he, iter->sample, evsel, al->addr); + perf_top__record_precise_ip(top, iter->he, iter->sample, evsel, al->addr= ); =20 hist__account_cycles(iter->sample->branch_stack, al, iter->sample, !(top->record_opts.branch_stack & PERF_SAMPLE_BRANCH_ANY), --=20 2.37.1.595.g718a3a8f04-goog From nobody Sat Apr 11 02:17:41 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 32E06C25B08 for ; Wed, 17 Aug 2022 05:40:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238556AbiHQFkO (ORCPT ); Wed, 17 Aug 2022 01:40:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238523AbiHQFj4 (ORCPT ); Wed, 17 Aug 2022 01:39:56 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D964D5A83A for ; Tue, 16 Aug 2022 22:39:51 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-335420c7bfeso8487937b3.16 for ; Tue, 16 Aug 2022 22:39:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=qHxxMbzf5P1kENTIcu/skD1A7VW/ZSQMIDyzork9iPw=; b=gqVyKJEKg7FHYfUlvFZRQ4gywaDxqgOla/wYNSrRrpQPIOeQgd8otSDUR81rYz06Pz 86FwoEQRXDngYehTse62DCp3ULAG3zl2VVSHPUTcSch9dCd1GVJmHLNIuS9Ice2KYHSE /Ph6X2GyUQLtHLZp3hUMsFENjq6wAqo+qn5EpWgzZcCvi33yqo5FpUFubMhztDoufgY/ s/YaI0T2hL8w14sHHW7W+c6Mmk2yfQ/ibvJzRLrLjAkzecGwLWICJuoLQBTNOna3XZbI VnFy770xGVxdjDk9dXHvkb/ZqSHfM1yhNZARL1EQll7tFtso8gJjlI04p5hAKF0gFFP7 BTDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=qHxxMbzf5P1kENTIcu/skD1A7VW/ZSQMIDyzork9iPw=; b=7TFLs6iY/uI9o/TCyOChTfAhPdtTfAo+3EK3E9ZjV7SkRKdHpfGu2biQtuZ4P1O0cS Zeohcg8v5ydTV2ves0Edl2pF+EX9tTVxyekPKxTf2dqC6MPmPUIlI8rZ0mLgxoNsbN5T RkSp7MOe2U8cPALjrwGKhvNpXDc1mkLTPezja85kumtklMEmc6vqn+oDvnvzfmmxrhVh KW2AsuGf7H7FhCyGP5tu0lIX7RwSW8gnRVwct2B7QLdb4TAmqIifSPh3pE7yJajx2d4J WI0jtT0x7TAfb3/p+owdecpp47d5TyM0H4ZZGnK2XYzCpWH0hIPguJQqkDZ9TOPhyfyb fbsQ== X-Gm-Message-State: ACgBeo2k5e+tEYez1bqU2MGmm3hUrqV2lPopU8LGFvRSC4Q3QHo3w+HB EaYwXyAEKQHawpp3NUXe/UfxnPuzQn+a X-Google-Smtp-Source: AA6agR6oqIM30UMn/90m2gApF2R7Le2AepInoK1oGfNY9eAWaYg7N++h7MaUpqoBJDhq2iKEZ3Oi69J7zqh3 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:3bec:858f:9a6d:63de]) (user=irogers job=sendgmr) by 2002:a25:ce92:0:b0:680:c480:4a8 with SMTP id x140-20020a25ce92000000b00680c48004a8mr19112893ybe.299.1660714791094; Tue, 16 Aug 2022 22:39:51 -0700 (PDT) Date: Tue, 16 Aug 2022 22:39:30 -0700 In-Reply-To: <20220817053930.769840-1-irogers@google.com> Message-Id: <20220817053930.769840-7-irogers@google.com> Mime-Version: 1.0 References: <20220817053930.769840-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.595.g718a3a8f04-goog Subject: [PATCH v1 6/6] perf build: Enable -Wthread-safety with clang 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?=" , Nathan Chancellor , Nick Desaulniers , Tom Rix , Athira Rajeev , Weiguo Li , Pavithra Gurushankar , Thomas Richter , Ravi Bangoria , Dario Petrillo , Wenyu Liu , Hewenliang , yaowenbin , Dave Marchevsky , Andrii Nakryiko , Alexandre Truong , Kim Phillips , Leo Yan , Quentin Monnet , William Cohen , Andres Freund , Song Liu , Adrian Hunter , "=?UTF-8?q?Martin=20Li=C5=A1ka?=" , Colin Ian King , James Clark , Fangrui Song , Stephane Eranian , Kajol Jain , Andi Kleen , Alexey Bayduraev , Riccardo Mancini , Masami Hiramatsu , Christophe JAILLET , Zechuan Chen , Jason Wang , Lexi Shao , Remi Bernon , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev Cc: 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" If building with clang then enable -Wthread-safety warnings. Signed-off-by: Ian Rogers --- tools/perf/Makefile.config | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 0661a1cf9855..0ef6f572485d 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -19,6 +19,11 @@ detected_var =3D $(shell echo "$(1)=3D$($(1))" >> $(OUTP= UT).config-detected) CFLAGS :=3D $(EXTRA_CFLAGS) $(filter-out -Wnested-externs,$(EXTRA_WARNINGS= )) HOSTCFLAGS :=3D $(filter-out -Wnested-externs,$(EXTRA_WARNINGS)) =20 +# Enabled Wthread-safety analysis for clang builds. +ifeq ($(CC_NO_CLANG), 0) + CFLAGS +=3D -Wthread-safety +endif + include $(srctree)/tools/scripts/Makefile.arch =20 $(call detected_var,SRCARCH) --=20 2.37.1.595.g718a3a8f04-goog