From nobody Mon Apr 6 10:42:07 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 33E27364E9E for ; Sun, 22 Mar 2026 00:58:44 +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=1774141125; cv=none; b=tUeudK50Ez9z6fkRGvnqOzOsaTSmWMcFuvD+TbKEUhnJN2ep+VetHR0N3vtLZ6bVFKfq6ViXJRky2IfEfA9HQ6rtcvgJ06HiyiueKV+PG+Tpf5Qpaw3917HJPkBGZVa8JiR4BJpdNOBcAb/h5pSvcR4S/xl2S7n+zJOpXhqhrbE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774141125; c=relaxed/simple; bh=oQAkcuOFIgliDB2fbpjYZzVDb5j+cfsOBBoc+A7NyIU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=afXSeEs6s3bWQm+xJMy9Xs6tNHecg3xvGUU3iDEnJb0PtPPeit0hWDzyvIgSciTVW1QtwAoxjoFnMFmcHz8RG0o4f4N5UcgLt4T1zHTypm2wrlMx/YsDNSFZelDl6uo4ox4+/oMjYM8BiviEupztPF8vch+V34g8cqJdteN71us= 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=ZSPAJ61R; 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="ZSPAJ61R" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2ba8013a9e3so2502132eec.0 for ; Sat, 21 Mar 2026 17:58:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1774141123; x=1774745923; 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=geGlWvya86jMnp6cvNdHPZH2HS7OrsgObVOuTyCYnPA=; b=ZSPAJ61R4rOZhGhLZgF9Y9IwVcy1laf9dYmG59oQ7etV3yMYAxl/mRTwRg6vlutdHt PyeqsyESJEVgc+4Lbdowmh1NcErgdyeOVr9rOPhwYspLg6f4wz9DiYvam5LjMq/oQV0B BAU/EhAKtBYgS4X5dSblc4OyWxgT3+4beifgXLsHlzBI2qFG7w55y0i44auNmreGJio3 4A62Bsyr1H1iGicwVtNCNI564IBv/gfblnPZoQH3dTtgJ6ziFiCydgoHmvTFvGwlJ6Gr jaF99VLEOPsolNfvew98MuGGx756j0NYvCn6uaaQMjNEpl4B4ZYYcatCiIvGqgnE1EM2 q6xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774141123; x=1774745923; 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=geGlWvya86jMnp6cvNdHPZH2HS7OrsgObVOuTyCYnPA=; b=DCmz7/LGeLLgnoTr6ZOQa1b4+s8n+D2uX9NAJyG4NgVxPFtDRhZCRzftvEOX7nZ7i0 3QsrE3RP7CDdOJCkf9y7YYTXoZguNmwjJy3IlEMPHQ/YU1Ph2rHgVd0uRFnnCCcEEklm +9F68/CVWNRFWMBVgU3Q2h2/AjhyjcEng53AU1WuCp3sgSnhJzUtSPk5vR6YEOn5V+4W It/pm+YTblDEwvlXcCtxIyXfWBxE64Lmv6yvt0swN2QWXPjBW9Hp+WvAQPwbuhhapckH JhVCzAOiSZo8Sl8DYIRF50pEjfkhr69WHyNuPqIpaUsf9WE+JtnZYSewudIvqOAD22FU Rk8Q== X-Forwarded-Encrypted: i=1; AJvYcCXJFVRZdAwPPptN7Ci171F+0HhJrUYoh21mz/Yp1kJduZKAyScVh0s4FbC0brbB6n442/BsajfDNs7C+GI=@vger.kernel.org X-Gm-Message-State: AOJu0YyQ/dojxQR4sq43heAl71ses+AjNN6zI+kMpwN0g8v+/RfPckes Ffbz/8dYBq4h53oBytACUh9Tw4H0sTiXuPr8lCTXN82ezUUQijpscuy+xN6zz0ePsK13CKK2JNr 2edbmo+xigw== X-Received: from dybms24.prod.google.com ([2002:a05:7300:d518:b0:2c1:7ca:ced1]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:e9cc:20b0:2c1:1588:55e3 with SMTP id 5a478bee46e88-2c115885b4amr1886985eec.14.1774141123129; Sat, 21 Mar 2026 17:58:43 -0700 (PDT) Date: Sat, 21 Mar 2026 17:58:23 -0700 In-Reply-To: <20260322005823.981079-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: <20260322005823.981079-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.959.g497ff81fa9-goog Message-ID: <20260322005823.981079-5-irogers@google.com> Subject: [PATCH v2 4/4] perf hashmap: Remove errptr usage from hashmap From: Ian Rogers To: irogers@google.com, acme@kernel.org, adrian.hunter@intel.com, james.clark@linaro.org, jolsa@kernel.org, mingo@redhat.com, namhyung@kernel.org, peterz@infradead.org Cc: alexander.shishkin@linux.intel.com, alexei.starovoitov@gmail.com, andrii@kernel.org, ast@kernel.org, bpf@vger.kernel.org, daniel@iogearbox.net, eddyz87@gmail.com, haoluo@google.com, john.fastabend@gmail.com, kpsingh@kernel.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, martin.lau@linux.dev, memxor@gmail.com, sdf@fomichev.me, song@kernel.org, yonghong.song@linux.dev Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The hashmap implementation in tools/perf/util was using ERR_PTR to return errors from perf_hashmap__new. This is non-standard for most of the perf codebase which prefers NULL on error and setting errno. As such it was a frequent source of bugs: commit d05073adda0f ("perf trace: Avoid an ERR_PTR in syscall_stats") commit 96f202eab813 ("perf trace: Fix IS_ERR() vs NULL check bug") commit 9f3c16a430e8 ("perf expr: Fix return value of ids__new()") commit 4d4d00dd321f ("perf tools: Update copy of libbpf's hashmap.c") Remove the dependency on linux/err.h in hashmap.c. Update perf_hashmap__new to set errno =3D ENOMEM and return NULL on failure. Update perf_hashmap__free to check for NULL instead of using IS_ERR_OR_NULL. Update all callers of perf_hashmap__new to check for NULL. In places where IS_ERR_OR_NULL was used on hashmap pointers, switch to regular NULL checks. Signed-off-by: Ian Rogers --- tools/perf/builtin-trace.c | 2 +- tools/perf/ui/browsers/annotate.c | 4 ++-- tools/perf/util/expr.c | 4 ++-- tools/perf/util/fncache.c | 10 +++++++--- tools/perf/util/hashmap.c | 9 +++++---- tools/perf/util/pmu.c | 6 ++++++ tools/perf/util/s390-sample-raw.c | 2 +- tools/perf/util/stat.c | 2 +- 8 files changed, 25 insertions(+), 14 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 88b2fac16457..7b186c32cb0d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1566,7 +1566,7 @@ static struct perf_hashmap *alloc_syscall_stats(void) { struct perf_hashmap *result =3D perf_hashmap__new(syscall_id_hash, syscal= l_id_equal, NULL); =20 - return IS_ERR(result) ? NULL : result; + return result; } =20 static void delete_syscall_stats(struct perf_hashmap *syscall_stats) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/ann= otate.c index c61415295dda..5c0656421084 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -143,7 +143,7 @@ static void annotate_browser__write(struct ui_browser *= browser, void *entry, int if (!browser->navkeypressed) ops.width +=3D 1; =20 - if (!IS_ERR_OR_NULL(ab->type_hash)) + if (ab->type_hash) apd.type_hash =3D ab->type_hash; =20 annotation_line__write(al, notes, &ops, &apd); @@ -1248,7 +1248,7 @@ int __hist_entry__tui_annotate(struct hist_entry *he,= struct map_symbol *ms, =20 debuginfo__delete(browser.dbg); =20 - if (!IS_ERR_OR_NULL(browser.type_hash)) { + if (browser.type_hash) { struct perf_hashmap_entry *cur; size_t bkt; =20 diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c index dc10c335e378..f96812bae318 100644 --- a/tools/perf/util/expr.c +++ b/tools/perf/util/expr.c @@ -68,7 +68,7 @@ struct perf_hashmap *ids__new(void) struct perf_hashmap *hash; =20 hash =3D perf_hashmap__new(key_hash, key_equal, NULL); - if (IS_ERR(hash)) + if (!hash) return NULL; return hash; } @@ -296,7 +296,7 @@ struct expr_parse_ctx *expr__ctx_new(void) return NULL; =20 ctx->ids =3D perf_hashmap__new(key_hash, key_equal, NULL); - if (IS_ERR(ctx->ids)) { + if (!ctx->ids) { free(ctx); return NULL; } diff --git a/tools/perf/util/fncache.c b/tools/perf/util/fncache.c index 9c49a914e784..0970b0bbd1d5 100644 --- a/tools/perf/util/fncache.c +++ b/tools/perf/util/fncache.c @@ -36,9 +36,10 @@ static struct perf_hashmap *fncache__get(void) =20 static bool lookup_fncache(const char *name, bool *res) { + struct perf_hashmap *map =3D fncache__get(); long val; =20 - if (!perf_hashmap__find(fncache__get(), name, &val)) + if (!map || !perf_hashmap__find(map, name, &val)) return false; =20 *res =3D (val !=3D 0); @@ -47,11 +48,14 @@ static bool lookup_fncache(const char *name, bool *res) =20 static void update_fncache(const char *name, bool res) { + struct perf_hashmap *map =3D fncache__get(); char *old_key =3D NULL, *key =3D strdup(name); =20 - if (key) { - perf_hashmap__set(fncache__get(), key, res, &old_key, /*old_value*/NULL); + if (map && key) { + perf_hashmap__set(map, key, res, &old_key, /*old_value*/NULL); free(old_key); + } else { + free(key); } } =20 diff --git a/tools/perf/util/hashmap.c b/tools/perf/util/hashmap.c index d90ef4ed384d..147e011a547f 100644 --- a/tools/perf/util/hashmap.c +++ b/tools/perf/util/hashmap.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "hashmap.h" =20 /* make sure libbpf doesn't use kernel-only integer typedefs */ @@ -55,8 +54,10 @@ struct perf_hashmap *perf_hashmap__new(perf_hashmap_hash= _fn hash_fn, { struct perf_hashmap *map =3D malloc(sizeof(struct perf_hashmap)); =20 - if (!map) - return ERR_PTR(-ENOMEM); + if (!map) { + errno =3D ENOMEM; + return NULL; + } perf_hashmap__init(map, hash_fn, equal_fn, ctx); return map; } @@ -76,7 +77,7 @@ void perf_hashmap__clear(struct perf_hashmap *map) =20 void perf_hashmap__free(struct perf_hashmap *map) { - if (IS_ERR_OR_NULL(map)) + if (!map) return; =20 perf_hashmap__clear(map); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index ace354b23501..01a7c0098797 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1305,6 +1305,12 @@ struct perf_pmu *perf_pmu__create_placeholder_core_p= mu(struct list_head *core_pm =20 INIT_LIST_HEAD(&pmu->format); pmu->aliases =3D perf_hashmap__new(aliases__hash, aliases__equal, /*ctx= =3D*/ NULL); + if (!pmu->aliases) { + perf_cpu_map__put(pmu->cpus); + free((char *)pmu->name); + free(pmu); + return NULL; + } INIT_LIST_HEAD(&pmu->caps); list_add_tail(&pmu->list, core_pmus); return pmu; diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sampl= e-raw.c index 80a5535089e0..52ab84e53173 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -201,7 +201,7 @@ static char *get_counter_name(int set, int nr, struct p= erf_pmu *pmu) get_counter_name_perf_hashmap_equal_fn, /*ctx=3D*/NULL); =20 - if (!IS_ERR(tmp)) { + if (tmp) { cache =3D tmp; cache_pmu =3D pmu; } diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 81b266c5d4f5..1359a1f81562 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -320,7 +320,7 @@ static int check_per_pkg(struct evsel *counter, struct = perf_counts_values *vals, =20 if (!mask) { mask =3D perf_hashmap__new(pkg_id_hash, pkg_id_equal, NULL); - if (IS_ERR(mask)) + if (!mask) return -ENOMEM; =20 counter->per_pkg_mask =3D mask; --=20 2.53.0.959.g497ff81fa9-goog