Linux Perf Users
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@kernel.org>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Ian Rogers <irogers@google.com>, Jiri Olsa <jolsa@kernel.org>,
	Adrian Hunter <adrian.hunter@intel.com>,
	James Clark <james.clark@linaro.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	linux-perf-users@vger.kernel.org
Subject: [PATCH v4 06/10] perf tools: Factor out dso__find_binary_type()
Date: Mon, 12 Oct 2026 16:46:50 -0700	[thread overview]
Message-ID: <20261012234654.60666-7-namhyung@kernel.org> (raw)
In-Reply-To: <20261012234654.60666-1-namhyung@kernel.org>

Separate out the logic to detect binary type of a DSO.  It checks if
the candidate file contains ".text" section.  There could be data-only
DSOs but as our use cases focus on the code (perf annotate or intel
PT), we can ignore them for now.

But it also can fail due to open file limit.  Handle the case by
retrying with _dso__data_open_lock.

Introduce bintype_searched flag and it accessors to prevent repeated
(failed) search.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/dso.c | 137 ++++++++++++++++++++++++++++++++++++++----
 tools/perf/util/dso.h |  13 ++++
 2 files changed, 138 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 913877b84b2d437e..c42ad0c5c66a7bcd 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -833,34 +833,147 @@ void dso__data_close(struct dso *dso)
 	mutex_unlock(dso__data_open_lock());
 }
 
