Received: by 2002:a05:7412:cfc7:b0:fc:a2b0:25d7 with SMTP id by7csp1043050rdb; Mon, 19 Feb 2024 02:17:18 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCX11beav5x3pKIyUThB4XehhVytoUBCq2QrVh8RYmibg976QaiT/5S1xTHa+TdhIqmENQxqQhkQbBOb+2JixyIIMNOr6yLysSrnq61k3w== X-Google-Smtp-Source: AGHT+IF3N2EwebOHkqUnmSBEx9JPSKwhcuOWwks4NFsSi+EhqmqZKPLxcm0VXYc0R/xaNvyywMPC X-Received: by 2002:a05:620a:1aa4:b0:785:da87:825b with SMTP id bl36-20020a05620a1aa400b00785da87825bmr17715263qkb.38.1708337837688; Mon, 19 Feb 2024 02:17:17 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708337837; cv=pass; d=google.com; s=arc-20160816; b=jkVTQ47BLJrVMgPxh7fwatOU/xyEyolHrO+Stck1oOQt/apJsLC6a0VJOm7QoJytPx fcd/gBxquQ0ZJGf22aw5WM9Ak6YEgkunq4N8kuju40Chw1qNZqMsIA3sMyMhNMRyRNWk 5jPOhb1wRSXQnNHHYClGKKkdpud706ZUwEeNl2FYoUou4pLwVBnn4ebMR89HCoDRYhwx fyeZw0i+podjpTJMMK6QXnanmzpZNhXD4uqHzrKx6RAKug2kYRu9fHhcchF52hlqhder V2HWZ12xV+XKycZ++ACUhl0Ni3bfZXoJZoTl9G6CW9x72oNCVh0ExaZnIQc71VKszv6r Odmg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:message-id; bh=jHRIe706NmorMSOK/Nb4SsfGXSC6CPUbYdnRNeCz+nk=; fh=0N6EMJaA89isPVe3D3vb/a4qc/cACK8kqQlYdWwqjw0=; b=MTxe70tJpmqf3iIdRxD9X63k1U6aRJo7QKmih12hFMqd7pOfZD/66Ao+bJ0n7JJEw6 j+lDtxr7YCLn3m+njwdcqEWoR/R22HVtf68/pF8zwciqu0MNHgJIwwR6LbEHMf1vn8cP O8sAnux6x1DSqyYj5rZqWAP047l7/7z/VgfIXvxHPBVc2aw5AdCBsXxtJO25hLzwo90d zhu76MdYnCtjMJavu3RQMe5ANWqkFcD2sFmRFDq7ZnyjiwEuyl6Ypdh5S3Y/ARYcMtaj gLfLyucMAo0rBeQDFq9yeAOu+OgxtqAvHUwBHl51IjY6pDc0PXyFGMnEAJZKk5wjk3NN u4Pg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=arm.com dmarc=pass fromdomain=arm.com); spf=pass (google.com: domain of linux-kernel+bounces-71112-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-71112-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id c12-20020a05620a200c00b0078732ec7373si5556771qka.519.2024.02.19.02.17.17 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Feb 2024 02:17:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-71112-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=arm.com dmarc=pass fromdomain=arm.com); spf=pass (google.com: domain of linux-kernel+bounces-71112-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-71112-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 2E7FF1C21665 for ; Mon, 19 Feb 2024 10:17:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 01732288CF; Mon, 19 Feb 2024 10:17:06 +0000 (UTC) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 39D4225628; Mon, 19 Feb 2024 10:17:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708337825; cv=none; b=I3wqNnLTDglI4FO8KcGVPFhmmf1fEFNcPL4GlQLeBvSzPqZmmti+MbS53eF7p3xlfLjWp8SWXyiC+wGH++BK4WPvvBDKK+zIhWZsQZ+Bbe7+XO38zyRVg6ugMxareXHd77VuduPdevOyfAeTfDKskDzZEBZEDrWG7xdw0jrv1Co= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708337825; c=relaxed/simple; bh=mfeqi+V0Uk81dQGUCG750LmHcTV8G6MdZH+WxBvptxs=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=LBTlkS1uReiPtuXvR+bOK0MczWgipnrHCWh6rRmK2v3WikEy3EQFblMl1/wRdV9YBlZVke4K3dBfdqIdX4slxs6Div1vNCfhi+2wyySmDY3mzSG5dP4RrMjwtkrT33v6dcG77tAUEbEA9OhLcy41/1ewZoRC9cSVmENT/gQ4wjs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3B8331007; Mon, 19 Feb 2024 02:17:42 -0800 (PST) Received: from [192.168.1.100] (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 34D783F762; Mon, 19 Feb 2024 02:16:54 -0800 (PST) Message-ID: Date: Mon, 19 Feb 2024 10:16:51 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.15.1 Subject: Re: [PATCH v3 3/8] perf arm-spe/cs-etm: Directly iterate CPU maps To: Ian Rogers , Namhyung Kim Cc: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Adrian Hunter , Suzuki K Poulose , Mike Leach , John Garry , Will Deacon , Thomas Gleixner , Darren Hart , Davidlohr Bueso , =?UTF-8?Q?Andr=c3=a9_Almeida?= , Kan Liang , K Prateek Nayak , Sean Christopherson , Paolo Bonzini , Kajol Jain , Athira Rajeev , Andrew Jones , Alexandre Ghiti , Atish Patra , "Steinar H. Gunderson" , Yang Jihong , Yang Li , Changbin Du , Sandipan Das , Ravi Bangoria , Paran Lee , Nick Desaulniers , Huacai Chen , Yanteng Si , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, bpf@vger.kernel.org, Leo Yan References: <20240202234057.2085863-1-irogers@google.com> <20240202234057.2085863-4-irogers@google.com> Content-Language: en-US From: James Clark In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 17/02/2024 01:33, Ian Rogers wrote: > On Fri, Feb 16, 2024 at 5:02 PM Namhyung Kim wrote: >> >> On Fri, Feb 2, 2024 at 3:41 PM Ian Rogers wrote: >>> >>> Rather than iterate all CPUs and see if they are in CPU maps, directly >>> iterate the CPU map. Similarly make use of the intersect function >>> taking care for when "any" CPU is specified. Switch >>> perf_cpu_map__has_any_cpu_or_is_empty to more appropriate >>> alternatives. >>> >>> Signed-off-by: Ian Rogers >>> --- >>> tools/perf/arch/arm/util/cs-etm.c | 114 ++++++++++++--------------- >>> tools/perf/arch/arm64/util/arm-spe.c | 4 +- >>> 2 files changed, 51 insertions(+), 67 deletions(-) >>> >>> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c >>> index 77e6663c1703..07be32d99805 100644 >>> --- a/tools/perf/arch/arm/util/cs-etm.c >>> +++ b/tools/perf/arch/arm/util/cs-etm.c >>> @@ -197,38 +197,37 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr, >>> static int cs_etm_validate_config(struct auxtrace_record *itr, >>> struct evsel *evsel) >>> { >>> - int i, err = -EINVAL; >>> + int idx, err = 0; >>> struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus; >>> - struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus(); >>> - >>> - /* Set option of each CPU we have */ >>> - for (i = 0; i < cpu__max_cpu().cpu; i++) { >>> - struct perf_cpu cpu = { .cpu = i, }; >>> + struct perf_cpu_map *intersect_cpus; >>> + struct perf_cpu cpu; >>> >>> - /* >>> - * In per-cpu case, do the validation for CPUs to work with. >>> - * In per-thread case, the CPU map is empty. Since the traced >>> - * program can run on any CPUs in this case, thus don't skip >>> - * validation. >>> - */ >>> - if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus) && >>> - !perf_cpu_map__has(event_cpus, cpu)) >>> - continue; >>> + /* >>> + * Set option of each CPU we have. In per-cpu case, do the validation >>> + * for CPUs to work with. In per-thread case, the CPU map has the "any" >>> + * CPU value. Since the traced program can run on any CPUs in this case, >>> + * thus don't skip validation. >>> + */ >>> + if (!perf_cpu_map__has_any_cpu(event_cpus)) { >>> + struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus(); >>> >>> - if (!perf_cpu_map__has(online_cpus, cpu)) >>> - continue; >>> + intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus); >>> + perf_cpu_map__put(online_cpus); >>> + } else { >>> + intersect_cpus = perf_cpu_map__new_online_cpus(); >>> + } >> >> Would it be ok if any of these operations fail? I believe the >> cpu map functions work well with NULL already. > > If the allocation fails then the loop below won't iterate (the map > will be empty). The map is released and not used elsewhere in the > code. An allocation failure here won't cause the code to crash, but > there are other places where the code assumes what the properties of > having done this function are and they won't be working as intended. > It's not uncommon to see ENOMEM to just be abort for this reason. > > Thanks, > Ian > >> Thanks, >> Namhyung >> Reviewed-by: James Clark About the out of memory case, I don't really have much preference about that. I doubt much of the code is tested or resiliant to it and the behaviour is probably already unpredictable. >>> >>> - err = cs_etm_validate_context_id(itr, evsel, i); >>> + perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) { >>> + err = cs_etm_validate_context_id(itr, evsel, cpu.cpu); >>> if (err) >>> - goto out; >>> - err = cs_etm_validate_timestamp(itr, evsel, i); >>> + break; >>> + >>> + err = cs_etm_validate_timestamp(itr, evsel, cpu.cpu); >>> if (err) >>> - goto out; >>> + break; >>> } >>> >>> - err = 0; >>> -out: >>> - perf_cpu_map__put(online_cpus); >>> + perf_cpu_map__put(intersect_cpus); >>> return err; >>> } >>> >>> @@ -435,7 +434,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, >>> * Also the case of per-cpu mmaps, need the contextID in order to be notified >>> * when a context switch happened. >>> */ >>> - if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) { >>> + if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) { >>> evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel, >>> "timestamp", 1); >>> evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel, >>> @@ -461,7 +460,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, >>> evsel->core.attr.sample_period = 1; >>> >>> /* In per-cpu case, always need the time of mmap events etc */ >>> - if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) >>> + if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) >>> evsel__set_sample_bit(evsel, TIME); >>> >>> err = cs_etm_validate_config(itr, cs_etm_evsel); >>> @@ -533,45 +532,31 @@ static size_t >>> cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, >>> struct evlist *evlist __maybe_unused) >>> { >>> - int i; >>> + int idx; >>> int etmv3 = 0, etmv4 = 0, ete = 0; >>> struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus; >>> - struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus(); >>> - >>> - /* cpu map is not empty, we have specific CPUs to work with */ >>> - if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) { >>> - for (i = 0; i < cpu__max_cpu().cpu; i++) { >>> - struct perf_cpu cpu = { .cpu = i, }; >>> + struct perf_cpu_map *intersect_cpus; >>> + struct perf_cpu cpu; >>> >>> - if (!perf_cpu_map__has(event_cpus, cpu) || >>> - !perf_cpu_map__has(online_cpus, cpu)) >>> - continue; >>> + if (!perf_cpu_map__has_any_cpu(event_cpus)) { >>> + /* cpu map is not "any" CPU , we have specific CPUs to work with */ >>> + struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus(); >>> >>> - if (cs_etm_is_ete(itr, i)) >>> - ete++; >>> - else if (cs_etm_is_etmv4(itr, i)) >>> - etmv4++; >>> - else >>> - etmv3++; >>> - } >>> + intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus); >>> + perf_cpu_map__put(online_cpus); >>> } else { >>> - /* get configuration for all CPUs in the system */ >>> - for (i = 0; i < cpu__max_cpu().cpu; i++) { >>> - struct perf_cpu cpu = { .cpu = i, }; >>> - >>> - if (!perf_cpu_map__has(online_cpus, cpu)) >>> - continue; >>> - >>> - if (cs_etm_is_ete(itr, i)) >>> - ete++; >>> - else if (cs_etm_is_etmv4(itr, i)) >>> - etmv4++; >>> - else >>> - etmv3++; >>> - } >>> + /* Event can be "any" CPU so count all online CPUs. */ >>> + intersect_cpus = perf_cpu_map__new_online_cpus(); >>> } >>> - >>> - perf_cpu_map__put(online_cpus); >>> + perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) { >>> + if (cs_etm_is_ete(itr, cpu.cpu)) >>> + ete++; >>> + else if (cs_etm_is_etmv4(itr, cpu.cpu)) >>> + etmv4++; >>> + else >>> + etmv3++; >>> + } >>> + perf_cpu_map__put(intersect_cpus); >>> >>> return (CS_ETM_HEADER_SIZE + >>> (ete * CS_ETE_PRIV_SIZE) + >>> @@ -813,16 +798,15 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, >>> if (!session->evlist->core.nr_mmaps) >>> return -EINVAL; >>> >>> - /* If the cpu_map is empty all online CPUs are involved */ >>> - if (perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) { >>> + /* If the cpu_map has the "any" CPU all online CPUs are involved */ >>> + if (perf_cpu_map__has_any_cpu(event_cpus)) { >>> cpu_map = online_cpus; >>> } else { >>> /* Make sure all specified CPUs are online */ >>> - for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) { >>> - struct perf_cpu cpu = { .cpu = i, }; >>> + struct perf_cpu cpu; >>> >>> - if (perf_cpu_map__has(event_cpus, cpu) && >>> - !perf_cpu_map__has(online_cpus, cpu)) >>> + perf_cpu_map__for_each_cpu(cpu, i, event_cpus) { >>> + if (!perf_cpu_map__has(online_cpus, cpu)) >>> return -EINVAL; >>> } >>> >>> diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c >>> index 51ccbfd3d246..0b52e67edb3b 100644 >>> --- a/tools/perf/arch/arm64/util/arm-spe.c >>> +++ b/tools/perf/arch/arm64/util/arm-spe.c >>> @@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, >>> * In the case of per-cpu mmaps, sample CPU for AUX event; >>> * also enable the timestamp tracing for samples correlation. >>> */ >>> - if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) { >>> + if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) { >>> evsel__set_sample_bit(arm_spe_evsel, CPU); >>> evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel, >>> "ts_enable", 1); >>> @@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, >>> tracking_evsel->core.attr.sample_period = 1; >>> >>> /* In per-cpu case, always need the time of mmap events etc */ >>> - if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) { >>> + if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) { >>> evsel__set_sample_bit(tracking_evsel, TIME); >>> evsel__set_sample_bit(tracking_evsel, CPU); >>> >>> -- >>> 2.43.0.594.gd9cf4e227d-goog >>>