From nobody Sun May 24 20:34:05 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A577F38D412 for ; Fri, 22 May 2026 22:04:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487484; cv=none; b=H/380pyMjq8yu0CJR0EUwXpJxAoc0znrYdM8xUQY/wKwD3J/Zz9bsqaV/ZzANLJeOCdgp6zauBpYLX/IP68/uWXTAgJkCtSGB7Wvv6O1ilTHKVPJY2N7xk12KemKR21YjY17W0qliDpPodscwszVn4k/ed8V2UDj+ttob1AAZbA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487484; c=relaxed/simple; bh=m5R+sCCXKM4jnUfwhDHD5GSN9hBWZMwmWUd1WWzWGVk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=I2oVRgJ33pOfCfmH/yoNKKBnSGFWEaKQtuNVLeEEncMsiWbjLPZz86I026jy2WGyfC82KSKD+v8cJtiePFSDm7K9Rw+2j6+T8+WejrisqNxspOC8NlN5HtcSx8DawJe2FLyo+pMarCj/QmtVDmUWjXnXf692k6pDoKISi68k4g8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=uT6hyeOP; arc=none smtp.client-ip=74.125.82.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="uT6hyeOP" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-1353bfdbf99so10479320c88.0 for ; Fri, 22 May 2026 15:04:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487482; x=1780092282; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=+PYEbQ/Ax7WxxTaHLwQ4Nrd/42MyXIVdzUn7wSkN0kc=; b=uT6hyeOP+mt53cxLyep3yvO6bA95QJ7SOH+AYeFtXfuMz9g5r7V/6yTE5O2epFn5/h vc+ZZTPqb3AjtQ3D3mb7zARuc+ik67B0/R+WrfQDLwaXoyb8uM7eh4Cm4jeqdEKSX3ZD kfybbl0oQYuv78Tivy9U5tKTU943lv3WLSj4NqSXMCeuM08x0Qn/bJh7bgu5M1BprGAg htkQPlQIU39Jzs/4pSpr9+nAL+OxBk01qaUJM4fQ5ZOxJ6ndz3ec7lbN6A/Rx2vUzyjP e/9Feiq39cdyNtVNeMJYCR07fJv0nDfou5mQjVdJwgO/SIUHHEktliqRJMhYF3egd8kc xm9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487482; x=1780092282; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=+PYEbQ/Ax7WxxTaHLwQ4Nrd/42MyXIVdzUn7wSkN0kc=; b=dCjhUIIhmDuKcjjxbTkt8p44qsQJTs3+eoDzlHMQjUMAlMV1ytoWwn//z1P+mmxg8c VK7V8ds2JHzWsw0NAiI3nqKSRp4tU0TL5VB1nQLCSF2XURABFIFuwotaJrNW2VIjfA30 mrdAnBZmbOvTAV8jTX8bElkE/eaBsSj3LHiPEiOouevF6S1tLdEknkFMnUnigFIylPxR mcqTeJn0jzRWRfz1xFhFOOS9jwSx+j7haaPfPVieFF2bB7n+R3wN/iw27jIop4zpDfxM ensqa7qLKQfNA07vEjr7vVETupVTgAmV8LhIlU8GNhlsFZHue7mWnDY1FAPJbOomxSsX zCZw== X-Forwarded-Encrypted: i=1; AFNElJ9z2OLpy5zEnAbwUtJESUheCZjBtQUsGcnUrcn87Zpd5TQ2WRWAEP84d4xNkc20Nc9iVF0vx2uHZefJfhE=@vger.kernel.org X-Gm-Message-State: AOJu0YxngxV6c0q0bJ7vjZAgipGWl0XVIojMyvmVk9rbIhoe4YEUHmdN zjJa4pMWo1iT0WSQbbrPrS1B2G1qlCFh6pvJtiq1IukfQlJhEFyVwjB0+P7hp0IWMR3YgQxdl+0 B976xFDVVbw== X-Received: from dlbpk9.prod.google.com ([2002:a05:7022:3849:b0:136:1858:9f25]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:62b:b0:12a:68cc:3efb with SMTP id a92af1059eb24-1365f821dc7mr2239685c88.16.1779487481501; Fri, 22 May 2026 15:04:41 -0700 (PDT) Date: Fri, 22 May 2026 15:04:12 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-2-irogers@google.com> Subject: [PATCH v9 01/23] perf arch arm: Sort includes and add missed explicit dependencies From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix missing #includes found while cleaning the evsel/evlist header files. Sort the remaining header files for consistency with the rest of the code. Signed-off-by: Ian Rogers --- tools/perf/arch/arm/util/cs-etm.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/c= s-etm.c index b7a839de8707..cdf8e3e60606 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -3,10 +3,13 @@ * Copyright(C) 2015 Linaro Limited. All rights reserved. * Author: Mathieu Poirier */ +#include "../../../util/cs-etm.h" + +#include +#include =20 -#include -#include #include +#include #include #include #include @@ -14,25 +17,24 @@ #include #include #include +#include + +#include +#include // page_size =20 -#include "cs-etm.h" -#include "../../../util/debug.h" -#include "../../../util/record.h" #include "../../../util/auxtrace.h" #include "../../../util/cpumap.h" +#include "../../../util/debug.h" #include "../../../util/event.h" #include "../../../util/evlist.h" #include "../../../util/evsel.h" -#include "../../../util/perf_api_probe.h" #include "../../../util/evsel_config.h" +#include "../../../util/perf_api_probe.h" +#include "../../../util/pmu.h" #include "../../../util/pmus.h" -#include "../../../util/cs-etm.h" -#include // page_size +#include "../../../util/record.h" #include "../../../util/session.h" - -#include -#include -#include +#include "cs-etm.h" =20 struct cs_etm_recording { struct auxtrace_record itr; --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEE42390610 for ; Fri, 22 May 2026 22:04:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487486; cv=none; b=Ns80AoeFqnqroOMmuWgoJAaVIcK36WQVKVZ6OYfel4Mtc7Yz+bOmtAB3BdXVEq/IjHuiDNFnQ9nPhmNPTPPJO/Es7O77TEZ6rTULXbgO99Pg7h70E+yFZn+BHC2JcFEG0YipltojO1jt+mxQNmyeen5ANIyaAfaz6qgGZrYhlEU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487486; c=relaxed/simple; bh=Z9EfuPTzMJXZQXnYTrZ4ffha0yrd3iGXR/sJfpw92rE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=X7hV9+bjy0FAa8Os/C/X9MhC3se/GCVPG/gXcfk+dzXP8+H/JkILIUW/9cMfvt4LE29Cmj2kyoy8rypccrqS62Np5EX2rbttlM+fLL1Eiq/9TffzLI/Nvm3fIFjeKwmd2IqRoqWHXo9VxFiOZsD1mD0g8Sv19aW9GeslZ7KJZK4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Ha51a3pe; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Ha51a3pe" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2bdd327d970so4356547eec.1 for ; Fri, 22 May 2026 15:04:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487484; x=1780092284; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=qK9dSpPcv6wOfbSQzn8e4LYSN0aiyiQIegu2xzHPiXg=; b=Ha51a3pefej7+mpOSWSD9ZfJTi5FCrZWXpqpLPwUlm3TzvfyhJyY3wbcr+6NXvMGex S1Dya7eNHoxtMt8KjrGkTc2KBQUZ1aoNgbQr32t7t4wrUaFVYpCyGMVr8LO0OsRousQZ Y5HHsPLuq9kcm43wFJAcvj9dHo8iaE2PqRPSV0zAbzIPf6qcBA74arzSZ5mvkeGO3c/+ +8aQ/Mfxu1o8pZffWONUeWAkhsdZRaiSJpwJ41LBJbjxjfwi4IBYY02eEySGmUEzn3Vl illSwr+TyxxTEa8ZmZ1PyUAp2eC9cGb3nO1Rz991m99H71LmtzOghvH6zFt1CLvfLo93 FYFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487484; x=1780092284; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=qK9dSpPcv6wOfbSQzn8e4LYSN0aiyiQIegu2xzHPiXg=; b=NxO0owRE5lN0EKfPVc5Y9/+OUfDTEc7eul5gpVAbJ6mdvA4cgILwcvCbNcFQHftnMW jDmOsPNxNQMEhxlhlqMg1OJRpDg2EiCG5vovUb2E35yq9KSJb8fYFH4wdGrvu0+UFic5 m+HIy9hLIvKIPQ5WBnDdYopQXMwaM+x9iSf9sKOO25Tb0LPGMArv5KBHb+iH2fgWxTyC bSx4ssxAvstTNd7NMqZBEMJX6KQq+uSEgX4ZbTKG06ebEkn2UJGw7ehadUabpjJb3tNi 8wX3inIGM2c5GOoe2GTn1YqhSDRmw4sZXMzPmP/CrVamEHMXroctF2QadixpU1zWf0bw nX2g== X-Forwarded-Encrypted: i=1; AFNElJ9ZObZOU9tQ+3q3t+O4S1Ao2YeCvRSAdlDOQnVH6N8JyshtzYEjVkqYoUv7s5QZ7YAlKdzKXim7dYw1cQc=@vger.kernel.org X-Gm-Message-State: AOJu0Yzk0U5I16Fv4ZcQQDHlRmmxvGuuJn998y6z+cTQFexJmjzkp6qy JRwc8fkIcBpWi66fjNwYWZ7ATa0O8tAFFWK8mpKR1kJB7zrNhzuckgcJdX4uDNn4i4VJ5gkt/qr B8C2mtC0niA== X-Received: from dyblz48.prod.google.com ([2002:a05:7301:1630:b0:304:59b1:e122]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:7483:b0:2ee:7b2e:8a3e with SMTP id 5a478bee46e88-304304fbfa4mr4638762eec.1.1779487483670; Fri, 22 May 2026 15:04:43 -0700 (PDT) Date: Fri, 22 May 2026 15:04:13 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-3-irogers@google.com> Subject: [PATCH v9 02/23] perf arch x86: Sort includes and add missed explicit dependencies From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix missing #includes found while cleaning the evsel/evlist header files. Sort the remaining header files for consistency with the rest of the code. Signed-off-by: Ian Rogers --- tools/perf/arch/x86/util/intel-bts.c | 20 +++++++++++-------- tools/perf/arch/x86/util/intel-pt.c | 29 +++++++++++++++------------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/uti= l/intel-bts.c index 85c8186300c8..100a23d27998 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -4,26 +4,30 @@ * Copyright (c) 2013-2015, Intel Corporation. */ =20 +#include "../../../util/intel-bts.h" + #include -#include -#include + #include +#include #include +#include #include =20 +#include // page_size + +#include "../../../util/auxtrace.h" #include "../../../util/cpumap.h" +#include "../../../util/debug.h" #include "../../../util/event.h" -#include "../../../util/evsel.h" #include "../../../util/evlist.h" +#include "../../../util/evsel.h" #include "../../../util/mmap.h" -#include "../../../util/session.h" +#include "../../../util/pmu.h" #include "../../../util/pmus.h" -#include "../../../util/debug.h" #include "../../../util/record.h" +#include "../../../util/session.h" #include "../../../util/tsc.h" -#include "../../../util/auxtrace.h" -#include "../../../util/intel-bts.h" -#include // page_size =20 #define KiB(x) ((x) * 1024) #define MiB(x) ((x) * 1024 * 1024) diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util= /intel-pt.c index c131a727774f..0307ff15d9fc 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -3,36 +3,39 @@ * intel_pt.c: Intel Processor Trace support * Copyright (c) 2013-2015, Intel Corporation. */ +#include "../../../util/intel-pt.h" =20 #include #include -#include -#include + #include +#include +#include #include +#include #include -#include =20 -#include "../../../util/session.h" +#include +#include // page_size +#include + +#include "../../../util/auxtrace.h" +#include "../../../util/config.h" +#include "../../../util/cpumap.h" +#include "../../../util/debug.h" #include "../../../util/event.h" #include "../../../util/evlist.h" #include "../../../util/evsel.h" #include "../../../util/evsel_config.h" -#include "../../../util/config.h" -#include "../../../util/cpumap.h" #include "../../../util/mmap.h" -#include #include "../../../util/parse-events.h" -#include "../../../util/pmus.h" -#include "../../../util/debug.h" -#include "../../../util/auxtrace.h" #include "../../../util/perf_api_probe.h" +#include "../../../util/pmu.h" +#include "../../../util/pmus.h" #include "../../../util/record.h" +#include "../../../util/session.h" #include "../../../util/target.h" #include "../../../util/tsc.h" -#include // page_size -#include "../../../util/intel-pt.h" -#include #include "cpuid.h" =20 #define KiB(x) ((x) * 1024) --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2B653911C7 for ; Fri, 22 May 2026 22:04:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487488; cv=none; b=VHjRjGTXDPC1yGt2pV4DsePo9fq6LMg8OqJWUm8OoU4bH7VrrDSSsB4HPkALh9dsE9je3PFaMyhYXyiub5lBHhrI5AMfw3XqLI+X7FOlCHd0Aa9w9Z+dBu06vmWsDn/cSYaeKpCOa8GnUjQV4QXlG8SYr6i8mRy9Nu2r4mB68OU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487488; c=relaxed/simple; bh=oYp56yQ9c3HTPir1o13TAxUrIQnMwxiHstNvNMPJJn8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LhSM9PQxdqwhBXkjwQQtt04utcb3eGSgmcbpUV5G/TLhvZAa8XEBlSsJMisb/D+96be/rPKFIftlJjZ9Y6rwkKWc9Y+Y7uz+B9XW1mjQSLMjKiKo7OtwT6owzjUeu/TEFOX0KW8KgTpEx1cl8cYi7cpzXj9iRcnyjQJqyQJGCFw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=eHBIakqU; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="eHBIakqU" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-304448ab58cso5503720eec.1 for ; Fri, 22 May 2026 15:04:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487486; x=1780092286; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=oLgxoRHXv6qZ3ND3G4At5I30r6SxZQ/gRRHwp7gOY3U=; b=eHBIakqUopjqjdgr6tBj3f9dQAjKt8xrghSgK6J/fsvvTTiy30qg3J+Y+g3nR3kPaI GoNECEqNdHgn3iHoNJJQDOkpJpBrVvBnkD1FVWYgp8I8L4v4HjYcq3wOObp27ievp8sZ t/SewWfHvrIqx6U1h9eENuupN2Dlkw8nsHgweT+mX5a1fW55/rEoeLWsHniTqjsF01tP 6iAtRaSmsBTIOc2jvWDMqr88CJkHIUQRjU8piEMxuQ+gJ8tzinYoJ1tj2dMbBhdcrAPY wTHtq0qujn4/R6SUlZA2QiRECiEYzz7bLqc44E0cGzp8Gdq3NfEAjP55gC3twtk0QEwl BIDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487486; x=1780092286; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=oLgxoRHXv6qZ3ND3G4At5I30r6SxZQ/gRRHwp7gOY3U=; b=KB4q2ryxUXelnDaEOvzziA1iG46MQGFgICZ/LFIupPemsS4J/PpYyYcKdqGrl4mGHp GDwDgFPQxmuZqU7tC2xKqF3fK0bCC1liYJortjoPWRWu2CyAOWZmS1Kl7yFRV4EWupp0 G/JpYrmPgz3kn/hH7bZC4hGkGIBsnunXOVha4Vm+cB+k4/4Cb5IcVd0hGMgZScV3Tsax vOB4hIKT66zAJF36bntGpaLxi1x4qm564/Y65lv+GpKXOGM3mcNG0pCZRZgeRAJWayfJ 3BZ3kKxPLacj9HtcWzmQ8j50RP68SlEiDcgHTqxYJZ0woQUZ2HNWTDtC2fJ202GSGcBH cv3w== X-Forwarded-Encrypted: i=1; AFNElJ8M0tvpDwnglO3XDsBsqjtJRzqnVrOkNYL+CfcaeMkR0Ttus4EsvvwYtae4yrST/GYTEnFCBTaaLjZEoFo=@vger.kernel.org X-Gm-Message-State: AOJu0YzxAu5p7hRaeFcOlwX0GNl5QDFwcbGJQSMriPJp3kaU3eCmkfC+ XBToHcC4SBLEzR1eFOAPgv1T39hnXxy7e7NfHkWqzy11wQf1Hhakp/3fkJZbxRzlaiRAGaPMl2e ZhE3ZJ4jcDA== X-Received: from dycok22.prod.google.com ([2002:a05:7301:db16:b0:2e5:fa99:f6e4]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:8b1f:b0:302:e560:afb5 with SMTP id 5a478bee46e88-3044915659dmr2907607eec.18.1779487485728; Fri, 22 May 2026 15:04:45 -0700 (PDT) Date: Fri, 22 May 2026 15:04:14 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-4-irogers@google.com> Subject: [PATCH v9 03/23] perf tests: Sort includes and add missed explicit dependencies From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix missing #includes found while cleaning the evsel/evlist header files. Sort the remaining header files for consistency with the rest of the code. Signed-off-by: Ian Rogers --- tools/perf/tests/hwmon_pmu.c | 14 +++++++++----- tools/perf/tests/mmap-basic.c | 18 +++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/tools/perf/tests/hwmon_pmu.c b/tools/perf/tests/hwmon_pmu.c index 4aa4aac94f09..ada6e445c4c4 100644 --- a/tools/perf/tests/hwmon_pmu.c +++ b/tools/perf/tests/hwmon_pmu.c @@ -1,15 +1,19 @@ // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) -#include "debug.h" -#include "evlist.h" #include "hwmon_pmu.h" -#include "parse-events.h" -#include "tests.h" + #include + #include -#include #include #include #include +#include + +#include "debug.h" +#include "evlist.h" +#include "parse-events.h" +#include "pmus.h" +#include "tests.h" =20 static const struct test_event { const char *name; diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index a18d84d858aa..a69cd1046e9a 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -1,25 +1,29 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include #include #include + +#include +#include +#include +#include + #include +#include +#include =20 #include "cpumap.h" #include "debug.h" #include "event.h" #include "evlist.h" #include "evsel.h" -#include "thread_map.h" +#include "pmu.h" +#include "pmus.h" #include "tests.h" +#include "thread_map.h" #include "util/affinity.h" #include "util/mmap.h" #include "util/sample.h" -#include -#include -#include -#include -#include =20 /* * This test will generate random numbers of calls to some getpid syscalls, --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA4F439150B for ; Fri, 22 May 2026 22:04:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487498; cv=none; b=Ta9gKNtE+vxkSV0td+MJoUR/3cHYDxdY+dVP/aOq1h+WU6inpeG5ioJQjDinZKgQK7GdHop94pdsOfNQyJMQgrws9ZC1WlUnLhbjK3/P+r4/yJZsYWvdlTMS+4MhATpFCgs+X2KGTuh8A57/Z6yZFD5Q/UTBu5KDMS/SOOYF43k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487498; c=relaxed/simple; bh=2FEiYgRloAO+itB1RzuEhbQ8K3QggZNls0cui+7Sh1s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Q/Nf3hO0FRjXvWtDKbaj/4IesiigV9jsOuJfuXnNuWGq0+rupKRWI+3wjsehSo24XfDP+qSRpqCASBtDY0XfLbeJMclhCPlFPcRWwzYWkSwV27bBEuzlB+mP2169OO++RFP1pjLV+pT0qm5KZ7SrN/ylZTHGf/sxDWVLpGbaQQE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=SzctptTu; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="SzctptTu" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2ee5b73c5f2so9414244eec.0 for ; Fri, 22 May 2026 15:04:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487488; x=1780092288; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=RZckQ+HwuCc0wRxxb6eUJU/ilfr6Pz3oy2PsBDZSEIc=; b=SzctptTuHmAAVXX3bb8w1ZSPJ0fc+KFF39mLvZ1BHmiIReEvTp+l+t0ZWwfzZ/v3Sq gapyk4kVcleUUZ55XcjoYGmST3fyKep1RkCU+EJ4/1V5hqVawKpVqj+Iuv85xv6QB8uV SqOuinUO8BueQeYuxFqy0oCDtv4lVzFY0liglzfXb1QfM45jFnZ0zSgnblK85IA/uDfq /Gbey3q+IFPrtCDgFdvLrqvt2AFAtJF2GqJvGd/zE4OMjvrn/82iSBD8Ds3Y8Srq4oKv k75+CwI6celZCSsNEo0J4hvAuJNyqMjG46ERZgwt4kUXv4XWqTWDNi746DZ8ZpJb15ex 7TOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487488; x=1780092288; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=RZckQ+HwuCc0wRxxb6eUJU/ilfr6Pz3oy2PsBDZSEIc=; b=Z59pYnsYgW313EZLSObxO0G9/awpfPm0672ZpDR81hjTLeM01avVt8TigDe/V/pENp l/BjWvCG8FLGqw0UlyGbApLN1eHxViSMvbvZyZJtqoUy/B2ntAo4HZxWNZnIys4s1w0e OHVYeynm3+6Y78DMQImQgQVuB7wwgxK6TgICWFPpxMwx1pRv+ZXcfM9Z1uM/edZdY3fr kYQC7Y9otfIEqY8ChT+RX84L7UZN7hy1XR6I3eIbJm7s7bt5oyeEj8qhTDz/qqShZePu OGJi9MjbE55xwZtG7exB78I5FzYOljW2IEeJUo7F7dWU32++0wlVd0m/AqbdDqXvahoX fnXg== X-Forwarded-Encrypted: i=1; AFNElJ/NzkGL2HCVxp65iXGKRzcTtPzxNqbUYLYIJCOeN0pqj4bNt4Q5Wl+VEcH8wT0Y5970qxif+PC57LHfFh4=@vger.kernel.org X-Gm-Message-State: AOJu0YyQ301V6hHH/e6eEOwPOWOZ55QnyoMgB7O6FQfR8iaKRcXd1aHm jQL2qWDjumhZP4/6dlJkVVHdD0XPSLu2ME29B8UmtRRezWY1HMMgbAPCv++MQwd0auZiFnQOb97 MLUcT8lVIxg== X-Received: from dyaz19-n1.prod.google.com ([2002:a05:693c:6393:10b0:303:98b0:efec]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:650b:b0:2b8:5159:eca5 with SMTP id 5a478bee46e88-30449024b3bmr3046039eec.14.1779487487711; Fri, 22 May 2026 15:04:47 -0700 (PDT) Date: Fri, 22 May 2026 15:04:15 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-5-irogers@google.com> Subject: [PATCH v9 04/23] perf script: Sort includes and add missed explicit dependencies From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix missing #include of pmu.h found while cleaning the evsel/evlist header files. Sort the remaining header files for consistency with the rest of the code. Doing this exposed a missing forward declaration of addr_location in print_insn.h, add this and sort the forward declarations. Signed-off-by: Ian Rogers --- tools/perf/builtin-script.c | 111 ++++++++++++++++++----------------- tools/perf/util/print_insn.h | 5 +- 2 files changed, 60 insertions(+), 56 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index c0918006e0ab..e330ae7f725e 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1,75 +1,78 @@ // SPDX-License-Identifier: GPL-2.0 -#include "builtin.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include =20 +#include +#include +#include +#include + +#include "asm/bug.h" +#include "builtin.h" +#include "perf.h" +#include "print_binary.h" +#include "print_insn.h" +#include "ui/ui.h" +#include "util/annotate.h" +#include "util/auxtrace.h" +#include "util/cgroup.h" +#include "util/color.h" #include "util/counts.h" +#include "util/cpumap.h" +#include "util/data.h" #include "util/debug.h" +#include "util/dlfilter.h" #include "util/dso.h" -#include -#include "util/header.h" -#include -#include "util/perf_regs.h" -#include "util/session.h" -#include "util/tool.h" -#include "util/map.h" -#include "util/srcline.h" -#include "util/symbol.h" -#include "util/thread.h" -#include "util/trace-event.h" +#include "util/dump-insn.h" #include "util/env.h" +#include "util/event.h" #include "util/evlist.h" #include "util/evsel.h" #include "util/evsel_fprintf.h" #include "util/evswitch.h" +#include "util/header.h" +#include "util/map.h" +#include "util/mem-events.h" +#include "util/mem-info.h" +#include "util/metricgroup.h" +#include "util/path.h" +#include "util/perf_regs.h" +#include "util/pmu.h" +#include "util/record.h" +#include "util/session.h" #include "util/sort.h" -#include "util/data.h" -#include "util/auxtrace.h" -#include "util/cpumap.h" -#include "util/thread_map.h" +#include "util/srcline.h" #include "util/stat.h" -#include "util/color.h" #include "util/string2.h" +#include "util/symbol.h" #include "util/thread-stack.h" +#include "util/thread.h" +#include "util/thread_map.h" #include "util/time-utils.h" -#include "util/path.h" -#include "util/event.h" -#include "util/mem-info.h" -#include "util/metricgroup.h" -#include "ui/ui.h" -#include "print_binary.h" -#include "print_insn.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "asm/bug.h" -#include "util/mem-events.h" -#include "util/dump-insn.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "util/dlfilter.h" -#include "util/record.h" +#include "util/tool.h" +#include "util/trace-event.h" #include "util/unwind.h" #include "util/util.h" -#include "util/cgroup.h" -#include "util/annotate.h" -#include "perf.h" =20 -#include #ifdef HAVE_LIBTRACEEVENT #include #endif diff --git a/tools/perf/util/print_insn.h b/tools/perf/util/print_insn.h index 07d11af3fc1c..a54f7e858e49 100644 --- a/tools/perf/util/print_insn.h +++ b/tools/perf/util/print_insn.h @@ -5,10 +5,11 @@ #include #include =20 -struct perf_sample; -struct thread; +struct addr_location; struct machine; struct perf_insn; +struct perf_sample; +struct thread; =20 #define PRINT_INSN_IMM_HEX (1<<0) =20 --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5590C34388A for ; Fri, 22 May 2026 22:04:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487498; cv=none; b=s3j/EHEAbQvpO9J6+5REivTTiN5Qf7+6RxkVbf6oi4OlJMfNIGnAr8iyD179cyoh+KC3XGUq8dpGPBuG80P2NnBJFW8QtoXh5a5zaVHpY0o473Z/cVnGvZIsptP7xCFYQqWTMADUHRY33vFReP6qwucSpuhfAn7yIWmfdCK7DE4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487498; c=relaxed/simple; bh=0yg6WkMLSkIsXi/6SsgGEd2Nyvi+S4S/NfYzyjqOaAE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=erm+QVZNz8zwN05TZitP3J9ghLdhw4tRY2mLp8+UX0/yZ4IZB+5mWU8R40cv4DKKbx0VQ9T+t1uuyphUDNTmm2HC3lz4PotLJv5mNwWeHMk25Xw56+SAO51FrEtcWA6zhQk2Ea2YkzQy1o78x1E59wcI/aBqUAhnhLSEyfK5bV4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=UsL3kxic; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="UsL3kxic" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-3041ab826ddso5854218eec.0 for ; Fri, 22 May 2026 15:04:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487490; x=1780092290; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=g56yn/AlgBv/1ajnEC1XwVG37xKzxRr80XaxIhB6ZD4=; b=UsL3kxicclDUJK1BbN2u3ER30tECDXzlbjBt4zFX+T5ue+jrUKfHJpyFzLGpihmV22 Gb0atwFx/rq1NcIWJCSxAG0T3Us1MOUIX0OItFWjtDvAQpdl/f/Kvnd3oGQa9Oi7yTFJ 3242H1hVlG+JE3O+1SX1vZE/V4ksRdQpjCUkP+GTpID2ZILL1l3miBhfjyEjFtpJR4l7 pUyFQgL+Wz3+ajrcewb5hkl20SKlTjuMagh+xmd7EDlOGsdx38he+Fw1VrNonzNgLvVe AIQLsBSv3C7ub6A8bECI66AIxYQlW5xLQ3FoiUI8XyYyTn8zWoqVV5DPppBLzkiqKYtX XxGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487490; x=1780092290; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=g56yn/AlgBv/1ajnEC1XwVG37xKzxRr80XaxIhB6ZD4=; b=m3XWfkFIvMfXMBic4Rp3Xb7n34qDPPaB61zmX82BvIH5NQxn57WqXkhMOLICyN6g7H 5nIXAwryMVvQyuX7GgV04/xIPSyxvJEKDhrAdY7EorkaazoKY6CPBXGkrbkJOiKi1f6t TehKb65KY9z9mCLQAuoZuZoCSkTzxEnJiVwGKFBzysX3PDuqVlFFmW3BOx+Ne1v33ChR H1WF3tbqX9mgd+TMMf5YpRcllq95Do0m2A581QOTJpwkhMs8hqPe65a0BAZKy5EATShQ Z8p3CTSL5VHNAsR7t/ADmbmxxF5Rjmp2gfGUKjAM+pXEUmC2Q2GENO1NaTsjf3mykh+X fSlQ== X-Forwarded-Encrypted: i=1; AFNElJ+AyyGNKMSenLummNYiTxwJrZXfO5j5MUXgFORtexfO4OTLwzmUH5S2lMR6LWhO7yfQwASrz8kiz9RIlpU=@vger.kernel.org X-Gm-Message-State: AOJu0YyF37EIIDdkAeel8TLKobbkhX2NRdh2J0FimsXZl9wc4UEAqasL T8F7EuXVGBm1NoF6KP9Ysc4Fe0nZIGoRplXeN+rRaVX33sZ80IofEDifdEpjBSXqmryHLuaW+ah 2eGKIbIZHTQ== X-Received: from dys14.prod.google.com ([2002:a05:693c:800e:b0:2d7:dc51:72ad]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:678c:b0:2dd:6937:79cb with SMTP id 5a478bee46e88-30448f91fbdmr2548497eec.12.1779487490290; Fri, 22 May 2026 15:04:50 -0700 (PDT) Date: Fri, 22 May 2026 15:04:16 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-6-irogers@google.com> Subject: [PATCH v9 05/23] perf util: Sort includes and add missed explicit dependencies From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix missing includes found while cleaning the evsel/evlist header files. Sort the remaining header files for consistency with the rest of the code. Signed-off-by: Ian Rogers --- tools/perf/util/bpf_off_cpu.c | 30 +++++----- tools/perf/util/bpf_trace_augment.c | 8 +-- tools/perf/util/evlist.c | 91 +++++++++++++++-------------- tools/perf/util/evsel.c | 75 ++++++++++++------------ tools/perf/util/map.h | 9 ++- tools/perf/util/perf_api_probe.c | 18 +++--- tools/perf/util/s390-sample-raw.c | 19 +++--- tools/perf/util/stat-shadow.c | 20 ++++--- tools/perf/util/stat.c | 16 +++-- 9 files changed, 152 insertions(+), 134 deletions(-) diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c index a3b699a5322f..48cb930cdd2e 100644 --- a/tools/perf/util/bpf_off_cpu.c +++ b/tools/perf/util/bpf_off_cpu.c @@ -1,23 +1,25 @@ // SPDX-License-Identifier: GPL-2.0 -#include "util/bpf_counter.h" -#include "util/debug.h" -#include "util/evsel.h" -#include "util/evlist.h" -#include "util/off_cpu.h" -#include "util/perf-hooks.h" -#include "util/record.h" -#include "util/session.h" -#include "util/target.h" -#include "util/cpumap.h" -#include "util/thread_map.h" -#include "util/cgroup.h" -#include "util/strlist.h" +#include + #include #include #include -#include =20 +#include "bpf_counter.h" #include "bpf_skel/off_cpu.skel.h" +#include "cgroup.h" +#include "cpumap.h" +#include "debug.h" +#include "evlist.h" +#include "evsel.h" +#include "off_cpu.h" +#include "parse-events.h" +#include "perf-hooks.h" +#include "record.h" +#include "session.h" +#include "strlist.h" +#include "target.h" +#include "thread_map.h" =20 #define MAX_STACKS 32 #define MAX_PROC 4096 diff --git a/tools/perf/util/bpf_trace_augment.c b/tools/perf/util/bpf_trac= e_augment.c index 9e706f0fa53d..a9cf2a77ded1 100644 --- a/tools/perf/util/bpf_trace_augment.c +++ b/tools/perf/util/bpf_trace_augment.c @@ -1,11 +1,11 @@ #include #include =20 -#include "util/debug.h" -#include "util/evlist.h" -#include "util/trace_augment.h" - #include "bpf_skel/augmented_raw_syscalls.skel.h" +#include "debug.h" +#include "evlist.h" +#include "parse-events.h" +#include "trace_augment.h" =20 static struct augmented_raw_syscalls_bpf *skel; static struct evsel *bpf_output; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index ee971d15b3c6..35d65fe50e06 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -5,67 +5,68 @@ * Parts came from builtin-{top,stat,record}.c, see those files for further * copyright notes. */ -#include +#include "evlist.h" + #include #include -#include -#include "cpumap.h" -#include "util/mmap.h" -#include "thread_map.h" -#include "target.h" -#include "dwarf-regs.h" -#include "evlist.h" -#include "evsel.h" -#include "record.h" -#include "debug.h" -#include "units.h" -#include "bpf_counter.h" -#include // page_size -#include "affinity.h" -#include "../perf.h" -#include "asm/bug.h" -#include "bpf-event.h" -#include "util/event.h" -#include "util/string2.h" -#include "util/perf_api_probe.h" -#include "util/evsel_fprintf.h" -#include "util/pmu.h" -#include "util/sample.h" -#include "util/bpf-filter.h" -#include "util/stat.h" -#include "util/util.h" -#include "util/env.h" -#include "util/intel-tpebs.h" -#include "util/metricgroup.h" -#include "util/strbuf.h" #include -#include -#include #include =20 -#include "parse-events.h" -#include - #include -#include -#include -#include -#include -#include - #include +#include #include #include -#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // page_size +#include +#include #include #include -#include #include +#include =20 -#include +#include "../perf.h" +#include "affinity.h" +#include "asm/bug.h" +#include "bpf-event.h" +#include "bpf-filter.h" +#include "bpf_counter.h" +#include "cpumap.h" +#include "debug.h" +#include "dwarf-regs.h" +#include "env.h" +#include "event.h" +#include "evsel.h" +#include "evsel_fprintf.h" +#include "intel-tpebs.h" +#include "metricgroup.h" +#include "mmap.h" +#include "parse-events.h" +#include "perf_api_probe.h" +#include "pmu.h" +#include "pmus.h" +#include "record.h" +#include "sample.h" +#include "stat.h" +#include "strbuf.h" +#include "string2.h" +#include "target.h" +#include "thread_map.h" +#include "units.h" +#include "util.h" =20 #ifdef LACKS_SIGQUEUE_PROTOTYPE int sigqueue(pid_t pid, int sig, const union sigval value); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 713a250c7374..91c3dfa234e6 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -11,68 +11,71 @@ */ #define __SANE_USERSPACE_TYPES__ =20 -#include +#include "evsel.h" + #include #include +#include + +#include #include -#include -#include -#include -#include #include +#include #include +#include +#include #include #include #include #include #include -#include -#include + +#include +#include +#include +#include +#include +#include +#include #include + +#include "../perf-sys.h" #include "asm/bug.h" +#include "bpf-filter.h" #include "bpf_counter.h" #include "callchain.h" #include "cgroup.h" #include "counts.h" +#include "debug.h" +#include "drm_pmu.h" #include "dwarf-regs.h" +#include "env.h" #include "event.h" -#include "evsel.h" -#include "time-utils.h" -#include "util/env.h" -#include "util/evsel_config.h" -#include "util/evsel_fprintf.h" #include "evlist.h" -#include -#include "thread_map.h" -#include "target.h" +#include "evsel_config.h" +#include "evsel_fprintf.h" +#include "hashmap.h" +#include "hist.h" +#include "hwmon_pmu.h" +#include "intel-tpebs.h" +#include "memswap.h" +#include "off_cpu.h" +#include "parse-branch-options.h" #include "perf_regs.h" +#include "pmu.h" +#include "pmus.h" #include "record.h" -#include "debug.h" -#include "trace-event.h" +#include "rlimit.h" #include "session.h" #include "stat.h" #include "string2.h" -#include "memswap.h" -#include "util.h" -#include "util/hashmap.h" -#include "off_cpu.h" -#include "pmu.h" -#include "pmus.h" -#include "drm_pmu.h" -#include "hwmon_pmu.h" +#include "target.h" +#include "thread_map.h" +#include "time-utils.h" #include "tool_pmu.h" #include "tp_pmu.h" -#include "rlimit.h" -#include "../perf-sys.h" -#include "util/parse-branch-options.h" -#include "util/bpf-filter.h" -#include "util/hist.h" -#include -#include -#include -#include "util/intel-tpebs.h" - -#include +#include "trace-event.h" +#include "util.h" =20 #ifdef HAVE_LIBTRACEEVENT #include diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 979b3e11b9bc..fb0279810ae9 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -2,14 +2,13 @@ #ifndef __PERF_MAP_H #define __PERF_MAP_H =20 -#include -#include -#include -#include +#include #include #include -#include + +#include #include + #include =20 struct dso; diff --git a/tools/perf/util/perf_api_probe.c b/tools/perf/util/perf_api_pr= obe.c index 6ecf38314f01..e1904a330b28 100644 --- a/tools/perf/util/perf_api_probe.c +++ b/tools/perf/util/perf_api_probe.c @@ -1,14 +1,18 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#include "perf_api_probe.h" =20 -#include "perf-sys.h" -#include "util/cloexec.h" -#include "util/evlist.h" -#include "util/evsel.h" -#include "util/parse-events.h" -#include "util/perf_api_probe.h" -#include #include =20 +#include + +#include "cloexec.h" +#include "evlist.h" +#include "evsel.h" +#include "parse-events.h" +#include "perf-sys.h" +#include "pmu.h" +#include "pmus.h" + typedef void (*setup_probe_fn_t)(struct evsel *evsel); =20 static int perf_do_probe_api(setup_probe_fn_t fn, struct perf_cpu cpu, con= st char *str) diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sampl= e-raw.c index 52bbca5c56c8..01111c4e3488 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -12,25 +12,26 @@ * sample was taken from. */ =20 -#include +#include #include #include -#include =20 -#include +#include #include #include -#include +#include +#include =20 +#include "color.h" #include "debug.h" -#include "session.h" #include "evlist.h" -#include "color.h" #include "hashmap.h" -#include "sample-raw.h" +#include "pmu.h" +#include "pmus.h" #include "s390-cpumcf-kernel.h" -#include "util/pmu.h" -#include "util/sample.h" +#include "sample-raw.h" +#include "sample.h" +#include "session.h" =20 static size_t ctrset_size(struct cf_ctrset_entry *set) { diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index bc2d44df7baf..48524450326d 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -2,20 +2,24 @@ #include #include #include -#include "evsel.h" -#include "stat.h" + +#include + +#include "cgroup.h" #include "color.h" #include "debug.h" -#include "pmu.h" -#include "rblist.h" #include "evlist.h" +#include "evsel.h" #include "expr.h" -#include "metricgroup.h" -#include "cgroup.h" -#include "units.h" +#include "hashmap.h" #include "iostat.h" -#include "util/hashmap.h" +#include "metricgroup.h" +#include "pmu.h" +#include "pmus.h" +#include "rblist.h" +#include "stat.h" #include "tool_pmu.h" +#include "units.h" =20 static bool tool_pmu__is_time_event(const struct perf_stat_config *config, const struct evsel *evsel, int *tool_aggr_idx) diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 14d169e22e8f..66eb9a66a4f7 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -1,21 +1,25 @@ // SPDX-License-Identifier: GPL-2.0 +#include "stat.h" + #include -#include #include #include #include + +#include +#include + #include "counts.h" #include "cpumap.h" #include "debug.h" +#include "evlist.h" +#include "evsel.h" +#include "hashmap.h" #include "header.h" -#include "stat.h" +#include "pmu.h" #include "session.h" #include "target.h" -#include "evlist.h" -#include "evsel.h" #include "thread_map.h" -#include "util/hashmap.h" -#include =20 void update_stats(struct stats *stats, u64 val) { --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 62DA6368277 for ; Fri, 22 May 2026 22:04:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487496; cv=none; b=s2W/mh3B8RmuAEjP4bNcNfWSLI8m83RpzG4D2709qLzCWU6bxM9etLwWVcI3AjBntF3dkRffRE4Qkxg3UcWUDlTES+47k2SUrvFKmbaEJNBsucGRG1hEMe8VVvB8QnbPncRGnXGvPxWpo2Por1tMOZKX/ac1pEq/QoDpXyaJV2U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487496; c=relaxed/simple; bh=AVq3snyWrKDDoDuCNejXayYqVthYN3vXW6RfemKwgqA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=px1QwqV9sl17BxLlgT0/Z35gQtc2AnwfBmXcs+WzfQz7e+Izc4awvr0ppinYXIPlseWsjFXK54QoFdw+6FOvCqLCcSeFZJ0IECkW3I/lMp70tKPPuZq/kJqrbh9tlfT9i7cpZE4oebmSp+htgKWgAH+DRo6X8bh91vCXxcbcRcw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=AUmqksuR; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AUmqksuR" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2efc342ef15so9644401eec.1 for ; Fri, 22 May 2026 15:04:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487493; x=1780092293; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=p+Ps4mCr8gi146N9Gz5RD0kRPKapXZPgmaFKoDB0Lgo=; b=AUmqksuRJUGy0gTrHAO0+iv9LdLMCdwqXcqJgXNyd/DmA9dcZJE9Q6BxOcA4rvo4VV t7t1RksZ7RRs4ed1Z0MyBRdQiBV/gznT8wTgV4iXFj8nRZWPMHTvpTCUB/DqHUlr9s9z A5Ay2iGET7pWBoZ2P06BfFWZihaiZKH1Cwm7yBQBfX48K65vC89y2UdUG9W7KnvrhqgW jg6YZ86norwgMLJ4cSLC+pNE7NBJa0VkJqYzBW/ly8SPcGIPfxLn4ibHJxBEr4AffgrQ BuRjMHOa2tEJtDDyR+obJdaRROyqpxGEmsjQddClSui19prB/ZyB5a5dd5fdGqX4ut3e AGgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487493; x=1780092293; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=p+Ps4mCr8gi146N9Gz5RD0kRPKapXZPgmaFKoDB0Lgo=; b=suUg1GcHwYKx3j4UYy97NVlz24jwAvgKZNrrLokh18m1iFplAByz2rOllzdk79E53h kAJeq3SPs95HvuswbxJ699ei7dfSUBZ6YFXZE+HIXlqtgDumWlZZ2Y85AOLlIPs3bRN+ iHVI182gFtPBiV+w7mN5LdyR8bPhfm2WkwNBXwgLs73L2/ium9TKEWkQyAEF6dCgL+nY K6dnH07Cu9Vl4wJylqK77L21YLe/13XJDpu1fZQVCUJ75HvMtClwzLM7hQl2JB58pIZi X/dBGNvZkHIxegf8Jpq6nul/PTita/xSFXnghdLH1lWbyissiuQ36eY9q9zkhcX8Tk81 hhoA== X-Forwarded-Encrypted: i=1; AFNElJ8cr04GBRo8mHiX1MTOay3mcxgC1i0ZcxgC7N2C9CgSG5wa01phhsVlXArbEgaqgAaajsgAiN0rl/lsZL4=@vger.kernel.org X-Gm-Message-State: AOJu0Yy7zePgMcwNIDXvlNse6+8c6jB4QWmYGb4ij+VU5G1gcmFWs/ik 4H4Xs6wlJ30eGyi+a7ODWlQOoJSRRfPregT6riPh+BJKHpbZg4ed62D9ulA/lIafn7khH3pUM3M Gwjbp2CMZUQ== X-Received: from dyjt24.prod.google.com ([2002:a05:7300:7b18:b0:2f2:fc0:8869]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:6446:b0:2f8:42b0:e63d with SMTP id 5a478bee46e88-30448f363demr2843328eec.2.1779487492324; Fri, 22 May 2026 15:04:52 -0700 (PDT) Date: Fri, 22 May 2026 15:04:17 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-7-irogers@google.com> Subject: [PATCH v9 06/23] perf python: Add missed explicit dependencies From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix missing #include of pmus.h found while cleaning the evsel/evlist header files. Signed-off-by: Ian Rogers --- tools/perf/util/python.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index cc1019d29a5d..dd937d714e99 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1,30 +1,35 @@ // SPDX-License-Identifier: GPL-2.0 -#include -#include #include -#include + #include +#include + +#include +#include #include -#ifdef HAVE_LIBTRACEEVENT -#include -#endif #include +#include + #include "callchain.h" #include "counts.h" +#include "event.h" #include "evlist.h" #include "evsel.h" -#include "event.h" #include "expr.h" +#include "metricgroup.h" +#include "mmap.h" +#include "pmus.h" #include "print_binary.h" #include "record.h" #include "strbuf.h" #include "thread_map.h" #include "tp_pmu.h" #include "trace-event.h" -#include "metricgroup.h" -#include "mmap.h" #include "util/sample.h" -#include + +#ifdef HAVE_LIBTRACEEVENT +#include +#endif =20 PyMODINIT_FUNC PyInit_perf(void); =20 --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84E6038D412 for ; Fri, 22 May 2026 22:04:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487496; cv=none; b=MpdbiFXamud/TkMq9GMQUhIHtOeJ0QxfujrHL610VhrGszYmgC/oE9GhEDjC2U6PE6zBcH6zN4Z+vIXnaY2eJcAAyIHKppLwB00C21gqSdT57r+zK/iHx1hDJfj5DLYHoH9ZlwIQ2LalJMx0YyWSnalmVN69sCwCrB5wWapN90E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487496; c=relaxed/simple; bh=vumwsMzw2OKnkaJH3dZkbheLZPdnOIMAA8QJLUg1C1o=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=CZWc4wYdEQJqsVB9VBZd6ZnU5sTh4JpRYQpUA3u0I05gS7ekq/RPRdlnUZaC8ND/6WHsCCf4lp9NDwVJqpdJOVfL9UHO6+cskPNNMW+gmOEsqXiEQKvjI0xrxwfZk59jPto3gNE4WnO4ckYlgdzM8ZfyU6fcVUHfG4P49oI+n6g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=lMrGZsYp; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="lMrGZsYp" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2fe1cf409a1so12931535eec.1 for ; Fri, 22 May 2026 15:04:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487495; x=1780092295; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=3dI6//58XLq+utXNtomlMShi/6Q6ufN1k/99x8z/TUk=; b=lMrGZsYpXTwKO9cnf2PDxAbwpl+6/8vLRADd0fwkKcPkfrzEvRN5wQhIjyhXVPhGVe vMeQcB6sf44SSbi2boj7FE8Jv1JwffjRyRheHwwgupt1mNtHOV3ivrW9Ny/6ny5GLn6S DLNlxuKSOwVnx7vqv7cDiz3PP2DrSDZANmKCdfTqhA8KaZiHmzsSUGShjDFQpvO8xhaU C3xK6ynSKmH4kE2iD8pLp4F2zx4IknS1AsTeAnpOiWSy+H78M1HGPUON3sjP+mCrFD8E k4n/DyUN2Ssk6S8rwQ4w9s3X2W1WXpi0+IhklaLzqzxGdNiV85nqdqFAom91C+Wtgu62 0heQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487495; x=1780092295; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3dI6//58XLq+utXNtomlMShi/6Q6ufN1k/99x8z/TUk=; b=dx0zBcdpX1KBW0d4t41msgCzHKpVzUIZX74cU+t9A1I44zkNm9wDIkbUlQ3UKaT7UI 3tD8VdDuEiwwvay9wEXNIXQy3pL4eAfqPGreosMJJo4uDcayx1nPQ14qFJNItfvIhKAW GIGo3wjNEBsmyIJDzmFYISEwy7KF7ZEbB8eHvnOIXLkLqGtY52auflwrG2AmsRWqELC/ mY9mQmBlTuWc4i/NDPO/Z06oCZzo4rdLkom36MVxdh+Tg8iFVhTI0pk3nxttGYHp40sB mA44/6xV01h79/jyKU+/0i3VZGwsOEXxl09YN3AJhrNJ9b6m/uO5mgi9SHGXk4tzwrdV Rf+g== X-Forwarded-Encrypted: i=1; AFNElJ8Ev4r21rTpbwrMbhFoc1d5E4SYCQ1StqkOxG8utKJfi325U8XblnDydXp0hZVCWw9c/V2AEJ55u+aFpww=@vger.kernel.org X-Gm-Message-State: AOJu0Yzx8AH0MuQjUmf2Wwg1EMJRqu3iPG1402hbQn6xQ5UB0sNTY/ot NbTD6y/WAnUS8/Aj+zg/o15pONAhTiU7xen/PNsvomzvGwvhsOfbsFVQpamwIytTjVIA084NyUC MdWnbV3dhOQ== X-Received: from dlb3.prod.google.com ([2002:a05:7022:603:b0:135:e6d6:d14d]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:699f:b0:128:d5bd:3572 with SMTP id a92af1059eb24-1365fb40573mr1929174c88.31.1779487494444; Fri, 22 May 2026 15:04:54 -0700 (PDT) Date: Fri, 22 May 2026 15:04:18 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-8-irogers@google.com> Subject: [PATCH v9 07/23] perf evsel/evlist: Avoid unnecessary #includes From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use forward declarations and remove unnecessary #includes in evsel.h. Sort the forward declarations in evsel.h and evlist.h. Signed-off-by: Ian Rogers --- tools/perf/util/evlist.h | 15 +++++++++------ tools/perf/util/evsel.h | 20 +++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index e507f5f20ef6..e54761c670b6 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -2,29 +2,32 @@ #ifndef __PERF_EVLIST_H #define __PERF_EVLIST_H 1 =20 +#include + #include #include -#include #include +#include +#include +#include + #include #include #include #include + #include "affinity.h" #include "events_stats.h" #include "evsel.h" #include "rblist.h" -#include -#include -#include =20 -struct pollfd; -struct thread_map; struct perf_cpu_map; struct perf_stat_config; +struct pollfd; struct record_opts; struct strbuf; struct target; +struct thread_map; =20 /* * State machine of bkw_mmap_state: diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 927e5b4756cc..2221694bb819 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -2,28 +2,30 @@ #ifndef __PERF_EVSEL_H #define __PERF_EVSEL_H 1 =20 -#include #include -#include + +#include #include #include +#include + #include #include + #include "symbol_conf.h" -#include "pmus.h" -#include "pmu.h" =20 +struct bperf_follower_bpf; +struct bperf_leader_bpf; +struct bpf_counter_ops; struct bpf_object; struct cgroup; +struct hashmap; struct perf_counts; +struct perf_pmu; struct perf_stat_config; struct perf_stat_evsel; -union perf_event; -struct bpf_counter_ops; struct target; -struct hashmap; -struct bperf_leader_bpf; -struct bperf_follower_bpf; +union perf_event; =20 typedef int (evsel__sb_cb_t)(union perf_event *event, void *data); =20 --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 34030390608 for ; Fri, 22 May 2026 22:04:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487505; cv=none; b=iSK2aSTI6160r4WuxvYyQDyDajp+gPMgLDnsGW4JSPu7/5Xp/azyJj38Ho16VJAOruSBH92X8c1oRyhv+Sv68yMVFymHPKdY9yJ8poN06TLR0QMSPMUdk/oqgeTKztS5e+i2D1MPOPhXh7FTjKezja/+abUYK78npGiuMAu48ZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487505; c=relaxed/simple; bh=uxCV9jppCE/H5q6yZLcRLCBj0mDjwse7q72zeU61xms=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=j1FXDs0IDoK3qXlNnZLezNY0Ct2002+tP9W26zxJ2o2u+s8wGOKygyueBnAP7MhC/hC0zBiYGkRq/W4PT6jO8Fb6rp/49EjbuGO0jGMuuF5Kv5F2tEf7iHZDjgnPz4giSsOaiXAB1+0JPjqNdKEnWMkUdc9lrl/a9UTOUatFhtY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=nkP8vO8D; arc=none smtp.client-ip=209.85.210.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="nkP8vO8D" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-835423c69ffso4059337b3a.1 for ; Fri, 22 May 2026 15:04:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487497; x=1780092297; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=oc0Kr6q/YLQ3soV5ofZAEXnCcqwAjSYBE+48VtKkBGU=; b=nkP8vO8DS6r1cO8IL0pokdVNIgyERG/CNW3OHsZEoHQvP1zDFRtNDVOi2ZZZit+wFw zfY2lnNevnprv+LmT6yWGRKrCixNwj7v+xWLn/HyzU35oJ7t5vmhIOtWuN+ycgnJy0Dm bskAo80u09zwWc4I3lv37y8zXjWCJuwx/sqdbmYiYwvNYT8k942nWwmPXchODu+geMNH pu/oKc6C5BvTv7C64eTEzwArGZt2/BvcGmFQmWX8ddIdd+YbcKQWGNFCac6g8cTVrlRA n8gdpzgg/Tz014oXSbg58LlBk0B4otc1KfldE7OliR7x4D0jopbkHH5xsM62SZuqft1/ 9HlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487497; x=1780092297; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=oc0Kr6q/YLQ3soV5ofZAEXnCcqwAjSYBE+48VtKkBGU=; b=KmzT+Me08N0c4nQY6wQkG0tdxIinmK4UFIfY0O5pNxIVnwkCeYfaVoBsz7ZKLPk6/j OUll5KnF0vztyt8jjftZOc5RJPG9I+VEMsZE0mY29NAu7b17DkoRZO9K/F20bPk2Pllx NCKpZ6aL0lentZgtfRRn6lh2tjAoX5LEjAQGIzRsjxJ4BSUygjb6m1T9y0DZD+dlfSAz E07paWMVBJ+eHy0bdha/2D0Y5a3z4E5VPdmHZ0KPBs+caPkSdvrzTuxzy8tWZsI9jmrq bV6VDL3WtLbpgm02nnAHJMOM7tNGsOc0zu8nelguP15bmKu0chfd73uZ9Ky6NxmabRE3 fAHA== X-Forwarded-Encrypted: i=1; AFNElJ9/8bRkRn1vZHkA1a728gGWX7KZTiURZytI2/UZXq4+rLR3xRZhsiYAVkMczto3HV3WcYpVWpHxGYR8EYk=@vger.kernel.org X-Gm-Message-State: AOJu0Ywdh0EfmDOBEZh0Axd+rUVlNh3+xX2StrifvAGPxBv4C2IZjTbh GGfy8zuzt8SagSdX+T+eCQD1f3gtwOuSHic+IXVLQ1cq+56/kgaKNIwkg0ryIF0RonZYLSi9gKL xzOTpUfv03A== X-Received: from pfnr26.prod.google.com ([2002:aa7:845a:0:b0:82f:805:b62a]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:14c8:b0:82f:559d:ece3 with SMTP id d2e1a72fcca58-8415f32d5ffmr4770377b3a.15.1779487496964; Fri, 22 May 2026 15:04:56 -0700 (PDT) Date: Fri, 22 May 2026 15:04:19 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-9-irogers@google.com> Subject: [PATCH v9 08/23] perf data: Add open flag From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Avoid double opens and ensure only open files are closed. This addresses some issues with python integration where the data file wants to be opened before being given to a session. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers Acked-by: Namhyung Kim --- Changes in v2: 1. Fixed File Rotation: In perf_data__switch() , I added data->open =3D false; after the file is closed. This ensures that the subsequent perf_data__open() call will not exit early and will successfully open the new file. 2. Fixed Memory Leak: In open_dir() , I added a call to zfree(&data->file.path) if mkdir() fails, preventing the leak of the path string. --- tools/perf/util/data.c | 27 ++++++++++++++++++++++----- tools/perf/util/data.h | 4 +++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 94dc534a7386..ebeb46331005 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -345,9 +345,10 @@ static int open_dir(struct perf_data *data) if (asprintf(&data->file.path, "%s/data", data->path) < 0) return -1; =20 - if (perf_data__is_write(data) && - mkdir(data->path, S_IRWXU) < 0) + if (perf_data__is_write(data) && mkdir(data->path, S_IRWXU) < 0) { + zfree(&data->file.path); return -1; + } =20 ret =3D open_file(data); =20 @@ -360,9 +361,16 @@ static int open_dir(struct perf_data *data) =20 int perf_data__open(struct perf_data *data) { - if (check_pipe(data)) + int ret; + + if (data->open) return 0; =20 + if (check_pipe(data)) { + data->open =3D true; + return 0; + } + /* currently it allows stdio for pipe only */ data->file.use_stdio =3D false; =20 @@ -375,16 +383,24 @@ int perf_data__open(struct perf_data *data) if (perf_data__is_read(data)) data->is_dir =3D is_dir(data); =20 - return perf_data__is_dir(data) ? - open_dir(data) : open_file_dup(data); + ret =3D perf_data__is_dir(data) ? open_dir(data) : open_file_dup(data); + + if (!ret) + data->open =3D true; + + return ret; } =20 void perf_data__close(struct perf_data *data) { + if (!data->open) + return; + if (perf_data__is_dir(data)) perf_data__close_dir(data); =20 perf_data_file__close(&data->file); + data->open =3D false; } =20 static ssize_t perf_data_file__read(struct perf_data_file *file, void *buf= , size_t size) @@ -457,6 +473,7 @@ int perf_data__switch(struct perf_data *data, =20 if (!at_exit) { perf_data_file__close(&data->file); + data->open =3D false; ret =3D perf_data__open(data); if (ret < 0) goto out; diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h index 8299fb5fa7da..76f57f60361f 100644 --- a/tools/perf/util/data.h +++ b/tools/perf/util/data.h @@ -50,6 +50,8 @@ struct perf_data { const char *path; /** @file: Underlying file to be used. */ struct perf_data_file file; + /** @open: Has the file or directory been opened. */ + bool open; /** @is_pipe: Underlying file is a pipe. */ bool is_pipe; /** @is_dir: Underlying file is a directory. */ @@ -59,7 +61,7 @@ struct perf_data { /** @in_place_update: A file opened for reading but will be written to. */ bool in_place_update; /** @mode: Read or write mode. */ - enum perf_data_mode mode; + enum perf_data_mode mode:8; =20 struct { /** @version: perf_dir_version. */ --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 904E7223323 for ; Fri, 22 May 2026 22:05:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487508; cv=none; b=LItWHMn3ujbkBboHLvXK2ESojfXGo9MN/M9ryGhU03bkWqBbcKHJ6VZW2pkjTff4R4zSEFQA4UcRDotqDKG0bi9960hIxvguq0Wn4XyrTHfi5en1iztc7IICKRhAmFuhwe1HdrNaS77azy8pwiTR9LBDKUqpRp5Ljj0wlOwrtII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487508; c=relaxed/simple; bh=SLuHWG1iiEaZ0n7Q4I1G6bQRrDO2kCU35aB1w20GPR8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=WQNuVbk6fui8Td5jYrvwUAxtKWokvM0NP9gdt4kxVg1ibjsH3U+ne2+Zwm4+ETPFeUIlccPLZnT3vQGogzKmkw1qjMy554Z+0lGyL2zmf7GahMZfYxKu+OIpVABDxs1vKL3T5dtKcYyq6183b/6hTvOd3fw9xHOS59w/ShZLMl4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=KpQ5QW/a; arc=none smtp.client-ip=74.125.82.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="KpQ5QW/a" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-134cf343c58so13788894c88.1 for ; Fri, 22 May 2026 15:05:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487500; x=1780092300; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=jWae9pr3JQ8BRjvdh44u8dct8NDtmbnpRBrYHQk0GFs=; b=KpQ5QW/aEOCy0bqjHnGvucMvmiQwB4u04xcJSzyz0clv26qtlwCeFukxPrpovAiIV7 D6GVIrTs0Luts+FqHS4Uj00Rup9rE9HzmRhCMlwa1P1ZNU/JH+qPUT/YlVTvZUsfZ7wU MkxzgE0ecpFCdv7zQkgeU8CZwiDuI78bGOvnGJteLWPk0r8nfHg4jBLTg39CUNSfJL/e C0g8Puv71mfkF21rSVyXFXCdqVdJcezs8XKApFWuG2/k2Y3kAJRCaOjw/J46UOjClthL 3y1b7VzIp/MZQMe31r+ohBMXdmTq7eAD1diZsKFgYkjz/injB2onU0g8a6qB6vSxtYmi c+kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487500; x=1780092300; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=jWae9pr3JQ8BRjvdh44u8dct8NDtmbnpRBrYHQk0GFs=; b=cJ7PiOvDjjWyTBRSXpyBTbAY63kaKgcXo60AWedx5je7o9x4iMWKISOqSmdL6ekRlC OPwGSTqiKWiLZbpBJiSgtiE8o1Kpz/DoXqBj0/ryYe3mn7u+E1PxRvcaQqQVgi/eUt9g XGtgKKerCdC+T9ccmAcWy/cltMs9YGT6GFtpXhJN5aqblD4CZ7l6ibSixH5M7UjWnIy9 CFR2eQ54KrxrAdCrqAFQS+XkWOFkufhHhdBs9qIKGwPOTFTbhWZw1jFCje95yaULWK5s rLjSj47vkPTFc90THN17c4VJc3LJS2Vx9LzI9jeJCgdL3UUEiBa0j41P+5Eujsgw05wG HSkw== X-Forwarded-Encrypted: i=1; AFNElJ+eAX5lw6VruGMrOXPDr6OPDuieX/jZSgwsKUaf0aT3loRSOM2FZ4oTf19vz+UpR4ISn4PDdgUq49PHsaM=@vger.kernel.org X-Gm-Message-State: AOJu0YxXKVlWTu9Y8xfFvPAWrK9OvIo7p+LwMiobVeUuIeAM4/WQmzld mClwty0h4y0bf04EXaJpCGgg0ewDOhtPE767zQFLyTk4ek07HtaF4szt6nSfaQMIPG0Sp5P5Erv yIabym7emDQ== X-Received: from dlw9.prod.google.com ([2002:a05:7022:49:b0:12a:c4ed:5eeb]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:1284:b0:134:7497:2153 with SMTP id a92af1059eb24-1365fa42d73mr1982315c88.20.1779487499410; Fri, 22 May 2026 15:04:59 -0700 (PDT) Date: Fri, 22 May 2026 15:04:20 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-10-irogers@google.com> Subject: [PATCH v9 09/23] perf evlist: Add reference count From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This a no-op for most of the perf tool. The reference count is set to 1 at allocation, the put will see the 1, decrement it and perform the delete. The purpose for adding the reference count is for the python code. Prior to this change the python code would clone evlists, but this has issues if events are opened, etc. This change adds a reference count for the evlists and a later change will add it to evsels. The combination is needed for the python code to operate correctly (not hit asserts in the evsel clone), but the changes are broken apart for the sake of smaller patches. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- v2: Added evlist__put to pyrf_evlist__init in case init is called more than once. I double-checked trace__replay() and confirmed that trace->evlist is not assigned to session->evlist in that function. trace__replay creates a new session and uses its own evlist for processing file events, leaving trace->evlist pointing to the empty list created at startup. Therefore, the evlist__put(trace->evlist) call in trace__exit() is safe and correct to avoid leaking that empty list. v7: - Added pyrf_evlist__new to zero-initialize pevlist->evlist to fix crash on re-initialization. --- tools/perf/arch/x86/tests/hybrid.c | 2 +- tools/perf/arch/x86/tests/topdown.c | 4 +- tools/perf/arch/x86/util/iostat.c | 2 +- tools/perf/bench/evlist-open-close.c | 18 +- tools/perf/builtin-ftrace.c | 8 +- tools/perf/builtin-kvm.c | 4 +- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-record.c | 4 +- tools/perf/builtin-sched.c | 6 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-stat.c | 10 +- tools/perf/builtin-top.c | 52 ++--- tools/perf/builtin-trace.c | 26 +-- tools/perf/tests/backward-ring-buffer.c | 18 +- tools/perf/tests/code-reading.c | 4 +- tools/perf/tests/event-times.c | 4 +- tools/perf/tests/event_update.c | 2 +- tools/perf/tests/evsel-roundtrip-name.c | 8 +- tools/perf/tests/expand-cgroup.c | 8 +- tools/perf/tests/hists_cumulate.c | 2 +- tools/perf/tests/hists_filter.c | 2 +- tools/perf/tests/hists_link.c | 2 +- tools/perf/tests/hists_output.c | 2 +- tools/perf/tests/hwmon_pmu.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/mmap-basic.c | 18 +- tools/perf/tests/openat-syscall-tp-fields.c | 18 +- tools/perf/tests/parse-events.c | 4 +- tools/perf/tests/parse-metric.c | 4 +- tools/perf/tests/parse-no-sample-id-all.c | 2 +- tools/perf/tests/perf-record.c | 18 +- tools/perf/tests/perf-time-to-tsc.c | 2 +- tools/perf/tests/pfm.c | 4 +- tools/perf/tests/pmu-events.c | 6 +- tools/perf/tests/pmu.c | 4 +- tools/perf/tests/sw-clock.c | 14 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 14 +- tools/perf/tests/tool_pmu.c | 2 +- tools/perf/tests/topology.c | 2 +- tools/perf/tests/uncore-event-sorting.c | 2 +- tools/perf/util/cgroup.c | 4 +- tools/perf/util/data-convert-bt.c | 2 +- tools/perf/util/evlist.c | 20 +- tools/perf/util/evlist.h | 7 +- tools/perf/util/expr.c | 2 +- tools/perf/util/header.c | 12 +- tools/perf/util/metricgroup.c | 6 +- tools/perf/util/parse-events.c | 4 +- tools/perf/util/perf_api_probe.c | 2 +- tools/perf/util/python.c | 216 ++++++++------------ tools/perf/util/record.c | 2 +- tools/perf/util/session.c | 2 +- tools/perf/util/sideband_evlist.c | 16 +- 54 files changed, 284 insertions(+), 323 deletions(-) diff --git a/tools/perf/arch/x86/tests/hybrid.c b/tools/perf/arch/x86/tests= /hybrid.c index e221ea104174..dfb0ffc0d030 100644 --- a/tools/perf/arch/x86/tests/hybrid.c +++ b/tools/perf/arch/x86/tests/hybrid.c @@ -268,7 +268,7 @@ static int test_event(const struct evlist_test *e) ret =3D e->check(evlist); } parse_events_error__exit(&err); - evlist__delete(evlist); + evlist__put(evlist); =20 return ret; } diff --git a/tools/perf/arch/x86/tests/topdown.c b/tools/perf/arch/x86/test= s/topdown.c index 221f2c4bbb61..2b6f47ce4932 100644 --- a/tools/perf/arch/x86/tests/topdown.c +++ b/tools/perf/arch/x86/tests/topdown.c @@ -56,7 +56,7 @@ static int event_cb(void *state, struct pmu_event_info *i= nfo) *ret =3D TEST_FAIL; } } - evlist__delete(evlist); + evlist__put(evlist); return 0; } =20 @@ -174,7 +174,7 @@ static int test_sort(const char *str, int expected_slot= s_group_size, CHECK_COND(slots_seen, "slots seen"); ret =3D TEST_OK; out_err: - evlist__delete(evlist); + evlist__put(evlist); parse_events_error__exit(&err); return ret; } diff --git a/tools/perf/arch/x86/util/iostat.c b/tools/perf/arch/x86/util/i= ostat.c index 7442a2cd87ed..e0417552b0cb 100644 --- a/tools/perf/arch/x86/util/iostat.c +++ b/tools/perf/arch/x86/util/iostat.c @@ -337,7 +337,7 @@ int iostat_prepare(struct evlist *evlist, struct perf_s= tat_config *config) if (evlist->core.nr_entries > 0) { pr_warning("The -e and -M options are not supported." "All chosen events/metrics will be dropped\n"); - evlist__delete(evlist); + evlist__put(evlist); evlist =3D evlist__new(); if (!evlist) return -ENOMEM; diff --git a/tools/perf/bench/evlist-open-close.c b/tools/perf/bench/evlist= -open-close.c index faf9c34b4a5d..304929d1f67f 100644 --- a/tools/perf/bench/evlist-open-close.c +++ b/tools/perf/bench/evlist-open-close.c @@ -76,7 +76,7 @@ static struct evlist *bench__create_evlist(char *evstr, c= onst char *uid_str) parse_events_error__exit(&err); pr_err("Run 'perf list' for a list of valid events\n"); ret =3D 1; - goto out_delete_evlist; + goto out_put_evlist; } parse_events_error__exit(&err); if (uid_str) { @@ -85,24 +85,24 @@ static struct evlist *bench__create_evlist(char *evstr,= const char *uid_str) if (uid =3D=3D UINT_MAX) { pr_err("Invalid User: %s", uid_str); ret =3D -EINVAL; - goto out_delete_evlist; + goto out_put_evlist; } ret =3D parse_uid_filter(evlist, uid); if (ret) - goto out_delete_evlist; + goto out_put_evlist; } ret =3D evlist__create_maps(evlist, &opts.target); if (ret < 0) { pr_err("Not enough memory to create thread/cpu maps\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 evlist__config(evlist, &opts, NULL); =20 return evlist; =20 -out_delete_evlist: - evlist__delete(evlist); +out_put_evlist: + evlist__put(evlist); return NULL; } =20 @@ -151,7 +151,7 @@ static int bench_evlist_open_close__run(char *evstr, co= nst char *uid_str) evlist->core.nr_entries, evlist__count_evsel_fds(evlist)); printf(" Number of iterations:\t%d\n", iterations); =20 - evlist__delete(evlist); + evlist__put(evlist); =20 for (i =3D 0; i < iterations; i++) { pr_debug("Started iteration %d\n", i); @@ -162,7 +162,7 @@ static int bench_evlist_open_close__run(char *evstr, co= nst char *uid_str) gettimeofday(&start, NULL); err =3D bench__do_evlist_open_close(evlist); if (err) { - evlist__delete(evlist); + evlist__put(evlist); return err; } =20 @@ -171,7 +171,7 @@ static int bench_evlist_open_close__run(char *evstr, co= nst char *uid_str) runtime_us =3D timeval2usec(&diff); update_stats(&time_stats, runtime_us); =20 - evlist__delete(evlist); + evlist__put(evlist); pr_debug("Iteration %d took:\t%" PRIu64 "us\n", i, runtime_us); } =20 diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 8a7dbfb14535..676239148b87 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -1999,20 +1999,20 @@ int cmd_ftrace(int argc, const char **argv) =20 ret =3D evlist__create_maps(ftrace.evlist, &ftrace.target); if (ret < 0) - goto out_delete_evlist; + goto out_put_evlist; =20 if (argc) { ret =3D evlist__prepare_workload(ftrace.evlist, &ftrace.target, argv, false, ftrace__workload_exec_failed_signal); if (ret < 0) - goto out_delete_evlist; + goto out_put_evlist; } =20 ret =3D cmd_func(&ftrace); =20 -out_delete_evlist: - evlist__delete(ftrace.evlist); +out_put_evlist: + evlist__put(ftrace.evlist); =20 out_delete_filters: delete_filter_func(&ftrace.filters); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index dd2ed21596aa..0ed3df4d0594 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1807,7 +1807,7 @@ static struct evlist *kvm_live_event_list(void) =20 out: if (err) { - evlist__delete(evlist); + evlist__put(evlist); evlist =3D NULL; } =20 @@ -1938,7 +1938,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, out: perf_session__delete(kvm->session); kvm->session =3D NULL; - evlist__delete(kvm->evlist); + evlist__put(kvm->evlist); =20 return err; } diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 94a8c35abb0b..92ad1635ab14 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -2147,7 +2147,7 @@ static int __cmd_contention(int argc, const char **ar= gv) =20 out_delete: lock_filter_finish(); - evlist__delete(con.evlist); + evlist__put(con.evlist); lock_contention_finish(&con); perf_session__delete(session); perf_env__exit(&host_env); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index cc601796b2c8..0739c834729e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -4285,7 +4285,7 @@ int cmd_record(int argc, const char **argv) goto out; =20 evlist__splice_list_tail(rec->evlist, &def_evlist->core.entries); - evlist__delete(def_evlist); + evlist__put(def_evlist); } =20 if (rec->opts.target.tid && !rec->opts.no_inherit_set) @@ -4395,7 +4395,7 @@ int cmd_record(int argc, const char **argv) auxtrace_record__free(rec->itr); out_opts: evlist__close_control(rec->opts.ctl_fd, rec->opts.ctl_fd_ack, &rec->opts.= ctl_fd_close); - evlist__delete(rec->evlist); + evlist__put(rec->evlist); return err; } =20 diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 812a1b0d56d6..f4916585aa75 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -3823,7 +3823,7 @@ static int perf_sched__schedstat_record(struct perf_s= ched *sched, session =3D perf_session__new(&data, &sched->tool); if (IS_ERR(session)) { pr_err("Perf session creation failed.\n"); - evlist__delete(evlist); + evlist__put(evlist); return PTR_ERR(session); } =20 @@ -3922,7 +3922,7 @@ static int perf_sched__schedstat_record(struct perf_s= ched *sched, else fprintf(stderr, "[ perf sched stats: Failed !! ]\n"); =20 - evlist__delete(evlist); + evlist__put(evlist); close(fd); return err; } @@ -4826,7 +4826,7 @@ static int perf_sched__schedstat_live(struct perf_sch= ed *sched, free_cpu_domain_info(cd_map, sv, nr); out: free_schedstat(&cpu_head); - evlist__delete(evlist); + evlist__put(evlist); return err; } =20 diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index e330ae7f725e..421520bdafdc 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2270,7 +2270,7 @@ static int script_find_metrics(const struct pmu_metri= c *pm, } pr_debug("Found metric '%s' whose evsels match those of in the perf data\= n", pm->metric_name); - evlist__delete(metric_evlist); + evlist__put(metric_evlist); out: return 0; } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 99d7db372b48..bfa3512e1686 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2113,7 +2113,7 @@ static int add_default_events(void) stat_config.user_requested_cpu_list, stat_config.system_wide, stat_config.hardware_aware_grouping) < 0) { - evlist__delete(metric_evlist); + evlist__put(metric_evlist); ret =3D -1; break; } @@ -2125,7 +2125,7 @@ static int add_default_events(void) metricgroup__copy_metric_events(evlist, /*cgrp=3D*/NULL, &evlist->metric_events, &metric_evlist->metric_events); - evlist__delete(metric_evlist); + evlist__put(metric_evlist); } list_sort(/*priv=3D*/NULL, &evlist->core.entries, default_evlist_evsel_c= mp); =20 @@ -2146,7 +2146,7 @@ static int add_default_events(void) metricgroup__copy_metric_events(evsel_list, /*cgrp=3D*/NULL, &evsel_list->metric_events, &evlist->metric_events); - evlist__delete(evlist); + evlist__put(evlist); return ret; } =20 @@ -2381,7 +2381,7 @@ static int __cmd_report(int argc, const char **argv) =20 perf_stat.session =3D session; stat_config.output =3D stderr; - evlist__delete(evsel_list); + evlist__put(evsel_list); evsel_list =3D session->evlist; =20 ret =3D perf_session__process_events(session); @@ -3060,7 +3060,7 @@ int cmd_stat(int argc, const char **argv) if (smi_cost && smi_reset) sysfs__write_int(FREEZE_ON_SMI_PATH, 0); =20 - evlist__delete(evsel_list); + evlist__put(evsel_list); =20 evlist__close_control(stat_config.ctl_fd, stat_config.ctl_fd_ack, &stat_c= onfig.ctl_fd_close); =20 diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index c8474f7ac658..ca9d6189f725 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1651,14 +1651,14 @@ int cmd_top(int argc, const char **argv) perf_env__init(&host_env); status =3D perf_config(perf_top_config, &top); if (status) - goto out_delete_evlist; + goto out_put_evlist; /* * Since the per arch annotation init routine may need the cpuid, read * it here, since we are not getting this from the perf.data header. */ status =3D perf_env__set_cmdline(&host_env, argc, argv); if (status) - goto out_delete_evlist; + goto out_put_evlist; =20 status =3D perf_env__read_cpuid(&host_env); if (status) { @@ -1679,30 +1679,30 @@ int cmd_top(int argc, const char **argv) annotate_opts.disassembler_style =3D strdup(disassembler_style); if (!annotate_opts.disassembler_style) { status =3D -ENOMEM; - goto out_delete_evlist; + goto out_put_evlist; } } if (objdump_path) { annotate_opts.objdump_path =3D strdup(objdump_path); if (!annotate_opts.objdump_path) { status =3D -ENOMEM; - goto out_delete_evlist; + goto out_put_evlist; } } if (addr2line_path) { symbol_conf.addr2line_path =3D strdup(addr2line_path); if (!symbol_conf.addr2line_path) { status =3D -ENOMEM; - goto out_delete_evlist; + goto out_put_evlist; } } =20 status =3D symbol__validate_sym_arguments(); if (status) - goto out_delete_evlist; + goto out_put_evlist; =20 if (annotate_check_args() < 0) - goto out_delete_evlist; + goto out_put_evlist; =20 status =3D target__validate(target); if (status) { @@ -1717,15 +1717,15 @@ int cmd_top(int argc, const char **argv) struct evlist *def_evlist =3D evlist__new_default(target, callchain_para= m.enabled); =20 if (!def_evlist) - goto out_delete_evlist; + goto out_put_evlist; =20 evlist__splice_list_tail(top.evlist, &def_evlist->core.entries); - evlist__delete(def_evlist); + evlist__put(def_evlist); } =20 status =3D evswitch__init(&top.evswitch, top.evlist, stderr); if (status) - goto out_delete_evlist; + goto out_put_evlist; =20 if (symbol_conf.report_hierarchy) { /* disable incompatible options */ @@ -1736,18 +1736,18 @@ int cmd_top(int argc, const char **argv) pr_err("Error: --hierarchy and --fields options cannot be used together= \n"); parse_options_usage(top_usage, options, "fields", 0); parse_options_usage(NULL, options, "hierarchy", 0); - goto out_delete_evlist; + goto out_put_evlist; } } =20 if (top.stitch_lbr && !(callchain_param.record_mode =3D=3D CALLCHAIN_LBR)= ) { pr_err("Error: --stitch-lbr must be used with --call-graph lbr\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 if (nr_cgroups > 0 && opts->record_cgroup) { pr_err("--cgroup and --all-cgroups cannot be used together\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 if (branch_call_mode) { @@ -1771,7 +1771,7 @@ int cmd_top(int argc, const char **argv) status =3D perf_env__read_core_pmu_caps(&host_env); if (status) { pr_err("PMU capability data is not available\n"); - goto out_delete_evlist; + goto out_put_evlist; } } =20 @@ -1794,7 +1794,7 @@ int cmd_top(int argc, const char **argv) if (IS_ERR(top.session)) { status =3D PTR_ERR(top.session); top.session =3D NULL; - goto out_delete_evlist; + goto out_put_evlist; } top.evlist->session =3D top.session; =20 @@ -1804,7 +1804,7 @@ int cmd_top(int argc, const char **argv) if (field_order) parse_options_usage(sort_order ? NULL : top_usage, options, "fields", 0); - goto out_delete_evlist; + goto out_put_evlist; } =20 if (top.uid_str) { @@ -1813,18 +1813,18 @@ int cmd_top(int argc, const char **argv) if (uid =3D=3D UINT_MAX) { ui__error("Invalid User: %s", top.uid_str); status =3D -EINVAL; - goto out_delete_evlist; + goto out_put_evlist; } status =3D parse_uid_filter(top.evlist, uid); if (status) - goto out_delete_evlist; + goto out_put_evlist; } =20 if (evlist__create_maps(top.evlist, target) < 0) { ui__error("Couldn't create thread/CPU maps: %s\n", errno =3D=3D ENOENT ? "No such process" : str_error_r(errno, errbuf, = sizeof(errbuf))); status =3D -errno; - goto out_delete_evlist; + goto out_put_evlist; } =20 if (top.delay_secs < 1) @@ -1832,7 +1832,7 @@ int cmd_top(int argc, const char **argv) =20 if (record_opts__config(opts)) { status =3D -EINVAL; - goto out_delete_evlist; + goto out_put_evlist; } =20 top.sym_evsel =3D evlist__first(top.evlist); @@ -1847,14 +1847,14 @@ int cmd_top(int argc, const char **argv) =20 status =3D symbol__annotation_init(); if (status < 0) - goto out_delete_evlist; + goto out_put_evlist; =20 annotation_config__init(); =20 symbol_conf.try_vmlinux_path =3D (symbol_conf.vmlinux_name =3D=3D NULL); status =3D symbol__init(NULL); if (status < 0) - goto out_delete_evlist; + goto out_put_evlist; =20 sort__setup_elide(stdout); =20 @@ -1874,13 +1874,13 @@ int cmd_top(int argc, const char **argv) if (top.sb_evlist =3D=3D NULL) { pr_err("Couldn't create side band evlist.\n."); status =3D -EINVAL; - goto out_delete_evlist; + goto out_put_evlist; } =20 if (evlist__add_bpf_sb_event(top.sb_evlist, &host_env)) { pr_err("Couldn't ask for PERF_RECORD_BPF_EVENT side band events.\n."); status =3D -EINVAL; - goto out_delete_evlist; + goto out_put_evlist; } } #endif @@ -1895,8 +1895,8 @@ int cmd_top(int argc, const char **argv) if (!opts->no_bpf_event) evlist__stop_sb_thread(top.sb_evlist); =20 -out_delete_evlist: - evlist__delete(top.evlist); +out_put_evlist: + evlist__put(top.evlist); perf_session__delete(top.session); annotation_options__exit(); perf_env__exit(&host_env); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 0730c1d9f0b3..06a75b36b3f8 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -4422,7 +4422,7 @@ static int trace__run(struct trace *trace, int argc, = const char **argv) =20 if (trace->summary_bpf) { if (trace_prepare_bpf_summary(trace->summary_mode) < 0) - goto out_delete_evlist; + goto out_put_evlist; =20 if (trace->summary_only) goto create_maps; @@ -4490,19 +4490,19 @@ static int trace__run(struct trace *trace, int argc= , const char **argv) err =3D evlist__create_maps(evlist, &trace->opts.target); if (err < 0) { fprintf(trace->output, "Problems parsing the target to trace, check your= options!\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 err =3D trace__symbols_init(trace, argc, argv, evlist); if (err < 0) { fprintf(trace->output, "Problems initializing symbol libraries!\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 if (trace->summary_mode =3D=3D SUMMARY__BY_TOTAL && !trace->summary_bpf) { trace->syscall_stats =3D alloc_syscall_stats(); if (!trace->syscall_stats) - goto out_delete_evlist; + goto out_put_evlist; } =20 evlist__config(evlist, &trace->opts, &callchain_param); @@ -4511,7 +4511,7 @@ static int trace__run(struct trace *trace, int argc, = const char **argv) err =3D evlist__prepare_workload(evlist, &trace->opts.target, argv, fals= e, NULL); if (err < 0) { fprintf(trace->output, "Couldn't run the workload!\n"); - goto out_delete_evlist; + goto out_put_evlist; } workload_pid =3D evlist->workload.pid; } @@ -4559,7 +4559,7 @@ static int trace__run(struct trace *trace, int argc, = const char **argv) =20 err =3D trace__expand_filters(trace, &evsel); if (err) - goto out_delete_evlist; + goto out_put_evlist; err =3D evlist__apply_filters(evlist, &evsel, &trace->opts.target); if (err < 0) goto out_error_apply_filters; @@ -4676,12 +4676,12 @@ static int trace__run(struct trace *trace, int argc= , const char **argv) } } =20 -out_delete_evlist: +out_put_evlist: trace_cleanup_bpf_summary(); delete_syscall_stats(trace->syscall_stats); trace__symbols__exit(trace); evlist__free_syscall_tp_fields(evlist); - evlist__delete(evlist); + evlist__put(evlist); cgroup__put(trace->cgroup); trace->evlist =3D NULL; trace->live =3D false; @@ -4706,21 +4706,21 @@ static int trace__run(struct trace *trace, int argc= , const char **argv) =20 out_error: fprintf(trace->output, "%s\n", errbuf); - goto out_delete_evlist; + goto out_put_evlist; =20 out_error_apply_filters: fprintf(trace->output, "Failed to set filter \"%s\" on event %s: %m\n", evsel->filter, evsel__name(evsel)); - goto out_delete_evlist; + goto out_put_evlist; } out_error_mem: fprintf(trace->output, "Not enough memory to run!\n"); - goto out_delete_evlist; + goto out_put_evlist; =20 out_errno: fprintf(trace->output, "%m\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 static int trace__replay(struct trace *trace) @@ -5398,7 +5398,7 @@ static void trace__exit(struct trace *trace) zfree(&trace->syscalls.table); } zfree(&trace->perfconfig_events); - evlist__delete(trace->evlist); + evlist__put(trace->evlist); trace->evlist =3D NULL; ordered_events__free(&trace->oe.data); #ifdef HAVE_LIBBPF_SUPPORT diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/bac= kward-ring-buffer.c index c5e7999f2817..2b49b002d749 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -111,7 +111,7 @@ static int test__backward_ring_buffer(struct test_suite= *test __maybe_unused, in err =3D evlist__create_maps(evlist, &opts.target); if (err < 0) { pr_debug("Not enough memory to create thread/cpu maps\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 parse_events_error__init(&parse_error); @@ -124,7 +124,7 @@ static int test__backward_ring_buffer(struct test_suite= *test __maybe_unused, in if (err) { pr_debug("Failed to parse tracepoint event, try use root\n"); ret =3D TEST_SKIP; - goto out_delete_evlist; + goto out_put_evlist; } =20 evlist__config(evlist, &opts, NULL); @@ -133,19 +133,19 @@ static int test__backward_ring_buffer(struct test_sui= te *test __maybe_unused, in if (err < 0) { pr_debug("perf_evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); - goto out_delete_evlist; + goto out_put_evlist; } =20 ret =3D TEST_FAIL; err =3D do_test(evlist, opts.mmap_pages, &sample_count, &comm_count); if (err !=3D TEST_OK) - goto out_delete_evlist; + goto out_put_evlist; =20 if ((sample_count !=3D NR_ITERS) || (comm_count !=3D NR_ITERS)) { pr_err("Unexpected counter: sample_count=3D%d, comm_count=3D%d\n", sample_count, comm_count); - goto out_delete_evlist; + goto out_put_evlist; } =20 evlist__close(evlist); @@ -154,16 +154,16 @@ static int test__backward_ring_buffer(struct test_sui= te *test __maybe_unused, in if (err < 0) { pr_debug("perf_evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); - goto out_delete_evlist; + goto out_put_evlist; } =20 err =3D do_test(evlist, 1, &sample_count, &comm_count); if (err !=3D TEST_OK) - goto out_delete_evlist; + goto out_put_evlist; =20 ret =3D TEST_OK; -out_delete_evlist: - evlist__delete(evlist); +out_put_evlist: + evlist__put(evlist); return ret; } =20 diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index 47043a3a2fb4..fc65a17f67f7 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -807,7 +807,7 @@ static int do_test_code_reading(bool try_kcore) } =20 perf_evlist__set_maps(&evlist->core, NULL, NULL); - evlist__delete(evlist); + evlist__put(evlist); evlist =3D NULL; continue; } @@ -844,7 +844,7 @@ static int do_test_code_reading(bool try_kcore) out_put: thread__put(thread); out_err: - evlist__delete(evlist); + evlist__put(evlist); perf_cpu_map__put(cpus); perf_thread_map__put(threads); machine__delete(machine); diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index ae3b98bb42cf..94ab54ecd3f9 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -186,7 +186,7 @@ static int test_times(int (attach)(struct evlist *), err =3D attach(evlist); if (err =3D=3D TEST_SKIP) { pr_debug(" SKIP : not enough rights\n"); - evlist__delete(evlist); + evlist__put(evlist); return err; } =20 @@ -205,7 +205,7 @@ static int test_times(int (attach)(struct evlist *), count.ena, count.run); =20 out_err: - evlist__delete(evlist); + evlist__put(evlist); return !err ? TEST_OK : TEST_FAIL; } =20 diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_updat= e.c index facc65e29f20..73141b122d2f 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -117,7 +117,7 @@ static int test__event_update(struct test_suite *test _= _maybe_unused, int subtes TEST_ASSERT_VAL("failed to synthesize attr update cpus", !perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_eve= nt_cpus)); =20 - evlist__delete(evlist); + evlist__put(evlist); return 0; } =20 diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evs= el-roundtrip-name.c index 1922cac13a24..6a220634c52f 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -33,7 +33,7 @@ static int perf_evsel__roundtrip_cache_name_test(void) if (err) { pr_debug("Failure to parse cache event '%s' possibly as PMUs don't su= pport it", name); - evlist__delete(evlist); + evlist__put(evlist); continue; } evlist__for_each_entry(evlist, evsel) { @@ -42,7 +42,7 @@ static int perf_evsel__roundtrip_cache_name_test(void) ret =3D TEST_FAIL; } } - evlist__delete(evlist); + evlist__put(evlist); } } } @@ -66,7 +66,7 @@ static int perf_evsel__name_array_test(const char *const = names[], int nr_names) if (err) { pr_debug("failed to parse event '%s', err %d\n", names[i], err); - evlist__delete(evlist); + evlist__put(evlist); ret =3D TEST_FAIL; continue; } @@ -76,7 +76,7 @@ static int perf_evsel__name_array_test(const char *const = names[], int nr_names) ret =3D TEST_FAIL; } } - evlist__delete(evlist); + evlist__put(evlist); } return ret; } diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index dd547f2f77cc..a7a445f12693 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -106,7 +106,7 @@ static int expand_default_events(void) TEST_ASSERT_VAL("failed to get evlist", evlist); =20 ret =3D test_expand_events(evlist); - evlist__delete(evlist); + evlist__put(evlist); return ret; } =20 @@ -133,7 +133,7 @@ static int expand_group_events(void) ret =3D test_expand_events(evlist); out: parse_events_error__exit(&err); - evlist__delete(evlist); + evlist__put(evlist); return ret; } =20 @@ -164,7 +164,7 @@ static int expand_libpfm_events(void) =20 ret =3D test_expand_events(evlist); out: - evlist__delete(evlist); + evlist__put(evlist); return ret; } =20 @@ -188,7 +188,7 @@ static int expand_metric_events(void) ret =3D test_expand_events(evlist); =20 out: - evlist__delete(evlist); + evlist__put(evlist); return ret; } =20 diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cum= ulate.c index 267cbc24691a..3467d782d4bd 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -743,7 +743,7 @@ static int test__hists_cumulate(struct test_suite *test= __maybe_unused, int subt =20 out: /* tear down everything */ - evlist__delete(evlist); + evlist__put(evlist); machines__exit(&machines); put_fake_samples(); =20 diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filte= r.c index 002e3a4c1ca5..57513763da36 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -331,7 +331,7 @@ static int test__hists_filter(struct test_suite *test _= _maybe_unused, int subtes =20 out: /* tear down everything */ - evlist__delete(evlist); + evlist__put(evlist); reset_output_field(); machines__exit(&machines); put_fake_samples(); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 996f5f0b3bd1..9646c3b7b4de 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -352,7 +352,7 @@ static int test__hists_link(struct test_suite *test __m= aybe_unused, int subtest =20 out: /* tear down everything */ - evlist__delete(evlist); + evlist__put(evlist); reset_output_field(); machines__exit(&machines); put_fake_samples(); diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_outpu= t.c index fa683fd7b1e5..2aa254ff10f4 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -630,7 +630,7 @@ static int test__hists_output(struct test_suite *test _= _maybe_unused, int subtes =20 out: /* tear down everything */ - evlist__delete(evlist); + evlist__put(evlist); machines__exit(&machines); put_fake_samples(); =20 diff --git a/tools/perf/tests/hwmon_pmu.c b/tools/perf/tests/hwmon_pmu.c index ada6e445c4c4..1b60c3a900f1 100644 --- a/tools/perf/tests/hwmon_pmu.c +++ b/tools/perf/tests/hwmon_pmu.c @@ -214,7 +214,7 @@ static int do_test(size_t i, bool with_pmu, bool with_a= lias) =20 out: parse_events_error__exit(&err); - evlist__delete(evlist); + evlist__put(evlist); return ret; } =20 diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-track= ing.c index 729cc9cc1cb7..51cfd6522867 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -153,7 +153,7 @@ static int test__keep_tracking(struct test_suite *test = __maybe_unused, int subte out_err: if (evlist) { evlist__disable(evlist); - evlist__delete(evlist); + evlist__put(evlist); } perf_cpu_map__put(cpus); perf_thread_map__put(threads); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index a69cd1046e9a..5ff58eb2af8d 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -94,7 +94,7 @@ static int test__basic_mmap(struct test_suite *test __may= be_unused, int subtest /* Permissions failure, flag the failure as a skip. */ err =3D TEST_SKIP; } - goto out_delete_evlist; + goto out_put_evlist; } =20 evsels[i]->core.attr.wakeup_events =3D 1; @@ -106,7 +106,7 @@ static int test__basic_mmap(struct test_suite *test __m= aybe_unused, int subtest pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", str_error_r(errno, sbuf, sizeof(sbuf))); - goto out_delete_evlist; + goto out_put_evlist; } =20 nr_events[i] =3D 0; @@ -116,7 +116,7 @@ static int test__basic_mmap(struct test_suite *test __m= aybe_unused, int subtest if (evlist__mmap(evlist, 128) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); - goto out_delete_evlist; + goto out_put_evlist; } =20 for (i =3D 0; i < nsyscalls; ++i) @@ -134,7 +134,7 @@ static int test__basic_mmap(struct test_suite *test __m= aybe_unused, int subtest if (event->header.type !=3D PERF_RECORD_SAMPLE) { pr_debug("unexpected %s event\n", perf_event__name(event->header.type)); - goto out_delete_evlist; + goto out_put_evlist; } =20 perf_sample__init(&sample, /*all=3D*/false); @@ -142,7 +142,7 @@ static int test__basic_mmap(struct test_suite *test __m= aybe_unused, int subtest if (err) { pr_err("Can't parse sample, err =3D %d\n", err); perf_sample__exit(&sample); - goto out_delete_evlist; + goto out_put_evlist; } =20 err =3D -1; @@ -153,7 +153,7 @@ static int test__basic_mmap(struct test_suite *test __m= aybe_unused, int subtest if (evsel =3D=3D NULL) { pr_debug("event with id %" PRIu64 " doesn't map to an evsel\n", sample.id); - goto out_delete_evlist; + goto out_put_evlist; } nr_events[evsel->core.idx]++; perf_mmap__consume(&md->core); @@ -168,12 +168,12 @@ static int test__basic_mmap(struct test_suite *test _= _maybe_unused, int subtest expected_nr_events[evsel->core.idx], evsel__name(evsel), nr_events[evsel->core.idx]); err =3D -1; - goto out_delete_evlist; + goto out_put_evlist; } } =20 -out_delete_evlist: - evlist__delete(evlist); +out_put_evlist: + evlist__put(evlist); out_free_cpus: perf_cpu_map__put(cpus); out_free_threads: diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests= /openat-syscall-tp-fields.c index 9ff8caff98c3..b30f286fb421 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -51,7 +51,7 @@ static int test__syscall_openat_tp_fields(struct test_sui= te *test __maybe_unused if (IS_ERR(evsel)) { pr_debug("%s: evsel__newtp\n", __func__); ret =3D PTR_ERR(evsel) =3D=3D -EACCES ? TEST_SKIP : TEST_FAIL; - goto out_delete_evlist; + goto out_put_evlist; } =20 evlist__add(evlist, evsel); @@ -59,7 +59,7 @@ static int test__syscall_openat_tp_fields(struct test_sui= te *test __maybe_unused err =3D evlist__create_maps(evlist, &opts.target); if (err < 0) { pr_debug("%s: evlist__create_maps\n", __func__); - goto out_delete_evlist; + goto out_put_evlist; } =20 evsel__config(evsel, &opts, NULL); @@ -70,14 +70,14 @@ static int test__syscall_openat_tp_fields(struct test_s= uite *test __maybe_unused if (err < 0) { pr_debug("perf_evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); - goto out_delete_evlist; + goto out_put_evlist; } =20 err =3D evlist__mmap(evlist, UINT_MAX); if (err < 0) { pr_debug("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); - goto out_delete_evlist; + goto out_put_evlist; } =20 evlist__enable(evlist); @@ -115,7 +115,7 @@ static int test__syscall_openat_tp_fields(struct test_s= uite *test __maybe_unused if (err) { pr_debug("Can't parse sample, err =3D %d\n", err); perf_sample__exit(&sample); - goto out_delete_evlist; + goto out_put_evlist; } =20 tp_flags =3D perf_sample__intval(&sample, "flags"); @@ -126,7 +126,7 @@ static int test__syscall_openat_tp_fields(struct test_s= uite *test __maybe_unused (tp_flags & flags) !=3D flags) { pr_debug("%s: Expected flags=3D%#x, got %#x\n", __func__, flags, tp_flags); - goto out_delete_evlist; + goto out_put_evlist; } =20 goto out_ok; @@ -139,13 +139,13 @@ static int test__syscall_openat_tp_fields(struct test= _suite *test __maybe_unused =20 if (++nr_polls > 5) { pr_debug("%s: no events!\n", __func__); - goto out_delete_evlist; + goto out_put_evlist; } } out_ok: ret =3D TEST_OK; -out_delete_evlist: - evlist__delete(evlist); +out_put_evlist: + evlist__put(evlist); out: return ret; } diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-event= s.c index 05c3e899b425..19dc7b7475d2 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -2568,7 +2568,7 @@ static int test_event(const struct evlist_test *e) ret =3D e->check(evlist); } parse_events_error__exit(&err); - evlist__delete(evlist); + evlist__put(evlist); =20 return ret; } @@ -2594,7 +2594,7 @@ static int test_event_fake_pmu(const char *str) } =20 parse_events_error__exit(&err); - evlist__delete(evlist); + evlist__put(evlist); =20 return ret; } diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 7c7f489a5eb0..3f0ec839c056 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -84,7 +84,7 @@ static int __compute_metric(const char *name, struct valu= e *vals, =20 cpus =3D perf_cpu_map__new("0"); if (!cpus) { - evlist__delete(evlist); + evlist__put(evlist); return -ENOMEM; } =20 @@ -113,7 +113,7 @@ static int __compute_metric(const char *name, struct va= lue *vals, /* ... cleanup. */ evlist__free_stats(evlist); perf_cpu_map__put(cpus); - evlist__delete(evlist); + evlist__put(evlist); return err; } =20 diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/p= arse-no-sample-id-all.c index 50e68b7d43aa..d5a8d065809e 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -49,7 +49,7 @@ static int process_events(union perf_event **events, size= _t count) for (i =3D 0; i < count && !err; i++) err =3D process_event(&evlist, events[i]); =20 - evlist__delete(evlist); + evlist__put(evlist); =20 return err; } diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index ad44cc68820b..f95752b2ed1c 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -105,7 +105,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest err =3D evlist__create_maps(evlist, &opts.target); if (err < 0) { pr_debug("Not enough memory to create thread/cpu maps\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 /* @@ -117,7 +117,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest err =3D evlist__prepare_workload(evlist, &opts.target, argv, false, NULL); if (err < 0) { pr_debug("Couldn't run the workload!\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 /* @@ -134,7 +134,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest pr_debug("sched__get_first_possible_cpu: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); evlist__cancel_workload(evlist); - goto out_delete_evlist; + goto out_put_evlist; } =20 cpu =3D err; @@ -146,7 +146,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest pr_debug("sched_setaffinity: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); evlist__cancel_workload(evlist); - goto out_delete_evlist; + goto out_put_evlist; } =20 /* @@ -158,7 +158,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest pr_debug("perf_evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); evlist__cancel_workload(evlist); - goto out_delete_evlist; + goto out_put_evlist; } =20 /* @@ -171,7 +171,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest pr_debug("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); evlist__cancel_workload(evlist); - goto out_delete_evlist; + goto out_put_evlist; } =20 /* @@ -209,7 +209,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest if (verbose > 0) perf_event__fprintf(event, NULL, stderr); pr_debug("Couldn't parse sample\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 if (verbose > 0) { @@ -350,9 +350,9 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]"); ++errs; } -out_delete_evlist: +out_put_evlist: CPU_FREE(cpu_mask); - evlist__delete(evlist); + evlist__put(evlist); out: perf_sample__exit(&sample); if (err =3D=3D -EACCES) diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-ti= me-to-tsc.c index cca41bd37ae3..d3538fa20af3 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -201,7 +201,7 @@ static int test__perf_time_to_tsc(struct test_suite *te= st __maybe_unused, int su err =3D TEST_OK; =20 out_err: - evlist__delete(evlist); + evlist__put(evlist); perf_cpu_map__put(cpus); perf_thread_map__put(threads); return err; diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c index fca4a86452df..8d19b1bfecbc 100644 --- a/tools/perf/tests/pfm.c +++ b/tools/perf/tests/pfm.c @@ -80,7 +80,7 @@ static int test__pfm_events(struct test_suite *test __may= be_unused, evlist__nr_groups(evlist), 0); =20 - evlist__delete(evlist); + evlist__put(evlist); } return 0; } @@ -165,7 +165,7 @@ static int test__pfm_group(struct test_suite *test __ma= ybe_unused, evlist__nr_groups(evlist), table[i].nr_groups); =20 - evlist__delete(evlist); + evlist__put(evlist); } return 0; } diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index b1609a7e1d8c..327025505970 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -798,7 +798,7 @@ static int check_parse_id(const char *id, struct parse_= events_error *error) /*warn_if_reordered=3D*/true, /*fake_tp=3D*/false); free(dup); =20 - evlist__delete(evlist); + evlist__put(evlist); return ret; } =20 @@ -865,7 +865,7 @@ static int test__parsing_callback(const struct pmu_metr= ic *pm, =20 cpus =3D perf_cpu_map__new("0"); if (!cpus) { - evlist__delete(evlist); + evlist__put(evlist); return -ENOMEM; } =20 @@ -919,7 +919,7 @@ static int test__parsing_callback(const struct pmu_metr= ic *pm, /* ... cleanup. */ evlist__free_stats(evlist); perf_cpu_map__put(cpus); - evlist__delete(evlist); + evlist__put(evlist); return err; } =20 diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index 0ebf2d7b2cb4..3d931c1f99dd 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -287,7 +287,7 @@ static int test__pmu_usr_chgs(struct test_suite *test _= _maybe_unused, int subtes ret =3D TEST_OK; err_out: parse_events_terms__exit(&terms); - evlist__delete(evlist); + evlist__put(evlist); test_pmu_put(dir, pmu); return ret; } @@ -339,7 +339,7 @@ static int test__pmu_events(struct test_suite *test __m= aybe_unused, int subtest ret =3D TEST_OK; err_out: parse_events_error__exit(&err); - evlist__delete(evlist); + evlist__put(evlist); test_pmu_put(dir, pmu); return ret; } diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index b6e46975379c..bb6b62cf51d1 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -59,7 +59,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_i= d) evsel =3D evsel__new(&attr); if (evsel =3D=3D NULL) { pr_debug("evsel__new\n"); - goto out_delete_evlist; + goto out_put_evlist; } evlist__add(evlist, evsel); =20 @@ -68,7 +68,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_i= d) if (!cpus || !threads) { err =3D -ENOMEM; pr_debug("Not enough memory to create thread/cpu maps\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 perf_evlist__set_maps(&evlist->core, cpus, threads); @@ -80,14 +80,14 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock= _id) pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in= this test.\n", str_error_r(errno, sbuf, sizeof(sbuf)), knob, (u64)attr.sample_freq); - goto out_delete_evlist; + goto out_put_evlist; } =20 err =3D evlist__mmap(evlist, 128); if (err < 0) { pr_debug("failed to mmap event: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); - goto out_delete_evlist; + goto out_put_evlist; } =20 evlist__enable(evlist); @@ -113,7 +113,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock= _id) if (err < 0) { pr_debug("Error during parse sample\n"); perf_sample__exit(&sample); - goto out_delete_evlist; + goto out_put_evlist; } =20 total_periods +=3D sample.period; @@ -131,10 +131,10 @@ static int __test__sw_clock_freq(enum perf_sw_ids clo= ck_id) err =3D -1; } =20 -out_delete_evlist: +out_put_evlist: perf_cpu_map__put(cpus); perf_thread_map__put(threads); - evlist__delete(evlist); + evlist__put(evlist); return err; } =20 diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-t= racking.c index e32331fee277..abd08d60179c 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -582,7 +582,7 @@ static int test__switch_tracking(struct test_suite *tes= t __maybe_unused, int sub out: if (evlist) { evlist__disable(evlist); - evlist__delete(evlist); + evlist__put(evlist); } perf_cpu_map__put(cpus); perf_thread_map__put(threads); diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 4053ff2813bb..a46650b10689 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -74,7 +74,7 @@ static int test__task_exit(struct test_suite *test __mayb= e_unused, int subtest _ if (!cpus || !threads) { err =3D -ENOMEM; pr_debug("Not enough memory to create thread/cpu maps\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 perf_evlist__set_maps(&evlist->core, cpus, threads); @@ -82,7 +82,7 @@ static int test__task_exit(struct test_suite *test __mayb= e_unused, int subtest _ err =3D evlist__prepare_workload(evlist, &target, argv, false, workload_e= xec_failed_signal); if (err < 0) { pr_debug("Couldn't run the workload!\n"); - goto out_delete_evlist; + goto out_put_evlist; } =20 evsel =3D evlist__first(evlist); @@ -101,14 +101,14 @@ static int test__task_exit(struct test_suite *test __= maybe_unused, int subtest _ if (err < 0) { pr_debug("Couldn't open the evlist: %s\n", str_error_r(-err, sbuf, sizeof(sbuf))); - goto out_delete_evlist; + goto out_put_evlist; } =20 if (evlist__mmap(evlist, 128) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); err =3D -1; - goto out_delete_evlist; + goto out_put_evlist; } =20 evlist__start_workload(evlist); @@ -133,7 +133,7 @@ static int test__task_exit(struct test_suite *test __ma= ybe_unused, int subtest _ if (retry_count++ > 1000) { pr_debug("Failed after retrying 1000 times\n"); err =3D -1; - goto out_delete_evlist; + goto out_put_evlist; } =20 goto retry; @@ -144,10 +144,10 @@ static int test__task_exit(struct test_suite *test __= maybe_unused, int subtest _ err =3D -1; } =20 -out_delete_evlist: +out_put_evlist: perf_cpu_map__put(cpus); perf_thread_map__put(threads); - evlist__delete(evlist); + evlist__put(evlist); return err; } =20 diff --git a/tools/perf/tests/tool_pmu.c b/tools/perf/tests/tool_pmu.c index 1e900ef92e37..e78ff9dcea97 100644 --- a/tools/perf/tests/tool_pmu.c +++ b/tools/perf/tests/tool_pmu.c @@ -67,7 +67,7 @@ static int do_test(enum tool_pmu_event ev, bool with_pmu) =20 out: parse_events_error__exit(&err); - evlist__delete(evlist); + evlist__put(evlist); return ret; } =20 diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index f54502ebef4b..4ecf5d750313 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -57,7 +57,7 @@ static int session_write_header(char *path) !perf_session__write_header(session, session->evlist, perf_data__fd(&data), true)); =20 - evlist__delete(session->evlist); + evlist__put(session->evlist); perf_session__delete(session); =20 return 0; diff --git a/tools/perf/tests/uncore-event-sorting.c b/tools/perf/tests/unc= ore-event-sorting.c index 7d2fc304e21f..2e741aef4a59 100644 --- a/tools/perf/tests/uncore-event-sorting.c +++ b/tools/perf/tests/uncore-event-sorting.c @@ -165,7 +165,7 @@ static int test__uncore_event_sorting(struct test_suite= *test __maybe_unused, ret =3D TEST_OK; =20 out_err: - evlist__delete(evlist); + evlist__put(evlist); parse_events_error__exit(&err); zfree(&pmu_prefix); zfree(&m.event1); diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 1b5664d1481f..652a45aac828 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -520,8 +520,8 @@ int evlist__expand_cgroup(struct evlist *evlist, const = char *str, bool open_cgro cgrp_event_expanded =3D true; =20 out_err: - evlist__delete(orig_list); - evlist__delete(tmp_list); + evlist__put(orig_list); + evlist__put(tmp_list); metricgroup__rblist_exit(&orig_metric_events); release_cgroup_list(); =20 diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-conve= rt-bt.c index b3f745cff2a7..74956f958337 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -1363,7 +1363,7 @@ static void cleanup_events(struct perf_session *sessi= on) zfree(&evsel->priv); } =20 - evlist__delete(evlist); + evlist__put(evlist); session->evlist =3D NULL; } =20 diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 35d65fe50e06..b5a7895debf5 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -75,7 +75,7 @@ int sigqueue(pid_t pid, int sig, const union sigval value= ); #define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) #define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y) =20 -void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, +static void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, struct perf_thread_map *threads) { perf_evlist__init(&evlist->core); @@ -88,6 +88,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_= map *cpus, evlist->nr_br_cntr =3D -1; metricgroup__rblist_init(&evlist->metric_events); INIT_LIST_HEAD(&evlist->deferred_samples); + refcount_set(&evlist->refcnt, 1); } =20 struct evlist *evlist__new(void) @@ -139,7 +140,7 @@ struct evlist *evlist__new_default(const struct target = *target, bool sample_call =20 return evlist; out_err: - evlist__delete(evlist); + evlist__put(evlist); return NULL; } =20 @@ -148,13 +149,19 @@ struct evlist *evlist__new_dummy(void) struct evlist *evlist =3D evlist__new(); =20 if (evlist && evlist__add_dummy(evlist)) { - evlist__delete(evlist); + evlist__put(evlist); evlist =3D NULL; } =20 return evlist; } =20 +struct evlist *evlist__get(struct evlist *evlist) +{ + refcount_inc(&evlist->refcnt); + return evlist; +} + /** * evlist__set_id_pos - set the positions of event ids. * @evlist: selected event list @@ -193,7 +200,7 @@ static void evlist__purge(struct evlist *evlist) evlist->core.nr_entries =3D 0; } =20 -void evlist__exit(struct evlist *evlist) +static void evlist__exit(struct evlist *evlist) { metricgroup__rblist_exit(&evlist->metric_events); event_enable_timer__exit(&evlist->eet); @@ -202,11 +209,14 @@ void evlist__exit(struct evlist *evlist) perf_evlist__exit(&evlist->core); } =20 -void evlist__delete(struct evlist *evlist) +void evlist__put(struct evlist *evlist) { if (evlist =3D=3D NULL) return; =20 + if (!refcount_dec_and_test(&evlist->refcnt)) + return; + evlist__free_stats(evlist); evlist__munmap(evlist); evlist__close(evlist); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index e54761c670b6..a9820a6aad5b 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -61,6 +61,7 @@ struct event_enable_timer; =20 struct evlist { struct perf_evlist core; + refcount_t refcnt; bool enabled; bool no_affinity; int id_pos; @@ -109,10 +110,8 @@ struct evsel_str_handler { struct evlist *evlist__new(void); struct evlist *evlist__new_default(const struct target *target, bool sampl= e_callchains); struct evlist *evlist__new_dummy(void); -void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, - struct perf_thread_map *threads); -void evlist__exit(struct evlist *evlist); -void evlist__delete(struct evlist *evlist); +struct evlist *evlist__get(struct evlist *evlist); +void evlist__put(struct evlist *evlist); =20 void evlist__add(struct evlist *evlist, struct evsel *entry); void evlist__remove(struct evlist *evlist, struct evsel *evsel); diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c index 644769e92708..cf54bbbc8ddc 100644 --- a/tools/perf/util/expr.c +++ b/tools/perf/util/expr.c @@ -450,7 +450,7 @@ double expr__has_event(const struct expr_parse_ctx *ctx= , bool compute_ids, const ret =3D parse_event(tmp, id) ? 0 : 1; } out: - evlist__delete(tmp); + evlist__put(tmp); return ret; } =20 diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f30e48eb3fc3..f9887d2fc8ed 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -4909,12 +4909,12 @@ int perf_session__read_header(struct perf_session *= session) evsel =3D evsel__new(&f_attr.attr); =20 if (evsel =3D=3D NULL) - goto out_delete_evlist; + goto out_put_evlist; =20 evsel->needs_swap =3D header->needs_swap; /* * Do it before so that if perf_evsel__alloc_id fails, this - * entry gets purged too at evlist__delete(). + * entry gets purged too at evlist__put(). */ evlist__add(session->evlist, evsel); =20 @@ -4925,7 +4925,7 @@ int perf_session__read_header(struct perf_session *se= ssion) * hattr->ids threads. */ if (perf_evsel__alloc_id(&evsel->core, 1, nr_ids)) - goto out_delete_evlist; + goto out_put_evlist; =20 lseek(fd, f_attr.ids.offset, SEEK_SET); =20 @@ -4944,7 +4944,7 @@ int perf_session__read_header(struct perf_session *se= ssion) perf_file_section__process); =20 if (evlist__prepare_tracepoint_events(session->evlist, session->tevent.pe= vent)) - goto out_delete_evlist; + goto out_put_evlist; #else perf_header__process_sections(header, fd, NULL, perf_file_section__proces= s); #endif @@ -4953,8 +4953,8 @@ int perf_session__read_header(struct perf_session *se= ssion) out_errno: return -errno; =20 -out_delete_evlist: - evlist__delete(session->evlist); +out_put_evlist: + evlist__put(session->evlist); session->evlist =3D NULL; return -ENOMEM; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 5a489e97c413..73908b049fed 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -214,7 +214,7 @@ static void metric__free(struct metric *m) zfree(&m->metric_refs); expr__ctx_free(m->pctx); zfree(&m->modifier); - evlist__delete(m->evlist); + evlist__put(m->evlist); free(m); } =20 @@ -1330,7 +1330,7 @@ static int parse_ids(bool metric_no_merge, bool fake_= pmu, parsed_evlist =3D NULL; err_out: parse_events_error__exit(&parse_error); - evlist__delete(parsed_evlist); + evlist__put(parsed_evlist); strbuf_release(&events); return ret; } @@ -1541,7 +1541,7 @@ static int parse_groups(struct evlist *perf_evlist, =20 if (combined_evlist) { evlist__splice_list_tail(perf_evlist, &combined_evlist->core.entries); - evlist__delete(combined_evlist); + evlist__put(combined_evlist); } =20 list_for_each_entry(m, &metric_list, nd) { diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 1497e1f2a08c..f0809be63ad8 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2316,7 +2316,7 @@ int __parse_events(struct evlist *evlist, const char = *str, const char *pmu_filte =20 /* * There are 2 users - builtin-record and builtin-test objects. - * Both call evlist__delete in case of error, so we dont + * Both call evlist__put in case of error, so we dont * need to bother. */ return ret; @@ -2519,7 +2519,7 @@ int parse_events_option_new_evlist(const struct optio= n *opt, const char *str, in } ret =3D parse_events_option(opt, str, unset); if (ret) { - evlist__delete(*args->evlistp); + evlist__put(*args->evlistp); *args->evlistp =3D NULL; } =20 diff --git a/tools/perf/util/perf_api_probe.c b/tools/perf/util/perf_api_pr= obe.c index e1904a330b28..f61c4ec52827 100644 --- a/tools/perf/util/perf_api_probe.c +++ b/tools/perf/util/perf_api_probe.c @@ -57,7 +57,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, struct = perf_cpu cpu, const cha err =3D 0; =20 out_delete: - evlist__delete(evlist); + evlist__put(evlist); return err; } =20 diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index dd937d714e99..de2c5f26c143 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1274,7 +1274,7 @@ static int pyrf_evsel__setup_types(void) struct pyrf_evlist { PyObject_HEAD =20 - struct evlist evlist; + struct evlist *evlist; }; =20 static int pyrf_evlist__init(struct pyrf_evlist *pevlist, @@ -1284,18 +1284,27 @@ static int pyrf_evlist__init(struct pyrf_evlist *pe= vlist, struct perf_cpu_map *cpus; struct perf_thread_map *threads; =20 - if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads)) + if (!PyArg_ParseTuple(args, "O!O!", + &pyrf_cpu_map__type, &pcpus, + &pyrf_thread_map__type, &pthreads)) return -1; =20 + evlist__put(pevlist->evlist); + pevlist->evlist =3D evlist__new(); + if (!pevlist->evlist) { + PyErr_NoMemory(); + return -1; + } threads =3D ((struct pyrf_thread_map *)pthreads)->threads; cpus =3D ((struct pyrf_cpu_map *)pcpus)->cpus; - evlist__init(&pevlist->evlist, cpus, threads); + perf_evlist__set_maps(&pevlist->evlist->core, cpus, threads); + return 0; } =20 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist) { - evlist__exit(&pevlist->evlist); + evlist__put(pevlist->evlist); Py_TYPE(pevlist)->tp_free((PyObject*)pevlist); } =20 @@ -1304,7 +1313,7 @@ static PyObject *pyrf_evlist__all_cpus(struct pyrf_ev= list *pevlist) struct pyrf_cpu_map *pcpu_map =3D PyObject_New(struct pyrf_cpu_map, &pyrf= _cpu_map__type); =20 if (pcpu_map) - pcpu_map->cpus =3D perf_cpu_map__get(pevlist->evlist.core.all_cpus); + pcpu_map->cpus =3D perf_cpu_map__get(pevlist->evlist->core.all_cpus); =20 return (PyObject *)pcpu_map; } @@ -1317,7 +1326,7 @@ static PyObject *pyrf_evlist__metrics(struct pyrf_evl= ist *pevlist) if (!list) return NULL; =20 - for (node =3D rb_first_cached(&pevlist->evlist.metric_events.entries); no= de; + for (node =3D rb_first_cached(&pevlist->evlist->metric_events.entries); n= ode; node =3D rb_next(node)) { struct metric_event *me =3D container_of(node, struct metric_event, nd); struct list_head *pos; @@ -1423,7 +1432,7 @@ static PyObject *pyrf_evlist__compute_metric(struct p= yrf_evlist *pevlist, if (!PyArg_ParseTuple(args, "sii", &metric, &cpu, &thread)) return NULL; =20 - for (node =3D rb_first_cached(&pevlist->evlist.metric_events.entries); + for (node =3D rb_first_cached(&pevlist->evlist->metric_events.entries); mexp =3D=3D NULL && node; node =3D rb_next(node)) { struct metric_event *me =3D container_of(node, struct metric_event, nd); @@ -1439,7 +1448,7 @@ static PyObject *pyrf_evlist__compute_metric(struct p= yrf_evlist *pevlist, if (e->metric_events[0] =3D=3D NULL) continue; =20 - evlist__for_each_entry(&pevlist->evlist, pos2) { + evlist__for_each_entry(pevlist->evlist, pos2) { if (pos2->metric_leader !=3D e->metric_events[0]) continue; cpu_idx =3D perf_cpu_map__idx(pos2->core.cpus, @@ -1484,7 +1493,7 @@ static PyObject *pyrf_evlist__compute_metric(struct p= yrf_evlist *pevlist, static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { - struct evlist *evlist =3D &pevlist->evlist; + struct evlist *evlist =3D pevlist->evlist; static char *kwlist[] =3D { "pages", "overwrite", NULL }; int pages =3D 128, overwrite =3D false; =20 @@ -1504,7 +1513,7 @@ static PyObject *pyrf_evlist__mmap(struct pyrf_evlist= *pevlist, static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { - struct evlist *evlist =3D &pevlist->evlist; + struct evlist *evlist =3D pevlist->evlist; static char *kwlist[] =3D { "timeout", NULL }; int timeout =3D -1, n; =20 @@ -1524,7 +1533,7 @@ static PyObject *pyrf_evlist__get_pollfd(struct pyrf_= evlist *pevlist, PyObject *args __maybe_unused, PyObject *kwargs __maybe_unused) { - struct evlist *evlist =3D &pevlist->evlist; + struct evlist *evlist =3D pevlist->evlist; PyObject *list =3D PyList_New(0); int i; =20 @@ -1553,7 +1562,7 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist = *pevlist, PyObject *args, PyObject *kwargs __maybe_unused) { - struct evlist *evlist =3D &pevlist->evlist; + struct evlist *evlist =3D pevlist->evlist; PyObject *pevsel; struct evsel *evsel; =20 @@ -1585,7 +1594,7 @@ static struct mmap *get_md(struct evlist *evlist, int= cpu) static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { - struct evlist *evlist =3D &pevlist->evlist; + struct evlist *evlist =3D pevlist->evlist; union perf_event *event; int sample_id_all =3D 1, cpu; static char *kwlist[] =3D { "cpu", "sample_id_all", NULL }; @@ -1642,7 +1651,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf= _evlist *pevlist, static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { - struct evlist *evlist =3D &pevlist->evlist; + struct evlist *evlist =3D pevlist->evlist; =20 if (evlist__open(evlist) < 0) { PyErr_SetFromErrno(PyExc_OSError); @@ -1655,7 +1664,7 @@ static PyObject *pyrf_evlist__open(struct pyrf_evlist= *pevlist, =20 static PyObject *pyrf_evlist__close(struct pyrf_evlist *pevlist) { - struct evlist *evlist =3D &pevlist->evlist; + struct evlist *evlist =3D pevlist->evlist; =20 evlist__close(evlist); =20 @@ -1681,7 +1690,7 @@ static PyObject *pyrf_evlist__config(struct pyrf_evli= st *pevlist) .no_buffering =3D true, .no_inherit =3D true, }; - struct evlist *evlist =3D &pevlist->evlist; + struct evlist *evlist =3D pevlist->evlist; =20 evlist__config(evlist, &opts, &callchain_param); Py_INCREF(Py_None); @@ -1690,14 +1699,14 @@ static PyObject *pyrf_evlist__config(struct pyrf_ev= list *pevlist) =20 static PyObject *pyrf_evlist__disable(struct pyrf_evlist *pevlist) { - evlist__disable(&pevlist->evlist); + evlist__disable(pevlist->evlist); Py_INCREF(Py_None); return Py_None; } =20 static PyObject *pyrf_evlist__enable(struct pyrf_evlist *pevlist) { - evlist__enable(&pevlist->evlist); + evlist__enable(pevlist->evlist); Py_INCREF(Py_None); return Py_None; } @@ -1788,7 +1797,23 @@ static Py_ssize_t pyrf_evlist__length(PyObject *obj) { struct pyrf_evlist *pevlist =3D (void *)obj; =20 - return pevlist->evlist.core.nr_entries; + return pevlist->evlist->core.nr_entries; +} + +static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel) +{ + struct pyrf_evsel *pevsel =3D PyObject_New(struct pyrf_evsel, &pyrf_evsel= __type); + + if (!pevsel) + return NULL; + + memset(&pevsel->evsel, 0, sizeof(pevsel->evsel)); + evsel__init(&pevsel->evsel, &evsel->core.attr, evsel->core.idx); + + evsel__clone(&pevsel->evsel, evsel); + if (evsel__is_group_leader(evsel)) + evsel__set_leader(&pevsel->evsel, &pevsel->evsel); + return (PyObject *)pevsel; } =20 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i) @@ -1796,17 +1821,16 @@ static PyObject *pyrf_evlist__item(PyObject *obj, P= y_ssize_t i) struct pyrf_evlist *pevlist =3D (void *)obj; struct evsel *pos; =20 - if (i >=3D pevlist->evlist.core.nr_entries) { + if (i >=3D pevlist->evlist->core.nr_entries) { PyErr_SetString(PyExc_IndexError, "Index out of range"); return NULL; } =20 - evlist__for_each_entry(&pevlist->evlist, pos) { + evlist__for_each_entry(pevlist->evlist, pos) { if (i-- =3D=3D 0) break; } - - return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel)); + return pyrf_evsel__from_evsel(pos); } =20 static PyObject *pyrf_evlist__str(PyObject *self) @@ -1818,7 +1842,7 @@ static PyObject *pyrf_evlist__str(PyObject *self) PyObject *result; =20 strbuf_addstr(&sb, "evlist(["); - evlist__for_each_entry(&pevlist->evlist, pos) { + evlist__for_each_entry(pevlist->evlist, pos) { if (!first) strbuf_addch(&sb, ','); if (!pos->pmu) @@ -1854,9 +1878,19 @@ static PyTypeObject pyrf_evlist__type =3D { .tp_str =3D pyrf_evlist__str, }; =20 +static PyObject *pyrf_evlist__new(PyTypeObject *type, PyObject *args, PyOb= ject *kwargs) +{ + struct pyrf_evlist *pevlist; + + pevlist =3D (struct pyrf_evlist *)PyType_GenericNew(type, args, kwargs); + if (pevlist) + pevlist->evlist =3D NULL; + return (PyObject *)pevlist; +} + static int pyrf_evlist__setup_types(void) { - pyrf_evlist__type.tp_new =3D PyType_GenericNew; + pyrf_evlist__type.tp_new =3D pyrf_evlist__new; return PyType_Ready(&pyrf_evlist__type); } =20 @@ -1959,157 +1993,74 @@ static PyObject *pyrf__tracepoint(struct pyrf_evse= l *pevsel, return PyLong_FromLong(tp_pmu__id(sys, name)); } =20 -static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel) -{ - struct pyrf_evsel *pevsel =3D PyObject_New(struct pyrf_evsel, &pyrf_evsel= __type); - - if (!pevsel) - return NULL; - - memset(&pevsel->evsel, 0, sizeof(pevsel->evsel)); - evsel__init(&pevsel->evsel, &evsel->core.attr, evsel->core.idx); - - evsel__clone(&pevsel->evsel, evsel); - if (evsel__is_group_leader(evsel)) - evsel__set_leader(&pevsel->evsel, &pevsel->evsel); - return (PyObject *)pevsel; -} - -static int evlist__pos(struct evlist *evlist, struct evsel *evsel) -{ - struct evsel *pos; - int idx =3D 0; - - evlist__for_each_entry(evlist, pos) { - if (evsel =3D=3D pos) - return idx; - idx++; - } - return -1; -} - -static struct evsel *evlist__at(struct evlist *evlist, int idx) -{ - struct evsel *pos; - int idx2 =3D 0; - - evlist__for_each_entry(evlist, pos) { - if (idx =3D=3D idx2) - return pos; - idx2++; - } - return NULL; -} - static PyObject *pyrf_evlist__from_evlist(struct evlist *evlist) { struct pyrf_evlist *pevlist =3D PyObject_New(struct pyrf_evlist, &pyrf_ev= list__type); - struct evsel *pos; - struct rb_node *node; =20 if (!pevlist) return NULL; =20 - memset(&pevlist->evlist, 0, sizeof(pevlist->evlist)); - evlist__init(&pevlist->evlist, evlist->core.all_cpus, evlist->core.thread= s); - evlist__for_each_entry(evlist, pos) { - struct pyrf_evsel *pevsel =3D (void *)pyrf_evsel__from_evsel(pos); - - evlist__add(&pevlist->evlist, &pevsel->evsel); - } - evlist__for_each_entry(&pevlist->evlist, pos) { - struct evsel *leader =3D evsel__leader(pos); - - if (pos !=3D leader) { - int idx =3D evlist__pos(evlist, leader); - - if (idx >=3D 0) - evsel__set_leader(pos, evlist__at(&pevlist->evlist, idx)); - else if (leader =3D=3D NULL) - evsel__set_leader(pos, pos); - } - - leader =3D pos->metric_leader; - - if (pos !=3D leader) { - int idx =3D evlist__pos(evlist, leader); - - if (idx >=3D 0) - pos->metric_leader =3D evlist__at(&pevlist->evlist, idx); - else if (leader =3D=3D NULL) - pos->metric_leader =3D pos; - } - } - metricgroup__copy_metric_events(&pevlist->evlist, /*cgrp=3D*/NULL, - &pevlist->evlist.metric_events, - &evlist->metric_events); - for (node =3D rb_first_cached(&pevlist->evlist.metric_events.entries); no= de; - node =3D rb_next(node)) { - struct metric_event *me =3D container_of(node, struct metric_event, nd); - struct list_head *mpos; - int idx =3D evlist__pos(evlist, me->evsel); - - if (idx >=3D 0) - me->evsel =3D evlist__at(&pevlist->evlist, idx); - list_for_each(mpos, &me->head) { - struct metric_expr *e =3D container_of(mpos, struct metric_expr, nd); - - for (int j =3D 0; e->metric_events[j]; j++) { - idx =3D evlist__pos(evlist, e->metric_events[j]); - if (idx >=3D 0) - e->metric_events[j] =3D evlist__at(&pevlist->evlist, idx); - } - } - } + pevlist->evlist =3D evlist__get(evlist); return (PyObject *)pevlist; } =20 static PyObject *pyrf__parse_events(PyObject *self, PyObject *args) { const char *input; - struct evlist evlist =3D {}; + struct evlist *evlist =3D evlist__new(); struct parse_events_error err; PyObject *result; PyObject *pcpus =3D NULL, *pthreads =3D NULL; struct perf_cpu_map *cpus; struct perf_thread_map *threads; =20 - if (!PyArg_ParseTuple(args, "s|OO", &input, &pcpus, &pthreads)) + if (!evlist) + return PyErr_NoMemory(); + + if (!PyArg_ParseTuple(args, "s|OO", &input, &pcpus, &pthreads)) { + evlist__put(evlist); return NULL; + } =20 threads =3D pthreads ? ((struct pyrf_thread_map *)pthreads)->threads : NU= LL; cpus =3D pcpus ? ((struct pyrf_cpu_map *)pcpus)->cpus : NULL; =20 parse_events_error__init(&err); - evlist__init(&evlist, cpus, threads); - if (parse_events(&evlist, input, &err)) { + perf_evlist__set_maps(&evlist->core, cpus, threads); + if (parse_events(evlist, input, &err)) { parse_events_error__print(&err, input); PyErr_SetFromErrno(PyExc_OSError); + evlist__put(evlist); return NULL; } - result =3D pyrf_evlist__from_evlist(&evlist); - evlist__exit(&evlist); + result =3D pyrf_evlist__from_evlist(evlist); + evlist__put(evlist); return result; } =20 static PyObject *pyrf__parse_metrics(PyObject *self, PyObject *args) { const char *input, *pmu =3D NULL; - struct evlist evlist =3D {}; + struct evlist *evlist =3D evlist__new(); PyObject *result; PyObject *pcpus =3D NULL, *pthreads =3D NULL; struct perf_cpu_map *cpus; struct perf_thread_map *threads; int ret; =20 - if (!PyArg_ParseTuple(args, "s|sOO", &input, &pmu, &pcpus, &pthreads)) + if (!evlist) + return PyErr_NoMemory(); + + if (!PyArg_ParseTuple(args, "s|sOO", &input, &pmu, &pcpus, &pthreads)) { + evlist__put(evlist); return NULL; + } =20 threads =3D pthreads ? ((struct pyrf_thread_map *)pthreads)->threads : NU= LL; cpus =3D pcpus ? ((struct pyrf_cpu_map *)pcpus)->cpus : NULL; =20 - evlist__init(&evlist, cpus, threads); - ret =3D metricgroup__parse_groups(&evlist, pmu ?: "all", input, + perf_evlist__set_maps(&evlist->core, cpus, threads); + ret =3D metricgroup__parse_groups(evlist, pmu ?: "all", input, /*metric_no_group=3D*/ false, /*metric_no_merge=3D*/ false, /*metric_no_threshold=3D*/ true, @@ -2117,12 +2068,13 @@ static PyObject *pyrf__parse_metrics(PyObject *self= , PyObject *args) /*system_wide=3D*/true, /*hardware_aware_grouping=3D*/ false); if (ret) { + evlist__put(evlist); errno =3D -ret; PyErr_SetFromErrno(PyExc_OSError); return NULL; } - result =3D pyrf_evlist__from_evlist(&evlist); - evlist__exit(&evlist); + result =3D pyrf_evlist__from_evlist(evlist); + evlist__put(evlist); return result; } =20 diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index e867de8ddaaa..8a5fc7d5e43c 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -264,7 +264,7 @@ bool evlist__can_select_event(struct evlist *evlist, co= nst char *str) ret =3D true; =20 out_delete: - evlist__delete(temp_evlist); + evlist__put(temp_evlist); return ret; } =20 diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 1e25892963b7..102489a11c41 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -264,7 +264,7 @@ void perf_session__delete(struct perf_session *session) machines__exit(&session->machines); if (session->data) { if (perf_data__is_read(session->data)) - evlist__delete(session->evlist); + evlist__put(session->evlist); perf_data__close(session->data); } #ifdef HAVE_LIBTRACEEVENT diff --git a/tools/perf/util/sideband_evlist.c b/tools/perf/util/sideband_e= vlist.c index 388846f17bc1..b84a5463e039 100644 --- a/tools/perf/util/sideband_evlist.c +++ b/tools/perf/util/sideband_evlist.c @@ -102,7 +102,7 @@ int evlist__start_sb_thread(struct evlist *evlist, stru= ct target *target) return 0; =20 if (evlist__create_maps(evlist, target)) - goto out_delete_evlist; + goto out_put_evlist; =20 if (evlist->core.nr_entries > 1) { bool can_sample_identifier =3D perf_can_sample_identifier(); @@ -116,25 +116,25 @@ int evlist__start_sb_thread(struct evlist *evlist, st= ruct target *target) evlist__for_each_entry(evlist, counter) { if (evsel__open(counter, evlist->core.user_requested_cpus, evlist->core.threads) < 0) - goto out_delete_evlist; + goto out_put_evlist; } =20 if (evlist__mmap(evlist, UINT_MAX)) - goto out_delete_evlist; + goto out_put_evlist; =20 evlist__for_each_entry(evlist, counter) { if (evsel__enable(counter)) - goto out_delete_evlist; + goto out_put_evlist; } =20 evlist->thread.done =3D 0; if (pthread_create(&evlist->thread.th, NULL, perf_evlist__poll_thread, ev= list)) - goto out_delete_evlist; + goto out_put_evlist; =20 return 0; =20 -out_delete_evlist: - evlist__delete(evlist); +out_put_evlist: + evlist__put(evlist); evlist =3D NULL; return -1; } @@ -145,5 +145,5 @@ void evlist__stop_sb_thread(struct evlist *evlist) return; evlist->thread.done =3D 1; pthread_join(evlist->thread.th, NULL); - evlist__delete(evlist); + evlist__put(evlist); } --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 942D93905E7 for ; Fri, 22 May 2026 22:05:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487508; cv=none; b=Hjd+lmI8b7hvPeJ7m61aWCiXsfZQIhMwMX4OkMe8+jp1ebir759xzoULz/vEFmNPi5TzA0EKJlOo3EytN5bRPhClD7/RiO69EycruoQZk4132WgoqyjdxspCM/VqVjPEsAtateN+E7brn1J4nudVqvxDWcWNRKajZleVC/jbd8c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487508; c=relaxed/simple; bh=ErWEZRkBmZkiC9dYHjiiaPW4rpn+9xx2Mq7qwIciUB4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=YAfId4xHyoH1Kf4jiIY1pRr1vWugjCA+xA6KHO3mF3d42pw1DkQ2bFijlcKM8nsH0bh2E6LjnsUWfAl22lSBgn5JbPrD4Tpa7KiQMxWF7RzYzJ6GQ05VqcznLWzxAPqb1mSN26BHwehZRmKz8xe5u8KNVabTfuCEFb9Y0yj+Res= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=cUwOkPgD; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="cUwOkPgD" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2ee1da7a13fso9377310eec.1 for ; Fri, 22 May 2026 15:05:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487503; x=1780092303; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=/ShLHqwlO8LY8U4lUh3W7Xk5JqcVHaZ60OFdWD/aPPM=; b=cUwOkPgDZYLm8VAotWAvZdgVkKEAebFYQ908eSf/hz4lYa5wuNK4RZJ/YWolZ3eTaY QLYTMaPbhBAW2lXkYgr+6ugQ3QDlihAacQz57pwougQGvubzeR381AE2kbb9R1YR1SZ3 JUXlwmwkqFdsu8/6TMfUeLiF56TxgAGW59wIfRAv54bXliX1OUfY6DWJx7YcEQePZsrm kU8tX9zqATYVNrDwbxqq9/uQ2aeBmXyHUMCR6UQaFiOGk88xRMAEY7bMaW7F3EN/bvFg 7sEQIGqWtzf0o7g3bsVHVB0arsRthO7aIw37JDROoNoKUs6xG6WS56Hb5Se42ZKGhewh MDWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487503; x=1780092303; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=/ShLHqwlO8LY8U4lUh3W7Xk5JqcVHaZ60OFdWD/aPPM=; b=pncL3hpPU761Fc6PulCyFxPQIeFrf6UzgTzF+VKQnl7GGuD/0RTc+NbAbBY4YUe0Hy IeOVLYEMJPJ+VXtjs3vGz7MnyqqKaHz2BXnD5kYr3kZ4rkImdClKLZFgclmZ4Gq8s2bZ InzKTCccfa7T7KoWMvPaYb6EyEcp9W9aptqG65cOsCjqTWfMjE3CYJ4Yh9PT4etj6oly myawJ0MurYC2PagEOGKhfnryaXqOqZcS4/Gr9W2c4m8kw4M8TFXLjanYa1u8Cb6uxh3J 2jZlqpHRmp61Ma/2laesodlpagWqi9FvtcvEZwn1+gGtbH+km75NbeMdy2Svh5Hdtlg+ 6xdw== X-Forwarded-Encrypted: i=1; AFNElJ9dO2SIaRYcke4OtUEzAjWGqaYEzeDRYHs1GgsCmv9vPOSd2mQIRMDnzB+sVrvcMydTtEsZjjaWmcasM5U=@vger.kernel.org X-Gm-Message-State: AOJu0Yy1fVMYZLK9AfOB2ngiyHUHXugJ7kb6be+eesCi03NgxRA4f4v9 zffPMTiWQDxkB01MkOGUmJcuccXt+jkm+ywWCn6E7o5nNfhIElNnriVmZg99WR+QFISqokI23TZ avL28d6ZXaA== X-Received: from dlbcf20.prod.google.com ([2002:a05:7022:4594:b0:12c:8bfc:84e3]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:117:b0:136:5511:1fd8 with SMTP id a92af1059eb24-1365fb42a76mr2106712c88.24.1779487502329; Fri, 22 May 2026 15:05:02 -0700 (PDT) Date: Fri, 22 May 2026 15:04:21 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-11-irogers@google.com> Subject: [PATCH v9 10/23] perf evsel: Add reference count From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" As with evlist this a no-op for most of the perf tool. The reference count is set to 1 at allocation, the put will see the 1, decrement it and perform the delete. The purpose for adding the reference count is for the python code. Prior to this change the python code would clone evsels, but this has issues if events are opened, etc. leading to assertion failures. With a reference count the same evsel can be used and the reference count incremented for the python usage. To not change the python evsel API getset functions are added for the evsel members, no set function is provided for size as it doesn't make sense to alter this. Signed-off-by: Ian Rogers --- v2: 1. Fixed Potential Crash in pyrf_event__new : Initialized pevent->evsel =3D NULL; to avoid garbage pointer dereference if evlist__event2evsel() fails in read_on_cpu . 2. Fixed Memory Leak in pyrf_evsel__init : Added evsel__put(pevsel->evsel) before overwriting it to handle repeated __init__ calls. 3. Fixed Exception Contract: Added PyErr_NoMemory() when evsel__new() fails in pyrf_evsel__init . 4. Fixed NULL Pointer Dereference on Property Access: Added a custom tp_getattro ( pyrf_evsel__getattro ) to pyrf_evsel__type to check if pevsel->evsel is NULL and raise a ValueError if so, covering all property accesses. 5. Fixed Reference Count in pyrf_evlist__add : Added evsel__get(evsel) when adding to the evlist . 6. Fixed Reference Count in pyrf_evlist__read_on_cpu : Added evsel__get(evsel) when assigning to pevent->evsel . v7: - Added pyrf_evsel__new to zero-initialize pevsel->evsel to fix crash on re-initialization. v8: - Added O! type validation to pyrf_evlist__add to prevent type confusion. --- tools/perf/builtin-trace.c | 12 +- tools/perf/tests/evsel-tp-sched.c | 4 +- tools/perf/tests/openat-syscall-all-cpus.c | 6 +- tools/perf/tests/openat-syscall.c | 6 +- tools/perf/util/bpf_counter_cgroup.c | 2 +- tools/perf/util/cgroup.c | 2 +- tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 26 ++- tools/perf/util/evsel.h | 11 +- tools/perf/util/parse-events.y | 2 +- tools/perf/util/pfm.c | 2 +- tools/perf/util/print-events.c | 2 +- tools/perf/util/python.c | 245 +++++++++++++++++---- tools/perf/util/session.c | 1 + 14 files changed, 249 insertions(+), 74 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 06a75b36b3f8..b6db70d62822 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -460,10 +460,10 @@ static int evsel__init_tp_ptr_field(struct evsel *evs= el, struct tp_field *field, ({ struct syscall_tp *sc =3D __evsel__syscall_tp(evsel);\ evsel__init_tp_ptr_field(evsel, &sc->name, #name); }) =20 -static void evsel__delete_priv(struct evsel *evsel) +static void evsel__put_and_free_priv(struct evsel *evsel) { zfree(&evsel->priv); - evsel__delete(evsel); + evsel__put(evsel); } =20 static int evsel__init_syscall_tp(struct evsel *evsel) @@ -543,7 +543,7 @@ static struct evsel *perf_evsel__raw_syscall_newtp(cons= t char *direction, void * return evsel; =20 out_delete: - evsel__delete_priv(evsel); + evsel__put_and_free_priv(evsel); return NULL; } =20 @@ -3616,7 +3616,7 @@ static bool evlist__add_vfs_getname(struct evlist *ev= list) =20 list_del_init(&evsel->core.node); evsel->evlist =3D NULL; - evsel__delete(evsel); + evsel__put(evsel); } =20 return found; @@ -3732,9 +3732,9 @@ static int trace__add_syscall_newtp(struct trace *tra= ce) return ret; =20 out_delete_sys_exit: - evsel__delete_priv(sys_exit); + evsel__put_and_free_priv(sys_exit); out_delete_sys_enter: - evsel__delete_priv(sys_enter); + evsel__put_and_free_priv(sys_enter); goto out; } =20 diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-= sched.c index 226196fb9677..9e456f88a13a 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c @@ -64,7 +64,7 @@ static int test__perf_evsel__tp_sched_test(struct test_su= ite *test __maybe_unuse if (evsel__test_field(evsel, "next_prio", 4, true)) ret =3D TEST_FAIL; =20 - evsel__delete(evsel); + evsel__put(evsel); =20 evsel =3D evsel__newtp("sched", "sched_wakeup"); =20 @@ -85,7 +85,7 @@ static int test__perf_evsel__tp_sched_test(struct test_su= ite *test __maybe_unuse if (evsel__test_field(evsel, "target_cpu", 4, true)) ret =3D TEST_FAIL; =20 - evsel__delete(evsel); + evsel__put(evsel); return ret; } =20 diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/= openat-syscall-all-cpus.c index 0be43f8db3bd..cc63df2b3bc5 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -59,7 +59,7 @@ static int test__openat_syscall_event_on_all_cpus(struct = test_suite *test __mayb "tweak /proc/sys/kernel/perf_event_paranoid?\n", str_error_r(errno, sbuf, sizeof(sbuf))); err =3D TEST_SKIP; - goto out_evsel_delete; + goto out_evsel_put; } =20 perf_cpu_map__for_each_cpu(cpu, idx, cpus) { @@ -116,8 +116,8 @@ static int test__openat_syscall_event_on_all_cpus(struc= t test_suite *test __mayb evsel__free_counts(evsel); out_close_fd: perf_evsel__close_fd(&evsel->core); -out_evsel_delete: - evsel__delete(evsel); +out_evsel_put: + evsel__put(evsel); out_cpu_map_delete: perf_cpu_map__put(cpus); out_thread_map_delete: diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-sy= scall.c index b54cbe5f1808..9f16f0dd3a29 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -42,7 +42,7 @@ static int test__openat_syscall_event(struct test_suite *= test __maybe_unused, "tweak /proc/sys/kernel/perf_event_paranoid?\n", str_error_r(errno, sbuf, sizeof(sbuf))); err =3D TEST_SKIP; - goto out_evsel_delete; + goto out_evsel_put; } =20 for (i =3D 0; i < nr_openat_calls; ++i) { @@ -64,8 +64,8 @@ static int test__openat_syscall_event(struct test_suite *= test __maybe_unused, err =3D TEST_OK; out_close_fd: perf_evsel__close_fd(&evsel->core); -out_evsel_delete: - evsel__delete(evsel); +out_evsel_put: + evsel__put(evsel); out_thread_map_delete: perf_thread_map__put(threads); return err; diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_cou= nter_cgroup.c index 519fee3dc3d0..339df94ef438 100644 --- a/tools/perf/util/bpf_counter_cgroup.c +++ b/tools/perf/util/bpf_counter_cgroup.c @@ -316,7 +316,7 @@ static int bperf_cgrp__destroy(struct evsel *evsel) return 0; =20 bperf_cgroup_bpf__destroy(skel); - evsel__delete(cgrp_switch); // it'll destroy on_switch progs too + evsel__put(cgrp_switch); // it'll destroy on_switch progs too =20 return 0; } diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 652a45aac828..914744724467 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -469,7 +469,7 @@ int evlist__expand_cgroup(struct evlist *evlist, const = char *str, bool open_cgro =20 /* copy the list and set to the new cgroup. */ evlist__for_each_entry(orig_list, pos) { - struct evsel *evsel =3D evsel__clone(/*dest=3D*/NULL, pos); + struct evsel *evsel =3D evsel__clone(pos); =20 if (evsel =3D=3D NULL) goto out_err; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b5a7895debf5..a362f338f104 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -194,7 +194,7 @@ static void evlist__purge(struct evlist *evlist) evlist__for_each_entry_safe(evlist, n, pos) { list_del_init(&pos->core.node); pos->evlist =3D NULL; - evsel__delete(pos); + evsel__put(pos); } =20 evlist->core.nr_entries =3D 0; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 91c3dfa234e6..3687a39a85b7 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -388,10 +388,11 @@ bool evsel__is_function_event(struct evsel *evsel) #undef FUNCTION_EVENT } =20 -void evsel__init(struct evsel *evsel, +static void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx) { perf_evsel__init(&evsel->core, attr, idx); + refcount_set(&evsel->refcnt, 1); evsel->tracking =3D !idx; evsel->unit =3D strdup(""); evsel->scale =3D 1.0; @@ -472,7 +473,7 @@ static int evsel__copy_config_terms(struct evsel *dst, = struct evsel *src) * The assumption is that @orig is not configured nor opened yet. * So we only care about the attributes that can be set while it's parsed. */ -struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig) +struct evsel *evsel__clone(struct evsel *orig) { struct evsel *evsel; =20 @@ -485,11 +486,7 @@ struct evsel *evsel__clone(struct evsel *dest, struct = evsel *orig) if (orig->bpf_obj) return NULL; =20 - if (dest) - evsel =3D dest; - else - evsel =3D evsel__new(&orig->core.attr); - + evsel =3D evsel__new(&orig->core.attr); if (evsel =3D=3D NULL) return NULL; =20 @@ -574,7 +571,7 @@ struct evsel *evsel__clone(struct evsel *dest, struct e= vsel *orig) return evsel; =20 out_err: - evsel__delete(evsel); + evsel__put(evsel); return NULL; } =20 @@ -633,6 +630,12 @@ struct evsel *evsel__newtp_idx(const char *sys, const = char *name, int idx, bool return ERR_PTR(err); } =20 +struct evsel *evsel__get(struct evsel *evsel) +{ + refcount_inc(&evsel->refcnt); + return evsel; +} + #ifdef HAVE_LIBTRACEEVENT struct tep_event *evsel__tp_format(struct evsel *evsel) { @@ -1857,7 +1860,7 @@ void evsel__set_priv_destructor(void (*destructor)(vo= id *priv)) evsel__priv_destructor =3D destructor; } =20 -void evsel__exit(struct evsel *evsel) +static void evsel__exit(struct evsel *evsel) { assert(list_empty(&evsel->core.node)); assert(evsel->evlist =3D=3D NULL); @@ -1892,11 +1895,14 @@ void evsel__exit(struct evsel *evsel) xyarray__delete(evsel->start_times); } =20 -void evsel__delete(struct evsel *evsel) +void evsel__put(struct evsel *evsel) { if (!evsel) return; =20 + if (!refcount_dec_and_test(&evsel->refcnt)) + return; + evsel__exit(evsel); free(evsel); } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 2221694bb819..4ce86eb330d7 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -6,6 +6,7 @@ =20 #include #include +#include #include #include =20 @@ -47,6 +48,7 @@ typedef int (evsel__sb_cb_t)(union perf_event *event, voi= d *data); struct evsel { struct perf_evsel core; struct evlist *evlist; + refcount_t refcnt; off_t id_offset; int id_pos; int is_pos; @@ -262,7 +264,7 @@ static inline struct evsel *evsel__new(struct perf_even= t_attr *attr) return evsel__new_idx(attr, 0); } =20 -struct evsel *evsel__clone(struct evsel *dest, struct evsel *orig); +struct evsel *evsel__clone(struct evsel *orig); =20 int copy_config_terms(struct list_head *dst, struct list_head *src); void free_config_terms(struct list_head *config_terms); @@ -277,14 +279,13 @@ static inline struct evsel *evsel__newtp(const char *= sys, const char *name) return evsel__newtp_idx(sys, name, 0, true); } =20 +struct evsel *evsel__get(struct evsel *evsel); +void evsel__put(struct evsel *evsel); + #ifdef HAVE_LIBTRACEEVENT struct tep_event *evsel__tp_format(struct evsel *evsel); #endif =20 -void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int id= x); -void evsel__exit(struct evsel *evsel); -void evsel__delete(struct evsel *evsel); - void evsel__set_priv_destructor(void (*destructor)(void *priv)); =20 struct callchain_param; diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index c194de5ec1ec..b531b1f0ceb3 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -47,7 +47,7 @@ static void free_list_evsel(struct list_head* list_evsel) =20 list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) { list_del_init(&evsel->core.node); - evsel__delete(evsel); + evsel__put(evsel); } free(list_evsel); } diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c index d9043f4afbe7..5f53c2f68a96 100644 --- a/tools/perf/util/pfm.c +++ b/tools/perf/util/pfm.c @@ -159,7 +159,7 @@ static bool is_libpfm_event_supported(const char *name,= struct perf_cpu_map *cpu result =3D false; =20 evsel__close(evsel); - evsel__delete(evsel); + evsel__put(evsel); =20 return result; } diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index cb27e2898aa0..0242243681b6 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -174,7 +174,7 @@ bool is_event_supported(u8 type, u64 config) } =20 evsel__close(evsel); - evsel__delete(evsel); + evsel__put(evsel); } =20 perf_thread_map__put(tmap); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index de2c5f26c143..2a75b06f6f04 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -276,6 +276,7 @@ static PyMemberDef pyrf_sample_event__members[] =3D { =20 static void pyrf_sample_event__delete(struct pyrf_event *pevent) { + evsel__put(pevent->evsel); perf_sample__exit(&pevent->sample); Py_TYPE(pevent)->tp_free((PyObject*)pevent); } @@ -508,8 +509,10 @@ static PyObject *pyrf_event__new(const union perf_even= t *event) =20 ptype =3D pyrf_event__type[event->header.type]; pevent =3D PyObject_New(struct pyrf_event, ptype); - if (pevent !=3D NULL) + if (pevent !=3D NULL) { memcpy(&pevent->event, event, event->header.size); + pevent->evsel =3D NULL; + } return (PyObject *)pevent; } =20 @@ -947,7 +950,7 @@ static int pyrf_counts_values__setup_types(void) struct pyrf_evsel { PyObject_HEAD =20 - struct evsel evsel; + struct evsel *evsel; }; =20 static int pyrf_evsel__init(struct pyrf_evsel *pevsel, @@ -1055,20 +1058,25 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevs= el, attr.sample_id_all =3D sample_id_all; attr.size =3D sizeof(attr); =20 - evsel__init(&pevsel->evsel, &attr, idx); + evsel__put(pevsel->evsel); + pevsel->evsel =3D evsel__new(&attr); + if (!pevsel->evsel) { + PyErr_NoMemory(); + return -1; + } return 0; } =20 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel) { - evsel__exit(&pevsel->evsel); + evsel__put(pevsel->evsel); Py_TYPE(pevsel)->tp_free((PyObject*)pevsel); } =20 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs) { - struct evsel *evsel =3D &pevsel->evsel; + struct evsel *evsel =3D pevsel->evsel; struct perf_cpu_map *cpus =3D NULL; struct perf_thread_map *threads =3D NULL; PyObject *pcpus =3D NULL, *pthreads =3D NULL; @@ -1104,7 +1112,7 @@ static PyObject *pyrf_evsel__cpus(struct pyrf_evsel *= pevsel) struct pyrf_cpu_map *pcpu_map =3D PyObject_New(struct pyrf_cpu_map, &pyrf= _cpu_map__type); =20 if (pcpu_map) - pcpu_map->cpus =3D perf_cpu_map__get(pevsel->evsel.core.cpus); + pcpu_map->cpus =3D perf_cpu_map__get(pevsel->evsel->core.cpus); =20 return (PyObject *)pcpu_map; } @@ -1115,7 +1123,7 @@ static PyObject *pyrf_evsel__threads(struct pyrf_evse= l *pevsel) PyObject_New(struct pyrf_thread_map, &pyrf_thread_map__type); =20 if (pthread_map) - pthread_map->threads =3D perf_thread_map__get(pevsel->evsel.core.threads= ); + pthread_map->threads =3D perf_thread_map__get(pevsel->evsel->core.thread= s); =20 return (PyObject *)pthread_map; } @@ -1149,7 +1157,7 @@ static int evsel__ensure_counts(struct evsel *evsel) static PyObject *pyrf_evsel__read(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs) { - struct evsel *evsel =3D &pevsel->evsel; + struct evsel *evsel =3D pevsel->evsel; int cpu =3D 0, cpu_idx, thread =3D 0, thread_idx; struct perf_counts_values *old_count, *new_count; struct pyrf_counts_values *count_values =3D PyObject_New(struct pyrf_coun= ts_values, @@ -1194,7 +1202,7 @@ static PyObject *pyrf_evsel__read(struct pyrf_evsel *= pevsel, static PyObject *pyrf_evsel__str(PyObject *self) { struct pyrf_evsel *pevsel =3D (void *)self; - struct evsel *evsel =3D &pevsel->evsel; + struct evsel *evsel =3D pevsel->evsel; =20 return PyUnicode_FromFormat("evsel(%s/%s/)", evsel__pmu_name(evsel), evse= l__name(evsel)); } @@ -1227,30 +1235,183 @@ static PyMethodDef pyrf_evsel__methods[] =3D { { .ml_name =3D NULL, } }; =20 -#define evsel_member_def(member, ptype, help) \ - { #member, ptype, \ - offsetof(struct pyrf_evsel, evsel.member), \ - 0, help } +static PyObject *pyrf_evsel__get_tracking(PyObject *self, void */*closure*= /) +{ + struct pyrf_evsel *pevsel =3D (void *)self; =20 -#define evsel_attr_member_def(member, ptype, help) \ - { #member, ptype, \ - offsetof(struct pyrf_evsel, evsel.core.attr.member), \ - 0, help } + if (pevsel->evsel->tracking) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} =20 -static PyMemberDef pyrf_evsel__members[] =3D { - evsel_member_def(tracking, T_BOOL, "tracking event."), - evsel_attr_member_def(type, T_UINT, "attribute type."), - evsel_attr_member_def(size, T_UINT, "attribute size."), - evsel_attr_member_def(config, T_ULONGLONG, "attribute config."), - evsel_attr_member_def(sample_period, T_ULONGLONG, "attribute sample_perio= d."), - evsel_attr_member_def(sample_type, T_ULONGLONG, "attribute sample_type."), - evsel_attr_member_def(read_format, T_ULONGLONG, "attribute read_format."), - evsel_attr_member_def(wakeup_events, T_UINT, "attribute wakeup_events."), - { .name =3D NULL, }, +static int pyrf_evsel__set_tracking(PyObject *self, PyObject *val, void */= *closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + pevsel->evsel->tracking =3D Py_IsTrue(val) ? true : false; + return 0; +} + +static int pyrf_evsel__set_attr_config(PyObject *self, PyObject *val, void= */*closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + pevsel->evsel->core.attr.config =3D PyLong_AsUnsignedLongLong(val); + return PyErr_Occurred() ? -1 : 0; +} + +static PyObject *pyrf_evsel__get_attr_config(PyObject *self, void */*closu= re*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.config); +} + +static int pyrf_evsel__set_attr_read_format(PyObject *self, PyObject *val,= void */*closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + pevsel->evsel->core.attr.read_format =3D PyLong_AsUnsignedLongLong(val); + return PyErr_Occurred() ? -1 : 0; +} + +static PyObject *pyrf_evsel__get_attr_read_format(PyObject *self, void */*= closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.read_format); +} + +static int pyrf_evsel__set_attr_sample_period(PyObject *self, PyObject *va= l, void */*closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + pevsel->evsel->core.attr.sample_period =3D PyLong_AsUnsignedLongLong(val); + return PyErr_Occurred() ? -1 : 0; +} + +static PyObject *pyrf_evsel__get_attr_sample_period(PyObject *self, void *= /*closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.sample_period= ); +} + +static int pyrf_evsel__set_attr_sample_type(PyObject *self, PyObject *val,= void */*closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + pevsel->evsel->core.attr.sample_type =3D PyLong_AsUnsignedLongLong(val); + return PyErr_Occurred() ? -1 : 0; +} + +static PyObject *pyrf_evsel__get_attr_sample_type(PyObject *self, void */*= closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.sample_type); +} + +static PyObject *pyrf_evsel__get_attr_size(PyObject *self, void */*closure= */) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.size); +} + +static int pyrf_evsel__set_attr_type(PyObject *self, PyObject *val, void *= /*closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + pevsel->evsel->core.attr.type =3D PyLong_AsUnsignedLong(val); + return PyErr_Occurred() ? -1 : 0; +} + +static PyObject *pyrf_evsel__get_attr_type(PyObject *self, void */*closure= */) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.type); +} + +static int pyrf_evsel__set_attr_wakeup_events(PyObject *self, PyObject *va= l, void */*closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + pevsel->evsel->core.attr.wakeup_events =3D PyLong_AsUnsignedLong(val); + return PyErr_Occurred() ? -1 : 0; +} + +static PyObject *pyrf_evsel__get_attr_wakeup_events(PyObject *self, void *= /*closure*/) +{ + struct pyrf_evsel *pevsel =3D (void *)self; + + return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.wakeup_events); +} + +static PyGetSetDef pyrf_evsel__getset[] =3D { + { + .name =3D "tracking", + .get =3D pyrf_evsel__get_tracking, + .set =3D pyrf_evsel__set_tracking, + .doc =3D "tracking event.", + }, + { + .name =3D "config", + .get =3D pyrf_evsel__get_attr_config, + .set =3D pyrf_evsel__set_attr_config, + .doc =3D "attribute config.", + }, + { + .name =3D "read_format", + .get =3D pyrf_evsel__get_attr_read_format, + .set =3D pyrf_evsel__set_attr_read_format, + .doc =3D "attribute read_format.", + }, + { + .name =3D "sample_period", + .get =3D pyrf_evsel__get_attr_sample_period, + .set =3D pyrf_evsel__set_attr_sample_period, + .doc =3D "attribute sample_period.", + }, + { + .name =3D "sample_type", + .get =3D pyrf_evsel__get_attr_sample_type, + .set =3D pyrf_evsel__set_attr_sample_type, + .doc =3D "attribute sample_type.", + }, + { + .name =3D "size", + .get =3D pyrf_evsel__get_attr_size, + .doc =3D "attribute size.", + }, + { + .name =3D "type", + .get =3D pyrf_evsel__get_attr_type, + .set =3D pyrf_evsel__set_attr_type, + .doc =3D "attribute type.", + }, + { + .name =3D "wakeup_events", + .get =3D pyrf_evsel__get_attr_wakeup_events, + .set =3D pyrf_evsel__set_attr_wakeup_events, + .doc =3D "attribute wakeup_events.", + }, + { .name =3D NULL}, }; =20 static const char pyrf_evsel__doc[] =3D PyDoc_STR("perf event selector lis= t object."); =20 +static PyObject *pyrf_evsel__getattro(struct pyrf_evsel *pevsel, PyObject = *attr_name) +{ + if (!pevsel->evsel) { + PyErr_SetString(PyExc_ValueError, "evsel not initialized"); + return NULL; + } + return PyObject_GenericGetAttr((PyObject *) pevsel, attr_name); +} + static PyTypeObject pyrf_evsel__type =3D { PyVarObject_HEAD_INIT(NULL, 0) .tp_name =3D "perf.evsel", @@ -1258,16 +1419,27 @@ static PyTypeObject pyrf_evsel__type =3D { .tp_dealloc =3D (destructor)pyrf_evsel__delete, .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc =3D pyrf_evsel__doc, - .tp_members =3D pyrf_evsel__members, + .tp_getset =3D pyrf_evsel__getset, .tp_methods =3D pyrf_evsel__methods, .tp_init =3D (initproc)pyrf_evsel__init, .tp_str =3D pyrf_evsel__str, .tp_repr =3D pyrf_evsel__str, + .tp_getattro =3D (getattrofunc) pyrf_evsel__getattro, }; =20 +static PyObject *pyrf_evsel__new(PyTypeObject *type, PyObject *args, PyObj= ect *kwargs) +{ + struct pyrf_evsel *pevsel; + + pevsel =3D (struct pyrf_evsel *)PyType_GenericNew(type, args, kwargs); + if (pevsel) + pevsel->evsel =3D NULL; + return (PyObject *)pevsel; +} + static int pyrf_evsel__setup_types(void) { - pyrf_evsel__type.tp_new =3D PyType_GenericNew; + pyrf_evsel__type.tp_new =3D pyrf_evsel__new; return PyType_Ready(&pyrf_evsel__type); } =20 @@ -1566,13 +1738,13 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlis= t *pevlist, PyObject *pevsel; struct evsel *evsel; =20 - if (!PyArg_ParseTuple(args, "O", &pevsel)) + if (!PyArg_ParseTuple(args, "O!", &pyrf_evsel__type, &pevsel)) return NULL; =20 Py_INCREF(pevsel); - evsel =3D &((struct pyrf_evsel *)pevsel)->evsel; + evsel =3D ((struct pyrf_evsel *)pevsel)->evsel; evsel->core.idx =3D evlist->core.nr_entries; - evlist__add(evlist, evsel); + evlist__add(evlist, evsel__get(evsel)); =20 return Py_BuildValue("i", evlist->core.nr_entries); } @@ -1630,7 +1802,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf= _evlist *pevlist, return Py_None; } =20 - pevent->evsel =3D evsel; + pevent->evsel =3D evsel__get(evsel); =20 perf_mmap__consume(&md->core); =20 @@ -1807,12 +1979,7 @@ static PyObject *pyrf_evsel__from_evsel(struct evsel= *evsel) if (!pevsel) return NULL; =20 - memset(&pevsel->evsel, 0, sizeof(pevsel->evsel)); - evsel__init(&pevsel->evsel, &evsel->core.attr, evsel->core.idx); - - evsel__clone(&pevsel->evsel, evsel); - if (evsel__is_group_leader(evsel)) - evsel__set_leader(&pevsel->evsel, &pevsel->evsel); + pevsel->evsel =3D evsel__get(evsel); return (PyObject *)pevsel; } =20 diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 102489a11c41..43fef473bbb4 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1375,6 +1375,7 @@ static int evlist__deliver_deferred_callchain(struct = evlist *evlist, =20 sample->evsel =3D evlist__id2evsel(evlist, sample->id); ret =3D tool->callchain_deferred(tool, event, sample, machine); + evsel__put(sample->evsel); sample->evsel =3D saved_evsel; return ret; } --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D3D9E39060F for ; Fri, 22 May 2026 22:05:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487516; cv=none; b=tqACmznuHkq+gvDc2QPgxo/DD+DI7isVwaXTabCgpadeIXuQsInAom+nunVjFaRdCfNPSrF4wwpnE4xzCpFp84rtzRi3tMV/9iy8f7SPlqCZg2oW8/gS7lXFP/ZW17wwa1G60m+pF4a8WtqHl3maDz/zqLA2UiwXlw6f7Ai7iQc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487516; c=relaxed/simple; bh=9OjnXdlXrstBVxgTzsuVE1ypN8Flf9B9b+p0yw/YRtI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=plkgIHVw7apstJYprOQlhMqPvHP/AJibrGaZPPk3IXM38zbPJStScHi16tkfTnxRvSfPpg5g3jlXazgVUhaUlokx/SWfcui9cqOK6CIeSQjsr0DyID6wO+dtRxd2W55s3D0aPRzJyD+ZxB63pfczygjkuAS5UxsJiSwdBF00fxA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=HYWkc9LN; arc=none smtp.client-ip=74.125.82.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="HYWkc9LN" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-135de949041so6510277c88.0 for ; Fri, 22 May 2026 15:05:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487505; x=1780092305; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=8x9tLzMpGTImJktTuk1QkDiX38mhaHWgUnfZNo9rK/0=; b=HYWkc9LNEjcOhBU0GHxz/CHaW1Jmw5HhgifZ4puzCYv3RVQ2u/qMv4eMoYQ6bf9y1L oSo0Ps3RwW3XIUALhj6Qs9qk8cFsciyy50orNmADDz7FkUp00RYpZO0G8IKh7N87BZMG yrZG/6VraJSFxEIBO50ZnvUvuF8clePZCXT5lJLDb8DD/jIDJjONVuiLNDuGfdgIrCXr JkTd4XB2MQInUpvyrK8o1Uda9AV6QAFDtjiX329cA4PtDISLtVNGXzBp6GJKRGCOmfWc dacoRddPnabFJc5otJpffyZPDmBFHEgmTkdT+EAeHwOPhDd4v4YFOm1mqoW7RTi2xZBH cdeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487505; x=1780092305; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=8x9tLzMpGTImJktTuk1QkDiX38mhaHWgUnfZNo9rK/0=; b=MaXnagizOImDF9iZPohZOsimcGvJ21W/beNGhWaqxO7c3ns3bnZHSJWAIktLmwa948 96G/FyTj1wG5BUj9rBaDaFvBCump4AjeqYJm/LILUWTGLF4REdT8MWfNyy8aBjWn2Xe/ Rmp7SyWCFVqVOpvCVJ4U0IOTXSu+byKIO2Ycfh66GM0Z1mBS8LUGdalq3VMqusJlRJb2 XdDMTnJRynuiNnyv+XenMZ2ts4BIcg6kDPnralNlcoc9rA+MYhJornmDqY1OLI6JEZoe 711L3G54ukPRsxYAYnLh8LnEl73GJbKABYM9WbYeiVhccNNt1dVq6GM2UsB7KPqhZh0D qU8g== X-Forwarded-Encrypted: i=1; AFNElJ8hNoIydl1gjcF72Wqc+loRd51X48Jg9YnMq5jLEUkcXqojc5DRtlzi/pXG0T7mU4NI1I6eqhK+pv5NiFo=@vger.kernel.org X-Gm-Message-State: AOJu0Yxg1N3vIGzqy2rglSrFJmFRBCOWVIdjDw7Mn02mETSvrwN7fBFa Xb3xcGEj7vCNBb+05E7P3bVUKiX3ieD92Cd5pnoabKVqhMsNVgsYhzBsv8DvhDg35M1sGp/6SBq T3fXLAXVqdw== X-Received: from dlai16.prod.google.com ([2002:a05:701b:2710:b0:12f:1fa4:1a93]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7023:b16:b0:135:dbd4:2eae with SMTP id a92af1059eb24-1365f8149fcmr1752972c88.18.1779487504345; Fri, 22 May 2026 15:05:04 -0700 (PDT) Date: Fri, 22 May 2026 15:04:22 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-12-irogers@google.com> Subject: [PATCH v9 11/23] perf evlist: Add reference count checking From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now the evlist is reference counted, add reference count checking so that gets and puts are paired and easy to debug. Reference count checking is documented here: https://perfwiki.github.io/main/reference-count-checking/ This large patch is adding accessors to evlist functions and switching to their use. There was some minor renaming as evlist__mmap is now an accessor to the mmap variable, and the original evlist__mmap is renamed to evlist__do_mmap. Signed-off-by: Ian Rogers --- v2: 1. Fixed Memory Leak in evlist__new : Added free(evlist) in the else branch if ADD_RC_CHK fails, preventing a leak of the allocated raw structure. 2. Fixed Potential NULL Dereference: Added a NULL check after from_list_start(_evlist) in perf_evlist__mmap_cb_get() . 3. Fixed Use-After-Free Risk: In evlist__add() , I changed entry->evlist =3D evlist; to entry->evlist =3D evlist__get(evlist); . This ensures that the evsel holds a valid reference (wrapper) to the evlist , preventing it from becoming a dangling pointer if the original wrapper is freed. 4. Fixed Test Masking Bug: In test__perf_time__parse_for_ranges() , I replaced TEST_ASSERT_VAL with a manual check and return false; to avoid boolean evaluation of -1 inadvertently passing the test. 5. Fix reference count checker memory leaks from missed puts and due to cyclic evsel to evlist references. A leak still exists in __perf_evlist__propagate_maps due to empty CPU maps and not deleting the removed evsel. v8: 1. Handle evsel__new failure in sample-parsing.c test and extra ref count checking integrity in evlist.c 2. Use standard per_sample initialization in cs-etm.c. --- tools/perf/arch/arm/util/cs-etm.c | 10 +- tools/perf/arch/arm64/util/arm-spe.c | 8 +- tools/perf/arch/arm64/util/hisi-ptt.c | 2 +- tools/perf/arch/x86/tests/hybrid.c | 20 +- tools/perf/arch/x86/util/auxtrace.c | 2 +- tools/perf/arch/x86/util/intel-bts.c | 6 +- tools/perf/arch/x86/util/intel-pt.c | 9 +- tools/perf/arch/x86/util/iostat.c | 6 +- tools/perf/bench/evlist-open-close.c | 11 +- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-ftrace.c | 6 +- tools/perf/builtin-inject.c | 4 +- tools/perf/builtin-kvm.c | 10 +- tools/perf/builtin-kwork.c | 8 +- tools/perf/builtin-record.c | 91 ++--- tools/perf/builtin-report.c | 6 +- tools/perf/builtin-sched.c | 20 +- tools/perf/builtin-script.c | 13 +- tools/perf/builtin-stat.c | 71 ++-- tools/perf/builtin-top.c | 52 +-- tools/perf/builtin-trace.c | 22 +- tools/perf/tests/backward-ring-buffer.c | 8 +- tools/perf/tests/code-reading.c | 10 +- tools/perf/tests/event-times.c | 2 +- tools/perf/tests/event_update.c | 2 +- tools/perf/tests/expand-cgroup.c | 4 +- tools/perf/tests/hwmon_pmu.c | 5 +- tools/perf/tests/keep-tracking.c | 8 +- tools/perf/tests/mmap-basic.c | 6 +- tools/perf/tests/openat-syscall-tp-fields.c | 8 +- tools/perf/tests/parse-events.c | 135 +++---- tools/perf/tests/parse-metric.c | 4 +- tools/perf/tests/perf-record.c | 20 +- tools/perf/tests/perf-time-to-tsc.c | 10 +- tools/perf/tests/pfm.c | 8 +- tools/perf/tests/pmu-events.c | 5 +- tools/perf/tests/sample-parsing.c | 42 ++- tools/perf/tests/sw-clock.c | 6 +- tools/perf/tests/switch-tracking.c | 8 +- tools/perf/tests/task-exit.c | 6 +- tools/perf/tests/time-utils-test.c | 14 +- tools/perf/tests/tool_pmu.c | 5 +- tools/perf/tests/topology.c | 2 +- tools/perf/ui/browsers/annotate.c | 2 +- tools/perf/ui/browsers/hists.c | 22 +- tools/perf/util/amd-sample-raw.c | 2 +- tools/perf/util/annotate-data.c | 2 +- tools/perf/util/annotate.c | 10 +- tools/perf/util/auxtrace.c | 14 +- tools/perf/util/block-info.c | 4 +- tools/perf/util/bpf_counter.c | 2 +- tools/perf/util/bpf_counter_cgroup.c | 8 +- tools/perf/util/bpf_ftrace.c | 9 +- tools/perf/util/bpf_lock_contention.c | 12 +- tools/perf/util/bpf_off_cpu.c | 14 +- tools/perf/util/cgroup.c | 20 +- tools/perf/util/cs-etm.c | 5 +- tools/perf/util/evlist.c | 391 ++++++++++++-------- tools/perf/util/evlist.h | 251 ++++++++++++- tools/perf/util/evsel.c | 6 +- tools/perf/util/evsel.h | 4 +- tools/perf/util/header.c | 39 +- tools/perf/util/header.h | 2 +- tools/perf/util/intel-tpebs.c | 7 +- tools/perf/util/metricgroup.c | 6 +- tools/perf/util/parse-events.c | 6 +- tools/perf/util/pfm.c | 2 +- tools/perf/util/python.c | 30 +- tools/perf/util/record.c | 9 +- tools/perf/util/sample-raw.c | 4 +- tools/perf/util/session.c | 54 +-- tools/perf/util/sideband_evlist.c | 24 +- tools/perf/util/sort.c | 2 +- tools/perf/util/stat-display.c | 6 +- tools/perf/util/stat-shadow.c | 4 +- tools/perf/util/stat.c | 4 +- tools/perf/util/stream.c | 4 +- tools/perf/util/synthetic-events.c | 11 +- tools/perf/util/time-utils.c | 12 +- tools/perf/util/top.c | 4 +- 80 files changed, 1015 insertions(+), 690 deletions(-) diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/c= s-etm.c index cdf8e3e60606..d2861d66a661 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -201,7 +201,7 @@ static int cs_etm_validate_config(struct perf_pmu *cs_e= tm_pmu, { unsigned int idx; int err =3D 0; - struct perf_cpu_map *event_cpus =3D evsel->evlist->core.user_requested_cp= us; + struct perf_cpu_map *event_cpus =3D evlist__core(evsel->evlist)->user_req= uested_cpus; struct perf_cpu_map *intersect_cpus; struct perf_cpu cpu; =20 @@ -325,7 +325,7 @@ static int cs_etm_recording_options(struct auxtrace_rec= ord *itr, container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu =3D ptr->cs_etm_pmu; struct evsel *evsel, *cs_etm_evsel =3D NULL; - struct perf_cpu_map *cpus =3D evlist->core.user_requested_cpus; + struct perf_cpu_map *cpus =3D evlist__core(evlist)->user_requested_cpus; bool privileged =3D perf_event_paranoid_check(-1); int err =3D 0; =20 @@ -551,7 +551,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr, { unsigned int idx; int etmv3 =3D 0, etmv4 =3D 0, ete =3D 0; - struct perf_cpu_map *event_cpus =3D evlist->core.user_requested_cpus; + struct perf_cpu_map *event_cpus =3D evlist__core(evlist)->user_requested_= cpus; struct perf_cpu_map *intersect_cpus; struct perf_cpu cpu; struct perf_pmu *cs_etm_pmu =3D cs_etm_get_pmu(itr); @@ -790,7 +790,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, u32 offset; u64 nr_cpu, type; struct perf_cpu_map *cpu_map; - struct perf_cpu_map *event_cpus =3D session->evlist->core.user_requested_= cpus; + struct perf_cpu_map *event_cpus =3D evlist__core(session->evlist)->user_r= equested_cpus; struct perf_cpu_map *online_cpus =3D perf_cpu_map__new_online_cpus(); struct cs_etm_recording *ptr =3D container_of(itr, struct cs_etm_recording, itr); @@ -800,7 +800,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, if (priv_size !=3D cs_etm_info_priv_size(itr, session->evlist)) return -EINVAL; =20 - if (!session->evlist->core.nr_mmaps) + if (!evlist__core(session->evlist)->nr_mmaps) return -EINVAL; =20 /* If the cpu_map has the "any" CPU all online CPUs are involved */ diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/u= til/arm-spe.c index f00d72d087fc..abbc67109fc0 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -60,7 +60,7 @@ static bool arm_spe_is_set_freq(struct evsel *evsel) */ static struct perf_cpu_map *arm_spe_find_cpus(struct evlist *evlist) { - struct perf_cpu_map *event_cpus =3D evlist->core.user_requested_cpus; + struct perf_cpu_map *event_cpus =3D evlist__core(evlist)->user_requested_= cpus; struct perf_cpu_map *online_cpus =3D perf_cpu_map__new_online_cpus(); struct perf_cpu_map *intersect_cpus; =20 @@ -157,7 +157,7 @@ static int arm_spe_info_fill(struct auxtrace_record *it= r, if (priv_size !=3D arm_spe_info_priv_size(itr, session->evlist)) return -EINVAL; =20 - if (!session->evlist->core.nr_mmaps) + if (!evlist__core(session->evlist)->nr_mmaps) return -EINVAL; =20 cpu_map =3D arm_spe_find_cpus(session->evlist); @@ -363,7 +363,7 @@ static int arm_spe_setup_tracking_event(struct evlist *= evlist, { int err; struct evsel *tracking_evsel; - struct perf_cpu_map *cpus =3D evlist->core.user_requested_cpus; + struct perf_cpu_map *cpus =3D evlist__core(evlist)->user_requested_cpus; =20 /* Add dummy event to keep tracking */ err =3D parse_event(evlist, "dummy:u"); @@ -396,7 +396,7 @@ static int arm_spe_recording_options(struct auxtrace_re= cord *itr, struct arm_spe_recording *sper =3D container_of(itr, struct arm_spe_recording, itr); struct evsel *evsel, *tmp; - struct perf_cpu_map *cpus =3D evlist->core.user_requested_cpus; + struct perf_cpu_map *cpus =3D evlist__core(evlist)->user_requested_cpus; bool discard =3D false; int err; u64 discard_bit; diff --git a/tools/perf/arch/arm64/util/hisi-ptt.c b/tools/perf/arch/arm64/= util/hisi-ptt.c index fe457fd58c9e..52257715d2b7 100644 --- a/tools/perf/arch/arm64/util/hisi-ptt.c +++ b/tools/perf/arch/arm64/util/hisi-ptt.c @@ -53,7 +53,7 @@ static int hisi_ptt_info_fill(struct auxtrace_record *itr, if (priv_size !=3D HISI_PTT_AUXTRACE_PRIV_SIZE) return -EINVAL; =20 - if (!session->evlist->core.nr_mmaps) + if (!evlist__core(session->evlist)->nr_mmaps) return -EINVAL; =20 auxtrace_info->type =3D PERF_AUXTRACE_HISI_PTT; diff --git a/tools/perf/arch/x86/tests/hybrid.c b/tools/perf/arch/x86/tests= /hybrid.c index dfb0ffc0d030..0477e17b8e53 100644 --- a/tools/perf/arch/x86/tests/hybrid.c +++ b/tools/perf/arch/x86/tests/hybrid.c @@ -26,7 +26,7 @@ static int test__hybrid_hw_event_with_pmu(struct evlist *= evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_VAL("wrong number of entries", 1 =3D=3D evlist->core.nr_entri= es); + TEST_ASSERT_VAL("wrong number of entries", 1 =3D=3D evlist__nr_entries(ev= list)); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE =3D=3D evsel->core.attr.= type); TEST_ASSERT_VAL("wrong hybrid type", test_hybrid_type(evsel, PERF_TYPE_RA= W)); TEST_ASSERT_VAL("wrong config", test_config(evsel, PERF_COUNT_HW_CPU_CYCL= ES)); @@ -38,7 +38,7 @@ static int test__hybrid_hw_group_event(struct evlist *evl= ist) struct evsel *evsel, *leader; =20 evsel =3D leader =3D evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist->core.nr_entri= es); + TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist__nr_entries(ev= list)); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE =3D=3D evsel->core.attr.= type); TEST_ASSERT_VAL("wrong hybrid type", test_hybrid_type(evsel, PERF_TYPE_RA= W)); TEST_ASSERT_VAL("wrong config", test_config(evsel, PERF_COUNT_HW_CPU_CYCL= ES)); @@ -57,7 +57,7 @@ static int test__hybrid_sw_hw_group_event(struct evlist *= evlist) struct evsel *evsel, *leader; =20 evsel =3D leader =3D evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist->core.nr_entri= es); + TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist__nr_entries(ev= list)); TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE =3D=3D evsel->core.attr.= type); TEST_ASSERT_VAL("wrong leader", evsel__has_leader(evsel, leader)); =20 @@ -74,7 +74,7 @@ static int test__hybrid_hw_sw_group_event(struct evlist *= evlist) struct evsel *evsel, *leader; =20 evsel =3D leader =3D evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist->core.nr_entri= es); + TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist__nr_entries(ev= list)); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE =3D=3D evsel->core.attr.= type); TEST_ASSERT_VAL("wrong hybrid type", test_hybrid_type(evsel, PERF_TYPE_RA= W)); TEST_ASSERT_VAL("wrong config", test_config(evsel, PERF_COUNT_HW_CPU_CYCL= ES)); @@ -91,7 +91,7 @@ static int test__hybrid_group_modifier1(struct evlist *ev= list) struct evsel *evsel, *leader; =20 evsel =3D leader =3D evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist->core.nr_entri= es); + TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist__nr_entries(ev= list)); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE =3D=3D evsel->core.attr.= type); TEST_ASSERT_VAL("wrong hybrid type", test_hybrid_type(evsel, PERF_TYPE_RA= W)); TEST_ASSERT_VAL("wrong config", test_config(evsel, PERF_COUNT_HW_CPU_CYCL= ES)); @@ -113,7 +113,7 @@ static int test__hybrid_raw1(struct evlist *evlist) { struct perf_evsel *evsel; =20 - perf_evlist__for_each_evsel(&evlist->core, evsel) { + perf_evlist__for_each_evsel(evlist__core(evlist), evsel) { struct perf_pmu *pmu =3D perf_pmus__find_by_type(evsel->attr.type); =20 TEST_ASSERT_VAL("missing pmu", pmu); @@ -127,7 +127,7 @@ static int test__hybrid_raw2(struct evlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_VAL("wrong number of entries", 1 =3D=3D evlist->core.nr_entri= es); + TEST_ASSERT_VAL("wrong number of entries", 1 =3D=3D evlist__nr_entries(ev= list)); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW =3D=3D evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", test_config(evsel, 0x1a)); return TEST_OK; @@ -137,7 +137,7 @@ static int test__hybrid_cache_event(struct evlist *evli= st) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_VAL("wrong number of entries", 1 =3D=3D evlist->core.nr_entri= es); + TEST_ASSERT_VAL("wrong number of entries", 1 =3D=3D evlist__nr_entries(ev= list)); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE =3D=3D evsel->core.attr.= type); TEST_ASSERT_VAL("wrong config", 0x2 =3D=3D (evsel->core.attr.config & 0xf= fffffff)); return TEST_OK; @@ -148,7 +148,7 @@ static int test__checkevent_pmu(struct evlist *evlist) =20 struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_VAL("wrong number of entries", 1 =3D=3D evlist->core.nr_entri= es); + TEST_ASSERT_VAL("wrong number of entries", 1 =3D=3D evlist__nr_entries(ev= list)); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW =3D=3D evsel->core.attr.type); TEST_ASSERT_VAL("wrong config", 10 =3D=3D evsel->core.attr.config); TEST_ASSERT_VAL("wrong config1", 1 =3D=3D evsel->core.attr.config1); @@ -168,7 +168,7 @@ static int test__hybrid_hw_group_event_2(struct evlist = *evlist) struct evsel *evsel, *leader; =20 evsel =3D leader =3D evlist__first(evlist); - TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist->core.nr_entri= es); + TEST_ASSERT_VAL("wrong number of entries", 2 =3D=3D evlist__nr_entries(ev= list)); TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE =3D=3D evsel->core.attr.= type); TEST_ASSERT_VAL("wrong hybrid type", test_hybrid_type(evsel, PERF_TYPE_RA= W)); TEST_ASSERT_VAL("wrong config", test_config(evsel, PERF_COUNT_HW_CPU_CYCL= ES)); diff --git a/tools/perf/arch/x86/util/auxtrace.c b/tools/perf/arch/x86/util= /auxtrace.c index ecbf61a7eb3a..84fce0b51ccf 100644 --- a/tools/perf/arch/x86/util/auxtrace.c +++ b/tools/perf/arch/x86/util/auxtrace.c @@ -55,7 +55,7 @@ struct auxtrace_record *auxtrace_record__init(struct evli= st *evlist, int *err) { char buffer[64]; - struct perf_cpu cpu =3D perf_cpu_map__min(evlist->core.all_cpus); + struct perf_cpu cpu =3D perf_cpu_map__min(evlist__core(evlist)->all_cpus); int ret; =20 *err =3D 0; diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/uti= l/intel-bts.c index 100a23d27998..d44d568a6d21 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c @@ -79,10 +79,10 @@ static int intel_bts_info_fill(struct auxtrace_record *= itr, if (priv_size !=3D INTEL_BTS_AUXTRACE_PRIV_SIZE) return -EINVAL; =20 - if (!session->evlist->core.nr_mmaps) + if (!evlist__core(session->evlist)->nr_mmaps) return -EINVAL; =20 - pc =3D session->evlist->mmap[0].core.base; + pc =3D evlist__mmap(session->evlist)[0].core.base; if (pc) { err =3D perf_read_tsc_conversion(pc, &tc); if (err) { @@ -114,7 +114,7 @@ static int intel_bts_recording_options(struct auxtrace_= record *itr, container_of(itr, struct intel_bts_recording, itr); struct perf_pmu *intel_bts_pmu =3D btsr->intel_bts_pmu; struct evsel *evsel, *intel_bts_evsel =3D NULL; - const struct perf_cpu_map *cpus =3D evlist->core.user_requested_cpus; + const struct perf_cpu_map *cpus =3D evlist__core(evlist)->user_requested_= cpus; bool privileged =3D perf_event_paranoid_check(-1); =20 if (opts->auxtrace_sample_mode) { diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util= /intel-pt.c index 0307ff15d9fc..a533114c0048 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -360,10 +360,10 @@ static int intel_pt_info_fill(struct auxtrace_record = *itr, filter =3D intel_pt_find_filter(session->evlist, ptr->intel_pt_pmu); filter_str_len =3D filter ? strlen(filter) : 0; =20 - if (!session->evlist->core.nr_mmaps) + if (!evlist__core(session->evlist)->nr_mmaps) return -EINVAL; =20 - pc =3D session->evlist->mmap[0].core.base; + pc =3D evlist__mmap(session->evlist)[0].core.base; if (pc) { err =3D perf_read_tsc_conversion(pc, &tc); if (err) { @@ -376,7 +376,8 @@ static int intel_pt_info_fill(struct auxtrace_record *i= tr, ui__warning("Intel Processor Trace: TSC not available\n"); } =20 - per_cpu_mmaps =3D !perf_cpu_map__is_any_cpu_or_is_empty(session->evlist->= core.user_requested_cpus); + per_cpu_mmaps =3D !perf_cpu_map__is_any_cpu_or_is_empty( + evlist__core(session->evlist)->user_requested_cpus); =20 auxtrace_info->type =3D PERF_AUXTRACE_INTEL_PT; auxtrace_info->priv[INTEL_PT_PMU_TYPE] =3D intel_pt_pmu->type; @@ -621,7 +622,7 @@ static int intel_pt_recording_options(struct auxtrace_r= ecord *itr, struct perf_pmu *intel_pt_pmu =3D ptr->intel_pt_pmu; bool have_timing_info, need_immediate =3D false; struct evsel *evsel, *intel_pt_evsel =3D NULL; - const struct perf_cpu_map *cpus =3D evlist->core.user_requested_cpus; + const struct perf_cpu_map *cpus =3D evlist__core(evlist)->user_requested_= cpus; bool privileged =3D perf_event_paranoid_check(-1); u64 tsc_bit; int err; diff --git a/tools/perf/arch/x86/util/iostat.c b/tools/perf/arch/x86/util/i= ostat.c index e0417552b0cb..a0baa6cdefd8 100644 --- a/tools/perf/arch/x86/util/iostat.c +++ b/tools/perf/arch/x86/util/iostat.c @@ -334,7 +334,7 @@ static int iostat_event_group(struct evlist *evl, =20 int iostat_prepare(struct evlist *evlist, struct perf_stat_config *config) { - if (evlist->core.nr_entries > 0) { + if (evlist__nr_entries(evlist) > 0) { pr_warning("The -e and -M options are not supported." "All chosen events/metrics will be dropped\n"); evlist__put(evlist); @@ -400,7 +400,7 @@ void iostat_prefix(struct evlist *evlist, struct perf_stat_config *config, char *prefix, struct timespec *ts) { - struct iio_root_port *rp =3D evlist->selected->priv; + struct iio_root_port *rp =3D evlist__selected(evlist)->priv; =20 if (rp) { /* @@ -463,7 +463,7 @@ void iostat_print_counters(struct evlist *evlist, iostat_prefix(evlist, config, prefix, ts); fprintf(config->output, "%s", prefix); evlist__for_each_entry(evlist, counter) { - perf_device =3D evlist->selected->priv; + perf_device =3D evlist__selected(evlist)->priv; if (perf_device && perf_device !=3D counter->priv) { evlist__set_selected(evlist, counter); iostat_prefix(evlist, config, prefix, ts); diff --git a/tools/perf/bench/evlist-open-close.c b/tools/perf/bench/evlist= -open-close.c index 304929d1f67f..748ebbe458f4 100644 --- a/tools/perf/bench/evlist-open-close.c +++ b/tools/perf/bench/evlist-open-close.c @@ -116,7 +116,7 @@ static int bench__do_evlist_open_close(struct evlist *e= vlist) return err; } =20 - err =3D evlist__mmap(evlist, opts.mmap_pages); + err =3D evlist__do_mmap(evlist, opts.mmap_pages); if (err < 0) { pr_err("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); return err; @@ -124,7 +124,7 @@ static int bench__do_evlist_open_close(struct evlist *e= vlist) =20 evlist__enable(evlist); evlist__disable(evlist); - evlist__munmap(evlist); + evlist__do_munmap(evlist); evlist__close(evlist); =20 return 0; @@ -145,10 +145,11 @@ static int bench_evlist_open_close__run(char *evstr, = const char *uid_str) =20 init_stats(&time_stats); =20 - printf(" Number of cpus:\t%d\n", perf_cpu_map__nr(evlist->core.user_requ= ested_cpus)); - printf(" Number of threads:\t%d\n", evlist->core.threads->nr); + printf(" Number of cpus:\t%d\n", + perf_cpu_map__nr(evlist__core(evlist)->user_requested_cpus)); + printf(" Number of threads:\t%d\n", evlist__core(evlist)->threads->nr); printf(" Number of events:\t%d (%d fds)\n", - evlist->core.nr_entries, evlist__count_evsel_fds(evlist)); + evlist__nr_entries(evlist), evlist__count_evsel_fds(evlist)); printf(" Number of iterations:\t%d\n", iterations); =20 evlist__put(evlist); diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 719b36d4eed5..42c8ab5a87ff 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -924,7 +924,7 @@ int cmd_annotate(int argc, const char **argv) */ if ((use_browser =3D=3D 1 || annotate.use_stdio2) && annotate.has_br_stac= k) { sort__mode =3D SORT_MODE__BRANCH; - if (annotate.session->evlist->nr_br_cntr > 0) + if (evlist__nr_br_cntr(annotate.session->evlist) > 0) annotate_opts.show_br_cntr =3D true; } =20 diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 676239148b87..9e4c5220d43c 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -377,9 +377,9 @@ static int set_tracing_pid(struct perf_ftrace *ftrace) if (target__has_cpu(&ftrace->target)) return 0; =20 - for (i =3D 0; i < perf_thread_map__nr(ftrace->evlist->core.threads); i++)= { + for (i =3D 0; i < perf_thread_map__nr(evlist__core(ftrace->evlist)->threa= ds); i++) { scnprintf(buf, sizeof(buf), "%d", - perf_thread_map__pid(ftrace->evlist->core.threads, i)); + perf_thread_map__pid(evlist__core(ftrace->evlist)->threads, i)); if (append_tracing_file("set_ftrace_pid", buf) < 0) return -1; } @@ -413,7 +413,7 @@ static int set_tracing_cpumask(struct perf_cpu_map *cpu= map) =20 static int set_tracing_cpu(struct perf_ftrace *ftrace) { - struct perf_cpu_map *cpumap =3D ftrace->evlist->core.user_requested_cpus; + struct perf_cpu_map *cpumap =3D evlist__core(ftrace->evlist)->user_reques= ted_cpus; =20 if (!target__has_cpu(&ftrace->target)) return 0; diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 41a3721a194d..5355e7763e40 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -1487,7 +1487,7 @@ static int synthesize_id_index(struct perf_inject *in= ject, size_t new_cnt) struct perf_session *session =3D inject->session; struct evlist *evlist =3D session->evlist; struct machine *machine =3D &session->machines.host; - size_t from =3D evlist->core.nr_entries - new_cnt; + size_t from =3D evlist__nr_entries(evlist) - new_cnt; =20 return __perf_event__synthesize_id_index(&inject->tool, perf_event__repip= e, evlist, machine, from); @@ -2022,7 +2022,7 @@ static int host__finished_init(const struct perf_tool= *tool, struct perf_session if (ret) return ret; =20 - ret =3D synthesize_id_index(inject, gs->session->evlist->core.nr_entries); + ret =3D synthesize_id_index(inject, evlist__nr_entries(gs->session->evlis= t)); if (ret) { pr_err("Failed to synthesize id_index\n"); return ret; diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 0ed3df4d0594..c5c1cce87a43 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1218,7 +1218,7 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_st= at *kvm, int idx, int err; =20 *mmap_time =3D ULLONG_MAX; - md =3D &evlist->mmap[idx]; + md =3D &evlist__mmap(evlist)[idx]; err =3D perf_mmap__read_init(&md->core); if (err < 0) return (err =3D=3D -EAGAIN) ? 0 : -1; @@ -1263,7 +1263,7 @@ static int perf_kvm__mmap_read(struct perf_kvm_stat *= kvm) s64 n, ntotal =3D 0; u64 flush_time =3D ULLONG_MAX, mmap_time; =20 - for (i =3D 0; i < kvm->evlist->core.nr_mmaps; i++) { + for (i =3D 0; i < evlist__core(kvm->evlist)->nr_mmaps; i++) { n =3D perf_kvm__mmap_read_idx(kvm, i, &mmap_time); if (n < 0) return -1; @@ -1446,7 +1446,7 @@ static int kvm_events_live_report(struct perf_kvm_sta= t *kvm) evlist__enable(kvm->evlist); =20 while (!done) { - struct fdarray *fda =3D &kvm->evlist->core.pollfd; + struct fdarray *fda =3D &evlist__core(kvm->evlist)->pollfd; int rc; =20 rc =3D perf_kvm__mmap_read(kvm); @@ -1528,7 +1528,7 @@ static int kvm_live_open_events(struct perf_kvm_stat = *kvm) goto out; } =20 - if (evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) { + if (evlist__do_mmap(evlist, kvm->opts.mmap_pages) < 0) { ui__error("Failed to mmap the events: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); evlist__close(evlist); @@ -1928,7 +1928,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, perf_session__set_id_hdr_size(kvm->session); ordered_events__set_copy_on_queue(&kvm->session->ordered_events, true); machine__synthesize_threads(&kvm->session->machines.host, &kvm->opts.targ= et, - kvm->evlist->core.threads, true, false, 1); + evlist__core(kvm->evlist)->threads, true, false, 1); err =3D kvm_live_open_events(kvm); if (err) goto out; diff --git a/tools/perf/builtin-kwork.c b/tools/perf/builtin-kwork.c index 59a54d11f7fa..3eb453c5f160 100644 --- a/tools/perf/builtin-kwork.c +++ b/tools/perf/builtin-kwork.c @@ -1749,7 +1749,7 @@ static int perf_kwork__check_config(struct perf_kwork= *kwork, } } =20 - list_for_each_entry(evsel, &session->evlist->core.entries, core.node) { + list_for_each_entry(evsel, &evlist__core(session->evlist)->entries, core.= node) { if (kwork->show_callchain && !evsel__has_callchain(evsel)) { pr_debug("Samples do not have callchains\n"); kwork->show_callchain =3D 0; @@ -1799,9 +1799,9 @@ static int perf_kwork__read_events(struct perf_kwork = *kwork) goto out_delete; } =20 - kwork->nr_events =3D session->evlist->stats.nr_events[0]; - kwork->nr_lost_events =3D session->evlist->stats.total_lost; - kwork->nr_lost_chunks =3D session->evlist->stats.nr_events[PERF_RECORD_LO= ST]; + kwork->nr_events =3D evlist__stats(session->evlist)->nr_events[0]; + kwork->nr_lost_events =3D evlist__stats(session->evlist)->total_lost; + kwork->nr_lost_chunks =3D evlist__stats(session->evlist)->nr_events[PERF_= RECORD_LOST]; =20 out_delete: perf_session__delete(session); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0739c834729e..a37d99f8e52e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -502,12 +502,12 @@ static void record__aio_mmap_read_sync(struct record = *rec) { int i; struct evlist *evlist =3D rec->evlist; - struct mmap *maps =3D evlist->mmap; + struct mmap *maps =3D evlist__mmap(evlist); =20 if (!record__aio_enabled(rec)) return; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { struct mmap *map =3D &maps[i]; =20 if (map->core.base) @@ -811,8 +811,8 @@ static int record__auxtrace_read_snapshot_all(struct re= cord *rec) int i; int rc =3D 0; =20 - for (i =3D 0; i < rec->evlist->core.nr_mmaps; i++) { - struct mmap *map =3D &rec->evlist->mmap[i]; + for (i =3D 0; i < evlist__core(rec->evlist)->nr_mmaps; i++) { + struct mmap *map =3D &evlist__mmap(rec->evlist)[i]; =20 if (!map->auxtrace_mmap.base) continue; @@ -1054,15 +1054,15 @@ static void record__thread_data_close_pipes(struct = record_thread *thread_data) =20 static bool evlist__per_thread(struct evlist *evlist) { - return cpu_map__is_dummy(evlist->core.user_requested_cpus); + return cpu_map__is_dummy(evlist__core(evlist)->user_requested_cpus); } =20 static int record__thread_data_init_maps(struct record_thread *thread_data= , struct evlist *evlist) { - int m, tm, nr_mmaps =3D evlist->core.nr_mmaps; - struct mmap *mmap =3D evlist->mmap; - struct mmap *overwrite_mmap =3D evlist->overwrite_mmap; - struct perf_cpu_map *cpus =3D evlist->core.all_cpus; + int m, tm, nr_mmaps =3D evlist__core(evlist)->nr_mmaps; + struct mmap *mmap =3D evlist__mmap(evlist); + struct mmap *overwrite_mmap =3D evlist__overwrite_mmap(evlist); + struct perf_cpu_map *cpus =3D evlist__core(evlist)->all_cpus; bool per_thread =3D evlist__per_thread(evlist); =20 if (per_thread) @@ -1117,16 +1117,17 @@ static int record__thread_data_init_pollfd(struct r= ecord_thread *thread_data, st overwrite_map =3D thread_data->overwrite_maps ? thread_data->overwrite_maps[tm] : NULL; =20 - for (f =3D 0; f < evlist->core.pollfd.nr; f++) { - void *ptr =3D evlist->core.pollfd.priv[f].ptr; + for (f =3D 0; f < evlist__core(evlist)->pollfd.nr; f++) { + void *ptr =3D evlist__core(evlist)->pollfd.priv[f].ptr; =20 if ((map && ptr =3D=3D map) || (overwrite_map && ptr =3D=3D overwrite_m= ap)) { pos =3D fdarray__dup_entry_from(&thread_data->pollfd, f, - &evlist->core.pollfd); + &evlist__core(evlist)->pollfd); if (pos < 0) return pos; pr_debug2("thread_data[%p]: pollfd[%d] <- event_fd=3D%d\n", - thread_data, pos, evlist->core.pollfd.entries[f].fd); + thread_data, pos, + evlist__core(evlist)->pollfd.entries[f].fd); } } } @@ -1170,7 +1171,7 @@ static int record__update_evlist_pollfd_from_thread(s= truct record *rec, struct evlist *evlist, struct record_thread *thread_data) { - struct pollfd *e_entries =3D evlist->core.pollfd.entries; + struct pollfd *e_entries =3D evlist__core(evlist)->pollfd.entries; struct pollfd *t_entries =3D thread_data->pollfd.entries; int err =3D 0; size_t i; @@ -1194,7 +1195,7 @@ static int record__dup_non_perf_events(struct record = *rec, struct evlist *evlist, struct record_thread *thread_data) { - struct fdarray *fda =3D &evlist->core.pollfd; + struct fdarray *fda =3D &evlist__core(evlist)->pollfd; int i, ret; =20 for (i =3D 0; i < fda->nr; i++) { @@ -1321,17 +1322,17 @@ static int record__mmap_evlist(struct record *rec, return ret; =20 if (record__threads_enabled(rec)) { - ret =3D perf_data__create_dir(&rec->data, evlist->core.nr_mmaps); + ret =3D perf_data__create_dir(&rec->data, evlist__core(evlist)->nr_mmaps= ); if (ret) { errno =3D -ret; pr_err("Failed to create data directory: %m\n"); return ret; } - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { - if (evlist->mmap) - evlist->mmap[i].file =3D &rec->data.dir.files[i]; - if (evlist->overwrite_mmap) - evlist->overwrite_mmap[i].file =3D &rec->data.dir.files[i]; + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { + if (evlist__mmap(evlist)) + evlist__mmap(evlist)[i].file =3D &rec->data.dir.files[i]; + if (evlist__overwrite_mmap(evlist)) + evlist__overwrite_mmap(evlist)[i].file =3D &rec->data.dir.files[i]; } } =20 @@ -1480,11 +1481,11 @@ static int record__open(struct record *rec) =20 static void set_timestamp_boundary(struct record *rec, u64 sample_time) { - if (rec->evlist->first_sample_time =3D=3D 0) - rec->evlist->first_sample_time =3D sample_time; + if (evlist__first_sample_time(rec->evlist) =3D=3D 0) + evlist__set_first_sample_time(rec->evlist, sample_time); =20 if (sample_time) - rec->evlist->last_sample_time =3D sample_time; + evlist__set_last_sample_time(rec->evlist, sample_time); } =20 static int process_sample_event(const struct perf_tool *tool, @@ -1652,7 +1653,7 @@ static int record__mmap_read_evlist(struct record *re= c, struct evlist *evlist, if (!maps) return 0; =20 - if (overwrite && evlist->bkw_mmap_state !=3D BKW_MMAP_DATA_PENDING) + if (overwrite && evlist__bkw_mmap_state(evlist) !=3D BKW_MMAP_DATA_PENDIN= G) return 0; =20 if (record__aio_enabled(rec)) @@ -1807,7 +1808,7 @@ static void record__init_features(struct record *rec) if (rec->no_buildid) perf_header__clear_feat(&session->header, HEADER_BUILD_ID); =20 - if (!have_tracepoints(&rec->evlist->core.entries)) + if (!have_tracepoints(&evlist__core(rec->evlist)->entries)) perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); =20 if (!rec->opts.branch_stack) @@ -1873,7 +1874,7 @@ static int record__synthesize_workload(struct record = *rec, bool tail) if (rec->opts.tail_synthesize !=3D tail) return 0; =20 - thread_map =3D thread_map__new_by_tid(rec->evlist->workload.pid); + thread_map =3D thread_map__new_by_tid(evlist__workload_pid(rec->evlist)); if (thread_map =3D=3D NULL) return -1; =20 @@ -2066,10 +2067,10 @@ static void alarm_sig_handler(int sig); static const struct perf_event_mmap_page *evlist__pick_pc(struct evlist *e= vlist) { if (evlist) { - if (evlist->mmap && evlist->mmap[0].core.base) - return evlist->mmap[0].core.base; - if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].core.base) - return evlist->overwrite_mmap[0].core.base; + if (evlist__mmap(evlist) && evlist__mmap(evlist)[0].core.base) + return evlist__mmap(evlist)[0].core.base; + if (evlist__overwrite_mmap(evlist) && evlist__overwrite_mmap(evlist)[0].= core.base) + return evlist__overwrite_mmap(evlist)[0].core.base; } return NULL; } @@ -2149,7 +2150,7 @@ static int record__synthesize(struct record *rec, boo= l tail) if (err) goto out; =20 - err =3D perf_event__synthesize_thread_map2(&rec->tool, rec->evlist->core.= threads, + err =3D perf_event__synthesize_thread_map2(&rec->tool, evlist__core(rec->= evlist)->threads, process_synthesized_event, NULL); if (err < 0) { @@ -2157,7 +2158,7 @@ static int record__synthesize(struct record *rec, boo= l tail) return err; } =20 - err =3D perf_event__synthesize_cpu_map(&rec->tool, rec->evlist->core.all_= cpus, + err =3D perf_event__synthesize_cpu_map(&rec->tool, evlist__core(rec->evli= st)->all_cpus, process_synthesized_event, NULL); if (err < 0) { pr_err("Couldn't synthesize cpu map.\n"); @@ -2190,7 +2191,7 @@ static int record__synthesize(struct record *rec, boo= l tail) bool needs_mmap =3D rec->opts.synth & PERF_SYNTH_MMAP; =20 err =3D __machine__synthesize_threads(machine, tool, &opts->target, - rec->evlist->core.threads, + evlist__core(rec->evlist)->threads, f, needs_mmap, opts->record_data_mmap, rec->opts.nr_threads_synthesize); } @@ -2543,7 +2544,7 @@ static int __cmd_record(struct record *rec, int argc,= const char **argv) * because we synthesize event name through the pipe * and need the id for that. */ - if (data->is_pipe && rec->evlist->core.nr_entries =3D=3D 1) + if (data->is_pipe && evlist__nr_entries(rec->evlist) =3D=3D 1) rec->opts.sample_id =3D true; =20 if (rec->timestamp_filename && perf_data__is_pipe(data)) { @@ -2567,7 +2568,7 @@ static int __cmd_record(struct record *rec, int argc,= const char **argv) } /* Debug message used by test scripts */ pr_debug3("perf record done opening and mmapping events\n"); - env->comp_mmap_len =3D session->evlist->core.mmap_len; + env->comp_mmap_len =3D evlist__core(session->evlist)->mmap_len; =20 if (rec->opts.kcore) { err =3D record__kcore_copy(&session->machines.host, data); @@ -2668,7 +2669,7 @@ static int __cmd_record(struct record *rec, int argc,= const char **argv) * Synthesize COMM event to prevent it. */ tgid =3D perf_event__synthesize_comm(tool, event, - rec->evlist->workload.pid, + evlist__workload_pid(rec->evlist), process_synthesized_event, machine); free(event); @@ -2688,7 +2689,7 @@ static int __cmd_record(struct record *rec, int argc,= const char **argv) * Synthesize NAMESPACES event for the command specified. */ perf_event__synthesize_namespaces(tool, event, - rec->evlist->workload.pid, + evlist__workload_pid(rec->evlist), tgid, process_synthesized_event, machine); free(event); @@ -2705,7 +2706,7 @@ static int __cmd_record(struct record *rec, int argc,= const char **argv) } } =20 - err =3D event_enable_timer__start(rec->evlist->eet); + err =3D event_enable_timer__start(evlist__event_enable_timer(rec->evlist)= ); if (err) goto out_child; =20 @@ -2767,7 +2768,7 @@ static int __cmd_record(struct record *rec, int argc,= const char **argv) * record__mmap_read_all() didn't collect data from * overwritable ring buffer. Read again. */ - if (rec->evlist->bkw_mmap_state =3D=3D BKW_MMAP_RUNNING) + if (evlist__bkw_mmap_state(rec->evlist) =3D=3D BKW_MMAP_RUNNING) continue; trigger_ready(&switch_output_trigger); =20 @@ -2836,7 +2837,7 @@ static int __cmd_record(struct record *rec, int argc,= const char **argv) } } =20 - err =3D event_enable_timer__process(rec->evlist->eet); + err =3D event_enable_timer__process(evlist__event_enable_timer(rec->evli= st)); if (err < 0) goto out_child; if (err) { @@ -2904,7 +2905,7 @@ static int __cmd_record(struct record *rec, int argc,= const char **argv) int exit_status; =20 if (!child_finished) - kill(rec->evlist->workload.pid, SIGTERM); + kill(evlist__workload_pid(rec->evlist), SIGTERM); =20 wait(&exit_status); =20 @@ -4026,7 +4027,7 @@ static int record__init_thread_default_masks(struct r= ecord *rec, struct perf_cpu static int record__init_thread_masks(struct record *rec) { int ret =3D 0; - struct perf_cpu_map *cpus =3D rec->evlist->core.all_cpus; + struct perf_cpu_map *cpus =3D evlist__core(rec->evlist)->all_cpus; =20 if (!record__threads_enabled(rec)) return record__init_thread_default_masks(rec, cpus); @@ -4277,14 +4278,14 @@ int cmd_record(int argc, const char **argv) if (record.opts.overwrite) record.opts.tail_synthesize =3D true; =20 - if (rec->evlist->core.nr_entries =3D=3D 0) { + if (evlist__nr_entries(rec->evlist) =3D=3D 0) { struct evlist *def_evlist =3D evlist__new_default(&rec->opts.target, callchain_param.enabled); =20 if (!def_evlist) goto out; =20 - evlist__splice_list_tail(rec->evlist, &def_evlist->core.entries); + evlist__splice_list_tail(rec->evlist, &evlist__core(def_evlist)->entries= ); evlist__put(def_evlist); } =20 diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 973d97af8501..858400a730c6 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -557,7 +557,7 @@ static int evlist__tty_browse_hists(struct evlist *evli= st, struct report *rep, c =20 if (!quiet) { fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n", - evlist->stats.total_lost_samples); + evlist__stats(evlist)->total_lost_samples); } =20 evlist__for_each_entry(evlist, pos) { @@ -1152,7 +1152,7 @@ static int __cmd_report(struct report *rep) PERF_HPP_REPORT__BLOCK_AVG_CYCLES, }; =20 - if (session->evlist->nr_br_cntr > 0) + if (evlist__nr_br_cntr(session->evlist) > 0) block_hpps[nr_hpps++] =3D PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER; =20 block_hpps[nr_hpps++] =3D PERF_HPP_REPORT__BLOCK_RANGE; @@ -1287,7 +1287,7 @@ static int process_attr(const struct perf_tool *tool = __maybe_unused, * on events sample_type. */ sample_type =3D evlist__combined_sample_type(*pevlist); - session =3D (*pevlist)->session; + session =3D evlist__session(*pevlist); callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_f= lags=3D*/NULL)); return 0; } diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index f4916585aa75..c23bc8eeef9d 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1950,9 +1950,9 @@ static int perf_sched__read_events(struct perf_sched = *sched) goto out_delete; } =20 - sched->nr_events =3D session->evlist->stats.nr_events[0]; - sched->nr_lost_events =3D session->evlist->stats.total_lost; - sched->nr_lost_chunks =3D session->evlist->stats.nr_events[PERF_RECORD_L= OST]; + sched->nr_events =3D evlist__stats(session->evlist)->nr_events[0]; + sched->nr_lost_events =3D evlist__stats(session->evlist)->total_lost; + sched->nr_lost_chunks =3D evlist__stats(session->evlist)->nr_events[PERF= _RECORD_LOST]; } =20 rc =3D 0; @@ -3200,7 +3200,7 @@ static int timehist_check_attr(struct perf_sched *sch= ed, struct evsel *evsel; struct evsel_runtime *er; =20 - list_for_each_entry(evsel, &evlist->core.entries, core.node) { + list_for_each_entry(evsel, &evlist__core(evlist)->entries, core.node) { er =3D evsel__get_runtime(evsel); if (er =3D=3D NULL) { pr_err("Failed to allocate memory for evsel runtime data\n"); @@ -3372,9 +3372,9 @@ static int perf_sched__timehist(struct perf_sched *sc= hed) goto out; } =20 - sched->nr_events =3D evlist->stats.nr_events[0]; - sched->nr_lost_events =3D evlist->stats.total_lost; - sched->nr_lost_chunks =3D evlist->stats.nr_events[PERF_RECORD_LOST]; + sched->nr_events =3D evlist__stats(evlist)->nr_events[0]; + sched->nr_lost_events =3D evlist__stats(evlist)->total_lost; + sched->nr_lost_chunks =3D evlist__stats(evlist)->nr_events[PERF_RECORD_LO= ST]; =20 if (sched->summary) timehist_print_summary(sched, session); @@ -3881,7 +3881,7 @@ static int perf_sched__schedstat_record(struct perf_s= ched *sched, if (err < 0) goto out; =20 - user_requested_cpus =3D evlist->core.user_requested_cpus; + user_requested_cpus =3D evlist__core(evlist)->user_requested_cpus; =20 err =3D perf_event__synthesize_schedstat(&(sched->tool), process_synthesized_schedstat_event, @@ -4598,7 +4598,7 @@ static int perf_sched__schedstat_report(struct perf_s= ched *sched) if (err < 0) goto out; =20 - user_requested_cpus =3D session->evlist->core.user_requested_cpus; + user_requested_cpus =3D evlist__core(session->evlist)->user_requested_cpu= s; =20 err =3D perf_session__process_events(session); =20 @@ -4774,7 +4774,7 @@ static int perf_sched__schedstat_live(struct perf_sch= ed *sched, if (err < 0) goto out; =20 - user_requested_cpus =3D evlist->core.user_requested_cpus; + user_requested_cpus =3D evlist__core(evlist)->user_requested_cpus; =20 err =3D perf_event__synthesize_schedstat(&(sched->tool), process_synthesized_event_live, diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 421520bdafdc..3fc66ad0b039 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2225,9 +2225,10 @@ static int script_find_metrics(const struct pmu_metr= ic *pm, evlist__for_each_entry(metric_evlist, metric_evsel) { struct evsel *script_evsel =3D map_metric_evsel_to_script_evsel(script_evlist, metric_evsel); - struct metric_event *metric_me =3D metricgroup__lookup(&metric_evlist->m= etric_events, - metric_evsel, - /*create=3D*/false); + struct metric_event *metric_me =3D + metricgroup__lookup(evlist__metric_events(metric_evlist), + metric_evsel, + /*create=3D*/false); =20 if (script_evsel->metric_id =3D=3D NULL) { script_evsel->metric_id =3D metric_evsel->metric_id; @@ -2247,7 +2248,7 @@ static int script_find_metrics(const struct pmu_metri= c *pm, if (metric_me) { struct metric_expr *expr; struct metric_event *script_me =3D - metricgroup__lookup(&script_evlist->metric_events, + metricgroup__lookup(evlist__metric_events(script_evlist), script_evsel, /*create=3D*/true); =20 @@ -2317,7 +2318,7 @@ static void perf_sample__fprint_metric(struct thread = *thread, assert(stat_config.aggr_mode =3D=3D AGGR_GLOBAL); stat_config.aggr_get_id =3D script_aggr_cpu_id_get; stat_config.aggr_map =3D - cpu_aggr_map__new(evsel->evlist->core.user_requested_cpus, + cpu_aggr_map__new(evlist__core(evsel->evlist)->user_requested_cpus, aggr_cpu_id__global, /*data=3D*/NULL, /*needs_sort=3D*/false); } @@ -3903,7 +3904,7 @@ static int set_maps(struct perf_script *script) if (WARN_ONCE(script->allocated, "stats double allocation\n")) return -EINVAL; =20 - perf_evlist__set_maps(&evlist->core, script->cpus, script->threads); + perf_evlist__set_maps(evlist__core(evlist), script->cpus, script->threads= ); =20 if (evlist__alloc_stats(&stat_config, evlist, /*alloc_raw=3D*/true)) return -ENOMEM; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index bfa3512e1686..fe06d057edf0 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -321,7 +321,7 @@ static int read_single_counter(struct evsel *counter, i= nt cpu_map_idx, int threa */ static int read_counter_cpu(struct evsel *counter, int cpu_map_idx) { - int nthreads =3D perf_thread_map__nr(evsel_list->core.threads); + int nthreads =3D perf_thread_map__nr(evlist__core(evsel_list)->threads); int thread; =20 if (!counter->supported) @@ -628,11 +628,12 @@ static int dispatch_events(bool forks, int timeout, i= nt interval, int *times) time_to_sleep =3D sleep_time; =20 while (!done) { - if (forks) + if (forks) { child_exited =3D waitpid(child_pid, &status, WNOHANG); - else - child_exited =3D !is_target_alive(&target, evsel_list->core.threads) ? = 1 : 0; - + } else { + child_exited =3D !is_target_alive(&target, + evlist__core(evsel_list)->threads) ? 1 : 0; + } if (child_exited) break; =20 @@ -681,14 +682,15 @@ static enum counter_recovery stat_handle_error(struct= evsel *counter, int err) return COUNTER_RETRY; } if (target__has_per_thread(&target) && err !=3D EOPNOTSUPP && - evsel_list->core.threads && evsel_list->core.threads->err_thread !=3D= -1) { + evlist__core(evsel_list)->threads && + evlist__core(evsel_list)->threads->err_thread !=3D -1) { /* * For global --per-thread case, skip current * error thread. */ - if (!thread_map__remove(evsel_list->core.threads, - evsel_list->core.threads->err_thread)) { - evsel_list->core.threads->err_thread =3D -1; + if (!thread_map__remove(evlist__core(evsel_list)->threads, + evlist__core(evsel_list)->threads->err_thread)) { + evlist__core(evsel_list)->threads->err_thread =3D -1; counter->supported =3D true; return COUNTER_RETRY; } @@ -787,11 +789,12 @@ static int __run_perf_stat(int argc, const char **arg= v, int run_idx) bool second_pass =3D false, has_supported_counters; =20 if (forks) { - if (evlist__prepare_workload(evsel_list, &target, argv, is_pipe, workloa= d_exec_failed_signal) < 0) { + if (evlist__prepare_workload(evsel_list, &target, argv, is_pipe, + workload_exec_failed_signal) < 0) { perror("failed to prepare workload"); return -1; } - child_pid =3D evsel_list->workload.pid; + child_pid =3D evlist__workload_pid(evsel_list); } =20 evlist__for_each_entry(evsel_list, counter) { @@ -1199,7 +1202,7 @@ static int parse_cputype(const struct option *opt, const struct perf_pmu *pmu; struct evlist *evlist =3D *(struct evlist **)opt->value; =20 - if (!list_empty(&evlist->core.entries)) { + if (!list_empty(&evlist__core(evlist)->entries)) { fprintf(stderr, "Must define cputype before events/metrics\n"); return -1; } @@ -1220,7 +1223,7 @@ static int parse_pmu_filter(const struct option *opt, { struct evlist *evlist =3D *(struct evlist **)opt->value; =20 - if (!list_empty(&evlist->core.entries)) { + if (!list_empty(&evlist__core(evlist)->entries)) { fprintf(stderr, "Must define pmu-filter before events/metrics\n"); return -1; } @@ -1586,8 +1589,9 @@ static int perf_stat_init_aggr_mode(void) =20 if (get_id) { bool needs_sort =3D stat_config.aggr_mode !=3D AGGR_NONE; - stat_config.aggr_map =3D cpu_aggr_map__new(evsel_list->core.user_request= ed_cpus, - get_id, /*data=3D*/NULL, needs_sort); + stat_config.aggr_map =3D cpu_aggr_map__new( + evlist__core(evsel_list)->user_requested_cpus, + get_id, /*data=3D*/NULL, needs_sort); if (!stat_config.aggr_map) { pr_err("cannot build %s map\n", aggr_mode__string[stat_config.aggr_mode= ]); return -1; @@ -1596,7 +1600,7 @@ static int perf_stat_init_aggr_mode(void) } =20 if (stat_config.aggr_mode =3D=3D AGGR_THREAD) { - nr =3D perf_thread_map__nr(evsel_list->core.threads); + nr =3D perf_thread_map__nr(evlist__core(evsel_list)->threads); stat_config.aggr_map =3D cpu_aggr_map__empty_new(nr); if (stat_config.aggr_map =3D=3D NULL) return -ENOMEM; @@ -1615,7 +1619,7 @@ static int perf_stat_init_aggr_mode(void) * taking the highest cpu number to be the size of * the aggregation translate cpumap. */ - nr =3D perf_cpu_map__max(evsel_list->core.all_cpus).cpu + 1; + nr =3D perf_cpu_map__max(evlist__core(evsel_list)->all_cpus).cpu + 1; stat_config.cpus_aggr_map =3D cpu_aggr_map__empty_new(nr); return stat_config.cpus_aggr_map ? 0 : -ENOMEM; } @@ -1896,7 +1900,7 @@ static int perf_stat_init_aggr_mode_file(struct perf_= stat *st) bool needs_sort =3D stat_config.aggr_mode !=3D AGGR_NONE; =20 if (stat_config.aggr_mode =3D=3D AGGR_THREAD) { - int nr =3D perf_thread_map__nr(evsel_list->core.threads); + int nr =3D perf_thread_map__nr(evlist__core(evsel_list)->threads); =20 stat_config.aggr_map =3D cpu_aggr_map__empty_new(nr); if (stat_config.aggr_map =3D=3D NULL) @@ -1914,7 +1918,7 @@ static int perf_stat_init_aggr_mode_file(struct perf_= stat *st) if (!get_id) return 0; =20 - stat_config.aggr_map =3D cpu_aggr_map__new(evsel_list->core.user_requeste= d_cpus, + stat_config.aggr_map =3D cpu_aggr_map__new(evlist__core(evsel_list)->user= _requested_cpus, get_id, env, needs_sort); if (!stat_config.aggr_map) { pr_err("cannot build %s map\n", aggr_mode__string[stat_config.aggr_mode]= ); @@ -2082,7 +2086,7 @@ static int add_default_events(void) if (!stat_config.topdown_level) stat_config.topdown_level =3D 1; =20 - if (!evlist->core.nr_entries && !evsel_list->core.nr_entries) { + if (!evlist__nr_entries(evlist) && !evlist__nr_entries(evsel_list)) { /* * Add Default metrics. To minimize multiplexing, don't request * threshold computation, but it will be computed if the events @@ -2121,13 +2125,13 @@ static int add_default_events(void) evlist__for_each_entry(metric_evlist, evsel) evsel->default_metricgroup =3D true; =20 - evlist__splice_list_tail(evlist, &metric_evlist->core.entries); + evlist__splice_list_tail(evlist, &evlist__core(metric_evlist)->entries); metricgroup__copy_metric_events(evlist, /*cgrp=3D*/NULL, - &evlist->metric_events, - &metric_evlist->metric_events); + evlist__metric_events(evlist), + evlist__metric_events(metric_evlist)); evlist__put(metric_evlist); } - list_sort(/*priv=3D*/NULL, &evlist->core.entries, default_evlist_evsel_c= mp); + list_sort(/*priv=3D*/NULL, &evlist__core(evlist)->entries, default_evlis= t_evsel_cmp); =20 } out: @@ -2142,10 +2146,10 @@ static int add_default_events(void) } } parse_events_error__exit(&err); - evlist__splice_list_tail(evsel_list, &evlist->core.entries); + evlist__splice_list_tail(evsel_list, &evlist__core(evlist)->entries); metricgroup__copy_metric_events(evsel_list, /*cgrp=3D*/NULL, - &evsel_list->metric_events, - &evlist->metric_events); + evlist__metric_events(evsel_list), + evlist__metric_events(evlist)); evlist__put(evlist); return ret; } @@ -2266,7 +2270,7 @@ static int set_maps(struct perf_stat *st) if (WARN_ONCE(st->maps_allocated, "stats double allocation\n")) return -EINVAL; =20 - perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads); + perf_evlist__set_maps(evlist__core(evsel_list), st->cpus, st->threads); =20 if (evlist__alloc_stats(&stat_config, evsel_list, /*alloc_raw=3D*/true)) return -ENOMEM; @@ -2418,7 +2422,7 @@ static void setup_system_wide(int forks) } } =20 - if (evsel_list->core.nr_entries) + if (evlist__nr_entries(evsel_list)) target.system_wide =3D true; } } @@ -2645,7 +2649,7 @@ int cmd_stat(int argc, const char **argv) stat_config.csv_sep =3D DEFAULT_SEPARATOR; =20 if (affinity_set) - evsel_list->no_affinity =3D !affinity; + evlist__set_no_affinity(evsel_list, !affinity); =20 if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) { argc =3D __cmd_record(stat_options, &opt_mode, argc, argv); @@ -2876,9 +2880,10 @@ int cmd_stat(int argc, const char **argv) } #ifdef HAVE_BPF_SKEL if (target.use_bpf && nr_cgroups && - (evsel_list->core.nr_entries / nr_cgroups) > BPERF_CGROUP__MAX_EVENTS= ) { + (evlist__nr_entries(evsel_list) / nr_cgroups) > BPERF_CGROUP__MAX_EVE= NTS) { pr_warning("Disabling BPF counters due to more events (%d) than the max = (%d)\n", - evsel_list->core.nr_entries / nr_cgroups, BPERF_CGROUP__MAX_EVENTS); + evlist__nr_entries(evsel_list) / nr_cgroups, + BPERF_CGROUP__MAX_EVENTS); target.use_bpf =3D false; } #endif // HAVE_BPF_SKEL @@ -2916,7 +2921,7 @@ int cmd_stat(int argc, const char **argv) * so we could print it out on output. */ if (stat_config.aggr_mode =3D=3D AGGR_THREAD) { - thread_map__read_comms(evsel_list->core.threads); + thread_map__read_comms(evlist__core(evsel_list)->threads); } =20 if (stat_config.aggr_mode =3D=3D AGGR_NODE) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index ca9d6189f725..ef7abf6b8ec5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -141,7 +141,7 @@ static int perf_top__parse_source(struct perf_top *top,= struct hist_entry *he) notes =3D symbol__annotation(sym); annotation__lock(notes); =20 - if (!symbol__hists(sym, top->evlist->core.nr_entries)) { + if (!symbol__hists(sym, evlist__nr_entries(top->evlist))) { annotation__unlock(notes); pr_err("Not enough memory for annotating '%s' symbol!\n", sym->name); @@ -267,7 +267,7 @@ static void perf_top__show_details(struct perf_top *top) =20 more =3D hist_entry__annotate_printf(he, top->sym_evsel); =20 - if (top->evlist->enabled) { + if (evlist__enabled(top->evlist)) { if (top->zero) symbol__annotate_zero_histogram(symbol, top->sym_evsel); else @@ -293,7 +293,7 @@ static void perf_top__resort_hists(struct perf_top *t) */ hists__unlink(hists); =20 - if (evlist->enabled) { + if (evlist__enabled(evlist)) { if (t->zero) { hists__delete_entries(hists); } else { @@ -334,13 +334,13 @@ static void perf_top__print_sym_table(struct perf_top= *top) printf("%-*.*s\n", win_width, win_width, graph_dotted_line); =20 if (!top->record_opts.overwrite && - (top->evlist->stats.nr_lost_warned !=3D - top->evlist->stats.nr_events[PERF_RECORD_LOST])) { - top->evlist->stats.nr_lost_warned =3D - top->evlist->stats.nr_events[PERF_RECORD_LOST]; + (evlist__stats(top->evlist)->nr_lost_warned !=3D + evlist__stats(top->evlist)->nr_events[PERF_RECORD_LOST])) { + evlist__stats(top->evlist)->nr_lost_warned =3D + evlist__stats(top->evlist)->nr_events[PERF_RECORD_LOST]; color_fprintf(stdout, PERF_COLOR_RED, "WARNING: LOST %d chunks, Check IO/CPU overload", - top->evlist->stats.nr_lost_warned); + evlist__stats(top->evlist)->nr_lost_warned); ++printed; } =20 @@ -447,7 +447,7 @@ static void perf_top__print_mapped_keys(struct perf_top= *top) fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", = top->delay_secs); fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", = top->print_entries); =20 - if (top->evlist->core.nr_entries > 1) + if (evlist__nr_entries(top->evlist) > 1) fprintf(stdout, "\t[E] active event counter. \t(%s)\n",= evsel__name(top->sym_evsel)); =20 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", = top->count_filter); @@ -482,7 +482,7 @@ static int perf_top__key_mapped(struct perf_top *top, i= nt c) case 'S': return 1; case 'E': - return top->evlist->core.nr_entries > 1 ? 1 : 0; + return evlist__nr_entries(top->evlist) > 1 ? 1 : 0; default: break; } @@ -528,7 +528,7 @@ static bool perf_top__handle_keypress(struct perf_top *= top, int c) } break; case 'E': - if (top->evlist->core.nr_entries > 1) { + if (evlist__nr_entries(top->evlist) > 1) { /* Select 0 as the default event: */ int counter =3D 0; =20 @@ -539,7 +539,7 @@ static bool perf_top__handle_keypress(struct perf_top *= top, int c) =20 prompt_integer(&counter, "Enter details event counter"); =20 - if (counter >=3D top->evlist->core.nr_entries) { + if (counter >=3D evlist__nr_entries(top->evlist)) { top->sym_evsel =3D evlist__first(top->evlist); fprintf(stderr, "Sorry, no such event, using %s.\n", evsel__name(top-= >sym_evsel)); sleep(1); @@ -598,8 +598,8 @@ static void perf_top__sort_new_samples(void *arg) { struct perf_top *t =3D arg; =20 - if (t->evlist->selected !=3D NULL) - t->sym_evsel =3D t->evlist->selected; + if (evlist__selected(t->evlist) !=3D NULL) + t->sym_evsel =3D evlist__selected(t->evlist); =20 perf_top__resort_hists(t); =20 @@ -766,7 +766,7 @@ static void perf_event__process_sample(const struct per= f_tool *tool, =20 if (!machine) { pr_err("%u unprocessable samples recorded.\r", - top->session->evlist->stats.nr_unprocessable_samples++); + evlist__stats(top->session->evlist)->nr_unprocessable_samples++); return; } =20 @@ -858,7 +858,7 @@ perf_top__process_lost(struct perf_top *top, union perf= _event *event, { top->lost +=3D event->lost.lost; top->lost_total +=3D event->lost.lost; - evsel->evlist->stats.total_lost +=3D event->lost.lost; + evlist__stats(evsel->evlist)->total_lost +=3D event->lost.lost; } =20 static void @@ -868,7 +868,7 @@ perf_top__process_lost_samples(struct perf_top *top, { top->lost +=3D event->lost_samples.lost; top->lost_total +=3D event->lost_samples.lost; - evsel->evlist->stats.total_lost_samples +=3D event->lost_samples.lost; + evlist__stats(evsel->evlist)->total_lost_samples +=3D event->lost_samples= .lost; } =20 static u64 last_timestamp; @@ -880,7 +880,7 @@ static void perf_top__mmap_read_idx(struct perf_top *to= p, int idx) struct mmap *md; union perf_event *event; =20 - md =3D opts->overwrite ? &evlist->overwrite_mmap[idx] : &evlist->mmap[idx= ]; + md =3D opts->overwrite ? &evlist__overwrite_mmap(evlist)[idx] : &evlist__= mmap(evlist)[idx]; if (perf_mmap__read_init(&md->core) < 0) return; =20 @@ -917,7 +917,7 @@ static void perf_top__mmap_read(struct perf_top *top) if (overwrite) evlist__toggle_bkw_mmap(evlist, BKW_MMAP_DATA_PENDING); =20 - for (i =3D 0; i < top->evlist->core.nr_mmaps; i++) + for (i =3D 0; i < evlist__core(top->evlist)->nr_mmaps; i++) perf_top__mmap_read_idx(top, i); =20 if (overwrite) { @@ -1062,7 +1062,7 @@ static int perf_top__start_counters(struct perf_top *= top) goto out_err; } =20 - if (evlist__mmap(evlist, opts->mmap_pages) < 0) { + if (evlist__do_mmap(evlist, opts->mmap_pages) < 0) { ui__error("Failed to mmap with %d (%s)\n", errno, str_error_r(errno, msg, sizeof(msg))); goto out_err; @@ -1217,10 +1217,10 @@ static int deliver_event(struct ordered_events *qe, } else if (event->header.type =3D=3D PERF_RECORD_LOST_SAMPLES) { perf_top__process_lost_samples(top, event, evsel); } else if (event->header.type < PERF_RECORD_MAX) { - events_stats__inc(&session->evlist->stats, event->header.type); + events_stats__inc(evlist__stats(session->evlist), event->header.type); machine__process_event(machine, event, &sample); } else - ++session->evlist->stats.nr_unknown_events; + ++evlist__stats(session->evlist)->nr_unknown_events; =20 ret =3D 0; next_event: @@ -1295,7 +1295,7 @@ static int __cmd_top(struct perf_top *top) pr_debug("Couldn't synthesize cgroup events.\n"); =20 machine__synthesize_threads(&top->session->machines.host, &opts->target, - top->evlist->core.threads, true, false, + evlist__core(top->evlist)->threads, true, false, top->nr_threads_synthesize); =20 perf_set_multithreaded(); @@ -1713,13 +1713,13 @@ int cmd_top(int argc, const char **argv) if (target__none(target)) target->system_wide =3D true; =20 - if (!top.evlist->core.nr_entries) { + if (!evlist__nr_entries(top.evlist)) { struct evlist *def_evlist =3D evlist__new_default(target, callchain_para= m.enabled); =20 if (!def_evlist) goto out_put_evlist; =20 - evlist__splice_list_tail(top.evlist, &def_evlist->core.entries); + evlist__splice_list_tail(top.evlist, &evlist__core(def_evlist)->entries); evlist__put(def_evlist); } =20 @@ -1796,7 +1796,7 @@ int cmd_top(int argc, const char **argv) top.session =3D NULL; goto out_put_evlist; } - top.evlist->session =3D top.session; + evlist__set_session(top.evlist, top.session); =20 if (setup_sorting(top.evlist, perf_session__env(top.session)) < 0) { if (sort_order) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b6db70d62822..62632968f50c 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2026,7 +2026,7 @@ static int trace__symbols_init(struct trace *trace, i= nt argc, const char **argv, goto out; =20 err =3D __machine__synthesize_threads(trace->host, &trace->tool, &trace->= opts.target, - evlist->core.threads, trace__tool_process, + evlist__core(evlist)->threads, trace__tool_process, /*needs_mmap=3D*/callchain_param.enabled && !trace->summary_only, /*mmap_data=3D*/false, @@ -4199,7 +4199,7 @@ static int trace__set_filter_pids(struct trace *trace) err =3D augmented_syscalls__set_filter_pids(trace->filter_pids.nr, trace->filter_pids.entries); } - } else if (perf_thread_map__pid(trace->evlist->core.threads, 0) =3D=3D -1= ) { + } else if (perf_thread_map__pid(evlist__core(trace->evlist)->threads, 0) = =3D=3D -1) { err =3D trace__set_filter_loop_pids(trace); } =20 @@ -4513,7 +4513,7 @@ static int trace__run(struct trace *trace, int argc, = const char **argv) fprintf(trace->output, "Couldn't run the workload!\n"); goto out_put_evlist; } - workload_pid =3D evlist->workload.pid; + workload_pid =3D evlist__workload_pid(evlist); } =20 err =3D evlist__open(evlist); @@ -4565,7 +4565,7 @@ static int trace__run(struct trace *trace, int argc, = const char **argv) goto out_error_apply_filters; =20 if (!trace->summary_only || !trace->summary_bpf) { - err =3D evlist__mmap(evlist, trace->opts.mmap_pages); + err =3D evlist__do_mmap(evlist, trace->opts.mmap_pages); if (err < 0) goto out_error_mmap; } @@ -4584,8 +4584,8 @@ static int trace__run(struct trace *trace, int argc, = const char **argv) if (trace->summary_bpf) trace_start_bpf_summary(); =20 - trace->multiple_threads =3D perf_thread_map__pid(evlist->core.threads, 0)= =3D=3D -1 || - perf_thread_map__nr(evlist->core.threads) > 1 || + trace->multiple_threads =3D perf_thread_map__pid(evlist__core(evlist)->th= reads, 0) =3D=3D -1 || + perf_thread_map__nr(evlist__core(evlist)->threads) > 1 || evlist__first(evlist)->core.attr.inherit; =20 /* @@ -4602,11 +4602,11 @@ static int trace__run(struct trace *trace, int argc= , const char **argv) again: before =3D trace->nr_events; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { union perf_event *event; struct mmap *md; =20 - md =3D &evlist->mmap[i]; + md =3D &evlist__mmap(evlist)[i]; if (perf_mmap__read_init(&md->core) < 0) continue; =20 @@ -5306,7 +5306,7 @@ static int trace__parse_cgroups(const struct option *= opt, const char *str, int u { struct trace *trace =3D opt->value; =20 - if (!list_empty(&trace->evlist->core.entries)) { + if (!list_empty(&evlist__core(trace->evlist)->entries)) { struct option o =3D { .value =3D &trace->evlist, }; @@ -5580,7 +5580,7 @@ int cmd_trace(int argc, const char **argv) * .perfconfig trace.add_events, and filter those out. */ if (!trace.trace_syscalls && !trace.trace_pgfaults && - trace.evlist->core.nr_entries =3D=3D 0 /* Was --events used? */) { + evlist__nr_entries(trace.evlist) =3D=3D 0 /* Was --events used? */) { trace.trace_syscalls =3D true; } /* @@ -5666,7 +5666,7 @@ int cmd_trace(int argc, const char **argv) symbol_conf.use_callchain =3D true; } =20 - if (trace.evlist->core.nr_entries > 0) { + if (evlist__nr_entries(trace.evlist) > 0) { bool use_btf =3D false; =20 evlist__set_default_evsel_handler(trace.evlist, trace__event_handler); diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/bac= kward-ring-buffer.c index 2b49b002d749..2735cc26d7ee 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -34,8 +34,8 @@ static int count_samples(struct evlist *evlist, int *samp= le_count, { int i; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { - struct mmap *map =3D &evlist->overwrite_mmap[i]; + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { + struct mmap *map =3D &evlist__overwrite_mmap(evlist)[i]; union perf_event *event; =20 perf_mmap__read_init(&map->core); @@ -65,7 +65,7 @@ static int do_test(struct evlist *evlist, int mmap_pages, int err; char sbuf[STRERR_BUFSIZE]; =20 - err =3D evlist__mmap(evlist, mmap_pages); + err =3D evlist__do_mmap(evlist, mmap_pages); if (err < 0) { pr_debug("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); @@ -77,7 +77,7 @@ static int do_test(struct evlist *evlist, int mmap_pages, evlist__disable(evlist); =20 err =3D count_samples(evlist, sample_count, comm_count); - evlist__munmap(evlist); + evlist__do_munmap(evlist); return err; } =20 diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index fc65a17f67f7..28c068a35ada 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -589,8 +589,8 @@ static int process_events(struct machine *machine, stru= ct evlist *evlist, struct mmap *md; int i, ret; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { - md =3D &evlist->mmap[i]; + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { + md =3D &evlist__mmap(evlist)[i]; if (perf_mmap__read_init(&md->core) < 0) continue; =20 @@ -778,7 +778,7 @@ static int do_test_code_reading(bool try_kcore) goto out_put; } =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); =20 str =3D events[evidx]; pr_debug("Parsing event '%s'\n", str); @@ -806,7 +806,7 @@ static int do_test_code_reading(bool try_kcore) pr_debug("perf_evlist__open() failed!\n%s\n", errbuf); } =20 - perf_evlist__set_maps(&evlist->core, NULL, NULL); + perf_evlist__set_maps(evlist__core(evlist), NULL, NULL); evlist__put(evlist); evlist =3D NULL; continue; @@ -817,7 +817,7 @@ static int do_test_code_reading(bool try_kcore) if (events[evidx] =3D=3D NULL) goto out_put; =20 - ret =3D evlist__mmap(evlist, UINT_MAX); + ret =3D evlist__do_mmap(evlist, UINT_MAX); if (ret < 0) { pr_debug("evlist__mmap failed\n"); goto out_put; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 94ab54ecd3f9..56dd37ca760e 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -50,7 +50,7 @@ static int attach__enable_on_exec(struct evlist *evlist) =20 static int detach__enable_on_exec(struct evlist *evlist) { - waitpid(evlist->workload.pid, NULL, 0); + waitpid(evlist__workload_pid(evlist), NULL, 0); return 0; } =20 diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_updat= e.c index 73141b122d2f..220cc0347747 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -92,7 +92,7 @@ static int test__event_update(struct test_suite *test __m= aybe_unused, int subtes TEST_ASSERT_VAL("failed to allocate ids", !perf_evsel__alloc_id(&evsel->core, 1, 1)); =20 - perf_evlist__id_add(&evlist->core, &evsel->core, 0, 0, 123); + perf_evlist__id_add(evlist__core(evlist), &evsel->core, 0, 0, 123); =20 free((char *)evsel->unit); evsel->unit =3D strdup("KRAVA"); diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgr= oup.c index a7a445f12693..549fbd473ab7 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -28,7 +28,7 @@ static int test_expand_events(struct evlist *evlist) =20 TEST_ASSERT_VAL("evlist is empty", !evlist__empty(evlist)); =20 - nr_events =3D evlist->core.nr_entries; + nr_events =3D evlist__nr_entries(evlist); ev_name =3D calloc(nr_events, sizeof(*ev_name)); if (ev_name =3D=3D NULL) { pr_debug("memory allocation failure\n"); @@ -54,7 +54,7 @@ static int test_expand_events(struct evlist *evlist) } =20 ret =3D TEST_FAIL; - if (evlist->core.nr_entries !=3D nr_events * nr_cgrps) { + if (evlist__nr_entries(evlist) !=3D nr_events * nr_cgrps) { pr_debug("event count doesn't match\n"); goto out; } diff --git a/tools/perf/tests/hwmon_pmu.c b/tools/perf/tests/hwmon_pmu.c index 1b60c3a900f1..9dfc890841bf 100644 --- a/tools/perf/tests/hwmon_pmu.c +++ b/tools/perf/tests/hwmon_pmu.c @@ -183,9 +183,10 @@ static int do_test(size_t i, bool with_pmu, bool with_= alias) } =20 ret =3D TEST_OK; - if (with_pmu ? (evlist->core.nr_entries !=3D 1) : (evlist->core.nr_entrie= s < 1)) { + if (with_pmu ? (evlist__nr_entries(evlist) !=3D 1) + : (evlist__nr_entries(evlist) < 1)) { pr_debug("FAILED %s:%d Unexpected number of events for '%s' of %d\n", - __FILE__, __LINE__, str, evlist->core.nr_entries); + __FILE__, __LINE__, str, evlist__nr_entries(evlist)); ret =3D TEST_FAIL; goto out; } diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-track= ing.c index 51cfd6522867..b760041bed30 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -37,8 +37,8 @@ static int find_comm(struct evlist *evlist, const char *c= omm) int i, found; =20 found =3D 0; - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { - md =3D &evlist->mmap[i]; + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { + md =3D &evlist__mmap(evlist)[i]; if (perf_mmap__read_init(&md->core) < 0) continue; while ((event =3D perf_mmap__read_event(&md->core)) !=3D NULL) { @@ -87,7 +87,7 @@ static int test__keep_tracking(struct test_suite *test __= maybe_unused, int subte evlist =3D evlist__new(); CHECK_NOT_NULL__(evlist); =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); =20 CHECK__(parse_event(evlist, "dummy:u")); CHECK__(parse_event(evlist, "cpu-cycles:u")); @@ -106,7 +106,7 @@ static int test__keep_tracking(struct test_suite *test = __maybe_unused, int subte goto out_err; } =20 - CHECK__(evlist__mmap(evlist, UINT_MAX)); + CHECK__(evlist__do_mmap(evlist, UINT_MAX)); =20 /* * First, test that a 'comm' event can be found when the event is diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 5ff58eb2af8d..5cec7644952c 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -81,7 +81,7 @@ static int test__basic_mmap(struct test_suite *test __may= be_unused, int subtest goto out_free_cpus; } =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); =20 for (i =3D 0; i < nsyscalls; ++i) { char name[64]; @@ -113,7 +113,7 @@ static int test__basic_mmap(struct test_suite *test __m= aybe_unused, int subtest expected_nr_events[i] =3D 1 + rand() % 127; } =20 - if (evlist__mmap(evlist, 128) < 0) { + if (evlist__do_mmap(evlist, 128) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); goto out_put_evlist; @@ -124,7 +124,7 @@ static int test__basic_mmap(struct test_suite *test __m= aybe_unused, int subtest syscalls[i](); } =20 - md =3D &evlist->mmap[0]; + md =3D &evlist__mmap(evlist)[0]; if (perf_mmap__read_init(&md->core) < 0) goto out_init; =20 diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests= /openat-syscall-tp-fields.c index b30f286fb421..5365889d326f 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -64,7 +64,7 @@ static int test__syscall_openat_tp_fields(struct test_sui= te *test __maybe_unused =20 evsel__config(evsel, &opts, NULL); =20 - perf_thread_map__set_pid(evlist->core.threads, 0, getpid()); + perf_thread_map__set_pid(evlist__core(evlist)->threads, 0, getpid()); =20 err =3D evlist__open(evlist); if (err < 0) { @@ -73,7 +73,7 @@ static int test__syscall_openat_tp_fields(struct test_sui= te *test __maybe_unused goto out_put_evlist; } =20 - err =3D evlist__mmap(evlist, UINT_MAX); + err =3D evlist__do_mmap(evlist, UINT_MAX); if (err < 0) { pr_debug("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); @@ -90,11 +90,11 @@ static int test__syscall_openat_tp_fields(struct test_s= uite *test __maybe_unused while (1) { int before =3D nr_events; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { union perf_event *event; struct mmap *md; =20 - md =3D &evlist->mmap[i]; + md =3D &evlist__mmap(evlist)[i]; if (perf_mmap__read_init(&md->core) < 0) continue; =20 diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-event= s.c index 19dc7b7475d2..0ad0273da923 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -109,7 +109,7 @@ static int test__checkevent_tracepoint(struct evlist *e= vlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVLIST("wrong number of groups", 0 =3D=3D evlist__nr_groups(e= vlist), evlist); TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_TRACEPOINT =3D=3D evsel->core.a= ttr.type, evsel); TEST_ASSERT_EVSEL("wrong sample_type", @@ -122,7 +122,7 @@ static int test__checkevent_tracepoint_multi(struct evl= ist *evlist) { struct evsel *evsel; =20 - TEST_ASSERT_EVLIST("wrong number of entries", evlist->core.nr_entries > 1= , evlist); + TEST_ASSERT_EVLIST("wrong number of entries", evlist__nr_entries(evlist) = > 1, evlist); TEST_ASSERT_EVLIST("wrong number of groups", 0 =3D=3D evlist__nr_groups(e= vlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { @@ -144,7 +144,7 @@ static int test__checkevent_raw(struct evlist *evlist) struct evsel *evsel; bool raw_type_match =3D false; =20 - TEST_ASSERT_EVLIST("wrong number of entries", 0 !=3D evlist->core.nr_entr= ies, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 0 !=3D evlist__nr_entries(e= vlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { struct perf_pmu *pmu __maybe_unused =3D NULL; @@ -182,7 +182,7 @@ static int test__checkevent_numeric(struct evlist *evli= st) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type", 1 =3D=3D evsel->core.attr.type, evsel); TEST_ASSERT_EVSEL("wrong config", 1 =3D=3D evsel->core.attr.config, evsel= ); return TEST_OK; @@ -193,7 +193,7 @@ static int test__checkevent_symbolic_name(struct evlist= *evlist) { struct evsel *evsel; =20 - TEST_ASSERT_EVLIST("wrong number of entries", 0 !=3D evlist->core.nr_entr= ies, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 0 !=3D evlist__nr_entries(e= vlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_EVSEL("unexpected event", @@ -207,7 +207,7 @@ static int test__checkevent_symbolic_name_config(struct= evlist *evlist) { struct evsel *evsel; =20 - TEST_ASSERT_EVLIST("wrong number of entries", 0 !=3D evlist->core.nr_entr= ies, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 0 !=3D evlist__nr_entries(e= vlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_EVSEL("unexpected event", @@ -228,7 +228,7 @@ static int test__checkevent_symbolic_alias(struct evlis= t *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type/config", evsel__match(evsel, SOFTWARE, SW_P= AGE_FAULTS), evsel); return TEST_OK; @@ -238,7 +238,7 @@ static int test__checkevent_genhw(struct evlist *evlist) { struct evsel *evsel; =20 - TEST_ASSERT_EVLIST("wrong number of entries", 0 !=3D evlist->core.nr_entr= ies, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 0 !=3D evlist__nr_entries(e= vlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_HW_CACHE =3D=3D evsel->core.at= tr.type, evsel); @@ -251,7 +251,7 @@ static int test__checkevent_breakpoint(struct evlist *e= vlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_BREAKPOINT =3D=3D evsel->core.a= ttr.type, evsel); TEST_ASSERT_EVSEL("wrong config", 0 =3D=3D evsel->core.attr.config, evsel= ); TEST_ASSERT_EVSEL("wrong bp_type", @@ -265,7 +265,7 @@ static int test__checkevent_breakpoint_x(struct evlist = *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_BREAKPOINT =3D=3D evsel->core.a= ttr.type, evsel); TEST_ASSERT_EVSEL("wrong config", 0 =3D=3D evsel->core.attr.config, evsel= ); TEST_ASSERT_EVSEL("wrong bp_type", HW_BREAKPOINT_X =3D=3D evsel->core.att= r.bp_type, evsel); @@ -278,7 +278,7 @@ static int test__checkevent_breakpoint_r(struct evlist = *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_BREAKPOINT =3D=3D evsel->core.a= ttr.type, evsel); TEST_ASSERT_EVSEL("wrong config", 0 =3D=3D evsel->core.attr.config, evsel= ); TEST_ASSERT_EVSEL("wrong bp_type", HW_BREAKPOINT_R =3D=3D evsel->core.att= r.bp_type, evsel); @@ -290,7 +290,7 @@ static int test__checkevent_breakpoint_w(struct evlist = *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_BREAKPOINT =3D=3D evsel->core.a= ttr.type, evsel); TEST_ASSERT_EVSEL("wrong config", 0 =3D=3D evsel->core.attr.config, evsel= ); TEST_ASSERT_EVSEL("wrong bp_type", HW_BREAKPOINT_W =3D=3D evsel->core.att= r.bp_type, evsel); @@ -302,7 +302,7 @@ static int test__checkevent_breakpoint_rw(struct evlist= *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_BREAKPOINT =3D=3D evsel->core.a= ttr.type, evsel); TEST_ASSERT_EVSEL("wrong config", 0 =3D=3D evsel->core.attr.config, evsel= ); TEST_ASSERT_EVSEL("wrong bp_type", @@ -316,7 +316,7 @@ static int test__checkevent_tracepoint_modifier(struct = evlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong exclude_user", evsel->core.attr.exclude_user, ev= sel); TEST_ASSERT_EVSEL("wrong exclude_kernel", !evsel->core.attr.exclude_kerne= l, evsel); TEST_ASSERT_EVSEL("wrong exclude_hv", evsel->core.attr.exclude_hv, evsel); @@ -330,7 +330,7 @@ test__checkevent_tracepoint_multi_modifier(struct evlis= t *evlist) { struct evsel *evsel; =20 - TEST_ASSERT_EVLIST("wrong number of entries", evlist->core.nr_entries > 1= , evlist); + TEST_ASSERT_EVLIST("wrong number of entries", evlist__nr_entries(evlist) = > 1, evlist); =20 evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_EVSEL("wrong exclude_user", !evsel->core.attr.exclude_user, = evsel); @@ -346,7 +346,7 @@ static int test__checkevent_raw_modifier(struct evlist = *evlist) { struct evsel *evsel; =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_EVSEL("wrong exclude_user", evsel->core.attr.exclude_user, e= vsel); @@ -361,7 +361,7 @@ static int test__checkevent_numeric_modifier(struct evl= ist *evlist) { struct evsel *evsel; =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_EVSEL("wrong exclude_user", evsel->core.attr.exclude_user, e= vsel); @@ -377,7 +377,7 @@ static int test__checkevent_symbolic_name_modifier(stru= ct evlist *evlist) struct evsel *evsel; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { @@ -394,7 +394,7 @@ static int test__checkevent_exclude_host_modifier(struc= t evlist *evlist) struct evsel *evsel; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { @@ -409,7 +409,7 @@ static int test__checkevent_exclude_guest_modifier(stru= ct evlist *evlist) struct evsel *evsel; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { @@ -423,7 +423,8 @@ static int test__checkevent_symbolic_alias_modifier(str= uct evlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", + 1 =3D=3D evlist__nr_entries(evlist), evlist); TEST_ASSERT_EVSEL("wrong exclude_user", !evsel->core.attr.exclude_user, e= vsel); TEST_ASSERT_EVSEL("wrong exclude_kernel", evsel->core.attr.exclude_kernel= , evsel); TEST_ASSERT_EVSEL("wrong exclude_hv", evsel->core.attr.exclude_hv, evsel); @@ -437,7 +438,7 @@ static int test__checkevent_genhw_modifier(struct evlis= t *evlist) struct evsel *evsel; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { @@ -454,7 +455,7 @@ static int test__checkevent_exclude_idle_modifier(struc= t evlist *evlist) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); =20 TEST_ASSERT_EVSEL("wrong exclude idle", evsel->core.attr.exclude_idle, ev= sel); @@ -473,7 +474,7 @@ static int test__checkevent_exclude_idle_modifier_1(str= uct evlist *evlist) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); =20 TEST_ASSERT_EVSEL("wrong exclude idle", evsel->core.attr.exclude_idle, ev= sel); @@ -622,7 +623,7 @@ static int test__checkevent_breakpoint_2_events(struct = evlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVSEL("wrong number of entries", 2 =3D=3D evlist->core.nr_ent= ries, evsel); + TEST_ASSERT_EVSEL("wrong number of entries", 2 =3D=3D evlist__nr_entries(= evlist), evsel); =20 TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_BREAKPOINT =3D=3D evsel->core.a= ttr.type, evsel); TEST_ASSERT_EVSEL("wrong name", evsel__name_is(evsel, "breakpoint1"), evs= el); @@ -641,7 +642,7 @@ static int test__checkevent_pmu(struct evlist *evlist) struct evsel *evsel =3D evlist__first(evlist); struct perf_pmu *core_pmu =3D perf_pmus__find_core_pmu(); =20 - TEST_ASSERT_EVSEL("wrong number of entries", 1 =3D=3D evlist->core.nr_ent= ries, evsel); + TEST_ASSERT_EVSEL("wrong number of entries", 1 =3D=3D evlist__nr_entries(= evlist), evsel); TEST_ASSERT_EVSEL("wrong type", core_pmu->type =3D=3D evsel->core.attr.ty= pe, evsel); TEST_ASSERT_EVSEL("wrong config", test_hw_config(evsel, 10), evsel); TEST_ASSERT_EVSEL("wrong config1", 1 =3D=3D evsel->core.attr.config1, = evsel); @@ -661,7 +662,7 @@ static int test__checkevent_list(struct evlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVSEL("wrong number of entries", 3 <=3D evlist->core.nr_entri= es, evsel); + TEST_ASSERT_EVSEL("wrong number of entries", 3 <=3D evlist__nr_entries(ev= list), evsel); =20 /* r1 */ TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_TRACEPOINT !=3D evsel->core.att= r.type, evsel); @@ -707,14 +708,15 @@ static int test__checkevent_pmu_name(struct evlist *e= vlist) char buf[256]; =20 /* default_core/config=3D1,name=3Dkrava/u */ - TEST_ASSERT_EVLIST("wrong number of entries", 2 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", + 2 =3D=3D evlist__nr_entries(evlist), evlist); TEST_ASSERT_EVSEL("wrong type", core_pmu->type =3D=3D evsel->core.attr.ty= pe, evsel); TEST_ASSERT_EVSEL("wrong config", 1 =3D=3D evsel->core.attr.config, evsel= ); TEST_ASSERT_EVSEL("wrong name", evsel__name_is(evsel, "krava"), evsel); =20 /* default_core/config=3D2/u" */ evsel =3D evsel__next(evsel); - TEST_ASSERT_EVSEL("wrong number of entries", 2 =3D=3D evlist->core.nr_ent= ries, evsel); + TEST_ASSERT_EVSEL("wrong number of entries", 2 =3D=3D evlist__nr_entries(= evlist), evsel); TEST_ASSERT_EVSEL("wrong type", core_pmu->type =3D=3D evsel->core.attr.ty= pe, evsel); TEST_ASSERT_EVSEL("wrong config", 2 =3D=3D evsel->core.attr.config, evsel= ); snprintf(buf, sizeof(buf), "%s/config=3D2/u", core_pmu->name); @@ -729,7 +731,8 @@ static int test__checkevent_pmu_partial_time_callgraph(= struct evlist *evlist) struct perf_pmu *core_pmu =3D perf_pmus__find_core_pmu(); =20 /* default_core/config=3D1,call-graph=3Dfp,time,period=3D100000/ */ - TEST_ASSERT_EVLIST("wrong number of entries", 2 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", + 2 =3D=3D evlist__nr_entries(evlist), evlist); TEST_ASSERT_EVSEL("wrong type", core_pmu->type =3D=3D evsel->core.attr.ty= pe, evsel); TEST_ASSERT_EVSEL("wrong config", 1 =3D=3D evsel->core.attr.config, evsel= ); /* @@ -760,7 +763,7 @@ static int test__checkevent_pmu_events(struct evlist *e= vlist) struct evsel *evsel; struct perf_pmu *core_pmu =3D perf_pmus__find_core_pmu(); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 <=3D evlist->core.nr_entr= ies, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 <=3D evlist__nr_entries(e= vlist), evlist); =20 evlist__for_each_entry(evlist, evsel) { TEST_ASSERT_EVSEL("wrong type", @@ -787,8 +790,9 @@ static int test__checkevent_pmu_events_mix(struct evlis= t *evlist) * The wild card event will be opened at least once, but it may be * opened on each core PMU. */ - TEST_ASSERT_EVLIST("wrong number of entries", evlist->core.nr_entries >= =3D 2, evlist); - for (int i =3D 0; i < evlist->core.nr_entries - 1; i++) { + TEST_ASSERT_EVLIST("wrong number of entries", + evlist__nr_entries(evlist) >=3D 2, evlist); + for (int i =3D 0; i < evlist__nr_entries(evlist) - 1; i++) { evsel =3D (i =3D=3D 0 ? evlist__first(evlist) : evsel__next(evsel)); /* pmu-event:u */ TEST_ASSERT_EVSEL("wrong exclude_user", !evsel->core.attr.exclude_user, = evsel); @@ -905,7 +909,7 @@ static int test__group1(struct evlist *evlist) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (num_core_entries(evlist) * 2), + evlist__nr_entries(evlist) =3D=3D (num_core_entries(evlist) * 2), evlist); TEST_ASSERT_EVLIST("wrong number of groups", evlist__nr_groups(evlist) =3D=3D num_core_entries(evlist), @@ -950,7 +954,7 @@ static int test__group2(struct evlist *evlist) struct evsel *evsel, *leader =3D NULL; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (2 * num_core_entries(evlist) + 1), + evlist__nr_entries(evlist) =3D=3D (2 * num_core_entries(evlist) + 1), evlist); /* * TODO: Currently the software event won't be grouped with the hardware @@ -1018,7 +1022,7 @@ static int test__group3(struct evlist *evlist __maybe= _unused) struct evsel *evsel, *group1_leader =3D NULL, *group2_leader =3D NULL; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (3 * perf_pmus__num_core_pmus() + 2), + evlist__nr_entries(evlist) =3D=3D (3 * perf_pmus__num_core_pmus() + = 2), evlist); /* * Currently the software event won't be grouped with the hardware event @@ -1144,7 +1148,7 @@ static int test__group4(struct evlist *evlist __maybe= _unused) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (num_core_entries(evlist) * 2), + evlist__nr_entries(evlist) =3D=3D (num_core_entries(evlist) * 2), evlist); TEST_ASSERT_EVLIST("wrong number of groups", num_core_entries(evlist) =3D=3D evlist__nr_groups(evlist), @@ -1191,7 +1195,7 @@ static int test__group5(struct evlist *evlist __maybe= _unused) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (5 * num_core_entries(evlist)), + evlist__nr_entries(evlist) =3D=3D (5 * num_core_entries(evlist)), evlist); TEST_ASSERT_EVLIST("wrong number of groups", evlist__nr_groups(evlist) =3D=3D (2 * num_core_entries(evlist)), @@ -1284,7 +1288,7 @@ static int test__group_gh1(struct evlist *evlist) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (2 * num_core_entries(evlist)), + evlist__nr_entries(evlist) =3D=3D (2 * num_core_entries(evlist)), evlist); TEST_ASSERT_EVLIST("wrong number of groups", evlist__nr_groups(evlist) =3D=3D num_core_entries(evlist), @@ -1329,7 +1333,7 @@ static int test__group_gh2(struct evlist *evlist) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (2 * num_core_entries(evlist)), + evlist__nr_entries(evlist) =3D=3D (2 * num_core_entries(evlist)), evlist); TEST_ASSERT_EVLIST("wrong number of groups", evlist__nr_groups(evlist) =3D=3D num_core_entries(evlist), @@ -1374,7 +1378,7 @@ static int test__group_gh3(struct evlist *evlist) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (2 * num_core_entries(evlist)), + evlist__nr_entries(evlist) =3D=3D (2 * num_core_entries(evlist)), evlist); TEST_ASSERT_EVLIST("wrong number of groups", evlist__nr_groups(evlist) =3D=3D num_core_entries(evlist), @@ -1419,7 +1423,7 @@ static int test__group_gh4(struct evlist *evlist) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (2 * num_core_entries(evlist)), + evlist__nr_entries(evlist) =3D=3D (2 * num_core_entries(evlist)), evlist); TEST_ASSERT_EVLIST("wrong number of groups", evlist__nr_groups(evlist) =3D=3D num_core_entries(evlist), @@ -1464,7 +1468,7 @@ static int test__leader_sample1(struct evlist *evlist) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (3 * num_core_entries(evlist)), + evlist__nr_entries(evlist) =3D=3D (3 * num_core_entries(evlist)), evlist); =20 for (int i =3D 0; i < num_core_entries(evlist); i++) { @@ -1520,7 +1524,7 @@ static int test__leader_sample2(struct evlist *evlist= __maybe_unused) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (2 * num_core_entries(evlist)), + evlist__nr_entries(evlist) =3D=3D (2 * num_core_entries(evlist)), evlist); =20 for (int i =3D 0; i < num_core_entries(evlist); i++) { @@ -1562,7 +1566,7 @@ static int test__checkevent_pinned_modifier(struct ev= list *evlist) struct evsel *evsel =3D NULL; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); =20 for (int i =3D 0; i < num_core_entries(evlist); i++) { @@ -1581,7 +1585,7 @@ static int test__pinned_group(struct evlist *evlist) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D (3 * num_core_entries(evlist)), + evlist__nr_entries(evlist) =3D=3D (3 * num_core_entries(evlist)), evlist); =20 for (int i =3D 0; i < num_core_entries(evlist); i++) { @@ -1618,7 +1622,7 @@ static int test__checkevent_exclusive_modifier(struct= evlist *evlist) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); TEST_ASSERT_EVSEL("wrong exclude_user", !evsel->core.attr.exclude_user, e= vsel); TEST_ASSERT_EVSEL("wrong exclude_kernel", evsel->core.attr.exclude_kernel= , evsel); @@ -1634,7 +1638,7 @@ static int test__exclusive_group(struct evlist *evlis= t) struct evsel *evsel =3D NULL, *leader; =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D 3 * num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D 3 * num_core_entries(evlist), evlist); =20 for (int i =3D 0; i < num_core_entries(evlist); i++) { @@ -1669,7 +1673,7 @@ static int test__checkevent_breakpoint_len(struct evl= ist *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_BREAKPOINT =3D=3D evsel->core.a= ttr.type, evsel); TEST_ASSERT_EVSEL("wrong config", 0 =3D=3D evsel->core.attr.config, evsel= ); TEST_ASSERT_EVSEL("wrong bp_type", @@ -1684,7 +1688,7 @@ static int test__checkevent_breakpoint_len_w(struct e= vlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_BREAKPOINT =3D=3D evsel->core.a= ttr.type, evsel); TEST_ASSERT_EVSEL("wrong config", 0 =3D=3D evsel->core.attr.config, evsel= ); TEST_ASSERT_EVSEL("wrong bp_type", HW_BREAKPOINT_W =3D=3D evsel->core.att= r.bp_type, evsel); @@ -1698,7 +1702,7 @@ test__checkevent_breakpoint_len_rw_modifier(struct ev= list *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong exclude_user", !evsel->core.attr.exclude_user, e= vsel); TEST_ASSERT_EVSEL("wrong exclude_kernel", evsel->core.attr.exclude_kernel= , evsel); TEST_ASSERT_EVSEL("wrong exclude_hv", evsel->core.attr.exclude_hv, evsel); @@ -1712,7 +1716,7 @@ static int test__checkevent_precise_max_modifier(stru= ct evlist *evlist) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D 1 + num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D 1 + num_core_entries(evlist), evlist); TEST_ASSERT_EVSEL("wrong type/config", evsel__match(evsel, SOFTWARE, SW_T= ASK_CLOCK), evsel); return TEST_OK; @@ -1723,7 +1727,7 @@ static int test__checkevent_config_symbol(struct evli= st *evlist) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); TEST_ASSERT_EVSEL("wrong name setting", evsel__name_is(evsel, "insn"), ev= sel); return TEST_OK; @@ -1733,7 +1737,7 @@ static int test__checkevent_config_raw(struct evlist = *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong name setting", evsel__name_is(evsel, "rawpmu"), = evsel); return TEST_OK; } @@ -1742,7 +1746,7 @@ static int test__checkevent_config_num(struct evlist = *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong name setting", evsel__name_is(evsel, "numpmu"), = evsel); return TEST_OK; } @@ -1752,7 +1756,7 @@ static int test__checkevent_config_cache(struct evlis= t *evlist) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); TEST_ASSERT_EVSEL("wrong name setting", evsel__name_is(evsel, "cachepmu")= , evsel); return test__checkevent_genhw(evlist); @@ -1777,7 +1781,7 @@ static int test__intel_pt(struct evlist *evlist) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong name setting", evsel__name_is(evsel, "intel_pt//= u"), evsel); return TEST_OK; } @@ -1798,7 +1802,8 @@ static int test__ratio_to_prev(struct evlist *evlist) { struct evsel *evsel, *leader; =20 - TEST_ASSERT_VAL("wrong number of entries", 2 * perf_pmus__num_core_pmus()= =3D=3D evlist->core.nr_entries); + TEST_ASSERT_VAL("wrong number of entries", + 2 * perf_pmus__num_core_pmus() =3D=3D evlist__nr_entries(evlist)); =20 evlist__for_each_entry(evlist, evsel) { if (evsel !=3D evsel__leader(evsel) || @@ -1842,7 +1847,7 @@ static int test__checkevent_complex_name(struct evlis= t *evlist) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); TEST_ASSERT_EVSEL("wrong complex name parsing", evsel__name_is(evsel, @@ -1855,7 +1860,7 @@ static int test__checkevent_raw_pmu(struct evlist *ev= list) { struct evsel *evsel =3D evlist__first(evlist); =20 - TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist->core.nr_en= tries, evlist); + TEST_ASSERT_EVLIST("wrong number of entries", 1 =3D=3D evlist__nr_entries= (evlist), evlist); TEST_ASSERT_EVSEL("wrong type", PERF_TYPE_SOFTWARE =3D=3D evsel->core.att= r.type, evsel); TEST_ASSERT_EVSEL("wrong config", 0x1a =3D=3D evsel->core.attr.config, ev= sel); return TEST_OK; @@ -1866,7 +1871,7 @@ static int test__sym_event_slash(struct evlist *evlis= t) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); TEST_ASSERT_EVSEL("unexpected event", evsel__match(evsel, HARDWARE, HW_CP= U_CYCLES), evsel); TEST_ASSERT_EVSEL("wrong exclude_kernel", evsel->core.attr.exclude_kernel= , evsel); @@ -1878,7 +1883,7 @@ static int test__sym_event_dc(struct evlist *evlist) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); TEST_ASSERT_EVSEL("unexpected event", evsel__match(evsel, HARDWARE, HW_CP= U_CYCLES), evsel); TEST_ASSERT_EVSEL("wrong exclude_user", evsel->core.attr.exclude_user, ev= sel); @@ -1890,7 +1895,7 @@ static int test__term_equal_term(struct evlist *evlis= t) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); TEST_ASSERT_EVSEL("unexpected event", evsel__match(evsel, HARDWARE, HW_CP= U_CYCLES), evsel); TEST_ASSERT_EVSEL("wrong name setting", strcmp(evsel->name, "name") =3D= =3D 0, evsel); @@ -1902,7 +1907,7 @@ static int test__term_equal_legacy(struct evlist *evl= ist) struct evsel *evsel =3D evlist__first(evlist); =20 TEST_ASSERT_EVLIST("wrong number of entries", - evlist->core.nr_entries =3D=3D num_core_entries(evlist), + evlist__nr_entries(evlist) =3D=3D num_core_entries(evlist), evlist); TEST_ASSERT_EVSEL("unexpected event", evsel__match(evsel, HARDWARE, HW_CP= U_CYCLES), evsel); TEST_ASSERT_EVSEL("wrong name setting", strcmp(evsel->name, "l1d") =3D=3D= 0, evsel); @@ -1958,7 +1963,7 @@ static int count_tracepoints(void) static int test__all_tracepoints(struct evlist *evlist) { TEST_ASSERT_VAL("wrong events count", - count_tracepoints() =3D=3D evlist->core.nr_entries); + count_tracepoints() =3D=3D evlist__nr_entries(evlist)); =20 return test__checkevent_tracepoint_multi(evlist); } diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metri= c.c index 3f0ec839c056..8f9211eaf341 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -53,7 +53,7 @@ static double compute_single(struct evlist *evlist, const= char *name) struct evsel *evsel; =20 evlist__for_each_entry(evlist, evsel) { - me =3D metricgroup__lookup(&evlist->metric_events, evsel, false); + me =3D metricgroup__lookup(evlist__metric_events(evlist), evsel, false); if (me !=3D NULL) { list_for_each_entry (mexp, &me->head, nd) { if (strcmp(mexp->metric_name, name)) @@ -88,7 +88,7 @@ static int __compute_metric(const char *name, struct valu= e *vals, return -ENOMEM; } =20 - perf_evlist__set_maps(&evlist->core, cpus, NULL); + perf_evlist__set_maps(evlist__core(evlist), cpus, NULL); =20 /* Parse the metric into metric_events list. */ pme_test =3D find_core_metrics_table("testarch", "testcpu"); diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index f95752b2ed1c..0bd418e1cdc6 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -129,7 +129,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest evsel__set_sample_bit(evsel, TIME); evlist__config(evlist, &opts, NULL); =20 - err =3D sched__get_first_possible_cpu(evlist->workload.pid, cpu_mask); + err =3D sched__get_first_possible_cpu(evlist__workload_pid(evlist), cpu_m= ask); if (err < 0) { pr_debug("sched__get_first_possible_cpu: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); @@ -142,7 +142,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest /* * So that we can check perf_sample.cpu on all the samples. */ - if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, cpu_mask) < 0)= { + if (sched_setaffinity(evlist__workload_pid(evlist), cpu_mask_size, cpu_ma= sk) < 0) { pr_debug("sched_setaffinity: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); evlist__cancel_workload(evlist); @@ -166,7 +166,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest * fds in the same CPU to be injected in the same mmap ring buffer * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)). */ - err =3D evlist__mmap(evlist, opts.mmap_pages); + err =3D evlist__do_mmap(evlist, opts.mmap_pages); if (err < 0) { pr_debug("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); @@ -188,11 +188,11 @@ static int test__PERF_RECORD(struct test_suite *test = __maybe_unused, int subtest while (1) { int before =3D total_events; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { union perf_event *event; struct mmap *md; =20 - md =3D &evlist->mmap[i]; + md =3D &evlist__mmap(evlist)[i]; if (perf_mmap__read_init(&md->core) < 0) continue; =20 @@ -231,15 +231,15 @@ static int test__PERF_RECORD(struct test_suite *test = __maybe_unused, int subtest ++errs; } =20 - if ((pid_t)sample.pid !=3D evlist->workload.pid) { + if ((pid_t)sample.pid !=3D evlist__workload_pid(evlist)) { pr_debug("%s with unexpected pid, expected %d, got %d\n", - name, evlist->workload.pid, sample.pid); + name, evlist__workload_pid(evlist), sample.pid); ++errs; } =20 - if ((pid_t)sample.tid !=3D evlist->workload.pid) { + if ((pid_t)sample.tid !=3D evlist__workload_pid(evlist)) { pr_debug("%s with unexpected tid, expected %d, got %d\n", - name, evlist->workload.pid, sample.tid); + name, evlist__workload_pid(evlist), sample.tid); ++errs; } =20 @@ -248,7 +248,7 @@ static int test__PERF_RECORD(struct test_suite *test __= maybe_unused, int subtest type =3D=3D PERF_RECORD_MMAP2 || type =3D=3D PERF_RECORD_FORK || type =3D=3D PERF_RECORD_EXIT) && - (pid_t)event->comm.pid !=3D evlist->workload.pid) { + (pid_t)event->comm.pid !=3D evlist__workload_pid(evlist)) { pr_debug("%s with unexpected pid/tid\n", name); ++errs; } diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-ti= me-to-tsc.c index d3538fa20af3..f8f71fdd32b1 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -99,7 +99,7 @@ static int test__perf_time_to_tsc(struct test_suite *test= __maybe_unused, int su evlist =3D evlist__new(); CHECK_NOT_NULL__(evlist); =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); =20 CHECK__(parse_event(evlist, "cpu-cycles:u")); =20 @@ -121,9 +121,9 @@ static int test__perf_time_to_tsc(struct test_suite *te= st __maybe_unused, int su goto out_err; } =20 - CHECK__(evlist__mmap(evlist, UINT_MAX)); + CHECK__(evlist__do_mmap(evlist, UINT_MAX)); =20 - pc =3D evlist->mmap[0].core.base; + pc =3D evlist__mmap(evlist)[0].core.base; ret =3D perf_read_tsc_conversion(pc, &tc); if (ret) { if (ret =3D=3D -EOPNOTSUPP) { @@ -145,8 +145,8 @@ static int test__perf_time_to_tsc(struct test_suite *te= st __maybe_unused, int su =20 evlist__disable(evlist); =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { - md =3D &evlist->mmap[i]; + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { + md =3D &evlist__mmap(evlist)[i]; if (perf_mmap__read_init(&md->core) < 0) continue; =20 diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c index 8d19b1bfecbc..f7bf55be5e6e 100644 --- a/tools/perf/tests/pfm.c +++ b/tools/perf/tests/pfm.c @@ -69,12 +69,12 @@ static int test__pfm_events(struct test_suite *test __m= aybe_unused, if (evlist =3D=3D NULL) return -ENOMEM; =20 - opt.value =3D evlist; + opt.value =3D &evlist; parse_libpfm_events_option(&opt, table[i].events, 0); TEST_ASSERT_EQUAL(table[i].events, - count_pfm_events(&evlist->core), + count_pfm_events(evlist__core(evlist)), table[i].nr_events); TEST_ASSERT_EQUAL(table[i].events, evlist__nr_groups(evlist), @@ -154,12 +154,12 @@ static int test__pfm_group(struct test_suite *test __= maybe_unused, if (evlist =3D=3D NULL) return -ENOMEM; =20 - opt.value =3D evlist; + opt.value =3D &evlist; parse_libpfm_events_option(&opt, table[i].events, 0); TEST_ASSERT_EQUAL(table[i].events, - count_pfm_events(&evlist->core), + count_pfm_events(evlist__core(evlist)), table[i].nr_events); TEST_ASSERT_EQUAL(table[i].events, evlist__nr_groups(evlist), diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 327025505970..3a9d42eded45 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -869,7 +869,7 @@ static int test__parsing_callback(const struct pmu_metr= ic *pm, return -ENOMEM; } =20 - perf_evlist__set_maps(&evlist->core, cpus, NULL); + perf_evlist__set_maps(evlist__core(evlist), cpus, NULL); =20 err =3D metricgroup__parse_groups_test(evlist, table, pm->metric_name); if (err) { @@ -895,7 +895,8 @@ static int test__parsing_callback(const struct pmu_metr= ic *pm, k++; } evlist__for_each_entry(evlist, evsel) { - struct metric_event *me =3D metricgroup__lookup(&evlist->metric_events, = evsel, false); + struct metric_event *me =3D metricgroup__lookup(evlist__metric_events(ev= list), + evsel, false); =20 if (me !=3D NULL) { struct metric_expr *mexp; diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-pa= rsing.c index 55f0b73ca20e..5db85f996cd8 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -205,15 +205,11 @@ static bool samples_same(struct perf_sample *s1, =20 static int do_test(u64 sample_type, u64 sample_regs, u64 read_format) { - struct evsel evsel =3D { - .needs_swap =3D false, - .core =3D { - . attr =3D { - .sample_type =3D sample_type, - .read_format =3D read_format, - }, - }, + struct perf_event_attr attr =3D{ + .sample_type =3D sample_type, + .read_format =3D read_format, }; + struct evsel *evsel; union perf_event *event; union { struct ip_callchain callchain; @@ -287,16 +283,21 @@ static int do_test(u64 sample_type, u64 sample_regs, = u64 read_format) size_t i, sz, bufsz; int err, ret =3D -1; =20 + evsel =3D evsel__new(&attr); + if (!evsel) { + pr_debug("evsel__new failed\n"); + return -1; + } perf_sample__init(&sample_out, /*all=3D*/false); perf_sample__init(&sample_out_endian, /*all=3D*/false); if (sample_type & PERF_SAMPLE_REGS_USER) - evsel.core.attr.sample_regs_user =3D sample_regs; + evsel->core.attr.sample_regs_user =3D sample_regs; =20 if (sample_type & PERF_SAMPLE_REGS_INTR) - evsel.core.attr.sample_regs_intr =3D sample_regs; + evsel->core.attr.sample_regs_intr =3D sample_regs; =20 if (sample_type & PERF_SAMPLE_BRANCH_STACK) - evsel.core.attr.branch_sample_type |=3D PERF_SAMPLE_BRANCH_HW_INDEX; + evsel->core.attr.branch_sample_type |=3D PERF_SAMPLE_BRANCH_HW_INDEX; =20 for (i =3D 0; i < sizeof(regs); i++) *(i + (u8 *)regs) =3D i & 0xfe; @@ -311,7 +312,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u6= 4 read_format) } =20 sz =3D perf_event__sample_event_size(&sample, sample_type, read_format, - evsel.core.attr.branch_sample_type); + evsel->core.attr.branch_sample_type); bufsz =3D sz + 4096; /* Add a bit for overrun checking */ event =3D malloc(bufsz); if (!event) { @@ -325,7 +326,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u6= 4 read_format) event->header.size =3D sz; =20 err =3D perf_event__synthesize_sample(event, sample_type, read_format, - evsel.core.attr.branch_sample_type, &sample); + evsel->core.attr.branch_sample_type, &sample); if (err) { pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", "perf_event__synthesize_sample", sample_type, err); @@ -343,32 +344,32 @@ static int do_test(u64 sample_type, u64 sample_regs, = u64 read_format) goto out_free; } =20 - evsel.sample_size =3D __evsel__sample_size(sample_type); + evsel->sample_size =3D __evsel__sample_size(sample_type); =20 - err =3D evsel__parse_sample(&evsel, event, &sample_out); + err =3D evsel__parse_sample(evsel, event, &sample_out); if (err) { pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", "evsel__parse_sample", sample_type, err); goto out_free; } =20 - if (!samples_same(&sample, &sample_out, sample_type, read_format, evsel.n= eeds_swap)) { + if (!samples_same(&sample, &sample_out, sample_type, read_format, evsel->= needs_swap)) { pr_debug("parsing failed for sample_type %#"PRIx64"\n", sample_type); goto out_free; } =20 if (sample_type =3D=3D PERF_SAMPLE_BRANCH_STACK) { - evsel.needs_swap =3D true; - evsel.sample_size =3D __evsel__sample_size(sample_type); - err =3D evsel__parse_sample(&evsel, event, &sample_out_endian); + evsel->needs_swap =3D true; + evsel->sample_size =3D __evsel__sample_size(sample_type); + err =3D evsel__parse_sample(evsel, event, &sample_out_endian); if (err) { pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", "evsel__parse_sample", sample_type, err); goto out_free; } =20 - if (!samples_same(&sample, &sample_out_endian, sample_type, read_format,= evsel.needs_swap)) { + if (!samples_same(&sample, &sample_out_endian, sample_type, read_format,= evsel->needs_swap)) { pr_debug("parsing failed for sample_type %#"PRIx64"\n", sample_type); goto out_free; @@ -380,6 +381,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u6= 4 read_format) free(event); perf_sample__exit(&sample_out_endian); perf_sample__exit(&sample_out); + evsel__put(evsel); if (ret && read_format) pr_debug("read_format %#"PRIx64"\n", read_format); return ret; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index bb6b62cf51d1..d18185881635 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -71,7 +71,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_i= d) goto out_put_evlist; } =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); =20 if (evlist__open(evlist)) { const char *knob =3D "/proc/sys/kernel/perf_event_max_sample_rate"; @@ -83,7 +83,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_i= d) goto out_put_evlist; } =20 - err =3D evlist__mmap(evlist, 128); + err =3D evlist__do_mmap(evlist, 128); if (err < 0) { pr_debug("failed to mmap event: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); @@ -98,7 +98,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_i= d) =20 evlist__disable(evlist); =20 - md =3D &evlist->mmap[0]; + md =3D &evlist__mmap(evlist)[0]; if (perf_mmap__read_init(&md->core) < 0) goto out_init; =20 diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-t= racking.c index abd08d60179c..2edc471aa5f7 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -282,8 +282,8 @@ static int process_events(struct evlist *evlist, struct mmap *md; int i, ret; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { - md =3D &evlist->mmap[i]; + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { + md =3D &evlist__mmap(evlist)[i]; if (perf_mmap__read_init(&md->core) < 0) continue; =20 @@ -374,7 +374,7 @@ static int test__switch_tracking(struct test_suite *tes= t __maybe_unused, int sub goto out_err; } =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); =20 /* First event */ err =3D parse_event(evlist, "cpu-clock:u"); @@ -471,7 +471,7 @@ static int test__switch_tracking(struct test_suite *tes= t __maybe_unused, int sub goto out; } =20 - err =3D evlist__mmap(evlist, UINT_MAX); + err =3D evlist__do_mmap(evlist, UINT_MAX); if (err) { pr_debug("evlist__mmap failed!\n"); goto out_err; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index a46650b10689..95393edbfe36 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -77,7 +77,7 @@ static int test__task_exit(struct test_suite *test __mayb= e_unused, int subtest _ goto out_put_evlist; } =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); =20 err =3D evlist__prepare_workload(evlist, &target, argv, false, workload_e= xec_failed_signal); if (err < 0) { @@ -104,7 +104,7 @@ static int test__task_exit(struct test_suite *test __ma= ybe_unused, int subtest _ goto out_put_evlist; } =20 - if (evlist__mmap(evlist, 128) < 0) { + if (evlist__do_mmap(evlist, 128) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, str_error_r(errno, sbuf, sizeof(sbuf))); err =3D -1; @@ -114,7 +114,7 @@ static int test__task_exit(struct test_suite *test __ma= ybe_unused, int subtest _ evlist__start_workload(evlist); =20 retry: - md =3D &evlist->mmap[0]; + md =3D &evlist__mmap(evlist)[0]; if (perf_mmap__read_init(&md->core) < 0) goto out_init; =20 diff --git a/tools/perf/tests/time-utils-test.c b/tools/perf/tests/time-uti= ls-test.c index 38df10373c1e..90a9a4b4f178 100644 --- a/tools/perf/tests/time-utils-test.c +++ b/tools/perf/tests/time-utils-test.c @@ -69,16 +69,19 @@ struct test_data { =20 static bool test__perf_time__parse_for_ranges(struct test_data *d) { - struct evlist evlist =3D { - .first_sample_time =3D d->first, - .last_sample_time =3D d->last, - }; - struct perf_session session =3D { .evlist =3D &evlist }; + struct evlist *evlist =3D evlist__new(); + struct perf_session session =3D { .evlist =3D evlist }; struct perf_time_interval *ptime =3D NULL; int range_size, range_num; bool pass =3D false; int i, err; =20 + if (!evlist) { + pr_debug("Missing evlist\n"); + return false; + } + evlist__set_first_sample_time(evlist, d->first); + evlist__set_last_sample_time(evlist, d->last); pr_debug("\nperf_time__parse_for_ranges(\"%s\")\n", d->str); =20 if (strchr(d->str, '%')) @@ -127,6 +130,7 @@ static bool test__perf_time__parse_for_ranges(struct te= st_data *d) =20 pass =3D true; out: + evlist__put(evlist); free(ptime); return pass; } diff --git a/tools/perf/tests/tool_pmu.c b/tools/perf/tests/tool_pmu.c index e78ff9dcea97..c6c5ebf0e935 100644 --- a/tools/perf/tests/tool_pmu.c +++ b/tools/perf/tests/tool_pmu.c @@ -40,9 +40,10 @@ static int do_test(enum tool_pmu_event ev, bool with_pmu) } =20 ret =3D TEST_OK; - if (with_pmu ? (evlist->core.nr_entries !=3D 1) : (evlist->core.nr_entrie= s < 1)) { + if (with_pmu ? (evlist__nr_entries(evlist) !=3D 1) + : (evlist__nr_entries(evlist) < 1)) { pr_debug("FAILED %s:%d Unexpected number of events for '%s' of %d\n", - __FILE__, __LINE__, str, evlist->core.nr_entries); + __FILE__, __LINE__, str, evlist__nr_entries(evlist)); ret =3D TEST_FAIL; goto out; } diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 4ecf5d750313..b3ca73b2d8fc 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -45,7 +45,7 @@ static int session_write_header(char *path) =20 session->evlist =3D evlist__new_default(&target, /*sample_callchains=3D*/= false); TEST_ASSERT_VAL("can't get evlist", session->evlist); - session->evlist->session =3D session; + evlist__set_session(session->evlist, session); =20 perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY); perf_header__set_feat(&session->header, HEADER_NRCPUS); diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/ann= otate.c index ea17e6d29a7e..99f143a52b5f 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -594,7 +594,7 @@ static bool annotate_browser__callq(struct annotate_bro= wser *browser, notes =3D symbol__annotation(dl->ops.target.sym); annotation__lock(notes); =20 - if (!symbol__hists(dl->ops.target.sym, evsel->evlist->core.nr_entries)) { + if (!symbol__hists(dl->ops.target.sym, evlist__nr_entries(evsel->evlist))= ) { annotation__unlock(notes); ui__warning("Not enough memory for annotating '%s' symbol!\n", dl->ops.target.sym->name); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index cfa6386e6e1d..da7cc195b9f4 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -688,10 +688,10 @@ static int hist_browser__handle_hotkey(struct hist_br= owser *browser, bool warn_l ui_browser__update_nr_entries(&browser->b, nr_entries); =20 if (warn_lost_event && - (evsel->evlist->stats.nr_lost_warned !=3D - evsel->evlist->stats.nr_events[PERF_RECORD_LOST])) { - evsel->evlist->stats.nr_lost_warned =3D - evsel->evlist->stats.nr_events[PERF_RECORD_LOST]; + (evlist__stats(evsel->evlist)->nr_lost_warned !=3D + evlist__stats(evsel->evlist)->nr_events[PERF_RECORD_LOST])) { + evlist__stats(evsel->evlist)->nr_lost_warned =3D + evlist__stats(evsel->evlist)->nr_events[PERF_RECORD_LOST]; ui_browser__warn_lost_events(&browser->b); } =20 @@ -3321,7 +3321,7 @@ static int evsel__hists_browse(struct evsel *evsel, i= nt nr_events, const char *h * No need to refresh, resort/decay histogram * entries if we are not collecting samples: */ - if (top->evlist->enabled) { + if (evlist__enabled(top->evlist)) { helpline =3D "Press 'f' to disable the events or 'h' to see other hot= keys"; hbt->refresh =3D delay_secs; } else { @@ -3493,7 +3493,7 @@ static void perf_evsel_menu__write(struct ui_browser = *browser, unit, unit =3D=3D ' ' ? "" : " ", ev_name); ui_browser__printf(browser, "%s", bf); =20 - nr_events =3D evsel->evlist->stats.nr_events[PERF_RECORD_LOST]; + nr_events =3D evlist__stats(evsel->evlist)->nr_events[PERF_RECORD_LOST]; if (nr_events !=3D 0) { menu->lost_events =3D true; if (!current_entry) @@ -3559,13 +3559,13 @@ static int perf_evsel_menu__run(struct evsel_menu *= menu, ui_browser__show_title(&menu->b, title); switch (key) { case K_TAB: - if (pos->core.node.next =3D=3D &evlist->core.entries) + if (pos->core.node.next =3D=3D &evlist__core(evlist)->entries) pos =3D evlist__first(evlist); else pos =3D evsel__next(pos); goto browse_hists; case K_UNTAB: - if (pos->core.node.prev =3D=3D &evlist->core.entries) + if (pos->core.node.prev =3D=3D &evlist__core(evlist)->entries) pos =3D evlist__last(evlist); else pos =3D evsel__prev(pos); @@ -3618,7 +3618,7 @@ static int __evlist__tui_browse_hists(struct evlist *= evlist, int nr_entries, con struct evsel *pos; struct evsel_menu menu =3D { .b =3D { - .entries =3D &evlist->core.entries, + .entries =3D &evlist__core(evlist)->entries, .refresh =3D ui_browser__list_head_refresh, .seek =3D ui_browser__list_head_seek, .write =3D perf_evsel_menu__write, @@ -3646,7 +3646,7 @@ static int __evlist__tui_browse_hists(struct evlist *= evlist, int nr_entries, con =20 static bool evlist__single_entry(struct evlist *evlist) { - int nr_entries =3D evlist->core.nr_entries; + int nr_entries =3D evlist__nr_entries(evlist); =20 if (nr_entries =3D=3D 1) return true; @@ -3664,7 +3664,7 @@ static bool evlist__single_entry(struct evlist *evlis= t) int evlist__tui_browse_hists(struct evlist *evlist, const char *help, stru= ct hist_browser_timer *hbt, float min_pcnt, struct perf_env *env, bool warn_lost_event) { - int nr_entries =3D evlist->core.nr_entries; + int nr_entries =3D evlist__nr_entries(evlist); =20 if (evlist__single_entry(evlist)) { single_entry: { diff --git a/tools/perf/util/amd-sample-raw.c b/tools/perf/util/amd-sample-= raw.c index b084dee76b1a..c64584b0f794 100644 --- a/tools/perf/util/amd-sample-raw.c +++ b/tools/perf/util/amd-sample-raw.c @@ -354,7 +354,7 @@ static void parse_cpuid(struct perf_env *env) */ bool evlist__has_amd_ibs(struct evlist *evlist) { - struct perf_env *env =3D perf_session__env(evlist->session); + struct perf_env *env =3D perf_session__env(evlist__session(evlist)); int ret, nr_pmu_mappings =3D perf_env__nr_pmu_mappings(env); const char *pmu_mapping =3D perf_env__pmu_mappings(env); char name[sizeof("ibs_fetch")]; diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 63e3c54fab42..4e4c58764082 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -1829,7 +1829,7 @@ int annotated_data_type__update_samples(struct annota= ted_data_type *adt, return 0; =20 if (adt->histograms =3D=3D NULL) { - int nr =3D evsel->evlist->core.nr_entries; + int nr =3D evlist__nr_entries(evsel->evlist); =20 if (alloc_data_type_histograms(adt, nr) < 0) return -1; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 470569745abe..7d424e43137a 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -327,7 +327,7 @@ static int symbol__inc_addr_samples(struct map_symbol *= ms, =20 if (sym =3D=3D NULL) return 0; - src =3D symbol__hists(sym, sample->evsel->evlist->core.nr_entries); + src =3D symbol__hists(sym, evlist__nr_entries(sample->evsel->evlist)); return src ? __symbol__inc_addr_samples(ms, src, addr, sample) : 0; } =20 @@ -338,7 +338,7 @@ static int symbol__account_br_cntr(struct annotated_bra= nch *branch, { unsigned int br_cntr_nr =3D evsel__leader(evsel)->br_cntr_nr; unsigned int base =3D evsel__leader(evsel)->br_cntr_idx; - unsigned int off =3D offset * evsel->evlist->nr_br_cntr; + unsigned int off =3D offset * evlist__nr_br_cntr(evsel->evlist); u64 *branch_br_cntr =3D branch->br_cntr; unsigned int i, mask, width; =20 @@ -368,7 +368,7 @@ static int symbol__account_cycles(u64 addr, u64 start, = struct symbol *sym, =20 if (sym =3D=3D NULL) return 0; - branch =3D symbol__find_branch_hist(sym, evsel->evlist->nr_br_cntr); + branch =3D symbol__find_branch_hist(sym, evlist__nr_br_cntr(evsel->evlist= )); if (!branch) return -ENOMEM; if (addr < sym->start || addr >=3D sym->end) @@ -510,7 +510,7 @@ static void annotation__count_and_fill(struct annotatio= n *notes, u64 start, u64 static int annotation__compute_ipc(struct annotation *notes, size_t size, struct evsel *evsel) { - unsigned int br_cntr_nr =3D evsel->evlist->nr_br_cntr; + unsigned int br_cntr_nr =3D evlist__nr_br_cntr(evsel->evlist); int err =3D 0; s64 offset; =20 @@ -1812,7 +1812,7 @@ int annotation_br_cntr_abbr_list(char **str, struct e= vsel *evsel, bool header) struct evsel *pos; struct strbuf sb; =20 - if (evsel->evlist->nr_br_cntr <=3D 0) + if (evlist__nr_br_cntr(evsel->evlist) <=3D 0) return -ENOTSUP; =20 strbuf_init(&sb, /*hint=3D*/ 0); diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index a224687ffbc1..4d9dfbde7f78 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -191,7 +191,7 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mmap= _params *mp, struct evlist *evlist, struct evsel *evsel, int idx) { - bool per_cpu =3D !perf_cpu_map__has_any_cpu(evlist->core.user_requested_c= pus); + bool per_cpu =3D !perf_cpu_map__has_any_cpu(evlist__core(evlist)->user_re= quested_cpus); =20 mp->mmap_needed =3D evsel->needs_auxtrace_mmap; =20 @@ -201,11 +201,11 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mm= ap_params *mp, mp->idx =3D idx; =20 if (per_cpu) { - mp->cpu =3D perf_cpu_map__cpu(evlist->core.all_cpus, idx); - mp->tid =3D perf_thread_map__pid(evlist->core.threads, 0); + mp->cpu =3D perf_cpu_map__cpu(evlist__core(evlist)->all_cpus, idx); + mp->tid =3D perf_thread_map__pid(evlist__core(evlist)->threads, 0); } else { mp->cpu.cpu =3D -1; - mp->tid =3D perf_thread_map__pid(evlist->core.threads, idx); + mp->tid =3D perf_thread_map__pid(evlist__core(evlist)->threads, idx); } } =20 @@ -667,10 +667,10 @@ int auxtrace_parse_snapshot_options(struct auxtrace_r= ecord *itr, =20 static int evlist__enable_event_idx(struct evlist *evlist, struct evsel *e= vsel, int idx) { - bool per_cpu_mmaps =3D !perf_cpu_map__has_any_cpu(evlist->core.user_reque= sted_cpus); + bool per_cpu_mmaps =3D !perf_cpu_map__has_any_cpu(evlist__core(evlist)->u= ser_requested_cpus); =20 if (per_cpu_mmaps) { - struct perf_cpu evlist_cpu =3D perf_cpu_map__cpu(evlist->core.all_cpus, = idx); + struct perf_cpu evlist_cpu =3D perf_cpu_map__cpu(evlist__core(evlist)->a= ll_cpus, idx); int cpu_map_idx =3D perf_cpu_map__idx(evsel->core.cpus, evlist_cpu); =20 if (cpu_map_idx =3D=3D -1) @@ -1806,7 +1806,7 @@ void perf_session__auxtrace_error_inc(struct perf_ses= sion *session, struct perf_record_auxtrace_error *e =3D &event->auxtrace_error; =20 if (e->type < PERF_AUXTRACE_ERROR_MAX) - session->evlist->stats.nr_auxtrace_errors[e->type] +=3D 1; + evlist__stats(session->evlist)->nr_auxtrace_errors[e->type] +=3D 1; } =20 void events_stats__auxtrace_error_warn(const struct events_stats *stats) diff --git a/tools/perf/util/block-info.c b/tools/perf/util/block-info.c index 8d3a9a661f26..1135e54f4c7f 100644 --- a/tools/perf/util/block-info.c +++ b/tools/perf/util/block-info.c @@ -472,7 +472,7 @@ struct block_report *block_info__create_report(struct e= vlist *evlist, int *nr_reps) { struct block_report *block_reports; - int nr_hists =3D evlist->core.nr_entries, i =3D 0; + int nr_hists =3D evlist__nr_entries(evlist), i =3D 0; struct evsel *pos; =20 block_reports =3D calloc(nr_hists, sizeof(struct block_report)); @@ -483,7 +483,7 @@ struct block_report *block_info__create_report(struct e= vlist *evlist, struct hists *hists =3D evsel__hists(pos); =20 process_block_report(hists, &block_reports[i], total_cycles, - block_hpps, nr_hpps, evlist->nr_br_cntr); + block_hpps, nr_hpps, evlist__nr_br_cntr(evlist)); i++; } =20 diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c index 34b6b0da18b7..9362e45e17ce 100644 --- a/tools/perf/util/bpf_counter.c +++ b/tools/perf/util/bpf_counter.c @@ -443,7 +443,7 @@ static int bperf_check_target(struct evsel *evsel, } else if (target->tid) { *filter_type =3D BPERF_FILTER_PID; *filter_entry_cnt =3D perf_thread_map__nr(evsel->core.threads); - } else if (target->pid || evsel->evlist->workload.pid !=3D -1) { + } else if (target->pid || evlist__workload_pid(evsel->evlist) !=3D -1) { *filter_type =3D BPERF_FILTER_TGID; *filter_entry_cnt =3D perf_thread_map__nr(evsel->core.threads); } else { diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_cou= nter_cgroup.c index 339df94ef438..27bb1a41ae4f 100644 --- a/tools/perf/util/bpf_counter_cgroup.c +++ b/tools/perf/util/bpf_counter_cgroup.c @@ -111,7 +111,7 @@ static int bperf_load_program(struct evlist *evlist) pr_err("Failed to open cgroup skeleton\n"); return -1; } - setup_rodata(skel, evlist->core.nr_entries); + setup_rodata(skel, evlist__nr_entries(evlist)); =20 err =3D bperf_cgroup_bpf__load(skel); if (err) { @@ -122,12 +122,12 @@ static int bperf_load_program(struct evlist *evlist) err =3D -1; =20 cgrp_switch =3D evsel__new(&cgrp_switch_attr); - if (evsel__open_per_cpu(cgrp_switch, evlist->core.all_cpus, -1) < 0) { + if (evsel__open_per_cpu(cgrp_switch, evlist__core(evlist)->all_cpus, -1) = < 0) { pr_err("Failed to open cgroup switches event\n"); goto out; } =20 - perf_cpu_map__for_each_cpu(cpu, i, evlist->core.all_cpus) { + perf_cpu_map__for_each_cpu(cpu, i, evlist__core(evlist)->all_cpus) { link =3D bpf_program__attach_perf_event(skel->progs.on_cgrp_switch, FD(cgrp_switch, i)); if (IS_ERR(link)) { @@ -238,7 +238,7 @@ static int bperf_cgrp__sync_counters(struct evlist *evl= ist) unsigned int idx; int prog_fd =3D bpf_program__fd(skel->progs.trigger_read); =20 - perf_cpu_map__for_each_cpu(cpu, idx, evlist->core.all_cpus) + perf_cpu_map__for_each_cpu(cpu, idx, evlist__core(evlist)->all_cpus) bperf_trigger_reading(prog_fd, cpu.cpu); =20 return 0; diff --git a/tools/perf/util/bpf_ftrace.c b/tools/perf/util/bpf_ftrace.c index c456d24efa30..abeafd406e8e 100644 --- a/tools/perf/util/bpf_ftrace.c +++ b/tools/perf/util/bpf_ftrace.c @@ -59,13 +59,13 @@ int perf_ftrace__latency_prepare_bpf(struct perf_ftrace= *ftrace) =20 /* don't need to set cpu filter for system-wide mode */ if (ftrace->target.cpu_list) { - ncpus =3D perf_cpu_map__nr(ftrace->evlist->core.user_requested_cpus); + ncpus =3D perf_cpu_map__nr(evlist__core(ftrace->evlist)->user_requested_= cpus); bpf_map__set_max_entries(skel->maps.cpu_filter, ncpus); skel->rodata->has_cpu =3D 1; } =20 if (target__has_task(&ftrace->target) || target__none(&ftrace->target)) { - ntasks =3D perf_thread_map__nr(ftrace->evlist->core.threads); + ntasks =3D perf_thread_map__nr(evlist__core(ftrace->evlist)->threads); bpf_map__set_max_entries(skel->maps.task_filter, ntasks); skel->rodata->has_task =3D 1; } @@ -87,7 +87,8 @@ int perf_ftrace__latency_prepare_bpf(struct perf_ftrace *= ftrace) fd =3D bpf_map__fd(skel->maps.cpu_filter); =20 for (i =3D 0; i < ncpus; i++) { - cpu =3D perf_cpu_map__cpu(ftrace->evlist->core.user_requested_cpus, i).= cpu; + cpu =3D perf_cpu_map__cpu( + evlist__core(ftrace->evlist)->user_requested_cpus, i).cpu; bpf_map_update_elem(fd, &cpu, &val, BPF_ANY); } } @@ -99,7 +100,7 @@ int perf_ftrace__latency_prepare_bpf(struct perf_ftrace = *ftrace) fd =3D bpf_map__fd(skel->maps.task_filter); =20 for (i =3D 0; i < ntasks; i++) { - pid =3D perf_thread_map__pid(ftrace->evlist->core.threads, i); + pid =3D perf_thread_map__pid(evlist__core(ftrace->evlist)->threads, i); bpf_map_update_elem(fd, &pid, &val, BPF_ANY); } } diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lo= ck_contention.c index cbd7435579fe..85727d154d9c 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -222,11 +222,11 @@ int lock_contention_prepare(struct lock_contention *c= on) =20 if (target__has_cpu(target)) { skel->rodata->has_cpu =3D 1; - ncpus =3D perf_cpu_map__nr(evlist->core.user_requested_cpus); + ncpus =3D perf_cpu_map__nr(evlist__core(evlist)->user_requested_cpus); } if (target__has_task(target)) { skel->rodata->has_task =3D 1; - ntasks =3D perf_thread_map__nr(evlist->core.threads); + ntasks =3D perf_thread_map__nr(evlist__core(evlist)->threads); } if (con->filters->nr_types) { skel->rodata->has_type =3D 1; @@ -327,7 +327,7 @@ int lock_contention_prepare(struct lock_contention *con) fd =3D bpf_map__fd(skel->maps.cpu_filter); =20 for (i =3D 0; i < ncpus; i++) { - cpu =3D perf_cpu_map__cpu(evlist->core.user_requested_cpus, i).cpu; + cpu =3D perf_cpu_map__cpu(evlist__core(evlist)->user_requested_cpus, i)= .cpu; bpf_map_update_elem(fd, &cpu, &val, BPF_ANY); } } @@ -339,13 +339,13 @@ int lock_contention_prepare(struct lock_contention *c= on) fd =3D bpf_map__fd(skel->maps.task_filter); =20 for (i =3D 0; i < ntasks; i++) { - pid =3D perf_thread_map__pid(evlist->core.threads, i); + pid =3D perf_thread_map__pid(evlist__core(evlist)->threads, i); bpf_map_update_elem(fd, &pid, &val, BPF_ANY); } } =20 - if (target__none(target) && evlist->workload.pid > 0) { - u32 pid =3D evlist->workload.pid; + if (target__none(target) && evlist__workload_pid(evlist) > 0) { + u32 pid =3D evlist__workload_pid(evlist); u8 val =3D 1; =20 fd =3D bpf_map__fd(skel->maps.task_filter); diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c index 48cb930cdd2e..c4639f6a5776 100644 --- a/tools/perf/util/bpf_off_cpu.c +++ b/tools/perf/util/bpf_off_cpu.c @@ -73,13 +73,13 @@ static void off_cpu_start(void *arg) =20 /* update task filter for the given workload */ if (skel->rodata->has_task && skel->rodata->uses_tgid && - perf_thread_map__pid(evlist->core.threads, 0) !=3D -1) { + perf_thread_map__pid(evlist__core(evlist)->threads, 0) !=3D -1) { int fd; u32 pid; u8 val =3D 1; =20 fd =3D bpf_map__fd(skel->maps.task_filter); - pid =3D perf_thread_map__pid(evlist->core.threads, 0); + pid =3D perf_thread_map__pid(evlist__core(evlist)->threads, 0); bpf_map_update_elem(fd, &pid, &val, BPF_ANY); } =20 @@ -168,7 +168,7 @@ int off_cpu_prepare(struct evlist *evlist, struct targe= t *target, =20 /* don't need to set cpu filter for system-wide mode */ if (target->cpu_list) { - ncpus =3D perf_cpu_map__nr(evlist->core.user_requested_cpus); + ncpus =3D perf_cpu_map__nr(evlist__core(evlist)->user_requested_cpus); bpf_map__set_max_entries(skel->maps.cpu_filter, ncpus); skel->rodata->has_cpu =3D 1; } @@ -199,7 +199,7 @@ int off_cpu_prepare(struct evlist *evlist, struct targe= t *target, skel->rodata->has_task =3D 1; skel->rodata->uses_tgid =3D 1; } else if (target__has_task(target)) { - ntasks =3D perf_thread_map__nr(evlist->core.threads); + ntasks =3D perf_thread_map__nr(evlist__core(evlist)->threads); bpf_map__set_max_entries(skel->maps.task_filter, ntasks); skel->rodata->has_task =3D 1; } else if (target__none(target)) { @@ -209,7 +209,7 @@ int off_cpu_prepare(struct evlist *evlist, struct targe= t *target, } =20 if (evlist__first(evlist)->cgrp) { - ncgrps =3D evlist->core.nr_entries - 1; /* excluding a dummy */ + ncgrps =3D evlist__nr_entries(evlist) - 1; /* excluding a dummy */ bpf_map__set_max_entries(skel->maps.cgroup_filter, ncgrps); =20 if (!cgroup_is_v2("perf_event")) @@ -240,7 +240,7 @@ int off_cpu_prepare(struct evlist *evlist, struct targe= t *target, fd =3D bpf_map__fd(skel->maps.cpu_filter); =20 for (i =3D 0; i < ncpus; i++) { - cpu =3D perf_cpu_map__cpu(evlist->core.user_requested_cpus, i).cpu; + cpu =3D perf_cpu_map__cpu(evlist__core(evlist)->user_requested_cpus, i)= .cpu; bpf_map_update_elem(fd, &cpu, &val, BPF_ANY); } } @@ -269,7 +269,7 @@ int off_cpu_prepare(struct evlist *evlist, struct targe= t *target, fd =3D bpf_map__fd(skel->maps.task_filter); =20 for (i =3D 0; i < ntasks; i++) { - pid =3D perf_thread_map__pid(evlist->core.threads, i); + pid =3D perf_thread_map__pid(evlist__core(evlist)->threads, i); bpf_map_update_elem(fd, &pid, &val, BPF_ANY); } } diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 914744724467..c7be16a7915e 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -367,7 +367,7 @@ int parse_cgroups(const struct option *opt, const char = *str, char *s; int ret, i; =20 - if (list_empty(&evlist->core.entries)) { + if (list_empty(&evlist__core(evlist)->entries)) { fprintf(stderr, "must define events before cgroups\n"); return -1; } @@ -423,7 +423,7 @@ int evlist__expand_cgroup(struct evlist *evlist, const = char *str, bool open_cgro int ret =3D -1; int prefix_len; =20 - if (evlist->core.nr_entries =3D=3D 0) { + if (evlist__nr_entries(evlist) =3D=3D 0) { fprintf(stderr, "must define events before cgroups\n"); return -EINVAL; } @@ -436,11 +436,11 @@ int evlist__expand_cgroup(struct evlist *evlist, cons= t char *str, bool open_cgro } =20 /* save original events and init evlist */ - evlist__splice_list_tail(orig_list, &evlist->core.entries); - evlist->core.nr_entries =3D 0; + evlist__splice_list_tail(orig_list, &evlist__core(evlist)->entries); + evlist__core(evlist)->nr_entries =3D 0; =20 - orig_metric_events =3D evlist->metric_events; - metricgroup__rblist_init(&evlist->metric_events); + orig_metric_events =3D *evlist__metric_events(evlist); + metricgroup__rblist_init(evlist__metric_events(evlist)); =20 if (has_pattern_string(str)) prefix_len =3D match_cgroups(str); @@ -503,15 +503,15 @@ int evlist__expand_cgroup(struct evlist *evlist, cons= t char *str, bool open_cgro nr_cgroups++; =20 if (metricgroup__copy_metric_events(tmp_list, cgrp, - &evlist->metric_events, + evlist__metric_events(evlist), &orig_metric_events) < 0) goto out_err; =20 - evlist__splice_list_tail(evlist, &tmp_list->core.entries); - tmp_list->core.nr_entries =3D 0; + evlist__splice_list_tail(evlist, &evlist__core(tmp_list)->entries); + evlist__core(tmp_list)->nr_entries =3D 0; } =20 - if (list_empty(&evlist->core.entries)) { + if (list_empty(&evlist__core(evlist)->entries)) { fprintf(stderr, "no cgroup matched: %s\n", str); goto out_err; } diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 6ec48de29441..fff1f38b5061 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1636,8 +1636,10 @@ static int cs_etm__synth_branch_sample(struct cs_etm= _queue *etmq, { int ret =3D 0; struct cs_etm_auxtrace *etm =3D etmq->etm; - struct perf_sample sample =3D {.ip =3D 0,}; + struct perf_sample sample; union perf_event *event =3D tidq->event_buf; + + perf_sample__init(&sample, /*all=3D*/true); struct dummy_branch_stack { u64 nr; u64 hw_idx; @@ -1698,6 +1700,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_= queue *etmq, "CS ETM Trace: failed to deliver instruction event, error %d\n", ret); =20 + perf_sample__exit(&sample); return ret; } =20 diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a362f338f104..82e9a7ade4fc 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -31,6 +31,7 @@ =20 #include #include // page_size +#include #include #include #include @@ -75,30 +76,31 @@ int sigqueue(pid_t pid, int sig, const union sigval val= ue); #define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) #define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y) =20 -static void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, - struct perf_thread_map *threads) -{ - perf_evlist__init(&evlist->core); - perf_evlist__set_maps(&evlist->core, cpus, threads); - evlist->workload.pid =3D -1; - evlist->bkw_mmap_state =3D BKW_MMAP_NOTREADY; - evlist->ctl_fd.fd =3D -1; - evlist->ctl_fd.ack =3D -1; - evlist->ctl_fd.pos =3D -1; - evlist->nr_br_cntr =3D -1; - metricgroup__rblist_init(&evlist->metric_events); - INIT_LIST_HEAD(&evlist->deferred_samples); - refcount_set(&evlist->refcnt, 1); -} +static void event_enable_timer__exit(struct event_enable_timer **ep); =20 struct evlist *evlist__new(void) { - struct evlist *evlist =3D zalloc(sizeof(*evlist)); - - if (evlist !=3D NULL) - evlist__init(evlist, NULL, NULL); - - return evlist; + struct evlist *result; + RC_STRUCT(evlist) *evlist; + + evlist =3D zalloc(sizeof(*evlist)); + if (ADD_RC_CHK(result, evlist)) { + perf_evlist__init(evlist__core(result)); + perf_evlist__set_maps(evlist__core(result), /*cpus=3D*/NULL, /*threads= =3D*/NULL); + evlist__set_workload_pid(result, -1); + evlist__set_bkw_mmap_state(result, BKW_MMAP_NOTREADY); + evlist__set_ctl_fd_fd(result, -1); + evlist__set_ctl_fd_ack(result, -1); + evlist__set_ctl_fd_pos(result, -1); + evlist__set_nr_br_cntr(result, -1); + metricgroup__rblist_init(evlist__metric_events(result)); + INIT_LIST_HEAD(&evlist->deferred_samples); + refcount_set(evlist__refcnt(result), 1); + } else { + free(evlist); + result =3D NULL; + } + return result; } =20 struct evlist *evlist__new_default(const struct target *target, bool sampl= e_callchains) @@ -106,7 +108,6 @@ struct evlist *evlist__new_default(const struct target = *target, bool sample_call struct evlist *evlist =3D evlist__new(); bool can_profile_kernel; struct perf_pmu *pmu =3D NULL; - struct evsel *evsel; char buf[256]; int err; =20 @@ -133,7 +134,9 @@ struct evlist *evlist__new_default(const struct target = *target, bool sample_call } =20 /* If there is only 1 event a sample identifier isn't necessary. */ - if (evlist->core.nr_entries > 1) { + if (evlist__nr_entries(evlist) > 1) { + struct evsel *evsel; + evlist__for_each_entry(evlist, evsel) evsel__set_sample_id(evsel, /*can_sample_identifier=3D*/false); } @@ -158,8 +161,12 @@ struct evlist *evlist__new_dummy(void) =20 struct evlist *evlist__get(struct evlist *evlist) { - refcount_inc(&evlist->refcnt); - return evlist; + struct evlist *result; + + if (RC_CHK_GET(result, evlist)) + refcount_inc(evlist__refcnt(evlist)); + + return result; } =20 /** @@ -173,8 +180,8 @@ void evlist__set_id_pos(struct evlist *evlist) { struct evsel *first =3D evlist__first(evlist); =20 - evlist->id_pos =3D first->id_pos; - evlist->is_pos =3D first->is_pos; + RC_CHK_ACCESS(evlist)->id_pos =3D first->id_pos; + RC_CHK_ACCESS(evlist)->is_pos =3D first->is_pos; } =20 static void evlist__update_id_pos(struct evlist *evlist) @@ -193,52 +200,81 @@ static void evlist__purge(struct evlist *evlist) =20 evlist__for_each_entry_safe(evlist, n, pos) { list_del_init(&pos->core.node); + if (pos->evlist) { + /* Minimal evlist__put. */ + refcount_dec_and_test(evlist__refcnt(pos->evlist)); + RC_CHK_PUT(pos->evlist); + } pos->evlist =3D NULL; evsel__put(pos); } =20 - evlist->core.nr_entries =3D 0; + evlist__core(evlist)->nr_entries =3D 0; } =20 static void evlist__exit(struct evlist *evlist) { - metricgroup__rblist_exit(&evlist->metric_events); - event_enable_timer__exit(&evlist->eet); - zfree(&evlist->mmap); - zfree(&evlist->overwrite_mmap); - perf_evlist__exit(&evlist->core); + metricgroup__rblist_exit(evlist__metric_events(evlist)); + event_enable_timer__exit(&RC_CHK_ACCESS(evlist)->eet); + free(evlist__mmap(evlist)); + free(evlist__overwrite_mmap(evlist)); + perf_evlist__exit(evlist__core(evlist)); } =20 void evlist__put(struct evlist *evlist) { + struct evsel *evsel; + unsigned int count, ref_cnt; + if (evlist =3D=3D NULL) return; =20 - if (!refcount_dec_and_test(&evlist->refcnt)) - return; + if (refcount_dec_and_test(evlist__refcnt(evlist))) + goto out_delete; + +retry: + count =3D refcount_read(evlist__refcnt(evlist)); + ref_cnt =3D count; + evlist__for_each_entry(evlist, evsel) { + if (RC_CHK_EQUAL(evsel->evlist, evlist) && count) + count--; + } + if (refcount_read(evlist__refcnt(evlist)) !=3D ref_cnt) + goto retry; =20 + if (count !=3D 0) { + /* + * Not the last reference except for back references from + * evsels. + */ + RC_CHK_PUT(evlist); + return; + } +out_delete: evlist__free_stats(evlist); - evlist__munmap(evlist); + evlist__do_munmap(evlist); evlist__close(evlist); evlist__purge(evlist); evlist__exit(evlist); - free(evlist); + RC_CHK_FREE(evlist); } =20 void evlist__add(struct evlist *evlist, struct evsel *entry) { - perf_evlist__add(&evlist->core, &entry->core); - entry->evlist =3D evlist; + perf_evlist__add(evlist__core(evlist), &entry->core); + evlist__put(entry->evlist); + entry->evlist =3D evlist__get(evlist); entry->tracking =3D !entry->core.idx; =20 - if (evlist->core.nr_entries =3D=3D 1) + if (evlist__nr_entries(evlist) =3D=3D 1) evlist__set_id_pos(evlist); } =20 void evlist__remove(struct evlist *evlist, struct evsel *evsel) { + perf_evlist__remove(evlist__core(evlist), &evsel->core); + evlist__put(evsel->evlist); evsel->evlist =3D NULL; - perf_evlist__remove(&evlist->core, &evsel->core); } =20 void evlist__splice_list_tail(struct evlist *evlist, struct list_head *lis= t) @@ -287,7 +323,7 @@ int __evlist__set_tracepoints_handlers(struct evlist *e= vlist, =20 static void evlist__set_leader(struct evlist *evlist) { - perf_evlist__set_leader(&evlist->core); + perf_evlist__set_leader(evlist__core(evlist)); } =20 static struct evsel *evlist__dummy_event(struct evlist *evlist) @@ -301,7 +337,7 @@ static struct evsel *evlist__dummy_event(struct evlist = *evlist) .sample_period =3D 1, }; =20 - return evsel__new_idx(&attr, evlist->core.nr_entries); + return evsel__new_idx(&attr, evlist__nr_entries(evlist)); } =20 int evlist__add_dummy(struct evlist *evlist) @@ -390,8 +426,8 @@ static bool evlist__use_affinity(struct evlist *evlist) struct perf_cpu_map *used_cpus =3D NULL; bool ret =3D false; =20 - if (evlist->no_affinity || !evlist->core.user_requested_cpus || - cpu_map__is_dummy(evlist->core.user_requested_cpus)) + if (evlist__no_affinity(evlist) || !evlist__core(evlist)->user_requested_= cpus || + cpu_map__is_dummy(evlist__core(evlist)->user_requested_cpus)) return false; =20 evlist__for_each_entry(evlist, pos) { @@ -446,7 +482,7 @@ void evlist_cpu_iterator__init(struct evlist_cpu_iterat= or *itr, struct evlist *e .evsel =3D NULL, .cpu_map_idx =3D 0, .evlist_cpu_map_idx =3D 0, - .evlist_cpu_map_nr =3D perf_cpu_map__nr(evlist->core.all_cpus), + .evlist_cpu_map_nr =3D perf_cpu_map__nr(evlist__core(evlist)->all_cpus), .cpu =3D (struct perf_cpu){ .cpu =3D -1}, .affinity =3D NULL, }; @@ -462,7 +498,7 @@ void evlist_cpu_iterator__init(struct evlist_cpu_iterat= or *itr, struct evlist *e itr->affinity =3D &itr->saved_affinity; } itr->evsel =3D evlist__first(evlist); - itr->cpu =3D perf_cpu_map__cpu(evlist->core.all_cpus, 0); + itr->cpu =3D perf_cpu_map__cpu(evlist__core(evlist)->all_cpus, 0); if (itr->affinity) affinity__set(itr->affinity, itr->cpu.cpu); itr->cpu_map_idx =3D perf_cpu_map__idx(itr->evsel->core.cpus, itr->cpu); @@ -497,7 +533,7 @@ void evlist_cpu_iterator__next(struct evlist_cpu_iterat= or *evlist_cpu_itr) if (evlist_cpu_itr->evlist_cpu_map_idx < evlist_cpu_itr->evlist_cpu_map_n= r) { evlist_cpu_itr->evsel =3D evlist__first(evlist_cpu_itr->container); evlist_cpu_itr->cpu =3D - perf_cpu_map__cpu(evlist_cpu_itr->container->core.all_cpus, + perf_cpu_map__cpu(evlist__core(evlist_cpu_itr->container)->all_cpus, evlist_cpu_itr->evlist_cpu_map_idx); if (evlist_cpu_itr->affinity) affinity__set(evlist_cpu_itr->affinity, evlist_cpu_itr->cpu.cpu); @@ -524,7 +560,7 @@ static int evsel__strcmp(struct evsel *pos, char *evsel= _name) return !evsel__name_is(pos, evsel_name); } =20 -static int evlist__is_enabled(struct evlist *evlist) +static bool evlist__is_enabled(struct evlist *evlist) { struct evsel *pos; =20 @@ -578,10 +614,7 @@ static void __evlist__disable(struct evlist *evlist, c= har *evsel_name, bool excl * If we disabled only single event, we need to check * the enabled state of the evlist manually. */ - if (evsel_name) - evlist->enabled =3D evlist__is_enabled(evlist); - else - evlist->enabled =3D false; + evlist__set_enabled(evlist, evsel_name ? evlist__is_enabled(evlist) : fal= se); } =20 void evlist__disable(struct evlist *evlist) @@ -629,7 +662,7 @@ static void __evlist__enable(struct evlist *evlist, cha= r *evsel_name, bool excl_ * so the toggle can work properly and toggle to * 'disabled' state. */ - evlist->enabled =3D true; + evlist__set_enabled(evlist, true); } =20 void evlist__enable(struct evlist *evlist) @@ -649,23 +682,24 @@ void evlist__enable_evsel(struct evlist *evlist, char= *evsel_name) =20 void evlist__toggle_enable(struct evlist *evlist) { - (evlist->enabled ? evlist__disable : evlist__enable)(evlist); + (evlist__enabled(evlist) ? evlist__disable : evlist__enable)(evlist); } =20 int evlist__add_pollfd(struct evlist *evlist, int fd) { - return perf_evlist__add_pollfd(&evlist->core, fd, NULL, POLLIN, fdarray_f= lag__default); + return perf_evlist__add_pollfd(evlist__core(evlist), fd, NULL, POLLIN, + fdarray_flag__default); } =20 int evlist__filter_pollfd(struct evlist *evlist, short revents_and_mask) { - return perf_evlist__filter_pollfd(&evlist->core, revents_and_mask); + return perf_evlist__filter_pollfd(evlist__core(evlist), revents_and_mask); } =20 #ifdef HAVE_EVENTFD_SUPPORT int evlist__add_wakeup_eventfd(struct evlist *evlist, int fd) { - return perf_evlist__add_pollfd(&evlist->core, fd, NULL, POLLIN, + return perf_evlist__add_pollfd(evlist__core(evlist), fd, NULL, POLLIN, fdarray_flag__nonfilterable | fdarray_flag__non_perf_event); } @@ -673,7 +707,7 @@ int evlist__add_wakeup_eventfd(struct evlist *evlist, i= nt fd) =20 int evlist__poll(struct evlist *evlist, int timeout) { - return perf_evlist__poll(&evlist->core, timeout); + return perf_evlist__poll(evlist__core(evlist), timeout); } =20 struct perf_sample_id *evlist__id2sid(struct evlist *evlist, u64 id) @@ -683,7 +717,7 @@ struct perf_sample_id *evlist__id2sid(struct evlist *ev= list, u64 id) int hash; =20 hash =3D hash_64(id, PERF_EVLIST__HLIST_BITS); - head =3D &evlist->core.heads[hash]; + head =3D &evlist__core(evlist)->heads[hash]; =20 hlist_for_each_entry(sid, head, node) if (sid->id =3D=3D id) @@ -696,7 +730,7 @@ struct evsel *evlist__id2evsel(struct evlist *evlist, u= 64 id) { struct perf_sample_id *sid; =20 - if (evlist->core.nr_entries =3D=3D 1 || !id) + if (evlist__nr_entries(evlist) =3D=3D 1 || !id) return evlist__first(evlist); =20 sid =3D evlist__id2sid(evlist, id); @@ -731,13 +765,13 @@ static int evlist__event2id(struct evlist *evlist, un= ion perf_event *event, u64 n =3D (event->header.size - sizeof(event->header)) >> 3; =20 if (event->header.type =3D=3D PERF_RECORD_SAMPLE) { - if (evlist->id_pos >=3D n) + if (evlist__id_pos(evlist) >=3D n) return -1; - *id =3D array[evlist->id_pos]; + *id =3D array[evlist__id_pos(evlist)]; } else { - if (evlist->is_pos > n) + if (evlist__is_pos(evlist) > n) return -1; - n -=3D evlist->is_pos; + n -=3D evlist__is_pos(evlist); *id =3D array[n]; } return 0; @@ -751,7 +785,7 @@ struct evsel *evlist__event2evsel(struct evlist *evlist= , union perf_event *event int hash; u64 id; =20 - if (evlist->core.nr_entries =3D=3D 1) + if (evlist__nr_entries(evlist) =3D=3D 1) return first; =20 if (!first->core.attr.sample_id_all && @@ -766,7 +800,7 @@ struct evsel *evlist__event2evsel(struct evlist *evlist= , union perf_event *event return first; =20 hash =3D hash_64(id, PERF_EVLIST__HLIST_BITS); - head =3D &evlist->core.heads[hash]; + head =3D &evlist__core(evlist)->heads[hash]; =20 hlist_for_each_entry(sid, head, node) { if (sid->id =3D=3D id) @@ -779,11 +813,11 @@ static int evlist__set_paused(struct evlist *evlist, = bool value) { int i; =20 - if (!evlist->overwrite_mmap) + if (!evlist__overwrite_mmap(evlist)) return 0; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { - int fd =3D evlist->overwrite_mmap[i].core.fd; + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { + int fd =3D evlist__overwrite_mmap(evlist)[i].core.fd; int err; =20 if (fd < 0) @@ -809,20 +843,20 @@ static void evlist__munmap_nofree(struct evlist *evli= st) { int i; =20 - if (evlist->mmap) - for (i =3D 0; i < evlist->core.nr_mmaps; i++) - perf_mmap__munmap(&evlist->mmap[i].core); + if (evlist__mmap(evlist)) + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) + perf_mmap__munmap(&evlist__mmap(evlist)[i].core); =20 - if (evlist->overwrite_mmap) - for (i =3D 0; i < evlist->core.nr_mmaps; i++) - perf_mmap__munmap(&evlist->overwrite_mmap[i].core); + if (evlist__overwrite_mmap(evlist)) + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) + perf_mmap__munmap(&evlist__overwrite_mmap(evlist)[i].core); } =20 -void evlist__munmap(struct evlist *evlist) +void evlist__do_munmap(struct evlist *evlist) { evlist__munmap_nofree(evlist); - zfree(&evlist->mmap); - zfree(&evlist->overwrite_mmap); + zfree(&RC_CHK_ACCESS(evlist)->mmap); + zfree(&RC_CHK_ACCESS(evlist)->overwrite_mmap); } =20 static void perf_mmap__unmap_cb(struct perf_mmap *map) @@ -836,12 +870,12 @@ static struct mmap *evlist__alloc_mmap(struct evlist = *evlist, bool overwrite) { int i; - struct mmap *map =3D calloc(evlist->core.nr_mmaps, sizeof(struct mmap)); + struct mmap *map =3D calloc(evlist__core(evlist)->nr_mmaps, sizeof(struct= mmap)); =20 if (!map) return NULL; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { struct perf_mmap *prev =3D i ? &map[i - 1].core : NULL; =20 /* @@ -859,41 +893,73 @@ static struct mmap *evlist__alloc_mmap(struct evlist = *evlist, return map; } =20 +static struct evlist *from_list_start(struct perf_evlist *core) +{ +#ifdef REFCNT_CHECKING + RC_STRUCT(evlist) *core_evlist =3D container_of(core, RC_STRUCT(evlist), = core); + struct evlist *evlist; + + if (ADD_RC_CHK(evlist, core_evlist)) + refcount_inc(evlist__refcnt(evlist)); + + return evlist; +#else + return container_of(core, struct evlist, core); +#endif +} + +static void from_list_end(struct evlist *evlist __maybe_unused) +{ +#ifdef REFCNT_CHECKING + evlist__put(evlist); +#endif +} + static void perf_evlist__mmap_cb_idx(struct perf_evlist *_evlist, struct perf_evsel *_evsel, struct perf_mmap_param *_mp, int idx) { - struct evlist *evlist =3D container_of(_evlist, struct evlist, core); + struct evlist *evlist =3D from_list_start(_evlist); struct mmap_params *mp =3D container_of(_mp, struct mmap_params, core); struct evsel *evsel =3D container_of(_evsel, struct evsel, core); =20 + if (!evlist) + return; + auxtrace_mmap_params__set_idx(&mp->auxtrace_mp, evlist, evsel, idx); + + from_list_end(evlist); } =20 static struct perf_mmap* perf_evlist__mmap_cb_get(struct perf_evlist *_evlist, bool overwrite, int = idx) { - struct evlist *evlist =3D container_of(_evlist, struct evlist, core); + struct evlist *evlist =3D from_list_start(_evlist); struct mmap *maps; =20 - maps =3D overwrite ? evlist->overwrite_mmap : evlist->mmap; + if (!evlist) + return NULL; + + maps =3D overwrite ? evlist__overwrite_mmap(evlist) : evlist__mmap(evlist= ); =20 if (!maps) { maps =3D evlist__alloc_mmap(evlist, overwrite); - if (!maps) + if (!maps) { + from_list_end(evlist); return NULL; + } =20 if (overwrite) { - evlist->overwrite_mmap =3D maps; - if (evlist->bkw_mmap_state =3D=3D BKW_MMAP_NOTREADY) + RC_CHK_ACCESS(evlist)->overwrite_mmap =3D maps; + if (evlist__bkw_mmap_state(evlist) =3D=3D BKW_MMAP_NOTREADY) evlist__toggle_bkw_mmap(evlist, BKW_MMAP_RUNNING); } else { - evlist->mmap =3D maps; + RC_CHK_ACCESS(evlist)->mmap =3D maps; } } - + from_list_end(evlist); return &maps[idx].core; } =20 @@ -1050,16 +1116,16 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned= int pages, .mmap =3D perf_evlist__mmap_cb_mmap, }; =20 - evlist->core.mmap_len =3D evlist__mmap_size(pages); - pr_debug("mmap size %zuB\n", evlist->core.mmap_len); + evlist__core(evlist)->mmap_len =3D evlist__mmap_size(pages); + pr_debug("mmap size %zuB\n", evlist__core(evlist)->mmap_len); =20 - auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist->core.mmap_len, + auxtrace_mmap_params__init(&mp.auxtrace_mp, evlist__core(evlist)->mmap_le= n, auxtrace_pages, auxtrace_overwrite); =20 - return perf_evlist__mmap_ops(&evlist->core, &ops, &mp.core); + return perf_evlist__mmap_ops(evlist__core(evlist), &ops, &mp.core); } =20 -int evlist__mmap(struct evlist *evlist, unsigned int pages) +int evlist__do_mmap(struct evlist *evlist, unsigned int pages) { return evlist__mmap_ex(evlist, pages, 0, false, 0, PERF_AFFINITY_SYS, 1, = 0); } @@ -1101,9 +1167,9 @@ int evlist__create_maps(struct evlist *evlist, struct= target *target) if (!cpus) goto out_delete_threads; =20 - evlist->core.has_user_cpus =3D !!target->cpu_list; + evlist__core(evlist)->has_user_cpus =3D !!target->cpu_list; =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); =20 /* as evlist now has references, put count here */ perf_cpu_map__put(cpus); @@ -1243,15 +1309,15 @@ bool evlist__valid_sample_type(struct evlist *evlis= t) { struct evsel *pos; =20 - if (evlist->core.nr_entries =3D=3D 1) + if (evlist__nr_entries(evlist) =3D=3D 1) return true; =20 - if (evlist->id_pos < 0 || evlist->is_pos < 0) + if (evlist__id_pos(evlist) < 0 || evlist__is_pos(evlist) < 0) return false; =20 evlist__for_each_entry(evlist, pos) { - if (pos->id_pos !=3D evlist->id_pos || - pos->is_pos !=3D evlist->is_pos) + if (pos->id_pos !=3D evlist__id_pos(evlist) || + pos->is_pos !=3D evlist__is_pos(evlist)) return false; } =20 @@ -1262,18 +1328,18 @@ u64 __evlist__combined_sample_type(struct evlist *e= vlist) { struct evsel *evsel; =20 - if (evlist->combined_sample_type) - return evlist->combined_sample_type; + if (RC_CHK_ACCESS(evlist)->combined_sample_type) + return RC_CHK_ACCESS(evlist)->combined_sample_type; =20 evlist__for_each_entry(evlist, evsel) - evlist->combined_sample_type |=3D evsel->core.attr.sample_type; + RC_CHK_ACCESS(evlist)->combined_sample_type |=3D evsel->core.attr.sample= _type; =20 - return evlist->combined_sample_type; + return RC_CHK_ACCESS(evlist)->combined_sample_type; } =20 u64 evlist__combined_sample_type(struct evlist *evlist) { - evlist->combined_sample_type =3D 0; + RC_CHK_ACCESS(evlist)->combined_sample_type =3D 0; return __evlist__combined_sample_type(evlist); } =20 @@ -1350,7 +1416,7 @@ void evlist__update_br_cntr(struct evlist *evlist) evlist__new_abbr_name(evsel->abbr_name); } } - evlist->nr_br_cntr =3D i; + evlist__set_nr_br_cntr(evlist, i); } =20 bool evlist__valid_read_format(struct evlist *evlist) @@ -1400,11 +1466,6 @@ bool evlist__sample_id_all(struct evlist *evlist) return first->core.attr.sample_id_all; } =20 -void evlist__set_selected(struct evlist *evlist, struct evsel *evsel) -{ - evlist->selected =3D evsel; -} - void evlist__close(struct evlist *evlist) { struct evsel *evsel; @@ -1421,7 +1482,7 @@ void evlist__close(struct evlist *evlist) perf_evsel__free_fd(&evsel->core); perf_evsel__free_id(&evsel->core); } - perf_evlist__reset_id_hash(&evlist->core); + perf_evlist__reset_id_hash(evlist__core(evlist)); } =20 static int evlist__create_syswide_maps(struct evlist *evlist) @@ -1448,7 +1509,7 @@ static int evlist__create_syswide_maps(struct evlist = *evlist) return -ENOMEM; } =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); perf_thread_map__put(threads); perf_cpu_map__put(cpus); return 0; @@ -1463,7 +1524,8 @@ int evlist__open(struct evlist *evlist) * Default: one fd per CPU, all threads, aka systemwide * as sys_perf_event_open(cpu =3D -1, thread =3D -1) is EINVAL */ - if (evlist->core.threads =3D=3D NULL && evlist->core.user_requested_cpus = =3D=3D NULL) { + if (evlist__core(evlist)->threads =3D=3D NULL && + evlist__core(evlist)->user_requested_cpus =3D=3D NULL) { err =3D evlist__create_syswide_maps(evlist); if (err < 0) goto out_err; @@ -1490,7 +1552,7 @@ int evlist__prepare_workload(struct evlist *evlist, s= truct target *target, const int child_ready_pipe[2], go_pipe[2]; char bf; =20 - evlist->workload.cork_fd =3D -1; + evlist__set_workload_cork_fd(evlist, -1); =20 if (pipe(child_ready_pipe) < 0) { perror("failed to create 'ready' pipe"); @@ -1502,13 +1564,13 @@ int evlist__prepare_workload(struct evlist *evlist,= struct target *target, const goto out_close_ready_pipe; } =20 - evlist->workload.pid =3D fork(); - if (evlist->workload.pid < 0) { + evlist__set_workload_pid(evlist, fork()); + if (evlist__workload_pid(evlist) < 0) { perror("failed to fork"); goto out_close_pipes; } =20 - if (!evlist->workload.pid) { + if (!evlist__workload_pid(evlist)) { int ret; =20 if (pipe_output) @@ -1574,12 +1636,13 @@ int evlist__prepare_workload(struct evlist *evlist,= struct target *target, const } =20 if (target__none(target)) { - if (evlist->core.threads =3D=3D NULL) { + if (evlist__core(evlist)->threads =3D=3D NULL) { fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%= s:%d).\n", __func__, __LINE__); goto out_close_pipes; } - perf_thread_map__set_pid(evlist->core.threads, 0, evlist->workload.pid); + perf_thread_map__set_pid(evlist__core(evlist)->threads, 0, + evlist__workload_pid(evlist)); } =20 close(child_ready_pipe[1]); @@ -1593,7 +1656,7 @@ int evlist__prepare_workload(struct evlist *evlist, s= truct target *target, const } =20 fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC); - evlist->workload.cork_fd =3D go_pipe[1]; + evlist__set_workload_cork_fd(evlist, go_pipe[1]); close(child_ready_pipe[0]); return 0; =20 @@ -1608,18 +1671,18 @@ int evlist__prepare_workload(struct evlist *evlist,= struct target *target, const =20 int evlist__start_workload(struct evlist *evlist) { - if (evlist->workload.cork_fd >=3D 0) { + if (evlist__workload_cork_fd(evlist) >=3D 0) { char bf =3D 0; int ret; /* * Remove the cork, let it rip! */ - ret =3D write(evlist->workload.cork_fd, &bf, 1); + ret =3D write(evlist__workload_cork_fd(evlist), &bf, 1); if (ret < 0) perror("unable to write to pipe"); =20 - close(evlist->workload.cork_fd); - evlist->workload.cork_fd =3D -1; + close(evlist__workload_cork_fd(evlist)); + evlist__set_workload_cork_fd(evlist, -1); return ret; } =20 @@ -1630,10 +1693,10 @@ void evlist__cancel_workload(struct evlist *evlist) { int status; =20 - if (evlist->workload.cork_fd >=3D 0) { - close(evlist->workload.cork_fd); - evlist->workload.cork_fd =3D -1; - waitpid(evlist->workload.pid, &status, WNOHANG); + if (evlist__workload_cork_fd(evlist) >=3D 0) { + close(evlist__workload_cork_fd(evlist)); + evlist__set_workload_cork_fd(evlist, -1); + waitpid(evlist__workload_pid(evlist), &status, WNOHANG); } } =20 @@ -1727,7 +1790,8 @@ int evlist__strerror_open(struct evlist *evlist, int = err, char *buf, size_t size =20 int evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_= t size) { - int pages_attempted =3D evlist->core.mmap_len / 1024, pages_max_per_user,= printed =3D 0; + int pages_attempted =3D evlist__core(evlist)->mmap_len / 1024; + int pages_max_per_user, printed =3D 0; =20 switch (err) { case EPERM: @@ -1770,7 +1834,7 @@ void evlist__to_front(struct evlist *evlist, struct e= vsel *move_evsel) list_move_tail(&evsel->core.node, &move); } =20 - list_splice(&move, &evlist->core.entries); + list_splice(&move, &evlist__core(evlist)->entries); } =20 struct evsel *evlist__get_tracking_event(struct evlist *evlist) @@ -1812,7 +1876,7 @@ struct evsel *evlist__findnew_tracking_event(struct e= vlist *evlist, bool system_ =20 evlist__set_tracking_event(evlist, evsel); } else if (system_wide) { - perf_evlist__go_system_wide(&evlist->core, &evsel->core); + perf_evlist__go_system_wide(evlist__core(evlist), &evsel->core); } =20 return evsel; @@ -1834,14 +1898,14 @@ struct evsel *evlist__find_evsel_by_str(struct evli= st *evlist, const char *str) =20 void evlist__toggle_bkw_mmap(struct evlist *evlist, enum bkw_mmap_state st= ate) { - enum bkw_mmap_state old_state =3D evlist->bkw_mmap_state; + enum bkw_mmap_state old_state =3D evlist__bkw_mmap_state(evlist); enum action { NONE, PAUSE, RESUME, } action =3D NONE; =20 - if (!evlist->overwrite_mmap) + if (!evlist__overwrite_mmap(evlist)) return; =20 switch (old_state) { @@ -1871,7 +1935,7 @@ void evlist__toggle_bkw_mmap(struct evlist *evlist, e= num bkw_mmap_state state) WARN_ONCE(1, "Shouldn't get there\n"); } =20 - evlist->bkw_mmap_state =3D state; + evlist__set_bkw_mmap_state(evlist, state); =20 switch (action) { case PAUSE: @@ -2049,40 +2113,41 @@ int evlist__initialize_ctlfd(struct evlist *evlist,= int fd, int ack) return 0; } =20 - evlist->ctl_fd.pos =3D perf_evlist__add_pollfd(&evlist->core, fd, NULL, P= OLLIN, - fdarray_flag__nonfilterable | - fdarray_flag__non_perf_event); - if (evlist->ctl_fd.pos < 0) { - evlist->ctl_fd.pos =3D -1; + evlist__set_ctl_fd_pos(evlist, + perf_evlist__add_pollfd(evlist__core(evlist), fd, NULL, POLLIN, + fdarray_flag__nonfilterable | + fdarray_flag__non_perf_event)); + if (evlist__ctl_fd_pos(evlist) < 0) { + evlist__set_ctl_fd_pos(evlist, -1); pr_err("Failed to add ctl fd entry: %m\n"); return -1; } =20 - evlist->ctl_fd.fd =3D fd; - evlist->ctl_fd.ack =3D ack; + evlist__set_ctl_fd_fd(evlist, fd); + evlist__set_ctl_fd_ack(evlist, ack); =20 return 0; } =20 bool evlist__ctlfd_initialized(struct evlist *evlist) { - return evlist->ctl_fd.pos >=3D 0; + return evlist__ctl_fd_pos(evlist) >=3D 0; } =20 int evlist__finalize_ctlfd(struct evlist *evlist) { - struct pollfd *entries =3D evlist->core.pollfd.entries; + struct pollfd *entries =3D evlist__core(evlist)->pollfd.entries; =20 if (!evlist__ctlfd_initialized(evlist)) return 0; =20 - entries[evlist->ctl_fd.pos].fd =3D -1; - entries[evlist->ctl_fd.pos].events =3D 0; - entries[evlist->ctl_fd.pos].revents =3D 0; + entries[evlist__ctl_fd_pos(evlist)].fd =3D -1; + entries[evlist__ctl_fd_pos(evlist)].events =3D 0; + entries[evlist__ctl_fd_pos(evlist)].revents =3D 0; =20 - evlist->ctl_fd.pos =3D -1; - evlist->ctl_fd.ack =3D -1; - evlist->ctl_fd.fd =3D -1; + evlist__set_ctl_fd_pos(evlist, -1); + evlist__set_ctl_fd_ack(evlist, -1); + evlist__set_ctl_fd_fd(evlist, -1); =20 return 0; } @@ -2099,7 +2164,7 @@ static int evlist__ctlfd_recv(struct evlist *evlist, = enum evlist_ctl_cmd *cmd, data_size--; =20 do { - err =3D read(evlist->ctl_fd.fd, &c, 1); + err =3D read(evlist__ctl_fd_fd(evlist), &c, 1); if (err > 0) { if (c =3D=3D '\n' || c =3D=3D '\0') break; @@ -2113,7 +2178,8 @@ static int evlist__ctlfd_recv(struct evlist *evlist, = enum evlist_ctl_cmd *cmd, if (errno =3D=3D EAGAIN || errno =3D=3D EWOULDBLOCK) err =3D 0; else - pr_err("Failed to read from ctlfd %d: %m\n", evlist->ctl_fd.fd); + pr_err("Failed to read from ctlfd %d: %m\n", + evlist__ctl_fd_fd(evlist)); } break; } while (1); @@ -2151,13 +2217,13 @@ int evlist__ctlfd_ack(struct evlist *evlist) { int err; =20 - if (evlist->ctl_fd.ack =3D=3D -1) + if (evlist__ctl_fd_ack(evlist) =3D=3D -1) return 0; =20 - err =3D write(evlist->ctl_fd.ack, EVLIST_CTL_CMD_ACK_TAG, + err =3D write(evlist__ctl_fd_ack(evlist), EVLIST_CTL_CMD_ACK_TAG, sizeof(EVLIST_CTL_CMD_ACK_TAG)); if (err =3D=3D -1) - pr_err("failed to write to ctl_ack_fd %d: %m\n", evlist->ctl_fd.ack); + pr_err("failed to write to ctl_ack_fd %d: %m\n", evlist__ctl_fd_ack(evli= st)); =20 return err; } @@ -2258,8 +2324,8 @@ int evlist__ctlfd_process(struct evlist *evlist, enum= evlist_ctl_cmd *cmd) { int err =3D 0; char cmd_data[EVLIST_CTL_CMD_MAX_LEN]; - int ctlfd_pos =3D evlist->ctl_fd.pos; - struct pollfd *entries =3D evlist->core.pollfd.entries; + int ctlfd_pos =3D evlist__ctl_fd_pos(evlist); + struct pollfd *entries =3D evlist__core(evlist)->pollfd.entries; =20 if (!evlist__ctlfd_initialized(evlist) || !entries[ctlfd_pos].revents) return 0; @@ -2430,14 +2496,15 @@ int evlist__parse_event_enable_time(struct evlist *= evlist, struct record_opts *o goto free_eet_times; } =20 - eet->pollfd_pos =3D perf_evlist__add_pollfd(&evlist->core, eet->timerfd, = NULL, POLLIN, flags); + eet->pollfd_pos =3D perf_evlist__add_pollfd(evlist__core(evlist), eet->ti= merfd, + NULL, POLLIN, flags); if (eet->pollfd_pos < 0) { err =3D eet->pollfd_pos; goto close_timerfd; } =20 eet->evlist =3D evlist; - evlist->eet =3D eet; + RC_CHK_ACCESS(evlist)->eet =3D eet; opts->target.initial_delay =3D eet->times[0].start; =20 return 0; @@ -2487,7 +2554,7 @@ int event_enable_timer__process(struct event_enable_t= imer *eet) if (!eet) return 0; =20 - entries =3D eet->evlist->core.pollfd.entries; + entries =3D evlist__core(eet->evlist)->pollfd.entries; revents =3D entries[eet->pollfd_pos].revents; entries[eet->pollfd_pos].revents =3D 0; =20 @@ -2523,7 +2590,7 @@ int event_enable_timer__process(struct event_enable_t= imer *eet) return 0; } =20 -void event_enable_timer__exit(struct event_enable_timer **ep) +static void event_enable_timer__exit(struct event_enable_timer **ep) { if (!ep || !*ep) return; @@ -2627,7 +2694,7 @@ void evlist__warn_user_requested_cpus(struct evlist *= evlist, const char *cpu_lis } =20 /* Should uniquify be disabled for the evlist? */ -static bool evlist__disable_uniquify(const struct evlist *evlist) +static bool evlist__disable_uniquify(struct evlist *evlist) { struct evsel *counter; struct perf_pmu *last_pmu =3D NULL; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index a9820a6aad5b..838e263b76f3 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -14,6 +14,7 @@ #include #include #include +#include #include =20 #include "affinity.h" @@ -59,7 +60,7 @@ enum bkw_mmap_state { =20 struct event_enable_timer; =20 -struct evlist { +DECLARE_RC_STRUCT(evlist) { struct perf_evlist core; refcount_t refcnt; bool enabled; @@ -86,7 +87,7 @@ struct evlist { struct { pthread_t th; volatile int done; - } thread; + } sb_thread; struct { int fd; /* control file descriptor */ int ack; /* ack file descriptor for control commands */ @@ -107,6 +108,227 @@ struct evsel_str_handler { void *handler; }; =20 +static inline struct perf_evlist *evlist__core(struct evlist *evlist) +{ + return &RC_CHK_ACCESS(evlist)->core; +} + +static inline const struct perf_evlist *evlist__const_core(const struct ev= list *evlist) +{ + return &RC_CHK_ACCESS(evlist)->core; +} + +static inline int evlist__nr_entries(const struct evlist *evlist) +{ + return evlist__const_core(evlist)->nr_entries; +} + +static inline bool evlist__enabled(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->enabled; +} + +static inline void evlist__set_enabled(struct evlist *evlist, bool enabled) +{ + RC_CHK_ACCESS(evlist)->enabled =3D enabled; +} + +static inline bool evlist__no_affinity(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->no_affinity; +} + +static inline void evlist__set_no_affinity(struct evlist *evlist, bool no_= affinity) +{ + RC_CHK_ACCESS(evlist)->no_affinity =3D no_affinity; +} + +static inline int evlist__sb_thread_done(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->sb_thread.done; +} + +static inline void evlist__set_sb_thread_done(struct evlist *evlist, int d= one) +{ + RC_CHK_ACCESS(evlist)->sb_thread.done =3D done; +} + +static inline pthread_t *evlist__sb_thread_th(struct evlist *evlist) +{ + return &RC_CHK_ACCESS(evlist)->sb_thread.th; +} + +static inline int evlist__id_pos(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->id_pos; +} + +static inline int evlist__is_pos(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->is_pos; +} + +static inline struct event_enable_timer *evlist__event_enable_timer(struct= evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->eet; +} + +static inline enum bkw_mmap_state evlist__bkw_mmap_state(const struct evli= st *evlist) +{ + return RC_CHK_ACCESS(evlist)->bkw_mmap_state; +} + +static inline void evlist__set_bkw_mmap_state(struct evlist *evlist, enum = bkw_mmap_state state) +{ + RC_CHK_ACCESS(evlist)->bkw_mmap_state =3D state; +} + +static inline struct mmap *evlist__mmap(struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->mmap; +} + +static inline struct mmap *evlist__overwrite_mmap(struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->overwrite_mmap; +} + +static inline struct events_stats *evlist__stats(struct evlist *evlist) +{ + return &RC_CHK_ACCESS(evlist)->stats; +} + +static inline u64 evlist__first_sample_time(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->first_sample_time; +} + +static inline void evlist__set_first_sample_time(struct evlist *evlist, u6= 4 first) +{ + RC_CHK_ACCESS(evlist)->first_sample_time =3D first; +} + +static inline u64 evlist__last_sample_time(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->last_sample_time; +} + +static inline void evlist__set_last_sample_time(struct evlist *evlist, u64= last) +{ + RC_CHK_ACCESS(evlist)->last_sample_time =3D last; +} + +static inline int evlist__nr_br_cntr(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->nr_br_cntr; +} + +static inline void evlist__set_nr_br_cntr(struct evlist *evlist, int nr) +{ + RC_CHK_ACCESS(evlist)->nr_br_cntr =3D nr; +} + +static inline struct perf_session *evlist__session(struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->session; +} + +static inline void evlist__set_session(struct evlist *evlist, struct perf_= session *session) +{ + RC_CHK_ACCESS(evlist)->session =3D session; +} + +static inline void (*evlist__trace_event_sample_raw(struct evlist *evlist)) + (struct evlist *evlist, + union perf_event *event, + struct perf_sample *sample) +{ + return RC_CHK_ACCESS(evlist)->trace_event_sample_raw; +} + +static inline void evlist__set_trace_event_sample_raw(struct evlist *evlis= t, + void (*fun)(struct evlist *evlist, + union perf_event *event, + struct perf_sample *sample)) +{ + RC_CHK_ACCESS(evlist)->trace_event_sample_raw =3D fun; +} + +static inline pid_t evlist__workload_pid(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->workload.pid; +} + +static inline void evlist__set_workload_pid(struct evlist *evlist, pid_t p= id) +{ + RC_CHK_ACCESS(evlist)->workload.pid =3D pid; +} + +static inline int evlist__workload_cork_fd(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->workload.cork_fd; +} + +static inline void evlist__set_workload_cork_fd(struct evlist *evlist, int= cork_fd) +{ + RC_CHK_ACCESS(evlist)->workload.cork_fd =3D cork_fd; +} + +static inline int evlist__ctl_fd_fd(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->ctl_fd.fd; +} + +static inline void evlist__set_ctl_fd_fd(struct evlist *evlist, int fd) +{ + RC_CHK_ACCESS(evlist)->ctl_fd.fd =3D fd; +} + +static inline int evlist__ctl_fd_ack(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->ctl_fd.ack; +} + +static inline void evlist__set_ctl_fd_ack(struct evlist *evlist, int ack) +{ + RC_CHK_ACCESS(evlist)->ctl_fd.ack =3D ack; +} + +static inline int evlist__ctl_fd_pos(const struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->ctl_fd.pos; +} + +static inline void evlist__set_ctl_fd_pos(struct evlist *evlist, int pos) +{ + RC_CHK_ACCESS(evlist)->ctl_fd.pos =3D pos; +} + +static inline refcount_t *evlist__refcnt(struct evlist *evlist) +{ + return &RC_CHK_ACCESS(evlist)->refcnt; +} + +static inline struct rblist *evlist__metric_events(struct evlist *evlist) +{ + return &RC_CHK_ACCESS(evlist)->metric_events; +} + +static inline struct list_head *evlist__deferred_samples(struct evlist *ev= list) +{ + return &RC_CHK_ACCESS(evlist)->deferred_samples; +} + +static inline struct evsel *evlist__selected(struct evlist *evlist) +{ + return RC_CHK_ACCESS(evlist)->selected; +} + +static inline void evlist__set_selected(struct evlist *evlist, struct evse= l *evsel) +{ + RC_CHK_ACCESS(evlist)->selected =3D evsel; +} + struct evlist *evlist__new(void); struct evlist *evlist__new_default(const struct target *target, bool sampl= e_callchains); struct evlist *evlist__new_dummy(void); @@ -200,8 +422,8 @@ int evlist__mmap_ex(struct evlist *evlist, unsigned int= pages, unsigned int auxtrace_pages, bool auxtrace_overwrite, int nr_cblocks, int affinity, int flush, int comp_level); -int evlist__mmap(struct evlist *evlist, unsigned int pages); -void evlist__munmap(struct evlist *evlist); +int evlist__do_mmap(struct evlist *evlist, unsigned int pages); +void evlist__do_munmap(struct evlist *evlist); =20 size_t evlist__mmap_size(unsigned long pages); =20 @@ -213,8 +435,6 @@ void evlist__enable_evsel(struct evlist *evlist, char *= evsel_name); void evlist__disable_non_dummy(struct evlist *evlist); void evlist__enable_non_dummy(struct evlist *evlist); =20 -void evlist__set_selected(struct evlist *evlist, struct evsel *evsel); - int evlist__create_maps(struct evlist *evlist, struct target *target); int evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel, struct target *target); @@ -237,26 +457,26 @@ void evlist__splice_list_tail(struct evlist *evlist, = struct list_head *list); =20 static inline bool evlist__empty(struct evlist *evlist) { - return list_empty(&evlist->core.entries); + return list_empty(&evlist__core(evlist)->entries); } =20 static inline struct evsel *evlist__first(struct evlist *evlist) { - struct perf_evsel *evsel =3D perf_evlist__first(&evlist->core); + struct perf_evsel *evsel =3D perf_evlist__first(evlist__core(evlist)); =20 return container_of(evsel, struct evsel, core); } =20 static inline struct evsel *evlist__last(struct evlist *evlist) { - struct perf_evsel *evsel =3D perf_evlist__last(&evlist->core); + struct perf_evsel *evsel =3D perf_evlist__last(evlist__core(evlist)); =20 return container_of(evsel, struct evsel, core); } =20 static inline int evlist__nr_groups(struct evlist *evlist) { - return perf_evlist__nr_groups(&evlist->core); + return perf_evlist__nr_groups(evlist__core(evlist)); } =20 int evlist__strerror_open(struct evlist *evlist, int err, char *buf, size_= t size); @@ -279,7 +499,7 @@ void evlist__to_front(struct evlist *evlist, struct evs= el *move_evsel); * @evsel: struct evsel iterator */ #define evlist__for_each_entry(evlist, evsel) \ - __evlist__for_each_entry(&(evlist)->core.entries, evsel) + __evlist__for_each_entry(&evlist__core(evlist)->entries, evsel) =20 /** * __evlist__for_each_entry_continue - continue iteration thru all the evs= els @@ -295,7 +515,7 @@ void evlist__to_front(struct evlist *evlist, struct evs= el *move_evsel); * @evsel: struct evsel iterator */ #define evlist__for_each_entry_continue(evlist, evsel) \ - __evlist__for_each_entry_continue(&(evlist)->core.entries, evsel) + __evlist__for_each_entry_continue(&evlist__core(evlist)->entries, evsel) =20 /** * __evlist__for_each_entry_from - continue iteration from @evsel (include= d) @@ -311,7 +531,7 @@ void evlist__to_front(struct evlist *evlist, struct evs= el *move_evsel); * @evsel: struct evsel iterator */ #define evlist__for_each_entry_from(evlist, evsel) \ - __evlist__for_each_entry_from(&(evlist)->core.entries, evsel) + __evlist__for_each_entry_from(&evlist__core(evlist)->entries, evsel) =20 /** * __evlist__for_each_entry_reverse - iterate thru all the evsels in rever= se order @@ -327,7 +547,7 @@ void evlist__to_front(struct evlist *evlist, struct evs= el *move_evsel); * @evsel: struct evsel iterator */ #define evlist__for_each_entry_reverse(evlist, evsel) \ - __evlist__for_each_entry_reverse(&(evlist)->core.entries, evsel) + __evlist__for_each_entry_reverse(&evlist__core(evlist)->entries, evsel) =20 /** * __evlist__for_each_entry_safe - safely iterate thru all the evsels @@ -345,7 +565,7 @@ void evlist__to_front(struct evlist *evlist, struct evs= el *move_evsel); * @tmp: struct evsel temp iterator */ #define evlist__for_each_entry_safe(evlist, tmp, evsel) \ - __evlist__for_each_entry_safe(&(evlist)->core.entries, tmp, evsel) + __evlist__for_each_entry_safe(&evlist__core(evlist)->entries, tmp, evsel) =20 /** Iterator state for evlist__for_each_cpu */ struct evlist_cpu_iterator { @@ -451,7 +671,6 @@ int evlist__ctlfd_ack(struct evlist *evlist); int evlist__parse_event_enable_time(struct evlist *evlist, struct record_o= pts *opts, const char *str, int unset); int event_enable_timer__start(struct event_enable_timer *eet); -void event_enable_timer__exit(struct event_enable_timer **ep); int event_enable_timer__process(struct event_enable_timer *eet); =20 struct evsel *evlist__find_evsel(struct evlist *evlist, int idx); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 3687a39a85b7..37e8950ee990 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3187,7 +3187,7 @@ static inline bool evsel__has_branch_counters(const s= truct evsel *evsel) if (!leader || !evsel->evlist) return false; =20 - if (evsel->evlist->nr_br_cntr < 0) + if (evlist__nr_br_cntr(evsel->evlist) < 0) evlist__update_br_cntr(evsel->evlist); =20 if (leader->br_cntr_nr > 0) @@ -4219,7 +4219,7 @@ int evsel__open_strerror(struct evsel *evsel, struct = target *target, =20 struct perf_session *evsel__session(struct evsel *evsel) { - return evsel && evsel->evlist ? evsel->evlist->session : NULL; + return evsel && evsel->evlist ? evlist__session(evsel->evlist) : NULL; } =20 struct perf_env *evsel__env(struct evsel *evsel) @@ -4244,7 +4244,7 @@ static int store_evsel_ids(struct evsel *evsel, struc= t evlist *evlist) thread++) { int fd =3D FD(evsel, cpu_map_idx, thread); =20 - if (perf_evlist__id_add_fd(&evlist->core, &evsel->core, + if (perf_evlist__id_add_fd(evlist__core(evlist), &evsel->core, cpu_map_idx, thread, fd) < 0) return -1; } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 4ce86eb330d7..2a49b2516408 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -501,7 +501,7 @@ for ((_evsel) =3D list_entry((_leader)->core.node.next,= struct evsel, core.node); (_evsel) =3D list_entry((_evsel)->core.node.next, struct evsel, core.node= )) =20 #define for_each_group_member(_evsel, _leader) \ - for_each_group_member_head(_evsel, _leader, &(_leader)->evlist->core.entr= ies) + for_each_group_member_head(_evsel, _leader, &evlist__core((_leader)->evli= st)->entries) =20 /* Iterates group WITH the leader. */ #define for_each_group_evsel_head(_evsel, _leader, _head) \ @@ -511,7 +511,7 @@ for ((_evsel) =3D _leader; \ (_evsel) =3D list_entry((_evsel)->core.node.next, struct evsel, core.node= )) =20 #define for_each_group_evsel(_evsel, _leader) \ - for_each_group_evsel_head(_evsel, _leader, &(_leader)->evlist->core.entri= es) + for_each_group_evsel_head(_evsel, _leader, &evlist__core((_leader)->evlis= t)->entries) =20 static inline bool evsel__has_branch_callstack(const struct evsel *evsel) { diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f9887d2fc8ed..2469e2741bc4 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -323,7 +323,7 @@ static int write_tracing_data(struct feat_fd *ff, return -1; =20 #ifdef HAVE_LIBTRACEEVENT - return read_tracing_data(ff->fd, &evlist->core.entries); + return read_tracing_data(ff->fd, &evlist__core(evlist)->entries); #else pr_err("ERROR: Trying to write tracing data without libtraceevent support= .\n"); return -1; @@ -397,7 +397,7 @@ static int write_e_machine(struct feat_fd *ff, { /* e_machine expanded from 16 to 32-bits for alignment. */ uint32_t e_flags; - uint32_t e_machine =3D perf_session__e_machine(evlist->session, &e_flags); + uint32_t e_machine =3D perf_session__e_machine(evlist__session(evlist), &= e_flags); int ret; =20 ret =3D do_write(ff, &e_machine, sizeof(e_machine)); @@ -533,7 +533,7 @@ static int write_event_desc(struct feat_fd *ff, u32 nre, nri, sz; int ret; =20 - nre =3D evlist->core.nr_entries; + nre =3D evlist__nr_entries(evlist); =20 /* * write number of events @@ -915,7 +915,7 @@ int __weak get_cpuid(char *buffer __maybe_unused, size_= t sz __maybe_unused, =20 static int write_cpuid(struct feat_fd *ff, struct evlist *evlist) { - struct perf_cpu cpu =3D perf_cpu_map__min(evlist->core.all_cpus); + struct perf_cpu cpu =3D perf_cpu_map__min(evlist__core(evlist)->all_cpus); char buffer[64]; int ret; =20 @@ -1348,14 +1348,14 @@ static int write_sample_time(struct feat_fd *ff, struct evlist *evlist) { int ret; + u64 data =3D evlist__first_sample_time(evlist); =20 - ret =3D do_write(ff, &evlist->first_sample_time, - sizeof(evlist->first_sample_time)); + ret =3D do_write(ff, &data, sizeof(data)); if (ret < 0) return ret; =20 - return do_write(ff, &evlist->last_sample_time, - sizeof(evlist->last_sample_time)); + data =3D evlist__last_sample_time(evlist); + return do_write(ff, &data, sizeof(data)); } =20 =20 @@ -2425,16 +2425,16 @@ static void print_sample_time(struct feat_fd *ff, F= ILE *fp) =20 session =3D container_of(ff->ph, struct perf_session, header); =20 - timestamp__scnprintf_usec(session->evlist->first_sample_time, + timestamp__scnprintf_usec(evlist__first_sample_time(session->evlist), time_buf, sizeof(time_buf)); fprintf(fp, "# time of first sample : %s\n", time_buf); =20 - timestamp__scnprintf_usec(session->evlist->last_sample_time, + timestamp__scnprintf_usec(evlist__last_sample_time(session->evlist), time_buf, sizeof(time_buf)); fprintf(fp, "# time of last sample : %s\n", time_buf); =20 - d =3D (double)(session->evlist->last_sample_time - - session->evlist->first_sample_time) / NSEC_PER_MSEC; + d =3D (double)(evlist__last_sample_time(session->evlist) - + evlist__first_sample_time(session->evlist)) / NSEC_PER_MSEC; =20 fprintf(fp, "# sample duration : %10.3f ms\n", d); } @@ -3326,8 +3326,8 @@ static int process_sample_time(struct feat_fd *ff, vo= id *data __maybe_unused) if (ret) return -1; =20 - session->evlist->first_sample_time =3D first_sample_time; - session->evlist->last_sample_time =3D last_sample_time; + evlist__set_first_sample_time(session->evlist, first_sample_time); + evlist__set_last_sample_time(session->evlist, last_sample_time); return 0; } =20 @@ -4396,7 +4396,7 @@ int perf_session__write_header(struct perf_session *s= ession, /*write_attrs_after_data=3D*/false); } =20 -size_t perf_session__data_offset(const struct evlist *evlist) +size_t perf_session__data_offset(struct evlist *evlist) { struct evsel *evsel; size_t data_offset; @@ -4405,7 +4405,7 @@ size_t perf_session__data_offset(const struct evlist = *evlist) evlist__for_each_entry(evlist, evsel) { data_offset +=3D evsel->core.ids * sizeof(u64); } - data_offset +=3D evlist->core.nr_entries * sizeof(struct perf_file_attr); + data_offset +=3D evlist__nr_entries(evlist) * sizeof(struct perf_file_att= r); =20 return data_offset; } @@ -4849,7 +4849,7 @@ int perf_session__read_header(struct perf_session *se= ssion) if (session->evlist =3D=3D NULL) return -ENOMEM; =20 - session->evlist->session =3D session; + evlist__set_session(session->evlist, session); session->machines.host.env =3D &header->env; =20 /* @@ -4933,7 +4933,8 @@ int perf_session__read_header(struct perf_session *se= ssion) if (perf_header__getbuffer64(header, fd, &f_id, sizeof(f_id))) goto out_errno; =20 - perf_evlist__id_add(&session->evlist->core, &evsel->core, 0, j, f_id); + perf_evlist__id_add(evlist__core(session->evlist), + &evsel->core, 0, j, f_id); } =20 lseek(fd, tmp, SEEK_SET); @@ -5126,7 +5127,7 @@ int perf_event__process_attr(const struct perf_tool *= tool __maybe_unused, =20 ids =3D perf_record_header_attr_id(event); for (i =3D 0; i < n_ids; i++) { - perf_evlist__id_add(&evlist->core, &evsel->core, 0, i, ids[i]); + perf_evlist__id_add(evlist__core(evlist), &evsel->core, 0, i, ids[i]); } =20 return 0; diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 86b1a72026d3..5e03f884b7cc 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -158,7 +158,7 @@ int perf_session__inject_header(struct perf_session *se= ssion, struct feat_copier *fc, bool write_attrs_after_data); =20 -size_t perf_session__data_offset(const struct evlist *evlist); +size_t perf_session__data_offset(struct evlist *evlist); =20 void perf_header__set_feat(struct perf_header *header, int feat); void perf_header__clear_feat(struct perf_header *header, int feat); diff --git a/tools/perf/util/intel-tpebs.c b/tools/perf/util/intel-tpebs.c index ed8cfe2ba2fa..675b11168216 100644 --- a/tools/perf/util/intel-tpebs.c +++ b/tools/perf/util/intel-tpebs.c @@ -95,8 +95,9 @@ static int evsel__tpebs_start_perf_record(struct evsel *e= vsel) record_argv[i++] =3D "-o"; record_argv[i++] =3D PERF_DATA; =20 - if (!perf_cpu_map__is_any_cpu_or_is_empty(evsel->evlist->core.user_reques= ted_cpus)) { - cpu_map__snprint(evsel->evlist->core.user_requested_cpus, cpumap_buf, + if (!perf_cpu_map__is_any_cpu_or_is_empty( + evlist__core(evsel->evlist)->user_requested_cpus)) { + cpu_map__snprint(evlist__core(evsel->evlist)->user_requested_cpus, cpuma= p_buf, sizeof(cpumap_buf)); record_argv[i++] =3D "-C"; record_argv[i++] =3D cpumap_buf; @@ -172,7 +173,7 @@ static bool should_ignore_sample(const struct perf_samp= le *sample, const struct if (t->evsel->evlist =3D=3D NULL) return true; =20 - workload_pid =3D t->evsel->evlist->workload.pid; + workload_pid =3D evlist__workload_pid(t->evsel->evlist); if (workload_pid < 0 || workload_pid =3D=3D sample_pid) return false; =20 diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 73908b049fed..3fd985e423c8 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1489,7 +1489,7 @@ static int parse_groups(struct evlist *perf_evlist, goto out; } =20 - me =3D metricgroup__lookup(&perf_evlist->metric_events, + me =3D metricgroup__lookup(evlist__metric_events(perf_evlist), pick_display_evsel(&metric_list, metric_events), /*create=3D*/true); =20 @@ -1540,13 +1540,13 @@ static int parse_groups(struct evlist *perf_evlist, =20 =20 if (combined_evlist) { - evlist__splice_list_tail(perf_evlist, &combined_evlist->core.entries); + evlist__splice_list_tail(perf_evlist, &evlist__core(combined_evlist)->en= tries); evlist__put(combined_evlist); } =20 list_for_each_entry(m, &metric_list, nd) { if (m->evlist) - evlist__splice_list_tail(perf_evlist, &m->evlist->core.entries); + evlist__splice_list_tail(perf_evlist, &evlist__core(m->evlist)->entries= ); } =20 out: diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index f0809be63ad8..3682053b23cb 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2267,7 +2267,7 @@ int __parse_events(struct evlist *evlist, const char = *str, const char *pmu_filte { struct parse_events_state parse_state =3D { .list =3D LIST_HEAD_INIT(parse_state.list), - .idx =3D evlist->core.nr_entries, + .idx =3D evlist__nr_entries(evlist), .error =3D err, .stoken =3D PE_START_EVENTS, .fake_pmu =3D fake_pmu, @@ -2541,7 +2541,7 @@ foreach_evsel_in_last_glob(struct evlist *evlist, * * So no need to WARN here, let *func do this. */ - if (evlist->core.nr_entries > 0) + if (evlist__nr_entries(evlist) > 0) last =3D evlist__last(evlist); =20 do { @@ -2551,7 +2551,7 @@ foreach_evsel_in_last_glob(struct evlist *evlist, if (!last) return 0; =20 - if (last->core.node.prev =3D=3D &evlist->core.entries) + if (last->core.node.prev =3D=3D &evlist__core(evlist)->entries) return 0; last =3D list_entry(last->core.node.prev, struct evsel, core.node); } while (!last->cmdline_group_boundary); diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c index 5f53c2f68a96..f80d6b0df47a 100644 --- a/tools/perf/util/pfm.c +++ b/tools/perf/util/pfm.c @@ -85,7 +85,7 @@ int parse_libpfm_events_option(const struct option *opt, = const char *str, } =20 pmu =3D perf_pmus__find_by_type((unsigned int)attr.type); - evsel =3D parse_events__add_event(evlist->core.nr_entries, + evsel =3D parse_events__add_event(evlist__nr_entries(evlist), &attr, q, /*metric_id=3D*/NULL, pmu); if (evsel =3D=3D NULL) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 2a75b06f6f04..7778f88c3810 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1469,7 +1469,7 @@ static int pyrf_evlist__init(struct pyrf_evlist *pevl= ist, } threads =3D ((struct pyrf_thread_map *)pthreads)->threads; cpus =3D ((struct pyrf_cpu_map *)pcpus)->cpus; - perf_evlist__set_maps(&pevlist->evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(pevlist->evlist), cpus, threads); =20 return 0; } @@ -1485,7 +1485,7 @@ static PyObject *pyrf_evlist__all_cpus(struct pyrf_ev= list *pevlist) struct pyrf_cpu_map *pcpu_map =3D PyObject_New(struct pyrf_cpu_map, &pyrf= _cpu_map__type); =20 if (pcpu_map) - pcpu_map->cpus =3D perf_cpu_map__get(pevlist->evlist->core.all_cpus); + pcpu_map->cpus =3D perf_cpu_map__get(evlist__core(pevlist->evlist)->all_= cpus); =20 return (PyObject *)pcpu_map; } @@ -1498,7 +1498,7 @@ static PyObject *pyrf_evlist__metrics(struct pyrf_evl= ist *pevlist) if (!list) return NULL; =20 - for (node =3D rb_first_cached(&pevlist->evlist->metric_events.entries); n= ode; + for (node =3D rb_first_cached(&evlist__metric_events(pevlist->evlist)->en= tries); node; node =3D rb_next(node)) { struct metric_event *me =3D container_of(node, struct metric_event, nd); struct list_head *pos; @@ -1604,7 +1604,7 @@ static PyObject *pyrf_evlist__compute_metric(struct p= yrf_evlist *pevlist, if (!PyArg_ParseTuple(args, "sii", &metric, &cpu, &thread)) return NULL; =20 - for (node =3D rb_first_cached(&pevlist->evlist->metric_events.entries); + for (node =3D rb_first_cached(&evlist__metric_events(pevlist->evlist)->en= tries); mexp =3D=3D NULL && node; node =3D rb_next(node)) { struct metric_event *me =3D container_of(node, struct metric_event, nd); @@ -1673,7 +1673,7 @@ static PyObject *pyrf_evlist__mmap(struct pyrf_evlist= *pevlist, &pages, &overwrite)) return NULL; =20 - if (evlist__mmap(evlist, pages) < 0) { + if (evlist__do_mmap(evlist, pages) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } @@ -1709,9 +1709,9 @@ static PyObject *pyrf_evlist__get_pollfd(struct pyrf_= evlist *pevlist, PyObject *list =3D PyList_New(0); int i; =20 - for (i =3D 0; i < evlist->core.pollfd.nr; ++i) { + for (i =3D 0; i < evlist__core(evlist)->pollfd.nr; ++i) { PyObject *file; - file =3D PyFile_FromFd(evlist->core.pollfd.entries[i].fd, "perf", "r", -= 1, + file =3D PyFile_FromFd(evlist__core(evlist)->pollfd.entries[i].fd, "perf= ", "r", -1, NULL, NULL, NULL, 0); if (file =3D=3D NULL) goto free_list; @@ -1743,18 +1743,18 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlis= t *pevlist, =20 Py_INCREF(pevsel); evsel =3D ((struct pyrf_evsel *)pevsel)->evsel; - evsel->core.idx =3D evlist->core.nr_entries; + evsel->core.idx =3D evlist__nr_entries(evlist); evlist__add(evlist, evsel__get(evsel)); =20 - return Py_BuildValue("i", evlist->core.nr_entries); + return Py_BuildValue("i", evlist__nr_entries(evlist)); } =20 static struct mmap *get_md(struct evlist *evlist, int cpu) { int i; =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { - struct mmap *md =3D &evlist->mmap[i]; + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { + struct mmap *md =3D &evlist__mmap(evlist)[i]; =20 if (md->core.cpu.cpu =3D=3D cpu) return md; @@ -1969,7 +1969,7 @@ static Py_ssize_t pyrf_evlist__length(PyObject *obj) { struct pyrf_evlist *pevlist =3D (void *)obj; =20 - return pevlist->evlist->core.nr_entries; + return evlist__nr_entries(pevlist->evlist); } =20 static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel) @@ -1988,7 +1988,7 @@ static PyObject *pyrf_evlist__item(PyObject *obj, Py_= ssize_t i) struct pyrf_evlist *pevlist =3D (void *)obj; struct evsel *pos; =20 - if (i >=3D pevlist->evlist->core.nr_entries) { + if (i >=3D evlist__nr_entries(pevlist->evlist)) { PyErr_SetString(PyExc_IndexError, "Index out of range"); return NULL; } @@ -2193,7 +2193,7 @@ static PyObject *pyrf__parse_events(PyObject *self, P= yObject *args) cpus =3D pcpus ? ((struct pyrf_cpu_map *)pcpus)->cpus : NULL; =20 parse_events_error__init(&err); - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); if (parse_events(evlist, input, &err)) { parse_events_error__print(&err, input); PyErr_SetFromErrno(PyExc_OSError); @@ -2226,7 +2226,7 @@ static PyObject *pyrf__parse_metrics(PyObject *self, = PyObject *args) threads =3D pthreads ? ((struct pyrf_thread_map *)pthreads)->threads : NU= LL; cpus =3D pcpus ? ((struct pyrf_cpu_map *)pcpus)->cpus : NULL; =20 - perf_evlist__set_maps(&evlist->core, cpus, threads); + perf_evlist__set_maps(evlist__core(evlist), cpus, threads); ret =3D metricgroup__parse_groups(evlist, pmu ?: "all", input, /*metric_no_group=3D*/ false, /*metric_no_merge=3D*/ false, diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 8a5fc7d5e43c..38e8aee3106b 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -99,7 +99,7 @@ void evlist__config(struct evlist *evlist, struct record_= opts *opts, struct call bool use_comm_exec; bool sample_id =3D opts->sample_id; =20 - if (perf_cpu_map__cpu(evlist->core.user_requested_cpus, 0).cpu < 0) + if (perf_cpu_map__cpu(evlist__core(evlist)->user_requested_cpus, 0).cpu <= 0) opts->no_inherit =3D true; =20 use_comm_exec =3D perf_can_comm_exec(); @@ -122,7 +122,7 @@ void evlist__config(struct evlist *evlist, struct recor= d_opts *opts, struct call */ use_sample_identifier =3D perf_can_sample_identifier(); sample_id =3D true; - } else if (evlist->core.nr_entries > 1) { + } else if (evlist__nr_entries(evlist) > 1) { struct evsel *first =3D evlist__first(evlist); =20 evlist__for_each_entry(evlist, evsel) { @@ -237,7 +237,8 @@ bool evlist__can_select_event(struct evlist *evlist, co= nst char *str) =20 evsel =3D evlist__last(temp_evlist); =20 - if (!evlist || perf_cpu_map__is_any_cpu_or_is_empty(evlist->core.user_req= uested_cpus)) { + if (!evlist || + perf_cpu_map__is_any_cpu_or_is_empty(evlist__core(evlist)->user_reque= sted_cpus)) { struct perf_cpu_map *cpus =3D perf_cpu_map__new_online_cpus(); =20 if (cpus) @@ -245,7 +246,7 @@ bool evlist__can_select_event(struct evlist *evlist, co= nst char *str) =20 perf_cpu_map__put(cpus); } else { - cpu =3D perf_cpu_map__cpu(evlist->core.user_requested_cpus, 0); + cpu =3D perf_cpu_map__cpu(evlist__core(evlist)->user_requested_cpus, 0); } =20 while (1) { diff --git a/tools/perf/util/sample-raw.c b/tools/perf/util/sample-raw.c index bcf442574d6e..ec33b864431c 100644 --- a/tools/perf/util/sample-raw.c +++ b/tools/perf/util/sample-raw.c @@ -18,10 +18,10 @@ void evlist__init_trace_event_sample_raw(struct evlist = *evlist, struct perf_env const char *cpuid =3D perf_env__cpuid(env); =20 if (arch_pf && !strcmp("s390", arch_pf)) - evlist->trace_event_sample_raw =3D evlist__s390_sample_raw; + evlist__set_trace_event_sample_raw(evlist, evlist__s390_sample_raw); else if (arch_pf && !strcmp("x86", arch_pf) && cpuid && strstarts(cpuid, "AuthenticAMD") && evlist__has_amd_ibs(evlist)) { - evlist->trace_event_sample_raw =3D evlist__amd_sample_raw; + evlist__set_trace_event_sample_raw(evlist, evlist__amd_sample_raw); } } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 43fef473bbb4..32c99dbfd42b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -204,7 +204,7 @@ struct perf_session *__perf_session__new(struct perf_da= ta *data, session->machines.host.env =3D host_env; } if (session->evlist) - session->evlist->session =3D session; + evlist__set_session(session->evlist, session); =20 session->machines.host.single_address_space =3D perf_env__single_address_space(session->machines.host.env); @@ -1099,8 +1099,8 @@ static void dump_event(struct evlist *evlist, union p= erf_event *event, file_offset, file_path, event->header.size, event->header.type); =20 trace_event(event); - if (event->header.type =3D=3D PERF_RECORD_SAMPLE && evlist->trace_event_s= ample_raw) - evlist->trace_event_sample_raw(evlist, event, sample); + if (event->header.type =3D=3D PERF_RECORD_SAMPLE && evlist__trace_event_s= ample_raw(evlist)) + evlist__trace_event_sample_raw(evlist)(evlist, event, sample); =20 if (sample) evlist__print_tstamp(evlist, event, sample); @@ -1281,7 +1281,7 @@ static int deliver_sample_value(struct evlist *evlist, } =20 if (!storage || sid->evsel =3D=3D NULL) { - ++evlist->stats.nr_unknown_id; + ++evlist__stats(evlist)->nr_unknown_id; return 0; } =20 @@ -1380,7 +1380,7 @@ static int evlist__deliver_deferred_callchain(struct = evlist *evlist, return ret; } =20 - list_for_each_entry_safe(de, tmp, &evlist->deferred_samples, list) { + list_for_each_entry_safe(de, tmp, evlist__deferred_samples(evlist), list)= { struct perf_sample orig_sample; =20 perf_sample__init(&orig_sample, /*all=3D*/false); @@ -1402,6 +1402,8 @@ static int evlist__deliver_deferred_callchain(struct = evlist *evlist, orig_sample.deferred_callchain =3D false; =20 orig_sample.evsel =3D evlist__id2evsel(evlist, orig_sample.id); + if (orig_sample.evsel) + orig_sample.evsel =3D evsel__get(orig_sample.evsel); ret =3D evlist__deliver_sample(evlist, tool, de->event, &orig_sample, machine); =20 @@ -1428,7 +1430,7 @@ static int session__flush_deferred_samples(struct per= f_session *session, struct deferred_event *de, *tmp; int ret =3D 0; =20 - list_for_each_entry_safe(de, tmp, &evlist->deferred_samples, list) { + list_for_each_entry_safe(de, tmp, evlist__deferred_samples(evlist), list)= { struct perf_sample sample; =20 perf_sample__init(&sample, /*all=3D*/false); @@ -1440,6 +1442,8 @@ static int session__flush_deferred_samples(struct per= f_session *session, } =20 sample.evsel =3D evlist__id2evsel(evlist, sample.id); + if (sample.evsel) + sample.evsel =3D evsel__get(sample.evsel); ret =3D evlist__deliver_sample(evlist, tool, de->event, &sample, machine); =20 @@ -1465,21 +1469,23 @@ static int machines__deliver_event(struct machines = *machines, =20 dump_event(evlist, event, file_offset, sample, file_path); =20 - if (!sample->evsel) + if (!sample->evsel) { sample->evsel =3D evlist__id2evsel(evlist, sample->id); - else + if (sample->evsel) + sample->evsel =3D evsel__get(sample->evsel); + } else { assert(sample->evsel =3D=3D evlist__id2evsel(evlist, sample->id)); - + } machine =3D machines__find_for_cpumode(machines, event, sample); =20 switch (event->header.type) { case PERF_RECORD_SAMPLE: if (sample->evsel =3D=3D NULL) { - ++evlist->stats.nr_unknown_id; + ++evlist__stats(evlist)->nr_unknown_id; return 0; } if (machine =3D=3D NULL) { - ++evlist->stats.nr_unprocessable_samples; + ++evlist__stats(evlist)->nr_unprocessable_samples; dump_sample(machine, event, sample); return 0; } @@ -1497,7 +1503,7 @@ static int machines__deliver_event(struct machines *m= achines, return -ENOMEM; } memcpy(de->event, event, sz); - list_add_tail(&de->list, &evlist->deferred_samples); + list_add_tail(&de->list, evlist__deferred_samples(evlist)); return 0; } return evlist__deliver_sample(evlist, tool, event, sample, machine); @@ -1505,7 +1511,7 @@ static int machines__deliver_event(struct machines *m= achines, return tool->mmap(tool, event, sample, machine); case PERF_RECORD_MMAP2: if (event->header.misc & PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT) - ++evlist->stats.nr_proc_map_timeout; + ++evlist__stats(evlist)->nr_proc_map_timeout; return tool->mmap2(tool, event, sample, machine); case PERF_RECORD_COMM: return tool->comm(tool, event, sample, machine); @@ -1519,13 +1525,13 @@ static int machines__deliver_event(struct machines = *machines, return tool->exit(tool, event, sample, machine); case PERF_RECORD_LOST: if (tool->lost =3D=3D perf_event__process_lost) - evlist->stats.total_lost +=3D event->lost.lost; + evlist__stats(evlist)->total_lost +=3D event->lost.lost; return tool->lost(tool, event, sample, machine); case PERF_RECORD_LOST_SAMPLES: if (event->header.misc & PERF_RECORD_MISC_LOST_SAMPLES_BPF) - evlist->stats.total_dropped_samples +=3D event->lost_samples.lost; + evlist__stats(evlist)->total_dropped_samples +=3D event->lost_samples.l= ost; else if (tool->lost_samples =3D=3D perf_event__process_lost_samples) - evlist->stats.total_lost_samples +=3D event->lost_samples.lost; + evlist__stats(evlist)->total_lost_samples +=3D event->lost_samples.lost; return tool->lost_samples(tool, event, sample, machine); case PERF_RECORD_READ: dump_read(sample->evsel, event); @@ -1537,11 +1543,11 @@ static int machines__deliver_event(struct machines = *machines, case PERF_RECORD_AUX: if (tool->aux =3D=3D perf_event__process_aux) { if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED) - evlist->stats.total_aux_lost +=3D 1; + evlist__stats(evlist)->total_aux_lost +=3D 1; if (event->aux.flags & PERF_AUX_FLAG_PARTIAL) - evlist->stats.total_aux_partial +=3D 1; + evlist__stats(evlist)->total_aux_partial +=3D 1; if (event->aux.flags & PERF_AUX_FLAG_COLLISION) - evlist->stats.total_aux_collision +=3D 1; + evlist__stats(evlist)->total_aux_collision +=3D 1; } return tool->aux(tool, event, sample, machine); case PERF_RECORD_ITRACE_START: @@ -1562,7 +1568,7 @@ static int machines__deliver_event(struct machines *m= achines, return evlist__deliver_deferred_callchain(evlist, tool, event, sample, machine); default: - ++evlist->stats.nr_unknown_events; + ++evlist__stats(evlist)->nr_unknown_events; return -1; } } @@ -1728,7 +1734,7 @@ int perf_session__deliver_synth_event(struct perf_ses= sion *session, struct evlist *evlist =3D session->evlist; const struct perf_tool *tool =3D session->tool; =20 - events_stats__inc(&evlist->stats, event->header.type); + events_stats__inc(evlist__stats(evlist), event->header.type); =20 if (event->header.type >=3D PERF_RECORD_USER_TYPE_START) return perf_session__process_user_event(session, event, 0, NULL); @@ -1876,7 +1882,7 @@ static s64 perf_session__process_event(struct perf_se= ssion *session, return event->header.size; } =20 - events_stats__inc(&evlist->stats, event->header.type); + events_stats__inc(evlist__stats(evlist), event->header.type); =20 if (event->header.type >=3D PERF_RECORD_USER_TYPE_START) return perf_session__process_user_event(session, event, file_offset, fil= e_path); @@ -1937,7 +1943,7 @@ perf_session__warn_order(const struct perf_session *s= ession) =20 static void perf_session__warn_about_errors(const struct perf_session *ses= sion) { - const struct events_stats *stats =3D &session->evlist->stats; + const struct events_stats *stats =3D evlist__stats(session->evlist); =20 if (session->tool->lost =3D=3D perf_event__process_lost && stats->nr_events[PERF_RECORD_LOST] !=3D 0) { @@ -2751,7 +2757,7 @@ size_t perf_session__fprintf_nr_events(struct perf_se= ssion *session, FILE *fp) =20 ret =3D fprintf(fp, "\nAggregated stats:%s\n", msg); =20 - ret +=3D events_stats__fprintf(&session->evlist->stats, fp); + ret +=3D events_stats__fprintf(evlist__stats(session->evlist), fp); return ret; } =20 diff --git a/tools/perf/util/sideband_evlist.c b/tools/perf/util/sideband_e= vlist.c index b84a5463e039..c07dacf3c54c 100644 --- a/tools/perf/util/sideband_evlist.c +++ b/tools/perf/util/sideband_evlist.c @@ -22,7 +22,7 @@ int evlist__add_sb_event(struct evlist *evlist, struct pe= rf_event_attr *attr, attr->sample_id_all =3D 1; } =20 - evsel =3D evsel__new_idx(attr, evlist->core.nr_entries); + evsel =3D evsel__new_idx(attr, evlist__nr_entries(evlist)); if (!evsel) return -1; =20 @@ -49,14 +49,14 @@ static void *perf_evlist__poll_thread(void *arg) while (!done) { bool got_data =3D false; =20 - if (evlist->thread.done) + if (evlist__sb_thread_done(evlist)) draining =3D true; =20 if (!draining) evlist__poll(evlist, 1000); =20 - for (i =3D 0; i < evlist->core.nr_mmaps; i++) { - struct mmap *map =3D &evlist->mmap[i]; + for (i =3D 0; i < evlist__core(evlist)->nr_mmaps; i++) { + struct mmap *map =3D &evlist__mmap(evlist)[i]; union perf_event *event; =20 if (perf_mmap__read_init(&map->core)) @@ -104,7 +104,7 @@ int evlist__start_sb_thread(struct evlist *evlist, stru= ct target *target) if (evlist__create_maps(evlist, target)) goto out_put_evlist; =20 - if (evlist->core.nr_entries > 1) { + if (evlist__nr_entries(evlist) > 1) { bool can_sample_identifier =3D perf_can_sample_identifier(); =20 evlist__for_each_entry(evlist, counter) @@ -114,12 +114,12 @@ int evlist__start_sb_thread(struct evlist *evlist, st= ruct target *target) } =20 evlist__for_each_entry(evlist, counter) { - if (evsel__open(counter, evlist->core.user_requested_cpus, - evlist->core.threads) < 0) + if (evsel__open(counter, evlist__core(evlist)->user_requested_cpus, + evlist__core(evlist)->threads) < 0) goto out_put_evlist; } =20 - if (evlist__mmap(evlist, UINT_MAX)) + if (evlist__do_mmap(evlist, UINT_MAX)) goto out_put_evlist; =20 evlist__for_each_entry(evlist, counter) { @@ -127,8 +127,8 @@ int evlist__start_sb_thread(struct evlist *evlist, stru= ct target *target) goto out_put_evlist; } =20 - evlist->thread.done =3D 0; - if (pthread_create(&evlist->thread.th, NULL, perf_evlist__poll_thread, ev= list)) + evlist__set_sb_thread_done(evlist, 0); + if (pthread_create(evlist__sb_thread_th(evlist), NULL, perf_evlist__poll_= thread, evlist)) goto out_put_evlist; =20 return 0; @@ -143,7 +143,7 @@ void evlist__stop_sb_thread(struct evlist *evlist) { if (!evlist) return; - evlist->thread.done =3D 1; - pthread_join(evlist->thread.th, NULL); + evlist__set_sb_thread_done(evlist, 1); + pthread_join(*evlist__sb_thread_th(evlist), NULL); evlist__put(evlist); } diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 0020089cb13c..f93154f8adfd 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -3481,7 +3481,7 @@ static struct evsel *find_evsel(struct evlist *evlist= , char *event_name) if (event_name[0] =3D=3D '%') { int nr =3D strtol(event_name+1, NULL, 0); =20 - if (nr > evlist->core.nr_entries) + if (nr > evlist__nr_entries(evlist)) return NULL; =20 evsel =3D evlist__first(evlist); diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 993f4c4b8f44..c8f49b56815d 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -669,7 +669,7 @@ static void print_metric_header(struct perf_stat_config= *config, =20 /* In case of iostat, print metric header for first root port only */ if (config->iostat_run && - os->evsel->priv !=3D os->evsel->evlist->selected->priv) + os->evsel->priv !=3D evlist__selected(os->evsel->evlist)->priv) return; =20 if (os->evsel->cgrp !=3D os->cgrp) @@ -1128,7 +1128,7 @@ static void print_no_aggr_metric(struct perf_stat_con= fig *config, unsigned int all_idx; struct perf_cpu cpu; =20 - perf_cpu_map__for_each_cpu(cpu, all_idx, evlist->core.user_requested_cpus= ) { + perf_cpu_map__for_each_cpu(cpu, all_idx, evlist__core(evlist)->user_reque= sted_cpus) { struct evsel *counter; bool first =3D true; =20 @@ -1545,7 +1545,7 @@ void evlist__print_counters(struct evlist *evlist, st= ruct perf_stat_config *conf evlist__uniquify_evsel_names(evlist, config); =20 if (config->iostat_run) - evlist->selected =3D evlist__first(evlist); + evlist__set_selected(evlist, evlist__first(evlist)); =20 if (config->interval) prepare_timestamp(config, &os, ts); diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 48524450326d..482cb70681ab 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -283,7 +283,7 @@ void *perf_stat__print_shadow_stats_metricgroup(struct = perf_stat_config *config, void *ctxp =3D out->ctx; bool header_printed =3D false; const char *name =3D NULL; - struct rblist *metric_events =3D &evsel->evlist->metric_events; + struct rblist *metric_events =3D evlist__metric_events(evsel->evlist); =20 me =3D metricgroup__lookup(metric_events, evsel, false); if (me =3D=3D NULL) @@ -351,5 +351,5 @@ bool perf_stat__skip_metric_event(struct evsel *evsel) if (!evsel->default_metricgroup) return false; =20 - return !metricgroup__lookup(&evsel->evlist->metric_events, evsel, false); + return !metricgroup__lookup(evlist__metric_events(evsel->evlist), evsel, = false); } diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 66eb9a66a4f7..25f31a174368 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -547,8 +547,8 @@ static void evsel__merge_aliases(struct evsel *evsel) struct evlist *evlist =3D evsel->evlist; struct evsel *alias; =20 - alias =3D list_prepare_entry(evsel, &(evlist->core.entries), core.node); - list_for_each_entry_continue(alias, &evlist->core.entries, core.node) { + alias =3D list_prepare_entry(evsel, &(evlist__core(evlist)->entries), cor= e.node); + list_for_each_entry_continue(alias, &evlist__core(evlist)->entries, core.= node) { if (alias->first_wildcard_match =3D=3D evsel) { /* Merge the same events on different PMUs. */ evsel__merge_aggr_counters(evsel, alias); diff --git a/tools/perf/util/stream.c b/tools/perf/util/stream.c index 3de4a6130853..7bccd2378344 100644 --- a/tools/perf/util/stream.c +++ b/tools/perf/util/stream.c @@ -131,7 +131,7 @@ static int evlist__init_callchain_streams(struct evlist= *evlist, struct evsel *pos; int i =3D 0; =20 - BUG_ON(els->nr_evsel < evlist->core.nr_entries); + BUG_ON(els->nr_evsel < evlist__nr_entries(evlist)); =20 evlist__for_each_entry(evlist, pos) { struct hists *hists =3D evsel__hists(pos); @@ -148,7 +148,7 @@ static int evlist__init_callchain_streams(struct evlist= *evlist, struct evlist_streams *evlist__create_streams(struct evlist *evlist, int nr_streams_max) { - int nr_evsel =3D evlist->core.nr_entries, ret =3D -1; + int nr_evsel =3D evlist__nr_entries(evlist), ret =3D -1; struct evlist_streams *els =3D evlist_streams__new(nr_evsel, nr_streams_max); =20 diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index d665b0f94b32..59823b855efb 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -2230,7 +2230,7 @@ int perf_event__synthesize_tracing_data(const struct = perf_tool *tool, int fd, st * - write the tracing data from the temp file * to the pipe */ - tdata =3D tracing_data_get(&evlist->core.entries, fd, true); + tdata =3D tracing_data_get(&evlist__core(evlist)->entries, fd, true); if (!tdata) return -1; =20 @@ -2387,13 +2387,16 @@ int perf_event__synthesize_stat_events(struct perf_= stat_config *config, const st } =20 err =3D perf_event__synthesize_extra_attr(tool, evlist, process, attrs); - err =3D perf_event__synthesize_thread_map2(tool, evlist->core.threads, pr= ocess, NULL); + err =3D perf_event__synthesize_thread_map2(tool, evlist__core(evlist)->th= reads, + process, /*machine=3D*/NULL); if (err < 0) { pr_err("Couldn't synthesize thread map.\n"); return err; } =20 - err =3D perf_event__synthesize_cpu_map(tool, evlist->core.user_requested_= cpus, process, NULL); + err =3D perf_event__synthesize_cpu_map(tool, + evlist__core(evlist)->user_requested_cpus, + process, /*machine=3D*/NULL); if (err < 0) { pr_err("Couldn't synthesize thread map.\n"); return err; @@ -2501,7 +2504,7 @@ int perf_event__synthesize_for_pipe(const struct perf= _tool *tool, ret +=3D err; =20 #ifdef HAVE_LIBTRACEEVENT - if (have_tracepoints(&evlist->core.entries)) { + if (have_tracepoints(&evlist__core(evlist)->entries)) { int fd =3D perf_data__fd(data); =20 /* diff --git a/tools/perf/util/time-utils.c b/tools/perf/util/time-utils.c index d43c4577d7eb..5558a5a0fea4 100644 --- a/tools/perf/util/time-utils.c +++ b/tools/perf/util/time-utils.c @@ -473,8 +473,8 @@ int perf_time__parse_for_ranges_reltime(const char *tim= e_str, return -ENOMEM; =20 if (has_percent || reltime) { - if (session->evlist->first_sample_time =3D=3D 0 && - session->evlist->last_sample_time =3D=3D 0) { + if (evlist__first_sample_time(session->evlist) =3D=3D 0 && + evlist__last_sample_time(session->evlist) =3D=3D 0) { pr_err("HINT: no first/last sample time found in perf data.\n" "Please use latest perf binary to execute 'perf record'\n" "(if '--buildid-all' is enabled, please set '--timestamp-boundar= y').\n"); @@ -486,8 +486,8 @@ int perf_time__parse_for_ranges_reltime(const char *tim= e_str, num =3D perf_time__percent_parse_str( ptime_range, size, time_str, - session->evlist->first_sample_time, - session->evlist->last_sample_time); + evlist__first_sample_time(session->evlist), + evlist__last_sample_time(session->evlist)); } else { num =3D perf_time__parse_strs(ptime_range, time_str, size); } @@ -499,8 +499,8 @@ int perf_time__parse_for_ranges_reltime(const char *tim= e_str, int i; =20 for (i =3D 0; i < num; i++) { - ptime_range[i].start +=3D session->evlist->first_sample_time; - ptime_range[i].end +=3D session->evlist->first_sample_time; + ptime_range[i].start +=3D evlist__first_sample_time(session->evlist); + ptime_range[i].end +=3D evlist__first_sample_time(session->evlist); } } =20 diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index b06e10a116bb..851a26be6931 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c @@ -71,7 +71,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, ch= ar *bf, size_t size) esamples_percent); } =20 - if (top->evlist->core.nr_entries =3D=3D 1) { + if (evlist__nr_entries(top->evlist) =3D=3D 1) { struct evsel *first =3D evlist__first(top->evlist); ret +=3D SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ", (uint64_t)first->core.attr.sample_period, @@ -94,7 +94,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, ch= ar *bf, size_t size) else ret +=3D SNPRINTF(bf + ret, size - ret, " (all"); =20 - nr_cpus =3D perf_cpu_map__nr(top->evlist->core.user_requested_cpus); + nr_cpus =3D perf_cpu_map__nr(evlist__core(top->evlist)->user_requested_cp= us); if (target->cpu_list) ret +=3D SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)", nr_cpus > 1 ? "s" : "", --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75A72390615 for ; Fri, 22 May 2026 22:05:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487509; cv=none; b=pjGMAA+TmIlNP2VQARiGnCclT/MFvr7epgtFZRoYLSledTS9STYvkniO+G94LRw53OAl/SzxXHCk8mFY/PNuaXRUi4gr2NtzGTCovnNbY4zalLsR+doWShuIvfcRpH7GugbmJlAMe0Pdh5tuM5cq52FGfXi67XkZdVhGuFGZrTU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487509; c=relaxed/simple; bh=M0rwChGT90H425KH15dEkzggJKx9AS7L316Ocxgc/2U=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=cCCymsegRauS+gkIMZACfKPofgnkTwU6FBfVdmcPUaYZQqg8G5/QrFyLv1RYJKOTgPtIoxgOizOxDYrOrJKWHMQFFKFtuOsXwZlUxVgtCVDGsn+KcyLi5hMXh/GjaYhTOnYnBNkLdvbx6ifveVRmJi1boc/3k2X9m8NU9Ngm5sg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ISVOH+7h; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ISVOH+7h" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2f3ec2e8d07so4657756eec.1 for ; Fri, 22 May 2026 15:05:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487507; x=1780092307; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=sDdmXqvEMI43mhKt8ZAE/A+JQXqAF6Df2G8xQMsdPH0=; b=ISVOH+7h60wQYOqyjSyFeRIKpMOztqLIsWq4w98grkA7GT27Y2124hL8ebnnGVMuHy ouYnPrZUml1J+2E4WZ32LHKEN9uDwgMLRHbrGI/HrmX79vM11O39OLRlwol0tdnuVyhq ZAacv14jRa+aRYqW/HtKCgfWUEUIlqk+i1Tyc3s9ID9Q067QJbl+Is4AOhXrrlIf2o1z HrvEkYjUncIeu2p4KzuLzRmNy3Z3dfQqTJy3z+AqUoS+glN9VrW14wtaeQlYoBPJbArb 3iADS1ZxjwuV3hhIUOb3QgianhlFUPacnBcMKW9vLKBkqVPBYPAVfbb/9PAIbMsLXOV/ 3R/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487507; x=1780092307; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=sDdmXqvEMI43mhKt8ZAE/A+JQXqAF6Df2G8xQMsdPH0=; b=M7zUiqG0et3v9kg7Ewse+0r/evROzjDLdlsGipZLrgK04PMLGuK1QC0mTCE5tE7ccl EdcX5YMhOFRO6IHCY+dI+Jfidb4876k1LUfC9QSMHCepnS9M5uk9Wct6BdlSciPmDUAu SDlc42gndWjkU7QqzUAr4VYc51vNGkkzTiOnAVrcOcL2b1o77Mgp49EM7rZhafUFMldQ mGdQzR48gj23Q+MSEuSj0pJsQ61lgEFZrAq8ZlIJ1Sy0XdErDVGh9ClPw3pwFEekeBVN k0ZllHAaoB25i4q2ZoW3cLYn8DM5l3xkut+/mcvTYpIf05fXLfkwP/QM6Ln1ML/m6H5Z e4mg== X-Forwarded-Encrypted: i=1; AFNElJ9Z/N3eJZGqEj/MWbXDsqbrrBadzcCnY5jueDmB0cURTCgeqQEHrrC0z01sbY3QGDoWP5bqMXPgswgyZiY=@vger.kernel.org X-Gm-Message-State: AOJu0YxXUHuQE84cyBB1USQaCmEMyMvc4eJMG7Lhm4wuv2sa5Kw3ep3T hxNM7cblUzLc8GaFUm+krMvv/8Olq0KBQB6A3ymGKrTecdTkSUrIFhqYYudq8nY9QJ9ky0veuBc 7cVj0SaoIew== X-Received: from dybtv21.prod.google.com ([2002:a05:7300:f495:b0:2f9:af7:503f]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:7f9f:b0:2d8:97d6:6ac8 with SMTP id 5a478bee46e88-30449141470mr2895866eec.21.1779487506383; Fri, 22 May 2026 15:05:06 -0700 (PDT) Date: Fri, 22 May 2026 15:04:23 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-13-irogers@google.com> Subject: [PATCH v9 12/23] perf python: Use evsel in sample in pyrf_event From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Avoid a duplicated evsel by using the one in sample. Add evsel__get/put to the evsel in perf_sample. Signed-off-by: Ian Rogers --- tools/perf/util/evsel.c | 2 +- tools/perf/util/python.c | 10 +++------- tools/perf/util/sample.c | 17 ++++++++++++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 37e8950ee990..957983e4fd53 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3244,7 +3244,7 @@ int evsel__parse_sample(struct evsel *evsel, union pe= rf_event *event, union u64_swap u; =20 perf_sample__init(data, /*all=3D*/true); - data->evsel =3D evsel; + data->evsel =3D evsel__get(evsel); data->cpu =3D data->pid =3D data->tid =3D -1; data->stream_id =3D data->id =3D data->time =3D -1ULL; data->period =3D evsel->core.attr.sample_period; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 7778f88c3810..e14e857cf90b 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -45,7 +45,6 @@ PyMODINIT_FUNC PyInit_perf(void); =20 struct pyrf_event { PyObject_HEAD - struct evsel *evsel; struct perf_sample sample; union perf_event event; }; @@ -276,7 +275,6 @@ static PyMemberDef pyrf_sample_event__members[] =3D { =20 static void pyrf_sample_event__delete(struct pyrf_event *pevent) { - evsel__put(pevent->evsel); perf_sample__exit(&pevent->sample); Py_TYPE(pevent)->tp_free((PyObject*)pevent); } @@ -298,7 +296,7 @@ static PyObject *pyrf_sample_event__repr(const struct p= yrf_event *pevent) #ifdef HAVE_LIBTRACEEVENT static bool is_tracepoint(const struct pyrf_event *pevent) { - return pevent->evsel->core.attr.type =3D=3D PERF_TYPE_TRACEPOINT; + return pevent->sample.evsel->core.attr.type =3D=3D PERF_TYPE_TRACEPOINT; } =20 static PyObject* @@ -345,7 +343,7 @@ tracepoint_field(const struct pyrf_event *pe, struct te= p_format_field *field) static PyObject* get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name) { - struct evsel *evsel =3D pevent->evsel; + struct evsel *evsel =3D pevent->sample.evsel; struct tep_event *tp_format =3D evsel__tp_format(evsel); struct tep_format_field *field; =20 @@ -511,7 +509,7 @@ static PyObject *pyrf_event__new(const union perf_event= *event) pevent =3D PyObject_New(struct pyrf_event, ptype); if (pevent !=3D NULL) { memcpy(&pevent->event, event, event->header.size); - pevent->evsel =3D NULL; + perf_sample__init(&pevent->sample, /*all=3D*/false); } return (PyObject *)pevent; } @@ -1802,8 +1800,6 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf= _evlist *pevlist, return Py_None; } =20 - pevent->evsel =3D evsel__get(evsel); - perf_mmap__consume(&md->core); =20 err =3D evsel__parse_sample(evsel, &pevent->event, &pevent->sample); diff --git a/tools/perf/util/sample.c b/tools/perf/util/sample.c index cf73329326d7..bccc19e2aaf2 100644 --- a/tools/perf/util/sample.c +++ b/tools/perf/util/sample.c @@ -1,18 +1,23 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include "sample.h" + +#include +#include + +#include +#include + +#include "../../arch/x86/include/asm/insn.h" #include "debug.h" +#include "evsel.h" #include "thread.h" -#include + #ifndef EM_CSKY #define EM_CSKY 252 #endif #ifndef EM_LOONGARCH #define EM_LOONGARCH 258 #endif -#include -#include -#include -#include "../../arch/x86/include/asm/insn.h" =20 void perf_sample__init(struct perf_sample *sample, bool all) { @@ -29,6 +34,8 @@ void perf_sample__init(struct perf_sample *sample, bool a= ll) =20 void perf_sample__exit(struct perf_sample *sample) { + evsel__put(sample->evsel); + sample->evsel =3D NULL; zfree(&sample->user_regs); zfree(&sample->intr_regs); if (sample->merged_callchain) { --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2682339150B for ; Fri, 22 May 2026 22:05:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487512; cv=none; b=Y7i95TwOuQprlAwZ5NemUpgVRVPtjUoy0CVqjZvKU+F/XGxBX5yaMmRGgFAR4sv2QcrQ64+U6G9hBjdGJ8DP5wvPRwnMTmKQtwrl/qw0+pzEr815I62L/w6/65aU3wG68arDk+8SK62NOZKBACaLV3S+IFxZmh7V4eYRfwhP6oE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487512; c=relaxed/simple; bh=R4trJEEv81oL2VTeqiSNBIQO4kDyBrBmJ4whvqXqDUk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=cr1A/A0gTxnmhpQJT69G/xvkMQuLSOmorZ6zrCe9hBe9PSipAOGU10abHEGPvfm+VFiq5Q5iN9kK8iRtKDR1uTQjxmlTc9BT/oweOO0DVUXMVAHOH2acbu5FWzZNUd+ICRBBMFeEvb+21hKl1QyiTe4HSQPbrOZ+iqYp2l/ge4E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=vMnoV2/h; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="vMnoV2/h" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2fded513994so521566eec.1 for ; Fri, 22 May 2026 15:05:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487510; x=1780092310; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=wzVRJfCxGadSbc6h6w850uaNmmNm6HgXxyQYTuFPM3I=; b=vMnoV2/h76vnZwjQymHaNK3e8Plj96BfRMUmAtr97KitlOPmgNsykLye4nH6+6skBS S9eH7/8qnCmYb7v+0Gfjdpg54hJGujZOTZ2lsJrxD30XINltm/VVcXJ47tMgTjuShj7A ropWcW3hJWUInDWEI4Ebh349haMEQWs/eUjjBwPHnw/L0BcIShIrbrxGIzqTnFG499Gy j8NE+P5D7aevzhJp+VKGqkkQRI9sQFpCRHjb9P1eeUUISVF22n4m+cWuz+BjjWLNcMxS bLoJI9puocERfeSt/ihNTi/zPJthmlOjtvqdr4H76j7UyXb3WPsu+QU2Qqs7PLoFekA4 pwig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487510; x=1780092310; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wzVRJfCxGadSbc6h6w850uaNmmNm6HgXxyQYTuFPM3I=; b=byD09bniaJCSiB5b09dVM0LRouc5ceuRuFE3v7Gk+K7CvXmV0avjipyvk7mdOYgxd6 8htAjuzFV0fE0F9vJX6hx9Q5ZNCiXlPjS2VMVx7Ll60deLZP+/IdrlH8DH375YdvrjDI QePeqN3oyVO7nfZwavtgcZdvOM6dymT9P7qgmH5rc0weFWHtkblH3fxMyBdzNRni2d1d Ie5la2XEisz1hGI32I6u0sQaomrN6rhC3zxRfcoUplIElvA9YFr4ExgxZU2M5Fs0aon1 YXyZ8EKvtGwb5G3OUYzYt08rEWpHEzYAKxgGxQWYdomslQ52wdLbWVElqUPCW4KzGe2h j2pg== X-Forwarded-Encrypted: i=1; AFNElJ8+qGPW35Ue83AwerzQ7AYl+bNyOu0UJ+CH07tgjaDwmhIuP11V2FPFKS0c85bjjOC8kDGrN8WmUnSBxMs=@vger.kernel.org X-Gm-Message-State: AOJu0YwtPE7SRaqVrkYLF4TpJkAcmsT4ydYsTCap6xhIWclEL1+pamH1 SacYc/GGTJaKEEWfsiJTWy+GNxC6RqfRfOfVtRIMbqhWEXyV1HNwoKZdr4QK9oZ2IrbHijQ5o+C tCR8Qw1g+YQ== X-Received: from dyem6.prod.google.com ([2002:a05:7300:8186:b0:2f6:cacc:a338]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:693c:638d:20b0:304:4f23:68d3 with SMTP id 5a478bee46e88-3044f2446d3mr1287805eec.18.1779487508392; Fri, 22 May 2026 15:05:08 -0700 (PDT) Date: Fri, 22 May 2026 15:04:24 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-14-irogers@google.com> Subject: [PATCH v9 13/23] perf python: Add wrapper for perf_data file abstraction From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The perf_data struct is needed for session supported. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- v2: 1. Fixed Memory & FD Leaks in pyrf_data__init : Added cleanup of old state (closing file and freeing path) if __init__ is called multiple times on the same object. 2. Fixed Invalid Free in pyrf_data__delete : Ensured pdata->data.path is always dynamically allocated via strdup() , even for the default "perf.data" . This avoids passing a static string literal to free(). 3. Fixed NULL Pointer Dereference in pyrf_data__str : Added a check for NULL path to prevent segfaults if str() or repr() is called on an uninitialized object. 4. Guarded fd Argument Usage: Added a check to ensure that if an fd is provided, it corresponds to a pipe, failing gracefully with a ValueError otherwise. v7: - Added pyrf_data__new to zero-initialize pdata->data to fix crash on re-initialization. --- tools/perf/util/python.c | 103 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index e14e857cf90b..82adc59ecd94 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -12,6 +12,7 @@ =20 #include "callchain.h" #include "counts.h" +#include "data.h" #include "event.h" #include "evlist.h" #include "evsel.h" @@ -2320,6 +2321,102 @@ static PyObject *pyrf__metrics(PyObject *self, PyOb= ject *args) return list; } =20 +struct pyrf_data { + PyObject_HEAD + + struct perf_data data; +}; + +static int pyrf_data__init(struct pyrf_data *pdata, PyObject *args, PyObje= ct *kwargs) +{ + static char *kwlist[] =3D { "path", "fd", NULL }; + char *path =3D NULL; + int fd =3D -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &path, &fd)) + return -1; + + if (pdata->data.open) + perf_data__close(&pdata->data); + free((char *)pdata->data.path); + + if (!path) + path =3D "perf.data"; + + pdata->data.path =3D strdup(path); + if (!pdata->data.path) { + PyErr_NoMemory(); + return -1; + } + + if (fd !=3D -1) { + struct stat st; + + if (fstat(fd, &st) < 0 || !S_ISFIFO(st.st_mode)) { + PyErr_SetString(PyExc_ValueError, + "fd argument is only supported for pipes"); + free((char *)pdata->data.path); + pdata->data.path =3D NULL; + return -1; + } + } + + pdata->data.mode =3D PERF_DATA_MODE_READ; + pdata->data.file.fd =3D fd; + if (perf_data__open(&pdata->data) < 0) { + PyErr_Format(PyExc_IOError, "Failed to open perf data: %s", + pdata->data.path ? pdata->data.path : "perf.data"); + return -1; + } + return 0; +} + +static void pyrf_data__delete(struct pyrf_data *pdata) +{ + perf_data__close(&pdata->data); + free((char *)pdata->data.path); + Py_TYPE(pdata)->tp_free((PyObject *)pdata); +} + +static PyObject *pyrf_data__str(PyObject *self) +{ + const struct pyrf_data *pdata =3D (const struct pyrf_data *)self; + + if (!pdata->data.path) + return PyUnicode_FromString("[uninitialized]"); + return PyUnicode_FromString(pdata->data.path); +} + +static PyObject *pyrf_data__new(PyTypeObject *type, PyObject *args, PyObje= ct *kwargs) +{ + struct pyrf_data *pdata; + + pdata =3D (struct pyrf_data *)PyType_GenericNew(type, args, kwargs); + if (pdata) + memset(&pdata->data, 0, sizeof(pdata->data)); + return (PyObject *)pdata; +} + +static const char pyrf_data__doc[] =3D PyDoc_STR("perf data file object."); + +static PyTypeObject pyrf_data__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.data", + .tp_basicsize =3D sizeof(struct pyrf_data), + .tp_dealloc =3D (destructor)pyrf_data__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_doc =3D pyrf_data__doc, + .tp_init =3D (initproc)pyrf_data__init, + .tp_repr =3D pyrf_data__str, + .tp_str =3D pyrf_data__str, +}; + +static int pyrf_data__setup_types(void) +{ + pyrf_data__type.tp_new =3D pyrf_data__new; + return PyType_Ready(&pyrf_data__type); +} + static PyMethodDef perf__methods[] =3D { { .ml_name =3D "metrics", @@ -2382,7 +2479,8 @@ PyMODINIT_FUNC PyInit_perf(void) pyrf_cpu_map__setup_types() < 0 || pyrf_pmu_iterator__setup_types() < 0 || pyrf_pmu__setup_types() < 0 || - pyrf_counts_values__setup_types() < 0) + pyrf_counts_values__setup_types() < 0 || + pyrf_data__setup_types() < 0) return module; =20 /* The page_size is placed in util object. */ @@ -2430,6 +2528,9 @@ PyMODINIT_FUNC PyInit_perf(void) Py_INCREF(&pyrf_counts_values__type); PyModule_AddObject(module, "counts_values", (PyObject *)&pyrf_counts_valu= es__type); =20 + Py_INCREF(&pyrf_data__type); + PyModule_AddObject(module, "data", (PyObject *)&pyrf_data__type); + dict =3D PyModule_GetDict(module); if (dict =3D=3D NULL) goto error; --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A768A391513 for ; Fri, 22 May 2026 22:05:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487513; cv=none; b=SIB0BdZxe6G0D9xJD4ytVt38+tZDcnJsRQ1NmSPCO9GAHWgRCGyf5dGI2PA0vA07pzIi64Hs7/58RGIWwv5dwKttfXXuPvMPABgrU5Qb2nPEREg+ozyM6RivYtUWSN+/19YOBtkLgAt0ZmHxXtB2gM+8QDrNJamUf7YGcydVLsM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487513; c=relaxed/simple; bh=gvBptQKaSgmfUfS145HUmhgpMcvrH5P5Pz4UOhnaArg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=J2vCD0zmkNr5x+srgzGhE6wILNlthAVjxJ2HVqaUxPwizzrmJUO6NBU2hmbiZJ1jFS7eZWiWVpbyr/RC3AFcI1hTlotjW5tTqh5dtRiLq050196O2zAlxtO1pLpApcrF7No2SVr5sQRmLtfXNNOPCDZXBOpHzQW0w/ExHNpBUu4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=dEfe6vdQ; arc=none smtp.client-ip=74.125.82.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dEfe6vdQ" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-1353bfdbf99so10481054c88.0 for ; Fri, 22 May 2026 15:05:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487511; x=1780092311; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=xoBU3gZcurjcKHYbf58ZwDiLxFElSjco1fizLq6p168=; b=dEfe6vdQyiA8Zi4f2iLVk3pUwmZ0fehShiUZSne5b3Fpa51WZwBwpm9ZadB4qyFJzE iJsp7axCNd+GIFbG8iyb9u44FeAM3aa17Vf7FhmKpbhVBdDVDwYiwhC1nR/ZF7wEdmGs VlWNt6GD3wu+KUpujiH8irxOOpU61bWP9qkP53zdK12LRZoUXoHxOZLwCXRKFS6hxJz5 55GUfMSHAJLlM0p34KUP2/nhuMM7gXabdTputctvvajIegKK8URQssESJL0hObkJvWww dz7Gd1w3K+90N6njnrt2+WfVvpuEhZTM+oiEdvAE+MvL8/547DsJTO9ZltOBtqdTPuOL NWsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487511; x=1780092311; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=xoBU3gZcurjcKHYbf58ZwDiLxFElSjco1fizLq6p168=; b=mHGzit3u7h95XAB6XKgsBPx0Es62VlYlxlSkCnerbmMFAnFfYu+Y1Rz+DkyShbgITj HXKFjHLcMtoKZA2b7S9MNhHCG9wPbOXJWQOJm+fSPBmLTlbL5jHVoKEToiHkS8mWzReQ Enu41aVzWBR5Hdi++Ncq5aGRZ3D9JrLo0ZQKNaxH83hSORxZTH/RInDWPY/WmD0u8uzz isePqlBqCfOExkbtm9wgWx1NV/uU+u7EE3a/QrbevjY3x8K5cZXeY9jogGqExIvhjrgL FIy/lHqOBhG2MvKHCfEHvi2kHebGZ5eWbpJj9oPFZnmO3lpiXTN+kpNEVZ/2guZiYELo IUxA== X-Forwarded-Encrypted: i=1; AFNElJ98ueUJWZ7reLPUkcxziBxe6OW+oyfR4sU8ftOy2OB8MwdjYLnWZpaRuFwpszfZHnqPu1UEycBaiUam1mI=@vger.kernel.org X-Gm-Message-State: AOJu0YwewLVM6LsM5j9gFzWqfaf+sD0HCKJiRpkIkoKfIjg7DSfjqh3V E6CAUxrp9QYIeY9tpAlCWG1RoM3EF+evYCfayvsGn4cSYC0pNytmgz2TwtHi37DFSPzVeZKE4qt VNxCp9QA6bQ== X-Received: from dlbrh17.prod.google.com ([2002:a05:7022:f311:b0:136:6230:5814]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:fa9:b0:11b:f056:a19b with SMTP id a92af1059eb24-1365f926a43mr2243202c88.18.1779487510178; Fri, 22 May 2026 15:05:10 -0700 (PDT) Date: Fri, 22 May 2026 15:04:25 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-15-irogers@google.com> Subject: [PATCH v9 14/23] perf python: Add python session abstraction wrapping perf's session From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Sessions are necessary to be able to use perf.data files within a tool. Add a wrapper python type that incorporates the tool. Allow a sample callback to be passed when creating the session. When process_events is run this callback will be called, if supplied, for sample events. An example use looks like: ``` $ perf record -e cycles,instructions -a sleep 3 $ PYTHONPATH=3D..../perf/python python3 Python 3.13.7 (main, Aug 20 2025, 22:17:40) [GCC 14.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import perf >>> count=3D0 ... def handle_sample(x): ... global count ... if count < 3: ... print(dir(x)) ... count =3D count + 1 ... perf.session(perf.data("perf.data"),sample=3Dhandle_sample).process_eve= nts() ... ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', = '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init= __', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduc= e__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', = '__subclasshook__', 'sample_addr', 'sample_cpu', 'sample_id', 'sample_ip', = 'sample_period', 'sample_pid', 'sample_stream_id', 'sample_tid', 'sample_ti= me', 'type'] ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', = '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init= __', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduc= e__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', = '__subclasshook__', 'sample_addr', 'sample_cpu', 'sample_id', 'sample_ip', = 'sample_period', 'sample_pid', 'sample_stream_id', 'sample_tid', 'sample_ti= me', 'type'] ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', = '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init= __', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduc= e__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', = '__subclasshook__', 'sample_addr', 'sample_cpu', 'sample_id', 'sample_ip', = 'sample_period', 'sample_pid', 'sample_stream_id', 'sample_tid', 'sample_ti= me', 'type'] ``` Also, add the ability to get the thread associated with a session. For threads, allow the comm string to be retrieved. This can be useful for filtering threads. Connect up some of the standard event handling in psession->tool to better support queries of the machine. Also connect up the symbols. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- v2: 1. Fixed Potential Crash in pyrf_thread__comm : Used thread__comm_str() to safely retrieve the command name, avoiding a crash if thread__comm() returns NULL. 2. Fixed Double Free Risk: Zeroed out user_regs , intr_regs , and callchain in the shallow copy of perf_sample to prevent Python from attempting to free pointers it doesn't own. 3. Fixed Memory Leak & Exception Handling in Callback: Handled the return value of PyObject_CallFunction() to avoid leaks, and checked for failure to abort the loop and propagate Python exceptions cleanly. 4. Enforced Type Safety: Used O! with &pyrf_data__type in PyArg_ParseTupleAndKeywords to prevent bad casts from passing arbitrary objects as perf.data. 5. Added Missing Build ID Handler: Registered perf_event__process_build_id to allow correct symbol resolution. 6. Fixed Double Free Crash on Init Failure: Set session and pdata to NULL on failure to prevent tp_dealloc from double-freeing them. 7. Preserved C-level Errors: Made pyrf_session__process_events return the error code integer rather than always returning None . v7: - Fixed NULL comm handling. - Avoided swallowing exceptions in module init. - Fixed checkpatch warning for missing blank line. v8: - Switch from pyrf_session__init to pyrf_session__new to avoid dealing with= a potentially NULL session variable. - Added pid, tid, ppid, and cpu attributes to perf.thread. --- tools/perf/util/python.c | 310 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 304 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 82adc59ecd94..18a48779c591 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -11,8 +11,10 @@ #include =20 #include "callchain.h" +#include "comm.h" #include "counts.h" #include "data.h" +#include "debug.h" #include "event.h" #include "evlist.h" #include "evsel.h" @@ -22,8 +24,12 @@ #include "pmus.h" #include "print_binary.h" #include "record.h" +#include "session.h" #include "strbuf.h" +#include "symbol.h" +#include "thread.h" #include "thread_map.h" +#include "tool.h" #include "tp_pmu.h" #include "trace-event.h" #include "util/sample.h" @@ -2417,6 +2423,287 @@ static int pyrf_data__setup_types(void) return PyType_Ready(&pyrf_data__type); } =20 +struct pyrf_thread { + PyObject_HEAD + + struct thread *thread; +}; + +static void pyrf_thread__delete(struct pyrf_thread *pthread) +{ + thread__put(pthread->thread); + Py_TYPE(pthread)->tp_free((PyObject *)pthread); +} + +static PyObject *pyrf_thread__comm(PyObject *obj) +{ + struct pyrf_thread *pthread =3D (void *)obj; + const char *str =3D thread__comm_str(pthread->thread); + + if (!str) + Py_RETURN_NONE; + + return PyUnicode_FromString(str); +} + +static PyMethodDef pyrf_thread__methods[] =3D { + { + .ml_name =3D "comm", + .ml_meth =3D (PyCFunction)pyrf_thread__comm, + .ml_flags =3D METH_NOARGS, + .ml_doc =3D PyDoc_STR("Comm(and) associated with this thread.") + }, + { .ml_name =3D NULL, } +}; + +static PyObject *pyrf_thread__get_pid(struct pyrf_thread *pthread, void *c= losure __maybe_unused) +{ + return PyLong_FromLong(thread__pid(pthread->thread)); +} + +static PyObject *pyrf_thread__get_tid(struct pyrf_thread *pthread, void *c= losure __maybe_unused) +{ + return PyLong_FromLong(thread__tid(pthread->thread)); +} + +static PyObject *pyrf_thread__get_ppid(struct pyrf_thread *pthread, void *= closure __maybe_unused) +{ + return PyLong_FromLong(thread__ppid(pthread->thread)); +} + +static PyObject *pyrf_thread__get_cpu(struct pyrf_thread *pthread, void *c= losure __maybe_unused) +{ + return PyLong_FromLong(thread__cpu(pthread->thread)); +} + +static PyGetSetDef pyrf_thread__getset[] =3D { + { .name =3D "pid", .get =3D (getter)pyrf_thread__get_pid, .doc =3D "proce= ss ID" }, + { .name =3D "tid", .get =3D (getter)pyrf_thread__get_tid, .doc =3D "threa= d ID" }, + { .name =3D "ppid", .get =3D (getter)pyrf_thread__get_ppid, .doc =3D "par= ent process ID" }, + { .name =3D "cpu", .get =3D (getter)pyrf_thread__get_cpu, .doc =3D "cpu n= umber" }, + { .name =3D NULL } +}; + +static const char pyrf_thread__doc[] =3D PyDoc_STR("perf thread object."); + +static PyTypeObject pyrf_thread__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.thread", + .tp_basicsize =3D sizeof(struct pyrf_thread), + .tp_dealloc =3D (destructor)pyrf_thread__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_methods =3D pyrf_thread__methods, + .tp_getset =3D pyrf_thread__getset, + .tp_doc =3D pyrf_thread__doc, +}; + +static int pyrf_thread__setup_types(void) +{ + return PyType_Ready(&pyrf_thread__type); +} + +static PyObject *pyrf_thread__from_thread(struct thread *thread) +{ + struct pyrf_thread *pthread =3D PyObject_New(struct pyrf_thread, &pyrf_th= read__type); + + if (!pthread) + return NULL; + + pthread->thread =3D thread__get(thread); + return (PyObject *)pthread; +} + +struct pyrf_session { + PyObject_HEAD + + struct perf_session *session; + struct perf_tool tool; + struct pyrf_data *pdata; + PyObject *sample; +}; + +static int pyrf_session_tool__sample(const struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample, + struct machine *machine __maybe_unused) +{ + struct pyrf_session *psession =3D container_of(tool, struct pyrf_session,= tool); + PyObject *pyevent =3D pyrf_event__new(event); + struct pyrf_event *pevent =3D (struct pyrf_event *)pyevent; + PyObject *ret; + + if (pyevent =3D=3D NULL) + return -ENOMEM; + + memcpy(&pevent->event, event, event->header.size); + if (evsel__parse_sample(sample->evsel, &pevent->event, &pevent->sample) <= 0) { + Py_DECREF(pyevent); + return -1; + } + + ret =3D PyObject_CallFunction(psession->sample, "O", pyevent); + if (!ret) { + Py_DECREF(pyevent); + return -1; + } + Py_DECREF(ret); + Py_DECREF(pyevent); + return 0; +} + +static PyObject *pyrf_session__find_thread(struct pyrf_session *psession, = PyObject *args) +{ + struct machine *machine; + struct thread *thread =3D NULL; + PyObject *result; + int pid; + + if (!PyArg_ParseTuple(args, "i", &pid)) + return NULL; + + machine =3D &psession->session->machines.host; + thread =3D machine__find_thread(machine, pid, pid); + + if (!thread) { + machine =3D perf_session__find_machine(psession->session, pid); + if (machine) + thread =3D machine__find_thread(machine, pid, pid); + } + + if (!thread) { + PyErr_Format(PyExc_TypeError, "Failed to find thread %d", pid); + return NULL; + } + result =3D pyrf_thread__from_thread(thread); + thread__put(thread); + return result; +} + +static PyObject *pyrf_session__new(PyTypeObject *type, PyObject *args, PyO= bject *kwargs) +{ + struct pyrf_data *pdata; + PyObject *sample =3D NULL; + static char *kwlist[] =3D { "data", "sample", NULL }; + struct pyrf_session *psession; + struct perf_session *session; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist, &pyrf_data= __type, &pdata, + &sample)) + return NULL; + + psession =3D PyObject_New(struct pyrf_session, type); + if (!psession) + return NULL; + + psession->session =3D NULL; + psession->sample =3D NULL; + psession->pdata =3D NULL; + + Py_INCREF(pdata); + psession->pdata =3D pdata; + + perf_tool__init(&psession->tool, /*ordered_events=3D*/true); + psession->tool.ordering_requires_timestamps =3D true; + + #define ADD_TOOL(name) \ + do { \ + if (name) { \ + if (!PyCallable_Check(name)) { \ + PyErr_SetString(PyExc_TypeError, #name " must be callable"); \ + goto err_out; \ + } \ + psession->tool.name =3D pyrf_session_tool__##name; \ + Py_INCREF(name); \ + psession->name =3D name; \ + } \ + } while (0) + + ADD_TOOL(sample); + #undef ADD_TOOL + + psession->tool.comm =3D perf_event__process_comm; + psession->tool.mmap =3D perf_event__process_mmap; + psession->tool.mmap2 =3D perf_event__process_mmap2; + psession->tool.namespaces =3D perf_event__process_namespaces; + psession->tool.cgroup =3D perf_event__process_cgroup; + psession->tool.exit =3D perf_event__process_exit; + psession->tool.fork =3D perf_event__process_fork; + psession->tool.ksymbol =3D perf_event__process_ksymbol; + psession->tool.text_poke =3D perf_event__process_text_poke; + psession->tool.build_id =3D perf_event__process_build_id; + session =3D perf_session__new(&pdata->data, &psession->tool); + if (IS_ERR(session)) { + PyErr_Format(PyExc_IOError, "failed to create session: %ld", PTR_ERR(ses= sion)); + goto err_out; + } + psession->session =3D session; + + if (symbol__init(perf_session__env(session)) < 0) { + PyErr_SetString(PyExc_OSError, "perf: symbol__init failed"); + goto err_out; + } + + if (perf_session__create_kernel_maps(session) < 0) + pr_warning("Cannot read kernel map\n"); + + return (PyObject *)psession; +err_out: + Py_DECREF(psession); + return NULL; +} + +static void pyrf_session__delete(struct pyrf_session *psession) +{ + perf_session__delete(psession->session); + Py_XDECREF(psession->pdata); + Py_XDECREF(psession->sample); + Py_TYPE(psession)->tp_free((PyObject *)psession); +} + +static PyObject *pyrf_session__find_thread_events(struct pyrf_session *pse= ssion) +{ + int err =3D perf_session__process_events(psession->session); + + if (PyErr_Occurred()) + return NULL; + + return PyLong_FromLong(err); +} + +static PyMethodDef pyrf_session__methods[] =3D { + { + .ml_name =3D "process_events", + .ml_meth =3D (PyCFunction)pyrf_session__find_thread_events, + .ml_flags =3D METH_NOARGS, + .ml_doc =3D PyDoc_STR("Iterate and process events.") + }, + { + .ml_name =3D "find_thread", + .ml_meth =3D (PyCFunction)pyrf_session__find_thread, + .ml_flags =3D METH_VARARGS, + .ml_doc =3D PyDoc_STR("Returns the thread associated with a pid.") + }, + { .ml_name =3D NULL, } +}; + +static const char pyrf_session__doc[] =3D PyDoc_STR("perf session object."= ); + +static PyTypeObject pyrf_session__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.session", + .tp_basicsize =3D sizeof(struct pyrf_session), + .tp_dealloc =3D (destructor)pyrf_session__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_methods =3D pyrf_session__methods, + .tp_doc =3D pyrf_session__doc, + .tp_new =3D pyrf_session__new, +}; + +static int pyrf_session__setup_types(void) +{ + return PyType_Ready(&pyrf_session__type); +} + static PyMethodDef perf__methods[] =3D { { .ml_name =3D "metrics", @@ -2471,8 +2758,10 @@ PyMODINIT_FUNC PyInit_perf(void) }; PyObject *module =3D PyModule_Create(&moduledef); =20 - if (module =3D=3D NULL || - pyrf_event__setup_types() < 0 || + if (module =3D=3D NULL) + return NULL; + + if (pyrf_event__setup_types() < 0 || pyrf_evlist__setup_types() < 0 || pyrf_evsel__setup_types() < 0 || pyrf_thread_map__setup_types() < 0 || @@ -2480,8 +2769,12 @@ PyMODINIT_FUNC PyInit_perf(void) pyrf_pmu_iterator__setup_types() < 0 || pyrf_pmu__setup_types() < 0 || pyrf_counts_values__setup_types() < 0 || - pyrf_data__setup_types() < 0) - return module; + pyrf_data__setup_types() < 0 || + pyrf_session__setup_types() < 0 || + pyrf_thread__setup_types() < 0) { + Py_DECREF(module); + return NULL; + } =20 /* The page_size is placed in util object. */ page_size =3D sysconf(_SC_PAGE_SIZE); @@ -2531,6 +2824,9 @@ PyMODINIT_FUNC PyInit_perf(void) Py_INCREF(&pyrf_data__type); PyModule_AddObject(module, "data", (PyObject *)&pyrf_data__type); =20 + Py_INCREF(&pyrf_session__type); + PyModule_AddObject(module, "session", (PyObject *)&pyrf_session__type); + dict =3D PyModule_GetDict(module); if (dict =3D=3D NULL) goto error; @@ -2544,7 +2840,9 @@ PyMODINIT_FUNC PyInit_perf(void) } =20 error: - if (PyErr_Occurred()) - PyErr_SetString(PyExc_ImportError, "perf: Init failed!"); + if (PyErr_Occurred()) { + Py_XDECREF(module); + return NULL; + } return module; } --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB762392C48 for ; Fri, 22 May 2026 22:05:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487518; cv=none; b=qSUryfdxY+fep+NUaA5r158BkARLeX1uL+sEZX8SHC6PZHqEzAP7Y4U8r+LlqEAZjlvT+U4TOPVu3wdQ8hZiUyfHNrFBS6jqhhgDr3QjhpfoFPqpP05sHWrsjfuLKSqEKSvLwEvUNjMJwkj0eHX3yZkTjRfOPLXvHtWye8ZPRY4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487518; c=relaxed/simple; bh=jJ1hq9UScThUWNy84KL5JsuzDNfEwEOzjcK9Vxfayms=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=TxdBKRv4i9I3v/pbcy2v12N+F8nWI6lhqAy3043JTDJ5p+s4GiJjOV9tDavesVAx6nf3VUzR/x10iy6n0Sle2wWWggm3c9+Mf/Bye+BhfH4ONWXR4G8kCGcTkNrZfZlmzgdRK5HRKRvALAK/FD2jlT9eNDg9V7Zqll/eWddN988= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=AZ7F/cdd; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AZ7F/cdd" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2ee34588671so8871723eec.0 for ; Fri, 22 May 2026 15:05:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487515; x=1780092315; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=vgwQv6hVW+kKgJ2hjv8Wx2O4MMy7o/9pGzID9sBFXtA=; b=AZ7F/cdda+j/SCjzpdMrBM325nZhFcOYbp2aLZcf2VFtmfSjGbtBuTUDy5C5Z+/Q6c ERhMWjWOFwC/bzKz32KIjaJ2bWbF99Jz6Rr7axhtTTE/t37K7OnGxyTHnqNFvAGEs02g Mvgd95nLZvhO0HrxYVsJn1CRgmEIeycMM4YwsLYPQKx4Tc9X3parpz3zhfXcevQ5Mt2Z BdHuyh3Id/Ai7pKq+X36wxFI1YrkfFKyZWrYUxHu+cXt3irDnVw2sv+svOPMSOpTM2dv rxmE75LyO9iX0ZmFbBoFP9oJdCTaYpKMZM/M6GMfulGAYjF7ABxar3AFNx6Z2AxKHCmX Zg6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487515; x=1780092315; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=vgwQv6hVW+kKgJ2hjv8Wx2O4MMy7o/9pGzID9sBFXtA=; b=iWK0GQVuCIckD6VcvPLIzELHKEuelqwv1dwPopihPkgXXXoQl1dKx4bZVSTH+sIXtL RJY/XUZGKI3O8VG9VaGmOlVF3YG1UxZwu2UrvjJrO9sv293qemnkD/Km/N5ZpCtwzMNr /KsXlba/m9FhTqq+HJyglNzu/yw+fY0QXcI4OX2LN30uoZHOJwlsXTBEwbeVc4usTN7M +gPDly8yi4lao2dPBGwo9v8D4FtiJ7sndYo55Kl3m0S98/vMUb9SoGkhopzKVL9QpJhu LxcynlmwTNHR1AbNCvu2TPvBg/trUeXvKSsaDTlNEiPV1roQ/kUFP0rSQH48tHM+HiIR P30w== X-Forwarded-Encrypted: i=1; AFNElJ/Tmmk9K+SGgk+YsfMLE1Qv/FAx3J4vatfW2cKgYrOtJeR7GHsHVWyVfrCSKU28NfLsY/l7ZF37kaODWPk=@vger.kernel.org X-Gm-Message-State: AOJu0Yw/Dh1juZ+bcHSW0CJwuu4XAK3dn3Xen0vfWgil6tJ1Mo86Wl04 JzrstCFBCivXwtqDhHP0Wneu0f/+ObEREBbSkjpfcZlPQoClbcyV+dj77IlkjPWhAPDYkoSZiz6 /rPuAz4yiUQ== X-Received: from dycac4.prod.google.com ([2002:a05:7301:5504:b0:2f9:af7:5047]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:9f05:b0:2ee:be86:7b90 with SMTP id 5a478bee46e88-3044912f80cmr2339689eec.29.1779487514868; Fri, 22 May 2026 15:05:14 -0700 (PDT) Date: Fri, 22 May 2026 15:04:26 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-16-irogers@google.com> Subject: [PATCH v9 15/23] perf python: Refactor and add accessors to sample event From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add common evsel field for events and move sample specific fields to only be present in sample events. Add accessors for sample events. Ensure offsets are within the bounds of the event. Allocate just enough memory for the copied event, don't make the maximum event size each time. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- v5: 1. Fix Uninitialized Memory: Restore zero-initialization of `pevent->sample` in `pyrf_event__new()` to prevent wild free crashes on error paths. v6: - Refactored `pyrf_event__new` to take `evsel` and `session`, and use dynamic allocation based on event size. Updated callers. v8: - Ensure events are properly deallocated. --- tools/perf/util/python.c | 618 +++++++++++++++++++++++++++++++++------ 1 file changed, 534 insertions(+), 84 deletions(-) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 18a48779c591..029915b7a1fe 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -10,21 +10,28 @@ #include #include =20 +#include "addr_location.h" +#include "build-id.h" #include "callchain.h" #include "comm.h" #include "counts.h" #include "data.h" #include "debug.h" +#include "dso.h" #include "event.h" #include "evlist.h" #include "evsel.h" #include "expr.h" +#include "map.h" #include "metricgroup.h" #include "mmap.h" #include "pmus.h" #include "print_binary.h" #include "record.h" +#include "sample.h" #include "session.h" +#include "srccode.h" +#include "srcline.h" #include "strbuf.h" #include "symbol.h" #include "thread.h" @@ -32,7 +39,6 @@ #include "tool.h" #include "tp_pmu.h" #include "trace-event.h" -#include "util/sample.h" =20 #ifdef HAVE_LIBTRACEEVENT #include @@ -40,6 +46,8 @@ =20 PyMODINIT_FUNC PyInit_perf(void); =20 +static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel); + #define member_def(type, member, ptype, help) \ { #member, ptype, \ offsetof(struct pyrf_event, event) + offsetof(struct type, member), \ @@ -52,21 +60,53 @@ PyMODINIT_FUNC PyInit_perf(void); =20 struct pyrf_event { PyObject_HEAD + /** @sample: The parsed sample from the event. */ struct perf_sample sample; - union perf_event event; + /** @al: The address location from machine__resolve, lazily computed. */ + struct addr_location al; + /** @al_resolved: True when machine__resolve been called. */ + bool al_resolved; + /** @event: The underlying perf_event that may be in a file or ring buffe= r. */ + union perf_event event; }; =20 #define sample_members \ - sample_member_def(sample_ip, ip, T_ULONGLONG, "event ip"), \ sample_member_def(sample_pid, pid, T_INT, "event pid"), \ sample_member_def(sample_tid, tid, T_INT, "event tid"), \ sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \ - sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \ sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \ sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream= id"), \ sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \ sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"), =20 +static PyObject *pyrf_event__get_evsel(PyObject *self, void *closure __may= be_unused) +{ + struct pyrf_event *pevent =3D (void *)self; + + if (!pevent->sample.evsel) + Py_RETURN_NONE; + + return pyrf_evsel__from_evsel(pevent->sample.evsel); +} + +static PyGetSetDef pyrf_event__getset[] =3D { + { + .name =3D "evsel", + .get =3D pyrf_event__get_evsel, + .set =3D NULL, + .doc =3D "tracking event.", + }, + { .name =3D NULL, }, +}; + +static void pyrf_event__delete(struct pyrf_event *pevent) +{ + if (pevent->al_resolved) + addr_location__exit(&pevent->al); + perf_sample__exit(&pevent->sample); + Py_TYPE(pevent)->tp_free((PyObject *)pevent); +} + static const char pyrf_mmap_event__doc[] =3D PyDoc_STR("perf mmap event ob= ject."); =20 static PyMemberDef pyrf_mmap_event__members[] =3D { @@ -105,9 +145,11 @@ static PyTypeObject pyrf_mmap_event__type =3D { PyVarObject_HEAD_INIT(NULL, 0) .tp_name =3D "perf.mmap_event", .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_dealloc =3D (destructor)pyrf_event__delete, .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc =3D pyrf_mmap_event__doc, .tp_members =3D pyrf_mmap_event__members, + .tp_getset =3D pyrf_event__getset, .tp_repr =3D (reprfunc)pyrf_mmap_event__repr, }; =20 @@ -140,9 +182,11 @@ static PyTypeObject pyrf_task_event__type =3D { PyVarObject_HEAD_INIT(NULL, 0) .tp_name =3D "perf.task_event", .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_dealloc =3D (destructor)pyrf_event__delete, .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc =3D pyrf_task_event__doc, .tp_members =3D pyrf_task_event__members, + .tp_getset =3D pyrf_event__getset, .tp_repr =3D (reprfunc)pyrf_task_event__repr, }; =20 @@ -169,9 +213,11 @@ static PyTypeObject pyrf_comm_event__type =3D { PyVarObject_HEAD_INIT(NULL, 0) .tp_name =3D "perf.comm_event", .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_dealloc =3D (destructor)pyrf_event__delete, .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc =3D pyrf_comm_event__doc, .tp_members =3D pyrf_comm_event__members, + .tp_getset =3D pyrf_event__getset, .tp_repr =3D (reprfunc)pyrf_comm_event__repr, }; =20 @@ -201,9 +247,11 @@ static PyTypeObject pyrf_throttle_event__type =3D { PyVarObject_HEAD_INIT(NULL, 0) .tp_name =3D "perf.throttle_event", .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_dealloc =3D (destructor)pyrf_event__delete, .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc =3D pyrf_throttle_event__doc, .tp_members =3D pyrf_throttle_event__members, + .tp_getset =3D pyrf_event__getset, .tp_repr =3D (reprfunc)pyrf_throttle_event__repr, }; =20 @@ -236,9 +284,11 @@ static PyTypeObject pyrf_lost_event__type =3D { PyVarObject_HEAD_INIT(NULL, 0) .tp_name =3D "perf.lost_event", .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_dealloc =3D (destructor)pyrf_event__delete, .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc =3D pyrf_lost_event__doc, .tp_members =3D pyrf_lost_event__members, + .tp_getset =3D pyrf_event__getset, .tp_repr =3D (reprfunc)pyrf_lost_event__repr, }; =20 @@ -266,9 +316,11 @@ static PyTypeObject pyrf_read_event__type =3D { PyVarObject_HEAD_INIT(NULL, 0) .tp_name =3D "perf.read_event", .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_dealloc =3D (destructor)pyrf_event__delete, .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc =3D pyrf_read_event__doc, .tp_members =3D pyrf_read_event__members, + .tp_getset =3D pyrf_event__getset, .tp_repr =3D (reprfunc)pyrf_read_event__repr, }; =20 @@ -276,16 +328,17 @@ static const char pyrf_sample_event__doc[] =3D PyDoc_= STR("perf sample event object =20 static PyMemberDef pyrf_sample_event__members[] =3D { sample_members + sample_member_def(sample_ip, ip, T_ULONGLONG, "event ip"), + sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), + sample_member_def(sample_phys_addr, phys_addr, T_ULONGLONG, "event physic= al addr"), + sample_member_def(sample_weight, weight, T_ULONGLONG, "event weight"), + sample_member_def(sample_data_src, data_src, T_ULONGLONG, "event data sou= rce"), + sample_member_def(sample_insn_count, insn_cnt, T_ULONGLONG, "event instru= ction count"), + sample_member_def(sample_cyc_count, cyc_cnt, T_ULONGLONG, "event cycle co= unt"), member_def(perf_event_header, type, T_UINT, "event type"), { .name =3D NULL, }, }; =20 -static void pyrf_sample_event__delete(struct pyrf_event *pevent) -{ - perf_sample__exit(&pevent->sample); - Py_TYPE(pevent)->tp_free((PyObject*)pevent); -} - static PyObject *pyrf_sample_event__repr(const struct pyrf_event *pevent) { PyObject *ret; @@ -303,6 +356,8 @@ static PyObject *pyrf_sample_event__repr(const struct p= yrf_event *pevent) #ifdef HAVE_LIBTRACEEVENT static bool is_tracepoint(const struct pyrf_event *pevent) { + if (!pevent->sample.evsel) + return false; return pevent->sample.evsel->core.attr.type =3D=3D PERF_TYPE_TRACEPOINT; } =20 @@ -373,6 +428,199 @@ get_tracepoint_field(struct pyrf_event *pevent, PyObj= ect *attr_name) } #endif /* HAVE_LIBTRACEEVENT */ =20 +static int pyrf_sample_event__resolve_al(struct pyrf_event *pevent) +{ + struct evsel *evsel =3D pevent->sample.evsel; + struct evlist *evlist =3D evsel ? evsel->evlist : NULL; + struct perf_session *session =3D evlist ? evlist__session(evlist) : NULL; + + if (pevent->al_resolved) + return 0; + + if (!session) + return -1; + + addr_location__init(&pevent->al); + if (machine__resolve(&session->machines.host, &pevent->al, &pevent->sampl= e) < 0) { + addr_location__exit(&pevent->al); + return -1; + } + + pevent->al_resolved =3D true; + return 0; +} + +static PyObject *pyrf_sample_event__get_dso(struct pyrf_event *pevent, + void *closure __maybe_unused) +{ + if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map) + Py_RETURN_NONE; + + return PyUnicode_FromString(dso__name(map__dso(pevent->al.map))); +} + +static PyObject *pyrf_sample_event__get_dso_long_name(struct pyrf_event *p= event, + void *closure __maybe_unused) +{ + if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map) + Py_RETURN_NONE; + + return PyUnicode_FromString(dso__long_name(map__dso(pevent->al.map))); +} + +static PyObject *pyrf_sample_event__get_dso_bid(struct pyrf_event *pevent, + void *closure __maybe_unused) +{ + char sbuild_id[SBUILD_ID_SIZE]; + + if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map) + Py_RETURN_NONE; + + build_id__snprintf(dso__bid(map__dso(pevent->al.map)), sbuild_id, sizeof(= sbuild_id)); + return PyUnicode_FromString(sbuild_id); +} + +static PyObject *pyrf_sample_event__get_map_start(struct pyrf_event *peven= t, + void *closure __maybe_unused) +{ + if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map) + Py_RETURN_NONE; + + return PyLong_FromUnsignedLong(map__start(pevent->al.map)); +} + +static PyObject *pyrf_sample_event__get_map_end(struct pyrf_event *pevent, + void *closure __maybe_unused) +{ + if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map) + Py_RETURN_NONE; + + return PyLong_FromUnsignedLong(map__end(pevent->al.map)); +} + +static PyObject *pyrf_sample_event__get_map_pgoff(struct pyrf_event *peven= t, + void *closure __maybe_unused) +{ + if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map) + Py_RETURN_NONE; + + return PyLong_FromUnsignedLongLong(map__pgoff(pevent->al.map)); +} + +static PyObject *pyrf_sample_event__get_symbol(struct pyrf_event *pevent, + void *closure __maybe_unused) +{ + if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.sym) + Py_RETURN_NONE; + + return PyUnicode_FromString(pevent->al.sym->name); +} + +static PyObject *pyrf_sample_event__get_sym_start(struct pyrf_event *peven= t, + void *closure __maybe_unused) +{ + if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.sym) + Py_RETURN_NONE; + + return PyLong_FromUnsignedLongLong(pevent->al.sym->start); +} + +static PyObject *pyrf_sample_event__get_sym_end(struct pyrf_event *pevent, + void *closure __maybe_unused) +{ + if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.sym) + Py_RETURN_NONE; + + return PyLong_FromUnsignedLongLong(pevent->al.sym->end); +} + +static PyObject *pyrf_sample_event__get_raw_buf(struct pyrf_event *pevent, + void *closure __maybe_unused) +{ + if (pevent->event.header.type !=3D PERF_RECORD_SAMPLE) + Py_RETURN_NONE; + + return PyBytes_FromStringAndSize((const char *)pevent->sample.raw_data, + pevent->sample.raw_size); +} + +static PyObject *pyrf_sample_event__srccode(PyObject *self, PyObject *args) +{ + struct pyrf_event *pevent =3D (void *)self; + u64 addr =3D pevent->sample.ip; + char *srcfile =3D NULL; + char *srccode =3D NULL; + unsigned int line =3D 0; + int len =3D 0; + PyObject *result; + struct addr_location al; + + if (!PyArg_ParseTuple(args, "|K", &addr)) + return NULL; + + if (pyrf_sample_event__resolve_al(pevent) < 0) + Py_RETURN_NONE; + + if (addr !=3D pevent->sample.ip) { + addr_location__init(&al); + thread__find_symbol_fb(pevent->al.thread, pevent->sample.cpumode, addr, = &al); + } else { + addr_location__init(&al); + al.thread =3D thread__get(pevent->al.thread); + al.map =3D map__get(pevent->al.map); + al.sym =3D pevent->al.sym; + al.addr =3D pevent->al.addr; + } + + if (al.map) { + struct dso *dso =3D map__dso(al.map); + + if (dso) { + srcfile =3D get_srcline_split(dso, map__rip_2objdump(al.map, addr), + &line); + } + } + addr_location__exit(&al); + + if (srcfile) { + srccode =3D find_sourceline(srcfile, line, &len); + result =3D Py_BuildValue("(sIs#)", srcfile, line, srccode, (Py_ssize_t)l= en); + free(srcfile); + } else { + result =3D Py_BuildValue("(sIs#)", NULL, 0, NULL, (Py_ssize_t)0); + } + + return result; +} + +static PyObject *pyrf_sample_event__insn(PyObject *self, PyObject *args __= maybe_unused) +{ + struct pyrf_event *pevent =3D (void *)self; + struct thread *thread; + struct machine *machine; + + if (pyrf_sample_event__resolve_al(pevent) < 0) + Py_RETURN_NONE; + + thread =3D pevent->al.thread; + + if (!thread || !thread__maps(thread)) + Py_RETURN_NONE; + + machine =3D maps__machine(thread__maps(thread)); + if (!machine) + Py_RETURN_NONE; + + if (pevent->sample.ip && !pevent->sample.insn_len) + perf_sample__fetch_insn(&pevent->sample, thread, machine); + + if (!pevent->sample.insn_len) + Py_RETURN_NONE; + + return PyBytes_FromStringAndSize((const char *)pevent->sample.insn, + pevent->sample.insn_len); +} + static PyObject* pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name) { @@ -386,13 +634,102 @@ pyrf_sample_event__getattro(struct pyrf_event *peven= t, PyObject *attr_name) return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name); } =20 +static PyGetSetDef pyrf_sample_event__getset[] =3D { + { + .name =3D "raw_buf", + .get =3D (getter)pyrf_sample_event__get_raw_buf, + .set =3D NULL, + .doc =3D "event raw buffer.", + }, + { + .name =3D "evsel", + .get =3D pyrf_event__get_evsel, + .set =3D NULL, + .doc =3D "tracking event.", + }, + { + .name =3D "dso", + .get =3D (getter)pyrf_sample_event__get_dso, + .set =3D NULL, + .doc =3D "event dso short name.", + }, + { + .name =3D "dso_long_name", + .get =3D (getter)pyrf_sample_event__get_dso_long_name, + .set =3D NULL, + .doc =3D "event dso long name.", + }, + { + .name =3D "dso_bid", + .get =3D (getter)pyrf_sample_event__get_dso_bid, + .set =3D NULL, + .doc =3D "event dso build id.", + }, + { + .name =3D "map_start", + .get =3D (getter)pyrf_sample_event__get_map_start, + .set =3D NULL, + .doc =3D "event map start address.", + }, + { + .name =3D "map_end", + .get =3D (getter)pyrf_sample_event__get_map_end, + .set =3D NULL, + .doc =3D "event map end address.", + }, + { + .name =3D "map_pgoff", + .get =3D (getter)pyrf_sample_event__get_map_pgoff, + .set =3D NULL, + .doc =3D "event map page offset.", + }, + { + .name =3D "symbol", + .get =3D (getter)pyrf_sample_event__get_symbol, + .set =3D NULL, + .doc =3D "event symbol name.", + }, + { + .name =3D "sym_start", + .get =3D (getter)pyrf_sample_event__get_sym_start, + .set =3D NULL, + .doc =3D "event symbol start address.", + }, + { + .name =3D "sym_end", + .get =3D (getter)pyrf_sample_event__get_sym_end, + .set =3D NULL, + .doc =3D "event symbol end address.", + }, + { .name =3D NULL, }, +}; + +static PyMethodDef pyrf_sample_event__methods[] =3D { + { + .ml_name =3D "srccode", + .ml_meth =3D (PyCFunction)pyrf_sample_event__srccode, + .ml_flags =3D METH_VARARGS, + .ml_doc =3D PyDoc_STR("Get source code for an address.") + }, + { + .ml_name =3D "insn", + .ml_meth =3D (PyCFunction)pyrf_sample_event__insn, + .ml_flags =3D METH_NOARGS, + .ml_doc =3D PyDoc_STR("Get instruction bytes for a sample.") + }, + { .ml_name =3D NULL, } +}; + static PyTypeObject pyrf_sample_event__type =3D { PyVarObject_HEAD_INIT(NULL, 0) .tp_name =3D "perf.sample_event", .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_dealloc =3D (destructor)pyrf_event__delete, .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc =3D pyrf_sample_event__doc, .tp_members =3D pyrf_sample_event__members, + .tp_getset =3D pyrf_sample_event__getset, + .tp_methods =3D pyrf_sample_event__methods, .tp_repr =3D (reprfunc)pyrf_sample_event__repr, .tp_getattro =3D (getattrofunc) pyrf_sample_event__getattro, }; @@ -428,25 +765,17 @@ static PyTypeObject pyrf_context_switch_event__type = =3D { PyVarObject_HEAD_INIT(NULL, 0) .tp_name =3D "perf.context_switch_event", .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_dealloc =3D (destructor)pyrf_event__delete, .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc =3D pyrf_context_switch_event__doc, .tp_members =3D pyrf_context_switch_event__members, + .tp_getset =3D pyrf_event__getset, .tp_repr =3D (reprfunc)pyrf_context_switch_event__repr, }; =20 static int pyrf_event__setup_types(void) { int err; - pyrf_mmap_event__type.tp_new =3D - pyrf_task_event__type.tp_new =3D - pyrf_comm_event__type.tp_new =3D - pyrf_lost_event__type.tp_new =3D - pyrf_read_event__type.tp_new =3D - pyrf_sample_event__type.tp_new =3D - pyrf_context_switch_event__type.tp_new =3D - pyrf_throttle_event__type.tp_new =3D PyType_GenericNew; - - pyrf_sample_event__type.tp_dealloc =3D (destructor)pyrf_sample_event__del= ete, =20 err =3D PyType_Ready(&pyrf_mmap_event__type); if (err < 0) @@ -490,33 +819,175 @@ static PyTypeObject *pyrf_event__type[] =3D { [PERF_RECORD_SWITCH_CPU_WIDE] =3D &pyrf_context_switch_event__type, }; =20 -static PyObject *pyrf_event__new(const union perf_event *event) +static PyObject *pyrf_event__new(const union perf_event *event, struct evs= el *evsel, + struct perf_session *session __maybe_unused) { struct pyrf_event *pevent; - PyTypeObject *ptype; + size_t size; + int err; + size_t min_size =3D sizeof(struct perf_event_header); =20 - if ((event->header.type < PERF_RECORD_MMAP || - event->header.type > PERF_RECORD_SAMPLE) && - !(event->header.type =3D=3D PERF_RECORD_SWITCH || - event->header.type =3D=3D PERF_RECORD_SWITCH_CPU_WIDE)) { - PyErr_Format(PyExc_TypeError, "Unexpected header type %u", + if (event->header.type >=3D ARRAY_SIZE(pyrf_event__type) || + pyrf_event__type[event->header.type] =3D=3D NULL) { + return PyErr_Format(PyExc_TypeError, "Unexpected header type %u", event->header.type); - return NULL; } =20 - // FIXME this better be dynamic or we need to parse everything - // before calling perf_mmap__consume(), including tracepoint fields. - if (sizeof(pevent->event) < event->header.size) { - PyErr_Format(PyExc_TypeError, "Unexpected event size: %zd < %u", - sizeof(pevent->event), event->header.size); - return NULL; + switch (event->header.type) { + case PERF_RECORD_MMAP: + min_size =3D offsetof(struct perf_record_mmap, filename) + 1; + break; + case PERF_RECORD_MMAP2: + min_size =3D offsetof(struct perf_record_mmap2, filename) + 1; + break; + case PERF_RECORD_COMM: + min_size =3D sizeof(struct perf_record_comm); + break; + case PERF_RECORD_FORK: + case PERF_RECORD_EXIT: + min_size =3D sizeof(struct perf_record_fork); + break; + case PERF_RECORD_THROTTLE: + case PERF_RECORD_UNTHROTTLE: + min_size =3D sizeof(struct perf_record_throttle); + break; + case PERF_RECORD_LOST: + min_size =3D sizeof(struct perf_record_lost); + break; + case PERF_RECORD_READ: + min_size =3D sizeof(struct perf_record_read); + break; + case PERF_RECORD_SWITCH: + case PERF_RECORD_SWITCH_CPU_WIDE: + min_size =3D sizeof(struct perf_record_switch); + break; + case PERF_RECORD_AUX: + min_size =3D sizeof(struct perf_record_aux); + break; + case PERF_RECORD_ITRACE_START: + min_size =3D sizeof(struct perf_record_itrace_start); + break; + case PERF_RECORD_LOST_SAMPLES: + min_size =3D sizeof(struct perf_record_lost_samples); + break; + case PERF_RECORD_NAMESPACES: + min_size =3D offsetof(struct perf_record_namespaces, link_info); + break; + case PERF_RECORD_KSYMBOL: + min_size =3D sizeof(struct perf_record_ksymbol); + break; + case PERF_RECORD_BPF_EVENT: + min_size =3D sizeof(struct perf_record_bpf_event); + break; + case PERF_RECORD_CGROUP: + min_size =3D sizeof(struct perf_record_cgroup); + break; + case PERF_RECORD_TEXT_POKE: + min_size =3D offsetof(struct perf_record_text_poke_event, bytes); + break; + case PERF_RECORD_AUX_OUTPUT_HW_ID: + min_size =3D sizeof(struct perf_record_aux_output_hw_id); + break; + case PERF_RECORD_CALLCHAIN_DEFERRED: + min_size =3D sizeof(struct perf_record_callchain_deferred); + break; + case PERF_RECORD_HEADER_ATTR: + min_size =3D sizeof(struct perf_record_header_attr); + break; + case PERF_RECORD_HEADER_TRACING_DATA: + min_size =3D sizeof(struct perf_record_header_tracing_data); + break; + case PERF_RECORD_HEADER_BUILD_ID: + min_size =3D offsetof(struct perf_record_header_build_id, filename) + 1; + break; + case PERF_RECORD_ID_INDEX: + min_size =3D offsetof(struct perf_record_id_index, entries); + break; + case PERF_RECORD_AUXTRACE_INFO: + min_size =3D offsetof(struct perf_record_auxtrace_info, priv); + break; + case PERF_RECORD_AUXTRACE: + min_size =3D sizeof(struct perf_record_auxtrace); + break; + case PERF_RECORD_AUXTRACE_ERROR: + min_size =3D sizeof(struct perf_record_auxtrace_error); + break; + case PERF_RECORD_THREAD_MAP: + min_size =3D offsetof(struct perf_record_thread_map, entries); + break; + case PERF_RECORD_CPU_MAP: + min_size =3D sizeof(struct perf_record_cpu_map); + break; + case PERF_RECORD_STAT_CONFIG: + min_size =3D offsetof(struct perf_record_stat_config, data); + break; + case PERF_RECORD_STAT: + min_size =3D sizeof(struct perf_record_stat); + break; + case PERF_RECORD_STAT_ROUND: + min_size =3D sizeof(struct perf_record_stat_round); + break; + case PERF_RECORD_EVENT_UPDATE: + min_size =3D sizeof(struct perf_record_event_update); + break; + case PERF_RECORD_TIME_CONV: + min_size =3D sizeof(struct perf_record_time_conv); + break; + case PERF_RECORD_HEADER_FEATURE: + min_size =3D offsetof(struct perf_record_header_feature, data); + break; + case PERF_RECORD_COMPRESSED: + min_size =3D offsetof(struct perf_record_compressed, data); + break; + case PERF_RECORD_COMPRESSED2: + min_size =3D offsetof(struct perf_record_compressed2, data); + break; + case PERF_RECORD_BPF_METADATA: + min_size =3D offsetof(struct perf_record_bpf_metadata, entries); + break; + case PERF_RECORD_SCHEDSTAT_CPU: + min_size =3D sizeof(struct perf_record_schedstat_cpu); + break; + case PERF_RECORD_SCHEDSTAT_DOMAIN: + min_size =3D sizeof(struct perf_record_schedstat_domain); + break; + default: + break; } + if (event->header.size < min_size) + return PyErr_Format(PyExc_ValueError, "Event size %u too small for type = %u", + event->header.size, event->header.type); + + /* Allocate just enough memory for the size of event. */ + size =3D offsetof(struct pyrf_event, event) + event->header.size; + pevent =3D (struct pyrf_event *)PyObject_Malloc(size); + if (pevent =3D=3D NULL) + return PyErr_NoMemory(); + + /* Copy the event for memory safety and initilaize variables. */ + PyObject_Init((PyObject *)pevent, pyrf_event__type[event->header.type]); + memcpy(&pevent->event, event, event->header.size); + + if (event->header.type =3D=3D PERF_RECORD_MMAP) { + /* Ensure '\0' string termination. */ + size_t max_len =3D pevent->event.header.size - offsetof(struct perf_reco= rd_mmap, filename); =20 - ptype =3D pyrf_event__type[event->header.type]; - pevent =3D PyObject_New(struct pyrf_event, ptype); - if (pevent !=3D NULL) { - memcpy(&pevent->event, event, event->header.size); - perf_sample__init(&pevent->sample, /*all=3D*/false); + pevent->event.mmap.filename[max_len - 1] =3D '\0'; + } + + perf_sample__init(&pevent->sample, /*all=3D*/true); + pevent->al_resolved =3D false; + addr_location__init(&pevent->al); + + if (!evsel) + return (PyObject *)pevent; + + /* Parse the sample again so that pointers are within the copied event. */ + err =3D evsel__parse_sample(evsel, &pevent->event, &pevent->sample); + if (err < 0) { + Py_DECREF(pevent); + return PyErr_Format(PyExc_OSError, + "perf: can't parse sample, err=3D%d", err); } return (PyObject *)pevent; } @@ -1209,7 +1680,7 @@ static PyObject *pyrf_evsel__str(PyObject *self) struct pyrf_evsel *pevsel =3D (void *)self; struct evsel *evsel =3D pevsel->evsel; =20 - return PyUnicode_FromFormat("evsel(%s/%s/)", evsel__pmu_name(evsel), evse= l__name(evsel)); + return PyUnicode_FromFormat("evsel(%s)", evsel__name(evsel)); } =20 static PyMethodDef pyrf_evsel__methods[] =3D { @@ -1773,9 +2244,11 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyr= f_evlist *pevlist, { struct evlist *evlist =3D pevlist->evlist; union perf_event *event; + struct evsel *evsel; int sample_id_all =3D 1, cpu; static char *kwlist[] =3D { "cpu", "sample_id_all", NULL }; struct mmap *md; + PyObject *pyevent; int err; =20 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, @@ -1783,44 +2256,31 @@ static PyObject *pyrf_evlist__read_on_cpu(struct py= rf_evlist *pevlist, return NULL; =20 md =3D get_md(evlist, cpu); - if (!md) { - PyErr_Format(PyExc_TypeError, "Unknown CPU '%d'", cpu); - return NULL; - } + if (!md) + return PyErr_Format(PyExc_TypeError, "Unknown CPU '%d'", cpu); =20 - if (perf_mmap__read_init(&md->core) < 0) - goto end; + err =3D perf_mmap__read_init(&md->core); + if (err < 0) { + return PyErr_Format(PyExc_OSError, + "perf: error mmap read init, err=3D%d", err); + } =20 event =3D perf_mmap__read_event(&md->core); - if (event !=3D NULL) { - PyObject *pyevent =3D pyrf_event__new(event); - struct pyrf_event *pevent =3D (struct pyrf_event *)pyevent; - struct evsel *evsel; - - if (pyevent =3D=3D NULL) - return PyErr_NoMemory(); - - evsel =3D evlist__event2evsel(evlist, event); - if (!evsel) { - Py_DECREF(pyevent); - Py_INCREF(Py_None); - return Py_None; - } + if (event =3D=3D NULL) + Py_RETURN_NONE; =20 + evsel =3D evlist__event2evsel(evlist, event); + if (!evsel) { + /* Unknown evsel. */ perf_mmap__consume(&md->core); - - err =3D evsel__parse_sample(evsel, &pevent->event, &pevent->sample); - if (err) { - Py_DECREF(pyevent); - return PyErr_Format(PyExc_OSError, - "perf: can't parse sample, err=3D%d", err); - } - - return pyevent; + Py_RETURN_NONE; } -end: - Py_INCREF(Py_None); - return Py_None; + pyevent =3D pyrf_event__new(event, evsel, evlist__session(evlist)); + perf_mmap__consume(&md->core); + if (pyevent =3D=3D NULL) + return PyErr_Occurred() ? NULL : PyErr_NoMemory(); + + return pyevent; } =20 static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist, @@ -2015,10 +2475,7 @@ static PyObject *pyrf_evlist__str(PyObject *self) evlist__for_each_entry(pevlist->evlist, pos) { if (!first) strbuf_addch(&sb, ','); - if (!pos->pmu) - strbuf_addstr(&sb, evsel__name(pos)); - else - strbuf_addf(&sb, "%s/%s/", pos->pmu->name, evsel__name(pos)); + strbuf_addstr(&sb, evsel__name(pos)); first =3D false; } strbuf_addstr(&sb, "])"); @@ -2528,19 +2985,12 @@ static int pyrf_session_tool__sample(const struct p= erf_tool *tool, struct machine *machine __maybe_unused) { struct pyrf_session *psession =3D container_of(tool, struct pyrf_session,= tool); - PyObject *pyevent =3D pyrf_event__new(event); - struct pyrf_event *pevent =3D (struct pyrf_event *)pyevent; + PyObject *pyevent =3D pyrf_event__new(event, sample->evsel, psession->ses= sion); PyObject *ret; =20 if (pyevent =3D=3D NULL) return -ENOMEM; =20 - memcpy(&pevent->event, event, event->header.size); - if (evsel__parse_sample(sample->evsel, &pevent->event, &pevent->sample) <= 0) { - Py_DECREF(pyevent); - return -1; - } - ret =3D PyObject_CallFunction(psession->sample, "O", pyevent); if (!ret) { Py_DECREF(pyevent); --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77236394783 for ; Fri, 22 May 2026 22:05:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487520; cv=none; b=omEzVqsiXnAKhnhjLquVMGPqGL8vzi1nm+mZyIvwk68egor22ZQQi8FKHc2FP0l2ztR6cDzo7llpQMPl1UtpKCRBHIAgtqCTfuwOuz2ZRwdGVcuoiMTiAu8475686YHdv5AY1zso6nvRlyiFThAMwlbfrDRJzvu0jrs/NICj+zo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487520; c=relaxed/simple; bh=xVplDaUq3qZvGrJDQoj5pZuBvUlQ61vPIu3v1gbI0j8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=UVK7oqBL3Wp2/+L5nPXd1s9Lu913KwsULjEc8muqFWFGKuiaOda1BjhpRWjE8nBL8fLPsVFtsU+J/nzWgqzo0jGdrL/jU1vIh3mGgFhISC2SJsIDQ8bt4+iefYuyz5GggCSsFDLbqSdmTF+NUN6sg8xmHSxQ4kTHt5hFTMNeKmU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=U9AP3C0l; arc=none smtp.client-ip=74.125.82.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="U9AP3C0l" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-135916eefa0so8069341c88.1 for ; Fri, 22 May 2026 15:05:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487517; x=1780092317; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Kc9+pnx9V5zJCzrrZnoMn6gdgHh5drL1PfGcHBn0LCE=; b=U9AP3C0l29lZNXgOfRo27UqggLWM+/DTowyCtbakFDAcfuP3QklSOYDtY2cFob88M3 Zn5GzSTT+hoOZ7yIx0qCe3hIZD0jZEKqlzJXYJPy0QB/YlyhaES7tY/uNmNcCQDN5By/ SM17i4Xc0cTaIDyjJkYVFN8H17vdxr17nOWGwr0v4npBTQ1JXhfa3obWFn7361qhgm4d ervGEWaKpdPN8/1yLb2E4blahGKgvphq0GAVmps3p3fk5/2z3MiZ2uilnOKz6kaetOwe XWQVbKiw7UC/oF8DRQZ9q8tEdcaDL5W2cTQ3vsf/NJ87OG2IPQ74hXo4FvqUhiR1bAhQ TyKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487517; x=1780092317; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Kc9+pnx9V5zJCzrrZnoMn6gdgHh5drL1PfGcHBn0LCE=; b=oDDkpdXETeP8WtHtKYSNQe3l2zUFGA55BaF4/4qzLxk72aSJZHLLT8eFg5lF3h59hb LNuBGpVDHms9EeGEtLzBAgQjdKhTRHeqPSQaHbYO6XpCkUYnlstiGRf4YjCjDVE/5kib ppdK8slXc0P1EByEoYteXIGOYZN4jTvZIXif69f8gWvplktPZzGe34wg9OLOawMRVLd+ zGNFcpQrj3urPB/PeKgUuIEDgJpYkLJ2/z0sBwnfVK+AKczMu/RF7wFEzjPn1quDiZ6n G5IvBr8GuJTmSuuWOUoeBLXTXX9n/XGU/LJF4m2//b6PBopRTnGKn7LEYTuJLyQtrB4I zGHw== X-Forwarded-Encrypted: i=1; AFNElJ9wZ1/oqtwIO3MfmLKEFl0qFcDyOzrFz0BtHQBZbSx/VEclC6K/U40Jd5F4GAqgWFLfyX3uOeoawbTkXiQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzdpqukRZmJArFW81aZraU5Xc0ALaT6b/TFWnN1WEAgjZZ8QWf0 el/JcMxBVb6QSdvOYDlyUsh/E3Q1ZuZE9poXnMhGLSn0/90I/Q9Vcug5UGC3ISOYBBBeMtp5Wui G8ABAQkmO+g== X-Received: from dlbtu11.prod.google.com ([2002:a05:7022:3c0b:b0:134:ea68:2940]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:6725:b0:12b:ebb9:1c18 with SMTP id a92af1059eb24-1365fc79de8mr2447524c88.31.1779487517130; Fri, 22 May 2026 15:05:17 -0700 (PDT) Date: Fri, 22 May 2026 15:04:27 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-17-irogers@google.com> Subject: [PATCH v9 16/23] perf python: Add mmap2 event From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If mmap is handled so should mmap2 events. Add support as a distinct python event type. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- tools/perf/util/python.c | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 029915b7a1fe..daedd67f12d5 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -153,6 +153,54 @@ static PyTypeObject pyrf_mmap_event__type =3D { .tp_repr =3D (reprfunc)pyrf_mmap_event__repr, }; =20 +static const char pyrf_mmap2_event__doc[] =3D PyDoc_STR("perf mmap2 event = object."); + +static PyMemberDef pyrf_mmap2_event__members[] =3D { + sample_members + member_def(perf_event_header, type, T_UINT, "event type"), + member_def(perf_event_header, misc, T_UINT, "event misc"), + member_def(perf_record_mmap2, pid, T_UINT, "event pid"), + member_def(perf_record_mmap2, tid, T_UINT, "event tid"), + member_def(perf_record_mmap2, start, T_ULONGLONG, "start of the map"), + member_def(perf_record_mmap2, len, T_ULONGLONG, "map length"), + member_def(perf_record_mmap2, pgoff, T_ULONGLONG, "page offset"), + member_def(perf_record_mmap2, prot, T_UINT, "protection"), + member_def(perf_record_mmap2, flags, T_UINT, "flags"), + member_def(perf_record_mmap2, filename, T_STRING_INPLACE, "backing store"= ), + { .name =3D NULL, }, +}; + +static PyObject *pyrf_mmap2_event__repr(const struct pyrf_event *pevent) +{ + PyObject *ret; + char *s; + + if (asprintf(&s, "{ type: mmap2, pid: %u, tid: %u, start: %#" PRI_lx64 ",= " + "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", " + "flags: %#x, prot: %#x, filename: %s }", + pevent->event.mmap2.pid, pevent->event.mmap2.tid, + pevent->event.mmap2.start, pevent->event.mmap2.len, + pevent->event.mmap2.pgoff, pevent->event.mmap2.flags, + pevent->event.mmap2.prot, pevent->event.mmap2.filename) < 0) + return PyErr_NoMemory(); + + ret =3D PyUnicode_FromString(s); + free(s); + return ret; +} + +static PyTypeObject pyrf_mmap2_event__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.mmap2_event", + .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_dealloc =3D (destructor)pyrf_event__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_doc =3D pyrf_mmap2_event__doc, + .tp_members =3D pyrf_mmap2_event__members, + .tp_getset =3D pyrf_event__getset, + .tp_repr =3D (reprfunc)pyrf_mmap2_event__repr, +}; + static const char pyrf_task_event__doc[] =3D PyDoc_STR("perf task (fork/ex= it) event object."); =20 static PyMemberDef pyrf_task_event__members[] =3D { @@ -778,6 +826,9 @@ static int pyrf_event__setup_types(void) int err; =20 err =3D PyType_Ready(&pyrf_mmap_event__type); + if (err < 0) + goto out; + err =3D PyType_Ready(&pyrf_mmap2_event__type); if (err < 0) goto out; err =3D PyType_Ready(&pyrf_lost_event__type); @@ -807,6 +858,7 @@ static int pyrf_event__setup_types(void) =20 static PyTypeObject *pyrf_event__type[] =3D { [PERF_RECORD_MMAP] =3D &pyrf_mmap_event__type, + [PERF_RECORD_MMAP2] =3D &pyrf_mmap2_event__type, [PERF_RECORD_LOST] =3D &pyrf_lost_event__type, [PERF_RECORD_COMM] =3D &pyrf_comm_event__type, [PERF_RECORD_EXIT] =3D &pyrf_task_event__type, @@ -973,6 +1025,11 @@ static PyObject *pyrf_event__new(const union perf_eve= nt *event, struct evsel *ev size_t max_len =3D pevent->event.header.size - offsetof(struct perf_reco= rd_mmap, filename); =20 pevent->event.mmap.filename[max_len - 1] =3D '\0'; + } else if (event->header.type =3D=3D PERF_RECORD_MMAP2) { + /* Ensure '\0' string termination. */ + size_t max_len =3D pevent->event.header.size - offsetof(struct perf_reco= rd_mmap2, filename); + + pevent->event.mmap2.filename[max_len - 1] =3D '\0'; } =20 perf_sample__init(&pevent->sample, /*all=3D*/true); @@ -3238,6 +3295,9 @@ PyMODINIT_FUNC PyInit_perf(void) Py_INCREF(&pyrf_mmap_event__type); PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__ty= pe); =20 + Py_INCREF(&pyrf_mmap2_event__type); + PyModule_AddObject(module, "mmap2_event", (PyObject *)&pyrf_mmap2_event__= type); + Py_INCREF(&pyrf_lost_event__type); PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__ty= pe); =20 --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 42DF73955CE for ; Fri, 22 May 2026 22:05:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487522; cv=none; b=Fs/s73Jq1/56FBDUjg/g9OpcT5TtvH2ZlaZfhzTL6M4zPubMmaFYcauJdxjwd9hUcXSDPxKd1UzN76p0+2QanDSTk7dA5PWqxtJz1yWnJGWT+TP6Y3gq2uoq4TDOK9LBTioTXJvHB+w0NmFTuoSHH+c2FwlglwAzn2UppaCW414= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487522; c=relaxed/simple; bh=UFH+SCufTNAWZPKLpGYQoKrPFz3DXmqxCwE9KFTLIQM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=aqEo1xnqqQfjnhfD26pdcihhjpEoy1yHT4z/zUcVlKgrL4kbFOx2zpNm3DsCMFy9doB6vLJb3QfTPwJi3SOW7QMLGI7a/QVMIKOFPP7cdCoWfG/gzYMjz1pazgBDnTs4sP6g800F4oy8Icas9sUCiru+YbPFLoCTNZ+b0ZAqzzM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=rRahgo0y; arc=none smtp.client-ip=74.125.82.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="rRahgo0y" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-135405e4035so37565496c88.1 for ; Fri, 22 May 2026 15:05:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487519; x=1780092319; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=1oiPPeerxAd2KDhCMXKVrpSVXvS8guW5A+bxiFsiP8I=; b=rRahgo0yJzdkyizaMw7zP9wXFvcDVR9ckeVq1hwhbNbA+hezw68e7R0inhneeych90 BUoCmNwrvFTZ67CPvItAw25freE66kU0DtiWuWcZ/N/R9hzJTRTkd+phN5/+Zp0zYl/l 3XFRVLEUHqZiR2xW8Ycaa6YE9M+XeT4frrH9t/+5CpZTUEiLgMB55lKW+hgpijDucGie edMaUI+Tja/YBjLaaHLrHiBHenfofC9hB3JkW2UqVG54CXMV9TXrJ+l/bW+KKoWgBFSi INx8eDUqUdxa6rweTa0GnX0dd6hwVMnwgJgU+d6Aa7hzz5G9NucsAsDKVAemZTX2IjEU MBYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487519; x=1780092319; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=1oiPPeerxAd2KDhCMXKVrpSVXvS8guW5A+bxiFsiP8I=; b=EpG5B++PZXKuLqYRAZhQhGUuZP+VIl27EtH2ePrXncN21fwKasSk+2sTO3iEFFmUHN TXXclofZz6/HWUblUKzfwWAcyq++dh2AgWv2voPdW8te6lZfaY6JaGI+/stGmuLGBDvB m3MIZkr+nxfT4oSrHyrqLcWnnOMW/F/DAH0wNxVOWDzn5SIrzJrYOjxl9e9STFCWwm6s FElv8h+M9D7zWvzuYX8zp5McU/BozyV5nFJoMTLXSQZAZ+QqTi+4u90/lvRbyrdVCQfy XxQnUisUwzhd3mqUQ35XkDtetZvuDaMRZf9sAZKlwJ/l5jd/LxjJ3J8ZyhTFMP1uEYD9 d9Ow== X-Forwarded-Encrypted: i=1; AFNElJ9JGcRXCO342y/0yJz7rZCdTJYAoMSR1LPv+wSSqmYBGGUQzZGDchnap0mm7JH7hq73daI/27y72pJvUmo=@vger.kernel.org X-Gm-Message-State: AOJu0YwhO8NH+EIy8wfFAedLf8WQmaAjcYkQY14mKxTdzoUEjUV7ScIA BHuqX+xZ1atgJu3nulV1u7WCMa6Z2nIQg9pVQjLoUJc2RgdarvTosm0Am5VswaEUJwA9fg6Veox o2Af5Ey2UIg== X-Received: from dlb3.prod.google.com ([2002:a05:7022:603:b0:135:e6d6:d14d]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:61b:b0:12d:b205:c737 with SMTP id a92af1059eb24-1365f91bdb4mr2206422c88.17.1779487519099; Fri, 22 May 2026 15:05:19 -0700 (PDT) Date: Fri, 22 May 2026 15:04:28 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-18-irogers@google.com> Subject: [PATCH v9 17/23] perf python: Add callchain support From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement pyrf_callchain_node and pyrf_callchain types for lazy iteration over callchain frames. Add callchain property to sample_event. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- v2: 1. Eager Callchain Resolution: Moved the callchain resolution from deferred iteration to eager processing in pyrf_session_tool__sample() . This avoids risks of reading from unmapped memory or following dangling pointers to closed sessions. 2. Cached Callchain: Added a callchain field to struct pyrf_event to store the resolved object. 3. Simplified Access: pyrf_sample_event__get_callchain() now just returns the cached object if available. 4. Avoided Double Free: Handled lazy cleanups properly. v6: - Moved callchain resolution from `session_tool__sample` to `pyrf_event__new`. --- tools/perf/util/python.c | 241 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 240 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index daedd67f12d5..de7a51389572 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -66,6 +66,8 @@ struct pyrf_event { struct addr_location al; /** @al_resolved: True when machine__resolve been called. */ bool al_resolved; + /** @callchain: Resolved callchain, eagerly computed if requested. */ + PyObject *callchain; /** @event: The underlying perf_event that may be in a file or ring buffe= r. */ union perf_event event; }; @@ -103,6 +105,7 @@ static void pyrf_event__delete(struct pyrf_event *peven= t) { if (pevent->al_resolved) addr_location__exit(&pevent->al); + Py_XDECREF(pevent->callchain); perf_sample__exit(&pevent->sample); Py_TYPE(pevent)->tp_free((PyObject *)pevent); } @@ -669,6 +672,181 @@ static PyObject *pyrf_sample_event__insn(PyObject *se= lf, PyObject *args __maybe_ pevent->sample.insn_len); } =20 +struct pyrf_callchain_node { + PyObject_HEAD + u64 ip; + struct map *map; + struct symbol *sym; +}; + +static void pyrf_callchain_node__delete(struct pyrf_callchain_node *pnode) +{ + map__put(pnode->map); + Py_TYPE(pnode)->tp_free((PyObject*)pnode); +} + +static PyObject *pyrf_callchain_node__get_ip(struct pyrf_callchain_node *p= node, + void *closure __maybe_unused) +{ + return PyLong_FromUnsignedLongLong(pnode->ip); +} + +static PyObject *pyrf_callchain_node__get_symbol(struct pyrf_callchain_nod= e *pnode, + void *closure __maybe_unused) +{ + if (pnode->sym) + return PyUnicode_FromString(pnode->sym->name); + return PyUnicode_FromString("[unknown]"); +} + +static PyObject *pyrf_callchain_node__get_dso(struct pyrf_callchain_node *= pnode, + void *closure __maybe_unused) +{ + const char *dsoname =3D "[unknown]"; + + if (pnode->map) { + struct dso *dso =3D map__dso(pnode->map); + if (dso) { + if (symbol_conf.show_kernel_path && dso__long_name(dso)) + dsoname =3D dso__long_name(dso); + else + dsoname =3D dso__name(dso); + } + } + return PyUnicode_FromString(dsoname); +} + +static PyGetSetDef pyrf_callchain_node__getset[] =3D { + { .name =3D "ip", .get =3D (getter)pyrf_callchain_node__get_ip, }, + { .name =3D "symbol", .get =3D (getter)pyrf_callchain_node__get_symbol, }, + { .name =3D "dso", .get =3D (getter)pyrf_callchain_node__get_dso, }, + { .name =3D NULL, }, +}; + +static PyTypeObject pyrf_callchain_node__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.callchain_node", + .tp_basicsize =3D sizeof(struct pyrf_callchain_node), + .tp_dealloc =3D (destructor)pyrf_callchain_node__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_doc =3D "perf callchain node object.", + .tp_getset =3D pyrf_callchain_node__getset, +}; + +struct pyrf_callchain_frame { + u64 ip; + struct map *map; + struct symbol *sym; +}; + +struct pyrf_callchain { + PyObject_HEAD + struct pyrf_event *pevent; + struct pyrf_callchain_frame *frames; + u64 nr_frames; + u64 pos; + bool resolved; +}; + +static void pyrf_callchain__delete(struct pyrf_callchain *pchain) +{ + Py_XDECREF(pchain->pevent); + if (pchain->frames) { + for (u64 i =3D 0; i < pchain->nr_frames; i++) + map__put(pchain->frames[i].map); + free(pchain->frames); + } + Py_TYPE(pchain)->tp_free((PyObject*)pchain); +} + +static PyObject *pyrf_callchain__next(struct pyrf_callchain *pchain) +{ + struct pyrf_callchain_node *pnode; + + if (!pchain->resolved) { + struct evsel *evsel =3D pchain->pevent->sample.evsel; + struct evlist *evlist =3D evsel->evlist; + struct perf_session *session =3D evlist ? evlist__session(evlist) : NULL; + struct addr_location al; + struct callchain_cursor *cursor; + struct callchain_cursor_node *node; + u64 i; + + if (!session || !pchain->pevent->sample.callchain) + return NULL; + + addr_location__init(&al); + if (machine__resolve(&session->machines.host, &al, &pchain->pevent->samp= le) < 0) { + addr_location__exit(&al); + return NULL; + } + + cursor =3D get_tls_callchain_cursor(); + if (thread__resolve_callchain(al.thread, cursor, + &pchain->pevent->sample, NULL, NULL, + PERF_MAX_STACK_DEPTH) !=3D 0) { + addr_location__exit(&al); + return NULL; + } + callchain_cursor_commit(cursor); + + pchain->nr_frames =3D cursor->nr; + if (pchain->nr_frames > 0) { + pchain->frames =3D calloc(pchain->nr_frames, sizeof(*pchain->frames)); + if (!pchain->frames) { + addr_location__exit(&al); + return PyErr_NoMemory(); + } + + for (i =3D 0; i < pchain->nr_frames; i++) { + node =3D callchain_cursor_current(cursor); + pchain->frames[i].ip =3D node->ip; + pchain->frames[i].map =3D map__get(node->ms.map); + pchain->frames[i].sym =3D node->ms.sym; + callchain_cursor_advance(cursor); + } + } + pchain->resolved =3D true; + addr_location__exit(&al); + } + + if (pchain->pos >=3D pchain->nr_frames) + return NULL; + + pnode =3D PyObject_New(struct pyrf_callchain_node, &pyrf_callchain_node__= type); + if (!pnode) + return NULL; + + pnode->ip =3D pchain->frames[pchain->pos].ip; + pnode->map =3D map__get(pchain->frames[pchain->pos].map); + pnode->sym =3D pchain->frames[pchain->pos].sym; + + pchain->pos++; + return (PyObject *)pnode; +} + +static PyTypeObject pyrf_callchain__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.callchain", + .tp_basicsize =3D sizeof(struct pyrf_callchain), + .tp_dealloc =3D (destructor)pyrf_callchain__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_doc =3D "perf callchain object.", + .tp_iter =3D PyObject_SelfIter, + .tp_iternext =3D (iternextfunc)pyrf_callchain__next, +}; + +static PyObject *pyrf_sample_event__get_callchain(PyObject *self, void *cl= osure __maybe_unused) +{ + struct pyrf_event *pevent =3D (void *)self; + + if (!pevent->callchain) + Py_RETURN_NONE; + + Py_INCREF(pevent->callchain); + return pevent->callchain; +} + static PyObject* pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name) { @@ -683,6 +861,12 @@ pyrf_sample_event__getattro(struct pyrf_event *pevent,= PyObject *attr_name) } =20 static PyGetSetDef pyrf_sample_event__getset[] =3D { + { + .name =3D "callchain", + .get =3D pyrf_sample_event__get_callchain, + .set =3D NULL, + .doc =3D "event callchain.", + }, { .name =3D "raw_buf", .get =3D (getter)pyrf_sample_event__get_raw_buf, @@ -852,6 +1036,12 @@ static int pyrf_event__setup_types(void) err =3D PyType_Ready(&pyrf_context_switch_event__type); if (err < 0) goto out; + err =3D PyType_Ready(&pyrf_callchain_node__type); + if (err < 0) + goto out; + err =3D PyType_Ready(&pyrf_callchain__type); + if (err < 0) + goto out; out: return err; } @@ -872,9 +1062,11 @@ static PyTypeObject *pyrf_event__type[] =3D { }; =20 static PyObject *pyrf_event__new(const union perf_event *event, struct evs= el *evsel, - struct perf_session *session __maybe_unused) + struct perf_session *session) { struct pyrf_event *pevent; + struct perf_sample *sample; + struct machine *machine =3D session ? &session->machines.host : NULL; size_t size; int err; size_t min_size =3D sizeof(struct perf_event_header); @@ -1033,6 +1225,7 @@ static PyObject *pyrf_event__new(const union perf_eve= nt *event, struct evsel *ev } =20 perf_sample__init(&pevent->sample, /*all=3D*/true); + pevent->callchain =3D NULL; pevent->al_resolved =3D false; addr_location__init(&pevent->al); =20 @@ -1046,6 +1239,49 @@ static PyObject *pyrf_event__new(const union perf_ev= ent *event, struct evsel *ev return PyErr_Format(PyExc_OSError, "perf: can't parse sample, err=3D%d", err); } + sample =3D &pevent->sample; + if (machine && sample->callchain) { + struct addr_location al; + struct callchain_cursor *cursor; + u64 i; + struct pyrf_callchain *pchain; + + addr_location__init(&al); + if (machine__resolve(machine, &al, sample) >=3D 0) { + cursor =3D get_tls_callchain_cursor(); + if (thread__resolve_callchain(al.thread, cursor, sample, + NULL, NULL, PERF_MAX_STACK_DEPTH) =3D=3D 0) { + callchain_cursor_commit(cursor); + + pchain =3D PyObject_New(struct pyrf_callchain, &pyrf_callchain__type); + if (pchain) { + pchain->pevent =3D pevent; + Py_INCREF(pevent); + pchain->nr_frames =3D cursor->nr; + pchain->pos =3D 0; + pchain->resolved =3D true; + pchain->frames =3D calloc(pchain->nr_frames, + sizeof(*pchain->frames)); + if (pchain->frames) { + struct callchain_cursor_node *node; + + for (i =3D 0; i < pchain->nr_frames; i++) { + node =3D callchain_cursor_current(cursor); + pchain->frames[i].ip =3D node->ip; + pchain->frames[i].map =3D + map__get(node->ms.map); + pchain->frames[i].sym =3D node->ms.sym; + callchain_cursor_advance(cursor); + } + pevent->callchain =3D (PyObject *)pchain; + } else { + Py_DECREF(pchain); + } + } + } + addr_location__exit(&al); + } + } return (PyObject *)pevent; } =20 @@ -3145,6 +3381,9 @@ static PyObject *pyrf_session__new(PyTypeObject *type= , PyObject *args, PyObject } psession->session =3D session; =20 + symbol_conf.use_callchain =3D true; + symbol_conf.show_kernel_path =3D true; + symbol_conf.inline_name =3D false; if (symbol__init(perf_session__env(session)) < 0) { PyErr_SetString(PyExc_OSError, "perf: symbol__init failed"); goto err_out; --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C3623955E5 for ; Fri, 22 May 2026 22:05:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487524; cv=none; b=rS97+5hP7s/85gPs3MMhnd1Y36iDhPQP9nOgftYkneFNDPDVFJqveJLM2gpo8/YrdiRP8eXuxV9cgowUkZ+XI/Y/SDe66h1rt4vpkM6P0fmHJnE2NumhAkWig6+Wjorzj159OwaR90disBGk+eJRfn9h1aDJG79K760IqrreNks= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487524; c=relaxed/simple; bh=dqKmg4nKf14S8ybLYiSbiatdZipReLdpeDHE6VkthxU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=MZh27tkEklnDU3QU1ydWuU/5y2v9CwQNAXdVt159o7YrSG9j5RPwIx1gvhnEdGn2PVzu8u9LM+xQjuh++5jsIb92rPkMIKW5Sdv+EntZhENXvSStEdxgMxV6TM1eSkiN+nPJlxnDoCChMLIVyjwYLRl8yTfS1g5h6OolyY6TC2w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=dm/IZq3k; arc=none smtp.client-ip=74.125.82.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dm/IZq3k" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-135f2aa4742so6169143c88.1 for ; Fri, 22 May 2026 15:05:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487521; x=1780092321; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=w8zoT8NtEq4Wo2jdLV0BHRgdjeNd/pAmkexwraDI86U=; b=dm/IZq3kKtJnO9GeoaqwWMSMYGc82plLnu8s+iLl9NKrO3fGqHYhvD5/ceJEtA+kl3 AFltzMReFisVj3nb+usnnuHWtCZn/3P9/94aBKxmawwF5B+INFov3GcUMmWo5QPh7DKE 8xYividXP9Z8hIl4uaEwbmAsg3kYjLkIwiJ5fHCp6cej36JHfrOKfAo8TkwKsSpwYWyD O2kaCh+3lc4NPoiothpid6pctKO1TwaGqccPADTbDhT9u6yRcA8z02Zldn8CEFOKptY/ Dm+KkMYT5kGyuyqhT5a0Q50JM1eB+fa7/Yzu0+alQR0fCEvOfD8OpeIayFFAC6PjuTy2 Okuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487521; x=1780092321; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=w8zoT8NtEq4Wo2jdLV0BHRgdjeNd/pAmkexwraDI86U=; b=q0u+1HF9YqveXwO3klVx60oP9V7TyqHtl5LV/BgNYb0vl/Yd3DNM4LDyLPbFPbPhW4 vdE/Jtff/bWwJhMFCLGOx0J90wuXpbftXv8GhvUxLlUCAD5kDXNyddgXtlXRfgye0D9q Q9gDTZgwNAtvB2IAIwOTUrZiKW6JXMVdx2j7vl64avSVe7Ex0W8Fw4Mk9GtduSLjfgVx YgQFvHd7VuPkTfUS1Wq6/OoUOvTfNyMjppzIXUpEstzSNYVOOELGa9pOge0FPzicuFcb MfRUXdwGrra+AgvXviRq38l6fs3m0qemAGLvRZd3pzgK6uN28zUG1xWIMrcbRyeGdru4 cw+g== X-Forwarded-Encrypted: i=1; AFNElJ+pGYIBKBcOdygRu71OsSx1dewjUdoVn556PQhNKA+h3kmgFG1bxnO61QVGceLh7eDLFqyrK5i8TzARByM=@vger.kernel.org X-Gm-Message-State: AOJu0YxoPkiOhrfXIRiRErE7zvyX8wUV7ieCYZzeZl0BePjXHpczZ/hz TIhdS68xlcuml6kaFwDcVAE9KwyJ6m/rOjeWwmAG9Y5mSudB6slELV4fUqDW1zPs9Lt5IAVDCz3 3tz8l97Kemw== X-Received: from dlbvc2.prod.google.com ([2002:a05:7022:fe02:b0:133:3081:bb33]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:128a:b0:135:dd7c:7 with SMTP id a92af1059eb24-1365fc6db3dmr2056201c88.38.1779487520955; Fri, 22 May 2026 15:05:20 -0700 (PDT) Date: Fri, 22 May 2026 15:04:29 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-19-irogers@google.com> Subject: [PATCH v9 18/23] perf python: Extend API for stat events in python.c From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add stat information to the session. Add call backs for stat events. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- v5: 1. Fix Memory Corruption: Corrected the memory offset for `stat_round_type` in `pyrf_stat_round_event__members` by adding the base offset of `struct pyrf_event`. 2. Fix Memory Leak: Added `Py_XDECREF()` to free the unused return value of the Python callback in `pyrf_session_tool__stat_round()`. --- v7: - Added comprehensive size checks in pyrf_event__new for all event types. - Fixed line length warning. --- tools/perf/util/python.c | 180 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index de7a51389572..4ee3fdbf35de 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -343,6 +343,77 @@ static PyTypeObject pyrf_lost_event__type =3D { .tp_repr =3D (reprfunc)pyrf_lost_event__repr, }; =20 +static const char pyrf_stat_event__doc[] =3D PyDoc_STR("perf stat event ob= ject."); + +static PyMemberDef pyrf_stat_event__members[] =3D { + sample_members + member_def(perf_event_header, type, T_UINT, "event type"), + member_def(perf_record_stat, id, T_ULONGLONG, "event id"), + member_def(perf_record_stat, cpu, T_UINT, "event cpu"), + member_def(perf_record_stat, thread, T_UINT, "event thread"), + member_def(perf_record_stat, val, T_ULONGLONG, "counter value"), + member_def(perf_record_stat, ena, T_ULONGLONG, "enabled time"), + member_def(perf_record_stat, run, T_ULONGLONG, "running time"), + { .name =3D NULL, }, +}; + +static PyObject *pyrf_stat_event__repr(const struct pyrf_event *pevent) +{ + return PyUnicode_FromFormat( + "{ type: stat, id: %llu, cpu: %u, thread: %u, val: %llu, ena: %llu, run:= %llu }", + pevent->event.stat.id, + pevent->event.stat.cpu, + pevent->event.stat.thread, + pevent->event.stat.val, + pevent->event.stat.ena, + pevent->event.stat.run); +} + +static PyTypeObject pyrf_stat_event__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.stat_event", + .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_new =3D PyType_GenericNew, + .tp_dealloc =3D (destructor)pyrf_event__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_doc =3D pyrf_stat_event__doc, + .tp_members =3D pyrf_stat_event__members, + .tp_getset =3D pyrf_event__getset, + .tp_repr =3D (reprfunc)pyrf_stat_event__repr, +}; + +static const char pyrf_stat_round_event__doc[] =3D PyDoc_STR("perf stat ro= und event object."); + +static PyMemberDef pyrf_stat_round_event__members[] =3D { + sample_members + member_def(perf_event_header, type, T_UINT, "event type"), + { .name =3D "stat_round_type", .type =3D T_ULONGLONG, + .offset =3D offsetof(struct pyrf_event, event) + offsetof(struct perf_r= ecord_stat_round, type), + .doc =3D "round type" }, + member_def(perf_record_stat_round, time, T_ULONGLONG, "round time"), + { .name =3D NULL, }, +}; + +static PyObject *pyrf_stat_round_event__repr(const struct pyrf_event *peve= nt) +{ + return PyUnicode_FromFormat("{ type: stat_round, type: %llu, time: %llu }= ", + pevent->event.stat_round.type, + pevent->event.stat_round.time); +} + +static PyTypeObject pyrf_stat_round_event__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.stat_round_event", + .tp_basicsize =3D sizeof(struct pyrf_event), + .tp_new =3D PyType_GenericNew, + .tp_dealloc =3D (destructor)pyrf_event__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_doc =3D pyrf_stat_round_event__doc, + .tp_members =3D pyrf_stat_round_event__members, + .tp_getset =3D pyrf_event__getset, + .tp_repr =3D (reprfunc)pyrf_stat_round_event__repr, +}; + static const char pyrf_read_event__doc[] =3D PyDoc_STR("perf read event ob= ject."); =20 static PyMemberDef pyrf_read_event__members[] =3D { @@ -1034,6 +1105,12 @@ static int pyrf_event__setup_types(void) if (err < 0) goto out; err =3D PyType_Ready(&pyrf_context_switch_event__type); + if (err < 0) + goto out; + err =3D PyType_Ready(&pyrf_stat_event__type); + if (err < 0) + goto out; + err =3D PyType_Ready(&pyrf_stat_round_event__type); if (err < 0) goto out; err =3D PyType_Ready(&pyrf_callchain_node__type); @@ -1059,6 +1136,8 @@ static PyTypeObject *pyrf_event__type[] =3D { [PERF_RECORD_SAMPLE] =3D &pyrf_sample_event__type, [PERF_RECORD_SWITCH] =3D &pyrf_context_switch_event__type, [PERF_RECORD_SWITCH_CPU_WIDE] =3D &pyrf_context_switch_event__type, + [PERF_RECORD_STAT] =3D &pyrf_stat_event__type, + [PERF_RECORD_STAT_ROUND] =3D &pyrf_stat_round_event__type, }; =20 static PyObject *pyrf_event__new(const union perf_event *event, struct evs= el *evsel, @@ -1091,13 +1170,13 @@ static PyObject *pyrf_event__new(const union perf_e= vent *event, struct evsel *ev case PERF_RECORD_EXIT: min_size =3D sizeof(struct perf_record_fork); break; + case PERF_RECORD_LOST: + min_size =3D sizeof(struct perf_record_lost); + break; case PERF_RECORD_THROTTLE: case PERF_RECORD_UNTHROTTLE: min_size =3D sizeof(struct perf_record_throttle); break; - case PERF_RECORD_LOST: - min_size =3D sizeof(struct perf_record_lost); - break; case PERF_RECORD_READ: min_size =3D sizeof(struct perf_record_read); break; @@ -2119,7 +2198,40 @@ static PyObject *pyrf_evsel__get_attr_wakeup_events(= PyObject *self, void */*clos return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.wakeup_events); } =20 +static PyObject *pyrf_evsel__get_ids(struct pyrf_evsel *pevsel, void *clos= ure __maybe_unused) +{ + struct evsel *evsel =3D pevsel->evsel; + PyObject *list =3D PyList_New(0); + + if (!list) + return NULL; + + for (u32 i =3D 0; i < evsel->core.ids; i++) { + PyObject *id =3D PyLong_FromUnsignedLongLong(evsel->core.id[i]); + int ret; + + if (!id) { + Py_DECREF(list); + return NULL; + } + ret =3D PyList_Append(list, id); + Py_DECREF(id); + if (ret < 0) { + Py_DECREF(list); + return NULL; + } + } + + return list; +} + static PyGetSetDef pyrf_evsel__getset[] =3D { + { + .name =3D "ids", + .get =3D (getter)pyrf_evsel__get_ids, + .set =3D NULL, + .doc =3D "event IDs.", + }, { .name =3D "tracking", .get =3D pyrf_evsel__get_tracking, @@ -2894,6 +3006,8 @@ static const struct perf_constant perf__constants[] = =3D { PERF_CONST(RECORD_LOST_SAMPLES), PERF_CONST(RECORD_SWITCH), PERF_CONST(RECORD_SWITCH_CPU_WIDE), + PERF_CONST(RECORD_STAT), + PERF_CONST(RECORD_STAT_ROUND), =20 PERF_CONST(RECORD_MISC_SWITCH_OUT), { .name =3D NULL, }, @@ -3270,6 +3384,7 @@ struct pyrf_session { struct perf_tool tool; struct pyrf_data *pdata; PyObject *sample; + PyObject *stat; }; =20 static int pyrf_session_tool__sample(const struct perf_tool *tool, @@ -3294,6 +3409,50 @@ static int pyrf_session_tool__sample(const struct pe= rf_tool *tool, return 0; } =20 +static int pyrf_session_tool__stat(const struct perf_tool *tool, + struct perf_session *session, + union perf_event *event) +{ + struct pyrf_session *psession =3D container_of(tool, struct pyrf_session,= tool); + struct evsel *evsel =3D evlist__id2evsel(session->evlist, event->stat.id); + PyObject *pyevent =3D pyrf_event__new(event, evsel, psession->session); + const char *name =3D evsel ? evsel__name(evsel) : "unknown"; + PyObject *ret; + + if (pyevent =3D=3D NULL) + return -ENOMEM; + + ret =3D PyObject_CallFunction(psession->stat, "Os", pyevent, name); + if (!ret) { + Py_DECREF(pyevent); + return -1; + } + Py_DECREF(ret); + Py_DECREF(pyevent); + return 0; +} + +static int pyrf_session_tool__stat_round(const struct perf_tool *tool, + struct perf_session *session __maybe_unused, + union perf_event *event) +{ + struct pyrf_session *psession =3D container_of(tool, struct pyrf_session,= tool); + PyObject *pyevent =3D pyrf_event__new(event, /*evsel=3D*/NULL, psession->= session); + PyObject *ret; + + if (pyevent =3D=3D NULL) + return -ENOMEM; + + ret =3D PyObject_CallFunction(psession->stat, "O", pyevent); + if (!ret) { + Py_DECREF(pyevent); + return -1; + } + Py_DECREF(ret); + Py_DECREF(pyevent); + return 0; +} + static PyObject *pyrf_session__find_thread(struct pyrf_session *psession, = PyObject *args) { struct machine *machine; @@ -3325,13 +3484,13 @@ static PyObject *pyrf_session__find_thread(struct p= yrf_session *psession, PyObje static PyObject *pyrf_session__new(PyTypeObject *type, PyObject *args, PyO= bject *kwargs) { struct pyrf_data *pdata; - PyObject *sample =3D NULL; - static char *kwlist[] =3D { "data", "sample", NULL }; + PyObject *sample =3D NULL, *stat =3D NULL; + static char *kwlist[] =3D { "data", "sample", "stat", NULL }; struct pyrf_session *psession; struct perf_session *session; =20 - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|O", kwlist, &pyrf_data= __type, &pdata, - &sample)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|OO", kwlist, &pyrf_dat= a__type, &pdata, + &sample, &stat)) return NULL; =20 psession =3D PyObject_New(struct pyrf_session, type); @@ -3340,6 +3499,7 @@ static PyObject *pyrf_session__new(PyTypeObject *type= , PyObject *args, PyObject =20 psession->session =3D NULL; psession->sample =3D NULL; + psession->stat =3D NULL; psession->pdata =3D NULL; =20 Py_INCREF(pdata); @@ -3362,8 +3522,13 @@ static PyObject *pyrf_session__new(PyTypeObject *typ= e, PyObject *args, PyObject } while (0) =20 ADD_TOOL(sample); + ADD_TOOL(stat); #undef ADD_TOOL =20 + if (stat) + psession->tool.stat_round =3D pyrf_session_tool__stat_round; + + psession->tool.comm =3D perf_event__process_comm; psession->tool.mmap =3D perf_event__process_mmap; psession->tool.mmap2 =3D perf_event__process_mmap2; @@ -3403,6 +3568,7 @@ static void pyrf_session__delete(struct pyrf_session = *psession) perf_session__delete(psession->session); Py_XDECREF(psession->pdata); Py_XDECREF(psession->sample); + Py_XDECREF(psession->stat); Py_TYPE(psession)->tp_free((PyObject *)psession); } =20 --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31EBF395AC6 for ; Fri, 22 May 2026 22:05:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487527; cv=none; b=V7+fRnEqQBMK5LfqocoN35i6HQAJCxaNCe29UGMp7HOHZ1Twbzu2GgZWMLg1MxEofKqGLibSbApknCAozuEbNTQZid/iYU0hFHw1KEuH9WPsyBpDZXOiIIDnC/Z7n4TzpEMq9x6mR6qdKIzJFPtGzgYWPCu6JjNPgK9Uqlq9Bh4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487527; c=relaxed/simple; bh=j3+Rlaqijmt5qgeyUxpXr8T2qsOrqB+zeDJaTcRKgAk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=tGCVTlJQ408oNlmXMuVueqjaAgpaTs+Po17xgCshXoALbxIrpkIgfCQUnNrddEU1HH40wDipBBiP5SMV1+qDvYLBxE8Jl8pMZZWIgfcaQYBmz917FhuN4iAUxpVOtz7w37nex1uHnLpASg4kMY0vc86Dcd4ImiKbRiqlXy4eAkY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=dz2ZhFCH; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dz2ZhFCH" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2bda35eab74so6832430eec.0 for ; Fri, 22 May 2026 15:05:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487524; x=1780092324; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=BiZW+4jI8OxUDjAVnAPFPTLaAfN5BKtS7dWyyal4m1A=; b=dz2ZhFCHmRmGnHlHP6P91i5Yp8dA6GGH+WX5/NB/H2MgBac8PLqTUaFqHDxIK7E2HL FDjIUIjWpCvpanchAq4+zUNbMHUL8YAxqeWS/7E//p4/woMZKg4xZsrw4coqTw8qY/Id x/oWz8zpIRfhuh2fEBtLfj+XFM01p5CAvKQGpsBVWVAHEtscPzw5NNai5PdbSdVC3waW Pu5GqBlGLdFGgKsNWNZhPa9ubYTJHdqvUsnE3FJxSBcQUiQSFrz0+fE5+4FpRUR+tzs6 8o56mxHUODkOZMa++Efcy3GMxvG/pUSEVsvwQq1Uqr5e5Zo8V1XaWEcAnXiFsXBuvJJ8 lqJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487524; x=1780092324; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=BiZW+4jI8OxUDjAVnAPFPTLaAfN5BKtS7dWyyal4m1A=; b=ZtOWrDbxxvvNv5iedYTvS+DuwpUd7FFh5zr34yau6ptiYdpe1dqrR2aSeRqSQ0lncv nEODLVsCPri6nrgLG8cnpI9o8RNSxo/bz7va+qujZJ4DMv2NUM0cmvMk53QOUA5rskjC TvrBxRqaxoYkLjQ5Mj2EUfX7d7oyWKxGOf2qAlLNipbRdUet7fYkS5TII0BB6gAQlbpJ +Rw9O0jv3F/ampuG6VA6uNQpgNR97ZDmMOn3sbFZS5KGQ3GKRQX6AWgaSIzLg5o23hL2 Et8pUFOgqOvjPi+1889v4TvcFKuz+bLKlL+jJntKvckb7gNRGy3iYRiW1aayVNJ8+4h0 HV8A== X-Forwarded-Encrypted: i=1; AFNElJ+KEvIAQXyw56shoy5QUfyNjs9ktqx2nShF/xHf6rpx7/uBwvwLtdVlejP2yPcDLF00/bMQI5XCJuHi+Tg=@vger.kernel.org X-Gm-Message-State: AOJu0YztOs48tVn4S9UaiBeMN0VuZYqlWZFhRTk1P+1WZlSByiEw7sxf p0UP3Ey/Y8D6moMPQjEvQgKe6fo8aPuoih2K7qBXJCkqYU6NW716Lbevr1pMocjedwRUtw4Ls3h IZczIGQqSig== X-Received: from dylq18.prod.google.com ([2002:a05:7300:5992:b0:2df:46bf:2390]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:6448:b0:2f3:5d44:eeba with SMTP id 5a478bee46e88-30430522a28mr4042945eec.6.1779487524005; Fri, 22 May 2026 15:05:24 -0700 (PDT) Date: Fri, 22 May 2026 15:04:30 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-20-irogers@google.com> Subject: [PATCH v9 19/23] perf python: Expose brstack in sample event From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement pyrf_branch_entry and pyrf_branch_stack for lazy iteration over branch stack entries. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- v2: 1. Avoided Keyword Collision: Renamed the properties "from" and "to" to "from_ip" and "to_ip" in pyrf_branch_entry__getset[] to prevent syntax errors in Python. 2. Eager Branch Stack Resolution: Updated pyrf_session_tool__sample() to allocate and copy the branch stack entries eagerly when the event is processed, instead of deferring it to iteration time. This avoids reading from potentially overwritten or unmapped mmap buffers. 3. Updated Iterators: Updated pyrf_branch_stack and pyrf_branch_stack__next() to use the copied entries rather than pointing directly to the sample's buffer. 4. Avoided Reference Leak on Init Failure: Added proper error checking for PyModule_AddObject() in the module initialization function, decrementing references on failure. v6: - Moved branch stack resolution from `session_tool__sample` to `pyrf_event__new`. --- tools/perf/util/python.c | 188 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 4ee3fdbf35de..218d772346e2 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -19,6 +19,7 @@ #include "debug.h" #include "dso.h" #include "event.h" +#include "branch.h" #include "evlist.h" #include "evsel.h" #include "expr.h" @@ -68,6 +69,8 @@ struct pyrf_event { bool al_resolved; /** @callchain: Resolved callchain, eagerly computed if requested. */ PyObject *callchain; + /** @brstack: Resolved branch stack, eagerly computed if requested. */ + PyObject *brstack; /** @event: The underlying perf_event that may be in a file or ring buffe= r. */ union perf_event event; }; @@ -106,6 +109,7 @@ static void pyrf_event__delete(struct pyrf_event *peven= t) if (pevent->al_resolved) addr_location__exit(&pevent->al); Py_XDECREF(pevent->callchain); + Py_XDECREF(pevent->brstack); perf_sample__exit(&pevent->sample); Py_TYPE(pevent)->tp_free((PyObject *)pevent); } @@ -918,6 +922,144 @@ static PyObject *pyrf_sample_event__get_callchain(PyO= bject *self, void *closure return pevent->callchain; } =20 +struct pyrf_branch_entry { + PyObject_HEAD + u64 from; + u64 to; + struct branch_flags flags; +}; + +static void pyrf_branch_entry__delete(struct pyrf_branch_entry *pentry) +{ + Py_TYPE(pentry)->tp_free((PyObject *)pentry); +} + +static PyObject *pyrf_branch_entry__get_from(struct pyrf_branch_entry *pen= try, + void *closure __maybe_unused) +{ + return PyLong_FromUnsignedLongLong(pentry->from); +} + +static PyObject *pyrf_branch_entry__get_to(struct pyrf_branch_entry *pentr= y, + void *closure __maybe_unused) +{ + return PyLong_FromUnsignedLongLong(pentry->to); +} + +static PyObject *pyrf_branch_entry__get_mispred(struct pyrf_branch_entry *= pentry, + void *closure __maybe_unused) +{ + return PyBool_FromLong(pentry->flags.mispred); +} + +static PyObject *pyrf_branch_entry__get_predicted(struct pyrf_branch_entry= *pentry, + void *closure __maybe_unused) +{ + return PyBool_FromLong(pentry->flags.predicted); +} + +static PyObject *pyrf_branch_entry__get_in_tx(struct pyrf_branch_entry *pe= ntry, + void *closure __maybe_unused) +{ + return PyBool_FromLong(pentry->flags.in_tx); +} + +static PyObject *pyrf_branch_entry__get_abort(struct pyrf_branch_entry *pe= ntry, + void *closure __maybe_unused) +{ + return PyBool_FromLong(pentry->flags.abort); +} + +static PyObject *pyrf_branch_entry__get_cycles(struct pyrf_branch_entry *p= entry, + void *closure __maybe_unused) +{ + return PyLong_FromUnsignedLongLong(pentry->flags.cycles); +} + +static PyObject *pyrf_branch_entry__get_type(struct pyrf_branch_entry *pen= try, + void *closure __maybe_unused) +{ + return PyLong_FromLong(pentry->flags.type); +} + +static PyGetSetDef pyrf_branch_entry__getset[] =3D { + { .name =3D "from_ip", .get =3D (getter)pyrf_branch_entry__get_from,= }, + { .name =3D "to_ip", .get =3D (getter)pyrf_branch_entry__get_to, }, + { .name =3D "mispred", .get =3D (getter)pyrf_branch_entry__get_mispred,= }, + { .name =3D "predicted", .get =3D (getter)pyrf_branch_entry__get_predicte= d, }, + { .name =3D "in_tx", .get =3D (getter)pyrf_branch_entry__get_in_tx, }, + { .name =3D "abort", .get =3D (getter)pyrf_branch_entry__get_abort, }, + { .name =3D "cycles", .get =3D (getter)pyrf_branch_entry__get_cycles, = }, + { .name =3D "type", .get =3D (getter)pyrf_branch_entry__get_type, }, + { .name =3D NULL, }, +}; + +static PyTypeObject pyrf_branch_entry__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.branch_entry", + .tp_basicsize =3D sizeof(struct pyrf_branch_entry), + .tp_dealloc =3D (destructor)pyrf_branch_entry__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_doc =3D "perf branch entry object.", + .tp_getset =3D pyrf_branch_entry__getset, +}; + +struct pyrf_branch_stack { + PyObject_HEAD + struct pyrf_event *pevent; + struct branch_entry *entries; + u64 nr; + u64 pos; +}; + +static void pyrf_branch_stack__delete(struct pyrf_branch_stack *pstack) +{ + Py_XDECREF(pstack->pevent); + free(pstack->entries); + Py_TYPE(pstack)->tp_free((PyObject *)pstack); +} + +static PyObject *pyrf_branch_stack__next(struct pyrf_branch_stack *pstack) +{ + struct pyrf_branch_entry *pentry; + + if (pstack->pos >=3D pstack->nr) + return NULL; + + pentry =3D PyObject_New(struct pyrf_branch_entry, &pyrf_branch_entry__typ= e); + if (!pentry) + return NULL; + + pentry->from =3D pstack->entries[pstack->pos].from; + pentry->to =3D pstack->entries[pstack->pos].to; + pentry->flags =3D pstack->entries[pstack->pos].flags; + + pstack->pos++; + return (PyObject *)pentry; +} + +static PyTypeObject pyrf_branch_stack__type =3D { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name =3D "perf.branch_stack", + .tp_basicsize =3D sizeof(struct pyrf_branch_stack), + .tp_dealloc =3D (destructor)pyrf_branch_stack__delete, + .tp_flags =3D Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + .tp_doc =3D "perf branch stack object.", + .tp_iter =3D PyObject_SelfIter, + .tp_iternext =3D (iternextfunc)pyrf_branch_stack__next, +}; + +static PyObject *pyrf_sample_event__get_brstack(PyObject *self, void *clos= ure __maybe_unused) +{ + struct pyrf_event *pevent =3D (void *)self; + + if (!pevent->brstack) + Py_RETURN_NONE; + + Py_INCREF(pevent->brstack); + return pevent->brstack; +} + static PyObject* pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name) { @@ -938,6 +1080,12 @@ static PyGetSetDef pyrf_sample_event__getset[] =3D { .set =3D NULL, .doc =3D "event callchain.", }, + { + .name =3D "brstack", + .get =3D pyrf_sample_event__get_brstack, + .set =3D NULL, + .doc =3D "event branch stack.", + }, { .name =3D "raw_buf", .get =3D (getter)pyrf_sample_event__get_raw_buf, @@ -1119,6 +1267,12 @@ static int pyrf_event__setup_types(void) err =3D PyType_Ready(&pyrf_callchain__type); if (err < 0) goto out; + err =3D PyType_Ready(&pyrf_branch_entry__type); + if (err < 0) + goto out; + err =3D PyType_Ready(&pyrf_branch_stack__type); + if (err < 0) + goto out; out: return err; } @@ -1305,6 +1459,7 @@ static PyObject *pyrf_event__new(const union perf_eve= nt *event, struct evsel *ev =20 perf_sample__init(&pevent->sample, /*all=3D*/true); pevent->callchain =3D NULL; + pevent->brstack =3D NULL; pevent->al_resolved =3D false; addr_location__init(&pevent->al); =20 @@ -1361,6 +1516,27 @@ static PyObject *pyrf_event__new(const union perf_ev= ent *event, struct evsel *ev addr_location__exit(&al); } } + if (sample->branch_stack) { + struct branch_stack *bs =3D sample->branch_stack; + struct branch_entry *entries =3D perf_sample__branch_entries(sample); + struct pyrf_branch_stack *pstack; + + pstack =3D PyObject_New(struct pyrf_branch_stack, &pyrf_branch_stack__ty= pe); + if (pstack) { + Py_INCREF(pevent); + pstack->pevent =3D pevent; + pstack->pos =3D 0; + pstack->nr =3D bs->nr; + pstack->entries =3D calloc(bs->nr, sizeof(struct branch_entry)); + if (pstack->entries) { + memcpy(pstack->entries, entries, + bs->nr * sizeof(struct branch_entry)); + pevent->brstack =3D (PyObject *)pstack; + } else { + Py_DECREF(pstack); + } + } + } return (PyObject *)pevent; } =20 @@ -3742,6 +3918,18 @@ PyMODINIT_FUNC PyInit_perf(void) Py_INCREF(&pyrf_session__type); PyModule_AddObject(module, "session", (PyObject *)&pyrf_session__type); =20 + Py_INCREF(&pyrf_branch_entry__type); + if (PyModule_AddObject(module, "branch_entry", (PyObject *)&pyrf_branch_e= ntry__type) < 0) { + Py_DECREF(&pyrf_branch_entry__type); + goto error; + } + + Py_INCREF(&pyrf_branch_stack__type); + if (PyModule_AddObject(module, "branch_stack", (PyObject *)&pyrf_branch_s= tack__type) < 0) { + Py_DECREF(&pyrf_branch_stack__type); + goto error; + } + dict =3D PyModule_GetDict(module); if (dict =3D=3D NULL) goto error; --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 29AFF399346 for ; Fri, 22 May 2026 22:05:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487529; cv=none; b=D4PUXFcAFl6p6GkRKSy8UW2m6tIfaWJpaEK5mbNfEPw/8EYGdXDkXlzla/Xgc6wHPcd+G4nZ/yW7eiuTxcI76Hxg1C5twlpJCul4IKJWabA/UScW2Ydjr1pPnMkoBqT32wFJgKlH54bHs3uQgMa0KUYSjo3LUSJBTgC4/yNC1KY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487529; c=relaxed/simple; bh=1HzIEyfchpBFETRM/gJfbDSVMw43NVkp9FBkAodJsTw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=iGjdK4C+Ffpll73r5zX1FaKwkQ5yuenzlFV2P9uWHZ42qEAta1Y9gkqFGp5ve76zy45730NQrJtltfkeI9I6vHF8gn+Ux5rt5vgs5z1p922TdSSBARHgK8ypXVO3KuLu3ekNhE55nkUlYbVwEpRX4bc39UuXwxXWz3/CpUXM0kQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=E8UW1Vqb; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="E8UW1Vqb" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-303b38ec2f6so11459566eec.0 for ; Fri, 22 May 2026 15:05:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487526; x=1780092326; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=jM4bdTdLVv/rhBQCW1JN696MSnte4z484SiWq30EwPI=; b=E8UW1VqbtejuallkIYTMp8Tt53m9NPqumItDSlFQ1OjLy+z+ggw5bCCMCPnZgok9JE c4hs0ByE9dHPNOcNZSZ6a5oTdwrYLviegY3+Ix6shLuBZG3EquM17j8eSlKk+Y+V9DKL Clt8RPAT1zCNFZmNsXBRcHa4hvLGmoLIobyncd9RZfwYkqNUQUEf1L+HYbxu1NwLMrUp fYUMcJkoLQEr7VC0AWagXpj4zUJQ0qfM2K1MTigQOiR524Q4uc9IaXZ/XoTqFA2ZPDS1 WxJ7yXAtQoIx+q8iuulSBNRPudp2i4kt7FcKT1bgUyCQLZ1AddH7GKcft5Yc5R6I4FAs DYeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487526; x=1780092326; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=jM4bdTdLVv/rhBQCW1JN696MSnte4z484SiWq30EwPI=; b=DQ8Irvgnk+4Nme/AQMEyIDoZlhzcXAKj0aPhdiqvlxI7nYOiurHFZrqor6JHczXDH7 DK2msCc3ZBl5EO8IE4U4/sQhyonTbCLvd0nuQBzR74SWRhY4d3lnuxlsnCybEgfAbyJ9 IAFYf3PHCn3AN0bgRyEnwupSsvi4jwn9NTpAlnpZwvmPaQdZBYULqL7XsBMTIo+srVAC EF0SunqdO0rytBFmRIlEXODjx+6HgEZ0FjKsViTzTgjFVQOwftzWTI8oNZBdxrjFCONT ylrD+nl5r6MerMVq7140yhl01GdjTsgBbWyqWjQ9jhaamuKYG4AfmYikbo7ZJLkACmTv p6RA== X-Forwarded-Encrypted: i=1; AFNElJ/LFWW3DXH8V9zCFNMnZkQmR2U2lNzE+sRoH89yh0hCUEfE185DOelZJ17Z9bio/W4MlgyvoPnwejWrONA=@vger.kernel.org X-Gm-Message-State: AOJu0Yy/1VBbL56TgrmeqSQetu+9SNoDnHv38+NvX9i3GmUb4LUYoxUz SF557T5J7rA5gf8tUe/IIuwqkoyOsmwmfEGhHS1xUxHk4a+WtSXKwy2hTfxrKZ7hkhew9MMZvly YY2J/krPQXg== X-Received: from dycac4.prod.google.com ([2002:a05:7301:5504:b0:2f9:af7:5047]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:7fa6:b0:2ea:edc0:4fbe with SMTP id 5a478bee46e88-30449095631mr3131034eec.14.1779487526120; Fri, 22 May 2026 15:05:26 -0700 (PDT) Date: Fri, 22 May 2026 15:04:31 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-21-irogers@google.com> Subject: [PATCH v9 20/23] perf python: Add syscall name/id to convert syscall number and name From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use perf's syscalltbl support to convert syscall number to name assuming the number is for the host machine. This avoids python libaudit support as tools/perf/scripts/python/syscall-counts.py requires. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- v2: 1. Guarded with HAVE_LIBTRACEEVENT : Wrapped the syscall functions and their entries in perf__methods with #ifdef HAVE_LIBTRACEEVENT to avoid potential linker errors if CONFIG_TRACE is disabled. 2. Changed Exception Type: Updated pyrf__syscall_id to raise a ValueError instead of a TypeError when a syscall is not found. 3. Fixed Typo: Corrected "name number" to "name" in the docstring for syscall_id. v6: - Added optional keyword-only `elf_machine` argument to `syscall_name` and `syscall_id`. v7: - Made syscalltbl.o unconditional in Build to fix undefined symbol when building without libtraceevent. --- tools/perf/util/Build | 1 - tools/perf/util/python.c | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 4bbc78b1f741..e37779f9dfe4 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -75,7 +75,6 @@ perf-util-y +=3D sample.o perf-util-y +=3D sample-raw.o perf-util-y +=3D s390-sample-raw.o perf-util-y +=3D amd-sample-raw.o - perf-util-y +=3D ordered-events.o perf-util-y +=3D namespaces.o perf-util-y +=3D comm.o diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 218d772346e2..23eb65adb392 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -18,6 +18,7 @@ #include "data.h" #include "debug.h" #include "dso.h" +#include "dwarf-regs.h" #include "event.h" #include "branch.h" #include "evlist.h" @@ -35,6 +36,7 @@ #include "srcline.h" #include "strbuf.h" #include "symbol.h" +#include "trace/beauty/syscalltbl.h" #include "thread.h" #include "thread_map.h" #include "tool.h" @@ -3792,6 +3794,40 @@ static int pyrf_session__setup_types(void) return PyType_Ready(&pyrf_session__type); } =20 +static PyObject *pyrf__syscall_name(PyObject *self, PyObject *args, PyObje= ct *kwargs) +{ + const char *name; + int id; + int elf_machine =3D EM_HOST; + static char * const kwlist[] =3D { "id", "elf_machine", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|$i", kwlist, &id, &elf_= machine)) + return NULL; + + name =3D syscalltbl__name(elf_machine, id); + if (!name) + Py_RETURN_NONE; + return PyUnicode_FromString(name); +} + +static PyObject *pyrf__syscall_id(PyObject *self, PyObject *args, PyObject= *kwargs) +{ + const char *name; + int id; + int elf_machine =3D EM_HOST; + static char * const kwlist[] =3D { "name", "elf_machine", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|$i", kwlist, &name, &el= f_machine)) + return NULL; + + id =3D syscalltbl__id(elf_machine, name); + if (id < 0) { + PyErr_Format(PyExc_ValueError, "Failed to find syscall %s", name); + return NULL; + } + return PyLong_FromLong(id); +} + static PyMethodDef perf__methods[] =3D { { .ml_name =3D "metrics", @@ -3825,6 +3861,18 @@ static PyMethodDef perf__methods[] =3D { .ml_flags =3D METH_NOARGS, .ml_doc =3D PyDoc_STR("Returns a sequence of pmus.") }, + { + .ml_name =3D "syscall_name", + .ml_meth =3D (PyCFunction) pyrf__syscall_name, + .ml_flags =3D METH_VARARGS | METH_KEYWORDS, + .ml_doc =3D PyDoc_STR("Turns a syscall number to a string.") + }, + { + .ml_name =3D "syscall_id", + .ml_meth =3D (PyCFunction) pyrf__syscall_id, + .ml_flags =3D METH_VARARGS | METH_KEYWORDS, + .ml_doc =3D PyDoc_STR("Turns a syscall name to a number.") + }, { .ml_name =3D NULL, } }; =20 --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3FBDF39A4A8 for ; Fri, 22 May 2026 22:05:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487530; cv=none; b=nnKeYPXFrAp8l6uFX61UFJU66U8wA3SWbCl1s5BlXTl2OYKklIEzLxiDek3v0jwB7VA0Xrz/MLbZdTjK+s2YIdSFkmaPbBWTD4xzQWIq+8G0T2pzuslIu6d+NxJJuA/88af9l0Y4x2a7sHtnd7qyn1qZalUt4NYlm/e7ppIT92E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487530; c=relaxed/simple; bh=c1ddBh53K2pNzpDiOqsVnlXKDiZX9MV3/Y0n9MFuxBM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Vpnrm5Lwpf/IuoKbtiVOfiLV31l9oX3nvv/iX3Jz/N4o3mjzpnD8MCb1x77fQrybNifMM2G/io6jPWCZcwH8o4CKT56GlCld3eXz8d6X/P49aIMGgD7baESNhFSnmZoYhjkSku8OksVynNz2MBYvsujerHyG3wh4KQac2XHJhrw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=L3sAN04s; arc=none smtp.client-ip=74.125.82.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="L3sAN04s" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-135f2aa4742so6169234c88.1 for ; Fri, 22 May 2026 15:05:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487528; x=1780092328; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=O/OkUfIECucUs4dgUQxXg6gu1NGDepTpokWupB8NdEw=; b=L3sAN04snxvHeago6Fs4lSWFENCtmvTi6dOe/JaiUAQa8GWmN5yPqIb7sSpv39zX/t ODBDmmSmBmDo9e0QOggVFOtc8vk3DklbPNftDGHdVx2tVUuvfEvKYT0W9umqRC0w8iqC xEiylote/AAMmewwfi8g1zFfq2Qp+vY1zenoM7x0MHMPj6Z6MH0wNu8Cnj2I2v6WoBlf JC2ELp6wWTsOgNBqeWn+118flQBb4chPfSjZtaWOH6oi0/6M2oKk0SRRuz3hw10mR3aG 8Pwhpn0Kp+UdtrrLJev4bGf1J25rN3gsC8WGxTv6wSl5PDkuNvFVdnxKy8PkOo7HDzeo tXiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487528; x=1780092328; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=O/OkUfIECucUs4dgUQxXg6gu1NGDepTpokWupB8NdEw=; b=aPX3zTop4MC8wz8cC0wPfJ3yVyn9Y7LePRRoaOpSeKl+xXiHQHKhm05l0dC6i5kDGq a6gVQpZSsh5IoZaImZiDOiLPS5b/ezuCw0ubOrSF1EM9Rdblqxwcp+qZS4lVjMeh9yqu sdrNOLzFG/QyPbdMBRljqg4qRjfon5hhuG+N5yig5gWf9v4LWQ4cXEMmbrIS1s7uwemC MuHpkSA/af/WIY1Vz+5pEIZI79DO6oK95nQPJV54axL73+mF6/B58+vlEmqWvgjo5ZUh SemG4rdZ1bqIJahmxj/vmzk0e6Y6MTOzPxa/QnY1R9/GpgUgvmBpL8fq4Pu3Q8wnR2by I3gg== X-Forwarded-Encrypted: i=1; AFNElJ9l3t6HCI4G/+c7jjEYgU9kopypvBMfxsEM8tpUdtOric/tiPyYBKdAxY2B71ichP7B5BqlXpY1AYiMK8o=@vger.kernel.org X-Gm-Message-State: AOJu0YxxiSQSnUV+P2irBIpPzOtBcnqyKmKPyqiDA+f9D/8BStbpXD1A 4RraMfUfT8kjfZCdB5KtTSXgClpuLrrs/BWV45wcvCaCuadLkgyDpW+jzrfEfjx03A8afE49jrf XlwbuQNA2+Q== X-Received: from dleb20-n1.prod.google.com ([2002:a05:701b:4254:10b0:12d:bbdf:edcb]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:41aa:b0:132:956b:3a3 with SMTP id a92af1059eb24-1365f70a0bemr1819078c88.10.1779487528034; Fri, 22 May 2026 15:05:28 -0700 (PDT) Date: Fri, 22 May 2026 15:04:32 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-22-irogers@google.com> Subject: [PATCH v9 21/23] perf python: Add config file access From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add perf.config_get(name) to expose the perf configuration system. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- tools/perf/util/python.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 23eb65adb392..458aca9db091 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -14,6 +14,7 @@ #include "build-id.h" #include "callchain.h" #include "comm.h" +#include "config.h" #include "counts.h" #include "data.h" #include "debug.h" @@ -3828,7 +3829,26 @@ static PyObject *pyrf__syscall_id(PyObject *self, Py= Object *args, PyObject *kwar return PyLong_FromLong(id); } =20 +static PyObject *pyrf__config_get(PyObject *self, PyObject *args) +{ + const char *config_name, *val; + + if (!PyArg_ParseTuple(args, "s", &config_name)) + return NULL; + + val =3D perf_config_get(config_name); + if (!val) + Py_RETURN_NONE; + return PyUnicode_FromString(val); +} + static PyMethodDef perf__methods[] =3D { + { + .ml_name =3D "config_get", + .ml_meth =3D (PyCFunction) pyrf__config_get, + .ml_flags =3D METH_VARARGS, + .ml_doc =3D PyDoc_STR("Get a perf config value.") + }, { .ml_name =3D "metrics", .ml_meth =3D (PyCFunction) pyrf__metrics, --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1A3173955CE for ; Fri, 22 May 2026 22:05:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487534; cv=none; b=r7f9+Xtwx8WeYwi9m/01q8wn5EptNczxtbFF0rhkAO6RRVhYDqVEXnohaI8QuFugIstSSgu/obqEGppmug9K0vHTnSf1HE/3C1GrFiC/y9ZBxG/ZGUxc/iyxrO7SjyHrpF9+X6HpddzWExFalXQhOMEoFDNrSM83wkQjNrqrBTI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487534; c=relaxed/simple; bh=b8glFyU2I1avKddyjBcGYnZh7kMjQj0MvpVm8BPTQIg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=WQS3tld1wd9PGQIHZiZU0zyeajDbkviJ5PXIGvHO9R57ifrDEwKBfZ6DZcBwIO4mTuBxxOGgB04vVJM6oXwuoz2LhdBVcBwcmFRUMIcb/f+2NTDRLi5LcXmvA0Fdk5A1sqfvk82l24Rw/vWOJkGBfnX00vWkfD/hxBAZSPwP5Zo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=TKpB2GrA; arc=none smtp.client-ip=74.125.82.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="TKpB2GrA" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-1353a6f29deso8912808c88.1 for ; Fri, 22 May 2026 15:05:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487530; x=1780092330; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=uQSu7brACUd78Dy4vNUNfc+wi8xqeme+e8m+c4x2hzI=; b=TKpB2GrA4mCG2IDBcqhg9QFtxldMfwEh6eiOq+oqShTMvyqhKjb3nGYTeoiTcZeVMk +MipgejAwY2ZPRQOnO3VA2RaBZn/DqWELCKvSpAEBrVV50T87lUD7slQ9y9YN6iiFomi ENXV3yQzCkx/XE1/1D6Thj+UsGFQOTrBRYZ2KVmfDGrr6H90dfMYJIfRNaKcsDpfCSO4 lOsq6dh1OWzH2s1OvBm2imV9dtWORCho222muauLrhQseB9K3MPnS01YhOt4FYWSVAT9 iXLzlutWmTvKredy640NKaX6xFz8JQKkWFE2h/ExGECGTLTGSWN82567938N81iX2fT2 HC7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487530; x=1780092330; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=uQSu7brACUd78Dy4vNUNfc+wi8xqeme+e8m+c4x2hzI=; b=MWqq9kCTWoGWIZ8E+8iPMPysJxaAwYPbefnWUCcTksmTIBN/Ow32pDSG3dGyV0cf7T eRANEI8JuD4Nfk/2zSd+ZtJgtDJO37VqSwMaDCb1YREHD5WqvYuIQJq16QUzLrh3a6J7 4cseCHb3urVyxM6vc5Z/G1A+Xm9XhdBbNrN5yNcu0hrXCbZju35UgP8R4CJ2Attqeyi6 xQ4AR+Y+tS5NF1szsL5YH3KzdGYGI5Binhh1Tclc0ADcFBVBgfZv4GgjbptoWYCQxyhQ JrdhKmrsJIPJtcVAdXWoq+lzyQCvt0CgPu48NaInGeCSUKwrThGkH+y93yQxAT6HRSBS cDsg== X-Forwarded-Encrypted: i=1; AFNElJ8WRWr+N/qpyvx0PMguJyj+xVomAqN4COicno6HiUXVc+WbjPi5VbfXQGsyC76xLsvqdiMp6AlMGLSTUlE=@vger.kernel.org X-Gm-Message-State: AOJu0Yx+VhXFU4ae4LyT7rwbw2TJvue58RoCkE15kDzXWKp1zSbbqY7P 0b1kuhFpOlIdVgb51dKXWkuaSmDLSFJY7Odn4KHhNzkvesUuqbpnv7lphlq1deUx+13ZBozAHqL KRPomxdraXA== X-Received: from dlb30.prod.google.com ([2002:a05:7022:61e:b0:135:d2a6:35f2]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:1003:b0:12d:c9b6:bbdc with SMTP id a92af1059eb24-1365fc6d69dmr2411131c88.30.1779487529783; Fri, 22 May 2026 15:05:29 -0700 (PDT) Date: Fri, 22 May 2026 15:04:33 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-23-irogers@google.com> Subject: [PATCH v9 22/23] perf python: Add perf.pyi stubs file From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add Python type stubs for the perf module to improve IDE support and static analysis. Includes docstrings for classes, methods, and constants derived from C source and JSON definitions. Assisted-by: Gemini:gemini-3.1-pro-preview Signed-off-by: Ian Rogers --- v2: 1. Added Missing Module Functions: Added parse_metrics and pmus. Renamed metrics to parse_metrics to match python.c . 2. Added Constructors: Added __init__ methods for data , evsel , and evlist with their appropriate arguments. 3. Removed sample_comm : Removed it from sample_event since it is not exported in python.c . 4. Keyword Handling in branch_entry : I used from_ip and to_ip in the stubs to match the rename I did in python.c (in turn 145) to avoid the Python from keyword conflict. 5. Added Missing Event Classes: Added mmap_event , lost_event , comm_event , task_event , throttle_event , read_event , and switch_event . 6. Added Missing evlist Methods: Added get_pollfd and add . 7. Updated Return Types: Changed process_events to return int . v6: - Updated `perf.pyi` to use `find_thread` and `elf_machine`. v8: - Added mmap2_event class and new evsel attributes to perf.pyi. - Added pid, tid, ppid, cpu attributes to class thread in perf.pyi. --- tools/perf/python/perf.pyi | 605 +++++++++++++++++++++++++++++++++++++ 1 file changed, 605 insertions(+) create mode 100644 tools/perf/python/perf.pyi diff --git a/tools/perf/python/perf.pyi b/tools/perf/python/perf.pyi new file mode 100644 index 000000000000..1d1d2a833f10 --- /dev/null +++ b/tools/perf/python/perf.pyi @@ -0,0 +1,605 @@ +"""Type stubs for the perf Python module.""" +from typing import Callable, Dict, List, Optional, Any, Iterator + +def config_get(name: str) -> Optional[str]: + """Get a configuration value from perf config. + + Args: + name: The configuration variable name (e.g., 'colors.top'). + + Returns: + The configuration value as a string, or None if not set. + """ + ... + +def metrics() -> List[Dict[str, str]]: + """Get a list of available metrics. + + Returns: + A list of dictionaries, each describing a metric. + """ + ... + +def syscall_name(sc_id: int, *, elf_machine: Optional[int] =3D None) -> st= r: + """Convert a syscall number to its name. + + Args: + sc_id: The syscall number. + elf_machine: Optional ELF machine type. + + Returns: + The name of the syscall. + """ + ... + +def syscall_id(name: str, *, elf_machine: Optional[int] =3D None) -> int: + """Convert a syscall name to its number. + + Args: + name: The syscall name. + elf_machine: Optional ELF machine type. + + Returns: + The number of the syscall. + """ + ... + +def parse_events( + event_string: str, + cpus: Optional[cpu_map] =3D None, + threads: Optional[Any] =3D None +) -> 'evlist': + """Parse an event string and return an evlist. + + Args: + event_string: The event string (e.g., 'cycles,instructions'). + cpus: Optional CPU map to bind events to. + threads: Optional thread map to bind events to. + + Returns: + An evlist containing the parsed events. + """ + ... + +def parse_metrics(metrics_string: str) -> 'evlist': + """Parse a string of metrics or metric groups and return an evlist.""" + ... + +def pmus() -> Iterator[Any]: + """Returns a sequence of pmus.""" + ... + +class data: + """Represents a perf data file.""" + def __init__(self, path: str =3D ..., fd: int =3D ...) -> None: ... + +class thread: + """Represents a thread in the system.""" + def comm(self) -> str: + """Get the command name of the thread.""" + ... + pid: int + tid: int + ppid: int + cpu: int + +class counts_values: + """Raw counter values.""" + val: int + ena: int + run: int + +class thread_map: + """Map of threads being monitored.""" + def __init__(self, pid: int =3D -1, tid: int =3D -1) -> None: + """Initialize a thread map. + + Args: + pid: Process ID to monitor (-1 for all). + tid: Thread ID to monitor (-1 for all). + """ + ... + def __len__(self) -> int: ... + def __getitem__(self, index: int) -> int: ... + def __iter__(self) -> Iterator[int]: ... + +class evsel: + """Event selector, represents a single event being monitored.""" + def __init__( + self, + type: int =3D ..., + config: int =3D ..., + sample_freq: int =3D ..., + sample_period: int =3D ..., + sample_type: int =3D ..., + read_format: int =3D ..., + disabled: bool =3D ..., + inherit: bool =3D ..., + pinned: bool =3D ..., + exclusive: bool =3D ..., + exclude_user: bool =3D ..., + exclude_kernel: bool =3D ..., + exclude_hv: bool =3D ..., + exclude_idle: bool =3D ..., + mmap: bool =3D ..., + context_switch: bool =3D ..., + comm: bool =3D ..., + freq: bool =3D ..., + idx: int =3D ..., + ) -> None: ... + def __str__(self) -> str: + """Return string representation of the event.""" + ... + def open(self) -> None: + """Open the event selector file descriptor table.""" + ... + def read(self, cpu: int, thread: int) -> counts_values: + """Read counter values for a specific CPU and thread.""" + ... + ids: List[int] + def cpus(self) -> cpu_map: + """Get CPU map for this event.""" + ... + def threads(self) -> thread_map: + """Get thread map for this event.""" + ... + tracking: bool + config: int + read_format: int + sample_period: int + sample_type: int + size: int + type: int + wakeup_events: int + + +class sample_event: + """Represents a sample event from perf.""" + evsel: evsel + sample_cpu: int + sample_time: int + sample_pid: int + type: int + brstack: Optional['branch_stack'] + callchain: Optional['callchain'] + def __getattr__(self, name: str) -> Any: ... + +class mmap_event: + """Represents a mmap event from perf.""" + type: int + pid: int + tid: int + addr: int + len: int + pgoff: int + filename: str + +class mmap2_event: + """Represents a mmap2 event from perf.""" + type: int + pid: int + tid: int + addr: int + len: int + pgoff: int + prot: int + flags: int + filename: str + +class lost_event: + """Represents a lost events record.""" + type: int + id: int + lost: int + +class comm_event: + """Represents a COMM record.""" + type: int + pid: int + tid: int + comm: str + +class task_event: + """Represents an EXIT or FORK record.""" + type: int + pid: int + ppid: int + tid: int + ptid: int + time: int + +class throttle_event: + """Represents a THROTTLE or UNTHROTTLE record.""" + type: int + time: int + id: int + stream_id: int + +class read_event: + """Represents a READ record.""" + type: int + pid: int + tid: int + value: int + +class switch_event: + """Represents a SWITCH or SWITCH_CPU_WIDE record.""" + type: int + +class branch_entry: + """Represents a branch entry in the branch stack. + + Attributes: + from_ip: Source address of the branch (corresponds to 'from' keywo= rd in C). + to_ip: Destination address of the branch. + mispred: True if the branch was mispredicted. + predicted: True if the branch was predicted. + in_tx: True if the branch was in a transaction. + abort: True if the branch was an abort. + cycles: Number of cycles since the last branch. + type: Type of branch. + """ + from_ip: int + to_ip: int + mispred: bool + predicted: bool + in_tx: bool + abort: bool + cycles: int + type: int + +class branch_stack: + """Iterator over branch entries in the branch stack.""" + def __iter__(self) -> Iterator[branch_entry]: ... + def __next__(self) -> branch_entry: ... + +class callchain_node: + """Represents a frame in the callchain.""" + ip: int + sym: Optional[Any] + map: Optional[Any] + +class callchain: + """Iterator over callchain frames.""" + def __iter__(self) -> Iterator[callchain_node]: ... + def __next__(self) -> callchain_node: ... + +class stat_event: + """Represents a stat event from perf.""" + type: int + id: int + cpu: int + thread: int + val: int + ena: int + run: int + +class stat_round_event: + """Represents a stat round event from perf.""" + type: int + time: int + +class cpu_map: + """Map of CPUs being monitored.""" + def __init__(self, cpustr: Optional[str] =3D None) -> None: ... + def __len__(self) -> int: ... + def __getitem__(self, index: int) -> int: ... + def __iter__(self) -> Iterator[int]: ... + + +class evlist: + def __init__(self, cpus: cpu_map, threads: thread_map) -> None: ... + def open(self) -> None: + """Open the events in the list.""" + ... + def close(self) -> None: + """Close the events in the list.""" + ... + def mmap(self) -> None: + """Memory map the event buffers.""" + ... + def poll(self, timeout: int) -> int: + """Poll for events. + + Args: + timeout: Timeout in milliseconds. + + Returns: + Number of events ready. + """ + ... + def read_on_cpu(self, cpu: int) -> Optional[sample_event]: + """Read a sample event from a specific CPU. + + Args: + cpu: The CPU number. + + Returns: + A sample_event if available, or None. + """ + ... + def all_cpus(self) -> cpu_map: + """Get a cpu_map of all CPUs in the system.""" + ... + def metrics(self) -> List[str]: + """Get a list of metric names within the evlist.""" + ... + def compute_metric(self, metric: str, cpu: int, thread: int) -> float: + """Compute metric for given name, cpu and thread. + + Args: + metric: The metric name. + cpu: The CPU number. + thread: The thread ID. + + Returns: + The computed metric value. + """ + ... + def config(self) -> None: + """Configure the events in the list.""" + ... + def disable(self) -> None: + """Disable all events in the list.""" + ... + def enable(self) -> None: + """Enable all events in the list.""" + ... + def get_pollfd(self) -> List[int]: + """Get a list of file descriptors for polling.""" + ... + def add(self, evsel: evsel) -> int: + """Add an event to the list.""" + ... + def __iter__(self) -> Iterator[evsel]: + """Iterate over the events (evsel) in the list.""" + ... + + +class session: + def __init__( + self, + data: data, + sample: Optional[Callable[[sample_event], None]] =3D None, + stat: Optional[Callable[[Any, Optional[str]], None]] =3D None + ) -> None: + """Initialize a perf session. + + Args: + data: The perf data file to read. + sample: Callback for sample events. + stat: Callback for stat events. + """ + ... + def process_events(self) -> int: + """Process all events in the session.""" + ... + def find_thread(self, pid: int) -> thread: + """Returns the thread associated with a pid.""" + ... + +# Event Types +TYPE_HARDWARE: int +"""Hardware event.""" + +TYPE_SOFTWARE: int +"""Software event.""" + +TYPE_TRACEPOINT: int +"""Tracepoint event.""" + +TYPE_HW_CACHE: int +"""Hardware cache event.""" + +TYPE_RAW: int +"""Raw hardware event.""" + +TYPE_BREAKPOINT: int +"""Breakpoint event.""" + + +# Hardware Counters +COUNT_HW_CPU_CYCLES: int +"""Total cycles. Be wary of what happens during CPU frequency scaling.""" + +COUNT_HW_INSTRUCTIONS: int +"""Retired instructions. Be careful, these can be affected by various issu= es, +most notably hardware interrupt counts.""" + +COUNT_HW_CACHE_REFERENCES: int +"""Cache accesses. Usually this indicates Last Level Cache accesses but th= is +may vary depending on your CPU.""" + +COUNT_HW_CACHE_MISSES: int +"""Cache misses. Usually this indicates Last Level Cache misses.""" + +COUNT_HW_BRANCH_INSTRUCTIONS: int +"""Retired branch instructions.""" + +COUNT_HW_BRANCH_MISSES: int +"""Mispredicted branch instructions.""" + +COUNT_HW_BUS_CYCLES: int +"""Bus cycles, which can be different from total cycles.""" + +COUNT_HW_STALLED_CYCLES_FRONTEND: int +"""Stalled cycles during issue [This event is an alias of idle-cycles-fron= tend].""" + +COUNT_HW_STALLED_CYCLES_BACKEND: int +"""Stalled cycles during retirement [This event is an alias of idle-cycles= -backend].""" + +COUNT_HW_REF_CPU_CYCLES: int +"""Total cycles; not affected by CPU frequency scaling.""" + + +# Cache Counters +COUNT_HW_CACHE_L1D: int +"""Level 1 data cache.""" + +COUNT_HW_CACHE_L1I: int +"""Level 1 instruction cache.""" + +COUNT_HW_CACHE_LL: int +"""Last Level Cache.""" + +COUNT_HW_CACHE_DTLB: int +"""Data TLB.""" + +COUNT_HW_CACHE_ITLB: int +"""Instruction TLB.""" + +COUNT_HW_CACHE_BPU: int +"""Branch Processing Unit.""" + +COUNT_HW_CACHE_OP_READ: int +"""Read accesses.""" + +COUNT_HW_CACHE_OP_WRITE: int +"""Write accesses.""" + +COUNT_HW_CACHE_OP_PREFETCH: int +"""Prefetch accesses.""" + +COUNT_HW_CACHE_RESULT_ACCESS: int +"""Accesses.""" + +COUNT_HW_CACHE_RESULT_MISS: int +"""Misses.""" + + +# Software Counters +COUNT_SW_CPU_CLOCK: int +"""CPU clock event.""" + +COUNT_SW_TASK_CLOCK: int +"""Task clock event.""" + +COUNT_SW_PAGE_FAULTS: int +"""Page faults.""" + +COUNT_SW_CONTEXT_SWITCHES: int +"""Context switches.""" + +COUNT_SW_CPU_MIGRATIONS: int +"""CPU migrations.""" + +COUNT_SW_PAGE_FAULTS_MIN: int +"""Minor page faults.""" + +COUNT_SW_PAGE_FAULTS_MAJ: int +"""Major page faults.""" + +COUNT_SW_ALIGNMENT_FAULTS: int +"""Alignment faults.""" + +COUNT_SW_EMULATION_FAULTS: int +"""Emulation faults.""" + +COUNT_SW_DUMMY: int +"""Dummy event.""" + + +# Sample Fields +SAMPLE_IP: int +"""Instruction pointer.""" + +SAMPLE_TID: int +"""Process and thread ID.""" + +SAMPLE_TIME: int +"""Timestamp.""" + +SAMPLE_ADDR: int +"""Sampled address.""" + +SAMPLE_READ: int +"""Read barcode.""" + +SAMPLE_CALLCHAIN: int +"""Call chain.""" + +SAMPLE_ID: int +"""Unique ID.""" + +SAMPLE_CPU: int +"""CPU number.""" + +SAMPLE_PERIOD: int +"""Sample period.""" + +SAMPLE_STREAM_ID: int +"""Stream ID.""" + +SAMPLE_RAW: int +"""Raw sample.""" + + +# Format Fields +FORMAT_TOTAL_TIME_ENABLED: int +"""Total time enabled.""" + +FORMAT_TOTAL_TIME_RUNNING: int +"""Total time running.""" + +FORMAT_ID: int +"""Event ID.""" + +FORMAT_GROUP: int +"""Event group.""" + + +# Record Types +RECORD_MMAP: int +"""MMAP record. Contains header, pid, tid, addr, len, pgoff, filename, and= sample_id.""" + +RECORD_LOST: int +"""Lost events record. Contains header, id, lost count, and sample_id.""" + +RECORD_COMM: int +"""COMM record. Contains header, pid, tid, comm, and sample_id.""" + +RECORD_EXIT: int +"""EXIT record. Contains header, pid, ppid, tid, ptid, time, and sample_id= .""" + +RECORD_THROTTLE: int +"""THROTTLE record. Contains header, time, id, stream_id, and sample_id.""" + +RECORD_UNTHROTTLE: int +"""UNTHROTTLE record. Contains header, time, id, stream_id, and sample_id.= """ + +RECORD_FORK: int +"""FORK record. Contains header, pid, ppid, tid, ptid, time, and sample_id= .""" + +RECORD_READ: int +"""READ record. Contains header, and read values.""" + +RECORD_SAMPLE: int +"""SAMPLE record. Contains header, and sample data requested by sample_typ= e.""" + +RECORD_MMAP2: int +"""MMAP2 record. Contains header, pid, tid, addr, len, pgoff, maj, min, in= o, +ino_generation, prot, flags, filename, and sample_id.""" + +RECORD_AUX: int +"""AUX record. Contains header, aux_offset, aux_size, flags, and sample_id= .""" + +RECORD_ITRACE_START: int +"""ITRACE_START record. Contains header, pid, tid, and sample_id.""" + +RECORD_LOST_SAMPLES: int +"""LOST_SAMPLES record. Contains header, lost count, and sample_id.""" + +RECORD_SWITCH: int +"""SWITCH record. Contains header, and sample_id.""" + +RECORD_SWITCH_CPU_WIDE: int +"""SWITCH_CPU_WIDE record. Contains header, and sample_id.""" + +RECORD_STAT: int +"""STAT record.""" + +RECORD_STAT_ROUND: int +"""STAT_ROUND record.""" + +RECORD_MISC_SWITCH_OUT: int +"""MISC_SWITCH_OUT record.""" --=20 2.54.0.794.g4f17f83d09-goog From nobody Sun May 24 20:34:05 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1944639DBFE for ; Fri, 22 May 2026 22:05:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487534; cv=none; b=puLXygsqT5y5sSv9CclIkkE0ocbfn5y4cjeB05Y2f4Q8+buruDjsR/5dRg7BbSuEqu4J/g9lLjzPJuuPNQxohec8/r1giQRvVv8xObdJVZ1wzAPPQTlaJTJQWU0n+hecL47qsc9iKHLNXeFZlNLn1Yl7EBfD/3pZ0rt5MJLMwys= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779487534; c=relaxed/simple; bh=GvT1eHGJnoFxKyjkoZM6IMo3RDaILeI8qNW/+RifZpo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Tyxt6x3r09vmexSQ7GoV2cNJKJ0hixjEjGuVteYOSYRyq6Eh8DNNXtJaycxsshJdNOre0IikoLEW/3Wu8p66HiZz6EQn64n9tdxuERxjJO4GmfO4iYM7+H7SoPsf2lHTEuSajnCz+wwJrfpT+t6ReogJFoYGr2cH+pPZK4/HaW8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=eLQcvS0T; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="eLQcvS0T" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2ef37c3f773so8143582eec.1 for ; Fri, 22 May 2026 15:05:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1779487532; x=1780092332; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=WoYL3oraokua0mUStpvckCOjCdPI3hrcUVdVldzeRF0=; b=eLQcvS0TuLSCmqtk1UDL1g6jx6xD+BEbqy88161NEBmaZq/aJrpAdsu5dkV/baVozn 1qVHDUyTo61uYt8irVTwtyPORCjLz5xwQDp7ekiw3Ig845b+ifDXgZ6SQkuw1FbrJFW2 jOSET/c5/hDXGUGbLn63HjIrjkyXw3tO8fpIYHfGJvkghEM0LCeMee1ePDl682QIArdp 9zNztLFrkrCCRbbO+h+AEoVBnfyYLO3/hxZV85YNYvHccjnivXVroJEFxTNrl1xiSdiO cjqv95o4QbysJYZkRgozHser/CY+cStECDIZZmZi5RXKUfo6REho9yGDG+1tuhP1/SgK VoRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779487532; x=1780092332; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=WoYL3oraokua0mUStpvckCOjCdPI3hrcUVdVldzeRF0=; b=b7wB7YqnZxN74PXKscOliCLqTLudWVt9nC4FfntQ1hujsVRTloevzmFP5S6qqBQQgt H93p7fsHDkQgovXXvKu+gExG39/qC2IGdzTfHxEubVXg/6LbjH7H3oUUGF1lJPLA1Y9W HjsruhJr1+NKtePQNGMsic21kibu1VLN0jNJQJhxU0x+aq/s3KChNp4OuYzJCbnWSdbN cQOOjO7FHgLOU432w6NgKCVZn+c9MJXxut82aAHcZyl144QSnXMuvGx0xtHw7dwmlRzO /pU7hUQzC9VJPId/IjZPLSMs2VocNAOXgJse/urEpe889xVud76x1S6CBVA2FJPbvA/W UC3w== X-Forwarded-Encrypted: i=1; AFNElJ+VpK7xW4kZd7w46GACU2FteRS7klqI8lQT1CD06tpItMEWZH5SWXtBPU1rCj6PWFGfHfcamoKNKR7rknw=@vger.kernel.org X-Gm-Message-State: AOJu0YzssdB1+MwbBhlP8zQYaimWwrrjQlb1UQYg7+32avwt67kxanGn q938MBb3s7PNYNKxqzTQ6hefdSCUcuFDZsiH60wJbaAvrXBSmW6lTzI0zkexxMleFTEOnr2r+ME 4kkqiolwJWQ== X-Received: from dyji10.prod.google.com ([2002:a05:7300:7a0a:b0:2ed:b77f:b02a]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:6743:b0:2da:a813:a60c with SMTP id 5a478bee46e88-30449103945mr2955830eec.20.1779487531932; Fri, 22 May 2026 15:05:31 -0700 (PDT) Date: Fri, 22 May 2026 15:04:34 -0700 In-Reply-To: <20260522220435.2378363-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260428071903.1886173-1-irogers@google.com> <20260522220435.2378363-1-irogers@google.com> X-Mailer: git-send-email 2.54.0.794.g4f17f83d09-goog Message-ID: <20260522220435.2378363-24-irogers@google.com> Subject: [PATCH v9 23/23] perf python: Add LiveSession helper From: Ian Rogers To: irogers@google.com, acme@kernel.org, namhyung@kernel.org Cc: adrian.hunter@intel.com, alice.mei.rogers@gmail.com, dapeng1.mi@linux.intel.com, james.clark@linaro.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, mingo@redhat.com, peterz@infradead.org, tmricht@linux.ibm.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add LiveSession class in tools/perf/python/perf_live.py to support live event collection using perf.evlist and perf.parse_events, avoiding the need to fork a separate perf record process. Signed-off-by: Ian Rogers Assisted-by: Gemini:gemini-3.1-pro-preview --- v2: 1. Fixed File Descriptor Leak: I moved self.evlist.mmap() inside the try block so that if it raises an exception, the finally block will still be executed and call self.evlist.close() , preventing file descriptor leaks. 2. Handled InterruptedError in poll() : I wrapped the poll() call in a try-except block to catch InterruptedError and continue the loop. This prevents the live session from crashing on non-fatal signals like SIGWINCH . 3. Added evlist.config() : I added a call to self.evlist.config() in the constructor after parse_events() . This applies the default record options to the events, enabling sampling and setting up PERF_SAMPLE_* fields so that the kernel will actually generate PERF_RECORD_SAMPLE events. 4. Enable the evlist and be robust to exceptions from reading unsupported events like mmap2. v8: - Drain all events from a CPU before moving to the next. --- tools/perf/python/perf_live.py | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100755 tools/perf/python/perf_live.py diff --git a/tools/perf/python/perf_live.py b/tools/perf/python/perf_live.py new file mode 100755 index 000000000000..2e5347349760 --- /dev/null +++ b/tools/perf/python/perf_live.py @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Live event session helper using perf.evlist. + +This module provides a LiveSession class that allows running a callback +for each event collected live from the system, similar to perf.session +but without requiring a perf.data file. +""" + +import perf + + +class LiveSession: + """Represents a live event collection session.""" + + def __init__(self, event_string: str, sample_callback): + self.event_string =3D event_string + self.sample_callback =3D sample_callback + # Create a cpu map for all online CPUs + self.cpus =3D perf.cpu_map() + # Parse events and set maps + self.evlist =3D perf.parse_events(self.event_string, self.cpus) + self.evlist.config() + + def run(self): + """Run the live session.""" + self.evlist.open() + try: + self.evlist.mmap() + self.evlist.enable() + + while True: + # Poll for events with 100ms timeout + try: + self.evlist.poll(100) + except InterruptedError: + continue + for cpu in self.cpus: + while True: + try: + event =3D self.evlist.read_on_cpu(cpu) + if event is None: + break + if event.type =3D=3D perf.RECORD_SAMPLE: + self.sample_callback(event) + except Exception as e: + import sys + print(f"Error processing event on CPU {cpu}: {= e}", file=3Dsys.stderr) + break + except KeyboardInterrupt: + pass + finally: + self.evlist.close() --=20 2.54.0.794.g4f17f83d09-goog