-static void try_to_open_dso(struct dso *dso, struct machine *machine)
-	EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
+static int dso__find_binary_type_locked(struct dso *dso)
+	EXCLUSIVE_LOCKS_REQUIRED(dso__lock(dso))
 {
 	enum dso_binary_type binary_type_data[] = {
 		DSO_BINARY_TYPE__BUILD_ID_CACHE,
 		DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+		dso__symtab_type(dso),
 		DSO_BINARY_TYPE__NOT_FOUND,
 	};
 	int i = 0;
-	struct dso_data *dso_data = dso__data(dso);
+	char *path;
+	bool found = false;
+	bool decomp = false;
+	int saved_errno;
 
-	if (dso_data->fd >= 0)
-		return;
+	if (dso__bintype_searched(dso))
+		return dso__binary_type(dso);
+	dso__set_bintype_searched(dso);
 
-	if (dso__binary_type(dso) != DSO_BINARY_TYPE__NOT_FOUND) {
-		dso_data->fd = open_dso(dso, machine);
-		goto out;
+	switch (dso__binary_type(dso)) {
+	case DSO_BINARY_TYPE__KALLSYMS:
+	case DSO_BINARY_TYPE__GUEST_KALLSYMS:
+	case DSO_BINARY_TYPE__VMLINUX:
+	case DSO_BINARY_TYPE__GUEST_VMLINUX:
+	case DSO_BINARY_TYPE__KCORE:
+	case DSO_BINARY_TYPE__GUEST_KCORE:
+		/* Nothing to do with kernel images */
+		WARN_ON(!dso__kernel(dso));
+		return dso__binary_type(dso);
+	case DSO_BINARY_TYPE__BPF_PROG_INFO:
+	case DSO_BINARY_TYPE__BPF_IMAGE:
+	case DSO_BINARY_TYPE__OOL:
+	case DSO_BINARY_TYPE__JAVA_JIT:
+		/* Same for the special DSOs */
+		return dso__binary_type(dso);
+	case DSO_BINARY_TYPE__GUEST_KMODULE:
+	case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
+	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
+	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
+	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
+	case DSO_BINARY_TYPE__BUILD_ID_CACHE:
+		/* We don't expect these are set; fall through */
+	case DSO_BINARY_TYPE__NOT_FOUND:
+		/* Let's find it out (for user DSOs or kernel modules) */
+		break;
+	case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
+	case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
+	case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO:
+	case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
+	case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO:
+	case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
+	case DSO_BINARY_TYPE__GNU_DEBUGDATA:
+	case DSO_BINARY_TYPE__DEBUGLINK:
+	default:
+		/* Unexpected binary types (usually debug only) */
+		break;
 	}
 
 	do {
 		dso__set_binary_type(dso, binary_type_data[i++]);
 
-		dso_data->fd = open_dso(dso, machine);
-		if (dso_data->fd >= 0)
-			goto out;
+		path = dso__get_filename(dso, "", &decomp, dso__binary_type(dso));
+		if (path == NULL) {
+			if (errno == EMFILE)
+				goto open_err;
+			continue;
+		}
+
+		errno = 0;
+		found = filename__has_section(path, ".text");
+		if (!found)
+			saved_errno = errno;
+		dso__put_filename(dso, path, decomp);
+
+		if (found)
+			return dso__binary_type(dso);
+		else if (saved_errno == EMFILE)
+			goto open_err;
 
 	} while (dso__binary_type(dso) != DSO_BINARY_TYPE__NOT_FOUND);
-out:
+
+	return dso__binary_type(dso);
+
+open_err:
+	/* Too many open files.  Allow retry after closing one. */
+	RC_CHK_ACCESS(dso)->bintype_searched = 0;
+	dso__set_binary_type(dso, DSO_BINARY_TYPE__NOT_FOUND);
+	return -1;
+}
+
+#define FIND_MAX_RETRY  3
+static int __dso__find_binary_type(struct dso *dso, bool needs_open_lock)
+{
+	int ret;
+	int retry = 0;
+
+again:
+	mutex_lock(dso__lock(dso));
+	ret = dso__find_binary_type_locked(dso);
+	mutex_unlock(dso__lock(dso));
+
+	if (ret == -1 && retry++ < FIND_MAX_RETRY) {
+		if (needs_open_lock && retry == 1)
+			mutex_lock(dso__data_open_lock());
+
+		if (dso__data_open_cnt) {
+			close_first_dso();
+			goto again;
+		}
+	}
+
+	if (retry > 0 && needs_open_lock)
+		mutex_unlock(dso__data_open_lock());
+
+	if (ret == -1) {
+		mutex_lock(dso__lock(dso));
+		ret = dso__binary_type(dso);
+		dso__set_bintype_searched(dso);
+		mutex_unlock(dso__lock(dso));
+	}
+
+	return ret;
+}
+#undef FIND_MAX_RETRY
+
+enum dso_binary_type dso__find_binary_type(struct dso *dso)
+{
+	return __dso__find_binary_type(dso, /*needs_open_lock=*/true);
+}
+
+static void try_to_open_dso(struct dso *dso, struct machine *machine)
+	EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
+{
+	struct dso_data *dso_data = dso__data(dso);
+
+	if (dso_data->fd >= 0)
+		return;
+
+	__dso__find_binary_type(dso, /*needs_open_lock=*/false);
+	dso_data->fd = open_dso(dso, machine);
+
 	if (dso_data->fd >= 0)
 		dso_data->status = DSO_DATA_STATUS_OK;
 	else
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 3f08d45e7f53a508..3329f417810c25a4 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -349,6 +349,7 @@ DECLARE_RC_STRUCT(dso) {
 	u8		 short_name_allocated:1;
 	u8		 long_name_allocated:1;
 	u8		 is_64_bit:1;
+	u8		 bintype_searched:1;
 	u8		 debuginfo_searched:1;
 	bool		 sorted_by_name;
 	bool		 loaded;
@@ -957,6 +958,8 @@ void dso__reset_find_symbol_cache(struct dso *dso);
 size_t dso__fprintf_symbols_by_name(struct dso *dso, FILE *fp);
 size_t dso__fprintf(struct dso *dso, FILE *fp);
 
+enum dso_binary_type dso__find_binary_type(struct dso *dso);
+
 static inline enum dso_binary_type dso__binary_type(const struct dso *dso)
 {
 	return RC_CHK_ACCESS(dso)->binary_type;
@@ -967,6 +970,16 @@ static inline void dso__set_binary_type(struct dso *dso, enum dso_binary_type bt
 	RC_CHK_ACCESS(dso)->binary_type = bt;
 }
 
+static inline bool dso__bintype_searched(const struct dso *dso)
+{
+	return RC_CHK_ACCESS(dso)->bintype_searched;
+}
+
+static inline void dso__set_bintype_searched(struct dso *dso)
+{
+	RC_CHK_ACCESS(dso)->bintype_searched = 1;
+}
+
 static inline bool dso__is_vmlinux(const struct dso *dso)
 {
 	enum dso_binary_type bt = dso__binary_type(dso);
-- 
2.56.0.385.gd3acb90ef8-goog


  parent reply	other threads:[~2026-10-12 23:47 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-12 23:46 [PATCH v4 00/10] perf symbol: Properly seto DSO binary/symtab types Namhyung Kim
2026-10-12 23:46 ` [PATCH v4 01/10] perf tools: Remove redundant dso data init Namhyung Kim
2026-10-12 23:50   ` sashiko-bot
2026-10-12 23:46 ` [PATCH v4 02/10] perf tools: Try linked debug files for DSO debug info Namhyung Kim
2026-10-12 23:56   ` sashiko-bot
2026-10-13  6:08     ` Namhyung Kim
2026-10-12 23:46 ` [PATCH v4 03/10] perf symbol: Update symtab type of vmlinux from build-id cache Namhyung Kim
2026-10-12 23:52   ` sashiko-bot
2026-10-12 23:46 ` [PATCH v4 04/10] perf symbol: Set binary/symtab type for split kallsyms Namhyung Kim
2026-10-12 23:53   ` sashiko-bot
2026-10-12 23:46 ` [PATCH v4 05/10] perf symbol: Get rid of machine_or_dso_e_machine() Namhyung Kim
2026-10-13  0:03   ` sashiko-bot
2026-10-12 23:46 ` Namhyung Kim [this message]
2026-10-12 23:58   ` [PATCH v4 06/10] perf tools: Factor out dso__find_binary_type() sashiko-bot
2026-10-13  6:11     ` Namhyung Kim
2026-10-12 23:46 ` [PATCH v4 07/10] perf symbol: Set binary type for JIT map DSOs Namhyung Kim
2026-10-12 23:59   ` sashiko-bot
2026-10-12 23:46 ` [PATCH v4 08/10] perf symbol: Do not set binary type from symtab type Namhyung Kim
2026-10-13  0:08   ` sashiko-bot
2026-10-13  6:18     ` Namhyung Kim
2026-10-12 23:46 ` [PATCH v4 09/10] perf annotate: Simplify symbol__disassemble() with dso binary_type Namhyung Kim
2026-10-13  0:06   ` sashiko-bot
2026-10-12 23:46 ` [PATCH v4 10/10] perf test: Fix dso data tests Namhyung Kim
2026-10-13  0:06   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261012234654.60666-7-namhyung@kernel.org \
    --to=namhyung@kernel.org \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=irogers@google.com \
    --cc=james.clark@linaro.org \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox