From patchwork Fri Feb 2 06:15:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195591 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp238304dyc; Thu, 1 Feb 2024 22:18:35 -0800 (PST) X-Google-Smtp-Source: AGHT+IFNUYZPpEEVmhuR2L5Ofk1dU0OtDpE5Km4yzOnnAcehpY/jlQt5pF676LCNbhbS5QaWugl7 X-Received: by 2002:a05:6a20:94c4:b0:19e:2d02:56c3 with SMTP id ht4-20020a056a2094c400b0019e2d0256c3mr1496636pzb.6.1706854715182; Thu, 01 Feb 2024 22:18:35 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854715; cv=pass; d=google.com; s=arc-20160816; b=leZPFiVzbb6DwaMNj1npAWxzmUj493sARnh0O5PoQ/nBommpND4RqFQZab5WOnKwFA FRMlpeVMg3PLad6wFqeD1kkHAkzfKur4p4LYPlHsQEOzvRko5DVvs3pAo+J9Y2TjbftJ 4FcEMvzuuknGH7IDYEELet507sQlBb2gcGe6Sd9hKJirX8kf4ZZI/VcFImuII5qosEX/ 2iaf7A0YA8lGmeMHnFg3OX/s0YsMd/BzgiWxsh9IgNhH3Hb68OeH9UztB/C31oMRsvFy 5ScfnNGc/JkDrm+ZJ9ns5YAQSewybGFAgqcGVI6c31b7t2fvxrptCVckF404lRUG/ZUs f6Ug== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=uOveehfWxcCj+86z5DWsT8T4x04wQ6gdOGLTWd0QSpU=; fh=lqwWEcyZ9UiT++paEiLEwvZOAsAh6wUHtYLhGB4RlbY=; b=dH1NwfVOija8xROaPwHuCXfDDa/l7KdbMUXDc/ccCONPnbehfIMTm5wlnAnUtdMdL+ M6GzGV6NjBkdUEXATvDrC4o383zkpSIjKtcr0yGSDyh/XSG89uLVQmjjuObTcMNCwDNi FftxmiwcE2X6ndLshy9/lWYdnEF0cd1OfZW2jK2pefkK4AWZaS5g6bofTIPotFlWcXYw mQeX+AyI7fvx164eu7hrb37ZC9A6bWIlNQc8jfrr/eCXlUxgrGJxE03sv8nzwi7eT7VT T1oG0qrZu4rJaF6wxKfKA6+ZsO06n+rAeGgBmCCj9GJGrw+CbKT+NNpsbEb04vyF73F7 cVgQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=WKnFunaR; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49240-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49240-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCWa15sdNkTUyyMykMn3V+KqMn2Kj5BlKCOQZZ/H2GDJuP6fbwVexO6Kpas+1wzn6xqQUEt4GDk3lSY37zsYXStnuT1lhQ== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id h18-20020a170902eed200b001d88bb0d2eesi1160023plb.108.2024.02.01.22.18.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:18:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49240-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=WKnFunaR; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49240-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49240-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 9F3302853D5 for ; Fri, 2 Feb 2024 06:17:39 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3030C18625; Fri, 2 Feb 2024 06:16:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="WKnFunaR" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 BDD8A17546 for ; Fri, 2 Feb 2024 06:15:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854552; cv=none; b=KmaUjibykgyDOT+OXKwZfx2AHCh8GGbB162VeD4xwI7Ac25v7saXitHaSp8Relhb00hgxosDBXItIkt7BkHxMjMCWxGDKLWjJVSbiotiBuvguN30p26za9fhUcNZBPsL7tsfM6Ij7tbIZ6Z0drYigPt+imKaNKPrTb7El6PqpJw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854552; c=relaxed/simple; bh=VvfUnjvvMGtqdKBjmWO/YOIN3l52rWg4a87QEEVMLiA=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=TG3sIV+aQx9Vu6UUlVJAHb0lh+kPRnJgwlgMdCrqaXvTN9MLffguW+wWglvzKEfZHzh6vDf42iWgnAB+q2v/ODDDizqQPE4SVAXM8jxPY9LENnxaWvGcJjvamIXRGQSQaEsDfOoOkktWJ+LecHg9QVKuqsswhflzGHKnMUItEYs= 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=WKnFunaR; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60405c0c9b0so40892307b3.1 for ; Thu, 01 Feb 2024 22:15:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854549; x=1707459349; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=uOveehfWxcCj+86z5DWsT8T4x04wQ6gdOGLTWd0QSpU=; b=WKnFunaRKQpSv/Lkb1vD+v0iaxHhO8l9Ds/hx9VJLHMdYxq27ACYHcL13NULF+N2qa jITBBcMW3e2Yr72wnMFS5lwC3BJ4y0uENudciMCbW0hXZ+uIkgFrSsUXvioS0OK9TxxK T0zMMnlbwhwcKRKwXA0azaSu4pJa0iQ+t0FyoWINkhOw7JH8xZfMq6GYlaeWgExo5Xp+ IFkGPyevXWGkzsEIKekS7sL4LTMQ9D/5cOjZy4yWmIto05V8uUq50Am8JL3tI5BhIOit GF9VfDDa6vaxSgHj7NORngj64CCUPnUKDLxntuw8fedPqA1YSVHdAOrLhR5NaIb6CAW2 84yA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854549; x=1707459349; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=uOveehfWxcCj+86z5DWsT8T4x04wQ6gdOGLTWd0QSpU=; b=ooMv70ddVZf+JP5vUvgE14UI/cpq2ePfOzoY+Tuj5MAl6P7jlP3g0gsoXJHutyiBWD 8KcGowQDjuddrTFBlnWTat2ovx5QTJ4iviYTVTPv3zTk5B5j9sGYZd1PY8fWjxpCTDOQ 1CarYl98Y4sBmIkvOMGTdonlJjs1m/SIVFNr/nnpjYdoKaNgwv8RdMD+Qfzznwi1XejU xlj7vdUUKJ3GeBT30bnoWJwhVsp4k6N0yf1ctFgeJtMbyvB3nAl0//BhjHifSdg5kTto EJRpkUd02AOiejxU2L3K6HOyGoeEA+jwWxHu5NkUi7cJt8wdl4LQpNZ5zYQwVJAw3Tn6 3x9g== X-Gm-Message-State: AOJu0YzxTCuRuaejntJCrsxyDruq0Dlu5Dup6KXmkoytsZar2fCf9hbj GxK8nywdWttiBCzHamdJmrn/Om2VTmBzzXz6WaagZFi21mTg/pzxrkBwanaxUxvYMmxnCWrnrEg +C+n3Gg== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:1605:b0:dc2:4d91:fb4b with SMTP id bw5-20020a056902160500b00dc24d91fb4bmr354033ybb.9.1706854548777; Thu, 01 Feb 2024 22:15:48 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:08 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-2-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 01/25] perf maps: Switch from rbtree to lazily sorted array for addresses From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766889963733260 X-GMAIL-MSGID: 1789766889963733260 Maps is a collection of maps primarily sorted by the starting address of the map. Prior to this change the maps were held in an rbtree requiring 4 pointers per node. Prior to reference count checking, the rbnode was embedded in the map so 3 pointers per node were necessary. This change switches the rbtree to an array lazily sorted by address, much as the array sorting nodes by name. 1 pointer is needed per node, but to avoid excessive resizing the backing array may be twice the number of used elements. Meaning the memory overhead is roughly half that of the rbtree. For a perf record with "--no-bpf-event -g -a" of true, the memory overhead of perf inject is reduce fom 3.3MB to 3MB, so 10% or 300KB is saved. Map inserts always happen at the end of the array. The code tracks whether the insertion violates the sorting property. O(log n) rb-tree complexity is switched to O(1). Remove slides the array, so O(log n) rb-tree complexity is degraded to O(n). A find may need to sort the array using qsort which is O(n*log n), but in general the maps should be sorted and so average performance should be O(log n) as with the rbtree. An rbtree node consumes a cache line, but with the array 4 nodes fit on a cache line. Iteration is simplified to scanning an array rather than pointer chasing. Overall it is expected the performance after the change should be comparable to before, but with half of the memory consumed. To avoid a list and repeated logic around splitting maps, maps__merge_in is rewritten in terms of maps__fixup_overlap_and_insert. maps_merge_in splits the given mapping inserting remaining gaps. maps__fixup_overlap_and_insert splits the existing mappings, then adds the incoming mapping. By adding the new mapping first, then re-inserting the existing mappings the splitting behavior matches. Signed-off-by: Ian Rogers --- tools/perf/tests/maps.c | 3 + tools/perf/util/map.c | 1 + tools/perf/util/maps.c | 1197 +++++++++++++++++++++++---------------- tools/perf/util/maps.h | 54 +- 4 files changed, 771 insertions(+), 484 deletions(-) diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index bb3fbfe5a73e..b15417a0d617 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -156,6 +156,9 @@ static int test__maps__merge_in(struct test_suite *t __maybe_unused, int subtest TEST_ASSERT_VAL("merge check failed", !ret); maps__zput(maps); + map__zput(map_kcore1); + map__zput(map_kcore2); + map__zput(map_kcore3); return TEST_OK; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 54c67cb7ecef..cf5a15db3a1f 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -168,6 +168,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, if (dso == NULL) goto out_delete; + assert(!dso->kernel); map__init(result, start, start + len, pgoff, dso); if (anon || no_dso) { diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 0334fc18d9c6..2fd81e2d622e 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -10,286 +10,490 @@ #include "ui/ui.h" #include "unwind.h" -struct map_rb_node { - struct rb_node rb_node; - struct map *map; -}; - -#define maps__for_each_entry(maps, map) \ - for (map = maps__first(maps); map; map = map_rb_node__next(map)) +static void check_invariants(const struct maps *maps __maybe_unused) +{ +#ifndef NDEBUG + assert(RC_CHK_ACCESS(maps)->nr_maps <= RC_CHK_ACCESS(maps)->nr_maps_allocated); + for (unsigned int i = 0; i < RC_CHK_ACCESS(maps)->nr_maps; i++) { + struct map *map = RC_CHK_ACCESS(maps)->maps_by_address[i]; + + /* Check map is well-formed. */ + assert(map__end(map) == 0 || map__start(map) <= map__end(map)); + /* Expect at least 1 reference count. */ + assert(refcount_read(map__refcnt(map)) > 0); + + if (map__dso(map) && map__dso(map)->kernel) + assert(RC_CHK_EQUAL(map__kmap(map)->kmaps, maps)); + + if (i > 0) { + struct map *prev = RC_CHK_ACCESS(maps)->maps_by_address[i - 1]; + + /* If addresses are sorted... */ + if (RC_CHK_ACCESS(maps)->maps_by_address_sorted) { + /* Maps should be in start address order. */ + assert(map__start(prev) <= map__start(map)); + /* + * If the ends of maps aren't broken (during + * construction) then they should be ordered + * too. + */ + if (!RC_CHK_ACCESS(maps)->ends_broken) { + assert(map__end(prev) <= map__end(map)); + assert(map__end(prev) <= map__start(map) || + map__start(prev) == map__start(map)); + } + } + } + } + if (RC_CHK_ACCESS(maps)->maps_by_name) { + for (unsigned int i = 0; i < RC_CHK_ACCESS(maps)->nr_maps; i++) { + struct map *map = RC_CHK_ACCESS(maps)->maps_by_name[i]; -#define maps__for_each_entry_safe(maps, map, next) \ - for (map = maps__first(maps), next = map_rb_node__next(map); map; \ - map = next, next = map_rb_node__next(map)) + /* + * Maps by name maps should be in maps_by_address, so + * the reference count should be higher. + */ + assert(refcount_read(map__refcnt(map)) > 1); + } + } +#endif +} -static struct rb_root *maps__entries(struct maps *maps) +static struct map **maps__maps_by_address(const struct maps *maps) { - return &RC_CHK_ACCESS(maps)->entries; + return RC_CHK_ACCESS(maps)->maps_by_address; } -static struct rw_semaphore *maps__lock(struct maps *maps) +static void maps__set_maps_by_address(struct maps *maps, struct map **new) { - return &RC_CHK_ACCESS(maps)->lock; + RC_CHK_ACCESS(maps)->maps_by_address = new; + } -static struct map **maps__maps_by_name(struct maps *maps) +static struct map ***maps__maps_by_name_addr(struct maps *maps) { - return RC_CHK_ACCESS(maps)->maps_by_name; + return &RC_CHK_ACCESS(maps)->maps_by_name; } -static struct map_rb_node *maps__first(struct maps *maps) +static void maps__set_nr_maps_allocated(struct maps *maps, unsigned int nr_maps_allocated) { - struct rb_node *first = rb_first(maps__entries(maps)); + RC_CHK_ACCESS(maps)->nr_maps_allocated = nr_maps_allocated; +} - if (first) - return rb_entry(first, struct map_rb_node, rb_node); - return NULL; +static void maps__set_nr_maps(struct maps *maps, unsigned int nr_maps) +{ + RC_CHK_ACCESS(maps)->nr_maps = nr_maps; } -static struct map_rb_node *map_rb_node__next(struct map_rb_node *node) +/* Not in the header, to aid reference counting. */ +static struct map **maps__maps_by_name(const struct maps *maps) { - struct rb_node *next; + return RC_CHK_ACCESS(maps)->maps_by_name; - if (!node) - return NULL; +} - next = rb_next(&node->rb_node); +static void maps__set_maps_by_name(struct maps *maps, struct map **new) +{ + RC_CHK_ACCESS(maps)->maps_by_name = new; - if (!next) - return NULL; +} - return rb_entry(next, struct map_rb_node, rb_node); +static bool maps__maps_by_address_sorted(const struct maps *maps) +{ + return RC_CHK_ACCESS(maps)->maps_by_address_sorted; } -static struct map_rb_node *maps__find_node(struct maps *maps, struct map *map) +static void maps__set_maps_by_address_sorted(struct maps *maps, bool value) { - struct map_rb_node *rb_node; + RC_CHK_ACCESS(maps)->maps_by_address_sorted = value; +} - maps__for_each_entry(maps, rb_node) { - if (rb_node->RC_CHK_ACCESS(map) == RC_CHK_ACCESS(map)) - return rb_node; - } - return NULL; +static bool maps__maps_by_name_sorted(const struct maps *maps) +{ + return RC_CHK_ACCESS(maps)->maps_by_name_sorted; } -static void maps__init(struct maps *maps, struct machine *machine) +static void maps__set_maps_by_name_sorted(struct maps *maps, bool value) { - refcount_set(maps__refcnt(maps), 1); - init_rwsem(maps__lock(maps)); - RC_CHK_ACCESS(maps)->entries = RB_ROOT; - RC_CHK_ACCESS(maps)->machine = machine; - RC_CHK_ACCESS(maps)->last_search_by_name = NULL; - RC_CHK_ACCESS(maps)->nr_maps = 0; - RC_CHK_ACCESS(maps)->maps_by_name = NULL; + RC_CHK_ACCESS(maps)->maps_by_name_sorted = value; } -static void __maps__free_maps_by_name(struct maps *maps) +static struct rw_semaphore *maps__lock(struct maps *maps) { /* - * Free everything to try to do it from the rbtree in the next search + * When the lock is acquired or released the maps invariants should + * hold. */ - for (unsigned int i = 0; i < maps__nr_maps(maps); i++) - map__put(maps__maps_by_name(maps)[i]); + check_invariants(maps); + return &RC_CHK_ACCESS(maps)->lock; +} - zfree(&RC_CHK_ACCESS(maps)->maps_by_name); +static void maps__init(struct maps *maps, struct machine *machine) +{ + init_rwsem(maps__lock(maps)); + RC_CHK_ACCESS(maps)->maps_by_address = NULL; + RC_CHK_ACCESS(maps)->maps_by_name = NULL; + RC_CHK_ACCESS(maps)->machine = machine; +#ifdef HAVE_LIBUNWIND_SUPPORT + RC_CHK_ACCESS(maps)->addr_space = NULL; + RC_CHK_ACCESS(maps)->unwind_libunwind_ops = NULL; +#endif + refcount_set(maps__refcnt(maps), 1); + RC_CHK_ACCESS(maps)->nr_maps = 0; RC_CHK_ACCESS(maps)->nr_maps_allocated = 0; + RC_CHK_ACCESS(maps)->last_search_by_name_idx = 0; + RC_CHK_ACCESS(maps)->maps_by_address_sorted = true; + RC_CHK_ACCESS(maps)->maps_by_name_sorted = false; } -static int __maps__insert(struct maps *maps, struct map *map) +static void maps__exit(struct maps *maps) { - struct rb_node **p = &maps__entries(maps)->rb_node; - struct rb_node *parent = NULL; - const u64 ip = map__start(map); - struct map_rb_node *m, *new_rb_node; + struct map **maps_by_address = maps__maps_by_address(maps); + struct map **maps_by_name = maps__maps_by_name(maps); - new_rb_node = malloc(sizeof(*new_rb_node)); - if (!new_rb_node) - return -ENOMEM; + for (unsigned int i = 0; i < maps__nr_maps(maps); i++) { + map__zput(maps_by_address[i]); + if (maps_by_name) + map__zput(maps_by_name[i]); + } + zfree(&maps_by_address); + zfree(&maps_by_name); + unwind__finish_access(maps); +} - RB_CLEAR_NODE(&new_rb_node->rb_node); - new_rb_node->map = map__get(map); +struct maps *maps__new(struct machine *machine) +{ + struct maps *result; + RC_STRUCT(maps) *maps = zalloc(sizeof(*maps)); - while (*p != NULL) { - parent = *p; - m = rb_entry(parent, struct map_rb_node, rb_node); - if (ip < map__start(m->map)) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } + if (ADD_RC_CHK(result, maps)) + maps__init(result, machine); - rb_link_node(&new_rb_node->rb_node, parent, p); - rb_insert_color(&new_rb_node->rb_node, maps__entries(maps)); - return 0; + return result; } -int maps__insert(struct maps *maps, struct map *map) +static void maps__delete(struct maps *maps) { - int err; - const struct dso *dso = map__dso(map); - - down_write(maps__lock(maps)); - err = __maps__insert(maps, map); - if (err) - goto out; + maps__exit(maps); + RC_CHK_FREE(maps); +} - ++RC_CHK_ACCESS(maps)->nr_maps; +struct maps *maps__get(struct maps *maps) +{ + struct maps *result; - if (dso && dso->kernel) { - struct kmap *kmap = map__kmap(map); + if (RC_CHK_GET(result, maps)) + refcount_inc(maps__refcnt(maps)); - if (kmap) - kmap->kmaps = maps; - else - pr_err("Internal error: kernel dso with non kernel map\n"); - } + return result; +} +void maps__put(struct maps *maps) +{ + if (maps && refcount_dec_and_test(maps__refcnt(maps))) + maps__delete(maps); + else + RC_CHK_PUT(maps); +} +static void __maps__free_maps_by_name(struct maps *maps) +{ /* - * If we already performed some search by name, then we need to add the just - * inserted map and resort. + * Free everything to try to do it from the rbtree in the next search */ - if (maps__maps_by_name(maps)) { - if (maps__nr_maps(maps) > RC_CHK_ACCESS(maps)->nr_maps_allocated) { - int nr_allocate = maps__nr_maps(maps) * 2; - struct map **maps_by_name = realloc(maps__maps_by_name(maps), - nr_allocate * sizeof(map)); + for (unsigned int i = 0; i < maps__nr_maps(maps); i++) + map__put(maps__maps_by_name(maps)[i]); - if (maps_by_name == NULL) { - __maps__free_maps_by_name(maps); - err = -ENOMEM; - goto out; - } + zfree(&RC_CHK_ACCESS(maps)->maps_by_name); +} - RC_CHK_ACCESS(maps)->maps_by_name = maps_by_name; - RC_CHK_ACCESS(maps)->nr_maps_allocated = nr_allocate; +static int map__start_cmp(const void *a, const void *b) +{ + const struct map *map_a = *(const struct map * const *)a; + const struct map *map_b = *(const struct map * const *)b; + u64 map_a_start = map__start(map_a); + u64 map_b_start = map__start(map_b); + + if (map_a_start == map_b_start) { + u64 map_a_end = map__end(map_a); + u64 map_b_end = map__end(map_b); + + if (map_a_end == map_b_end) { + /* Ensure maps with the same addresses have a fixed order. */ + if (RC_CHK_ACCESS(map_a) == RC_CHK_ACCESS(map_b)) + return 0; + return (intptr_t)RC_CHK_ACCESS(map_a) > (intptr_t)RC_CHK_ACCESS(map_b) + ? 1 : -1; } - maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] = map__get(map); - __maps__sort_by_name(maps); + return map_a_end > map_b_end ? 1 : -1; } - out: - up_write(maps__lock(maps)); - return err; + return map_a_start > map_b_start ? 1 : -1; } -static void __maps__remove(struct maps *maps, struct map_rb_node *rb_node) +static void __maps__sort_by_address(struct maps *maps) { - rb_erase_init(&rb_node->rb_node, maps__entries(maps)); - map__put(rb_node->map); - free(rb_node); + if (maps__maps_by_address_sorted(maps)) + return; + + qsort(maps__maps_by_address(maps), + maps__nr_maps(maps), + sizeof(struct map *), + map__start_cmp); + maps__set_maps_by_address_sorted(maps, true); } -void maps__remove(struct maps *maps, struct map *map) +static void maps__sort_by_address(struct maps *maps) { - struct map_rb_node *rb_node; - down_write(maps__lock(maps)); - if (RC_CHK_ACCESS(maps)->last_search_by_name == map) - RC_CHK_ACCESS(maps)->last_search_by_name = NULL; - - rb_node = maps__find_node(maps, map); - assert(rb_node->RC_CHK_ACCESS(map) == RC_CHK_ACCESS(map)); - __maps__remove(maps, rb_node); - if (maps__maps_by_name(maps)) - __maps__free_maps_by_name(maps); - --RC_CHK_ACCESS(maps)->nr_maps; + __maps__sort_by_address(maps); up_write(maps__lock(maps)); } -static void __maps__purge(struct maps *maps) +static int map__strcmp(const void *a, const void *b) { - struct map_rb_node *pos, *next; - - if (maps__maps_by_name(maps)) - __maps__free_maps_by_name(maps); + const struct map *map_a = *(const struct map * const *)a; + const struct map *map_b = *(const struct map * const *)b; + const struct dso *dso_a = map__dso(map_a); + const struct dso *dso_b = map__dso(map_b); + int ret = strcmp(dso_a->short_name, dso_b->short_name); - maps__for_each_entry_safe(maps, pos, next) { - rb_erase_init(&pos->rb_node, maps__entries(maps)); - map__put(pos->map); - free(pos); + if (ret == 0 && RC_CHK_ACCESS(map_a) != RC_CHK_ACCESS(map_b)) { + /* Ensure distinct but name equal maps have an order. */ + return map__start_cmp(a, b); } + return ret; } -static void maps__exit(struct maps *maps) +static int maps__sort_by_name(struct maps *maps) { + int err = 0; down_write(maps__lock(maps)); - __maps__purge(maps); + if (!maps__maps_by_name_sorted(maps)) { + struct map **maps_by_name = maps__maps_by_name(maps); + + if (!maps_by_name) { + maps_by_name = malloc(RC_CHK_ACCESS(maps)->nr_maps_allocated * + sizeof(*maps_by_name)); + if (!maps_by_name) + err = -ENOMEM; + else { + struct map **maps_by_address = maps__maps_by_address(maps); + unsigned int n = maps__nr_maps(maps); + + maps__set_maps_by_name(maps, maps_by_name); + for (unsigned int i = 0; i < n; i++) + maps_by_name[i] = map__get(maps_by_address[i]); + } + } + if (!err) { + qsort(maps_by_name, + maps__nr_maps(maps), + sizeof(struct map *), + map__strcmp); + maps__set_maps_by_name_sorted(maps, true); + } + } up_write(maps__lock(maps)); + return err; } -bool maps__empty(struct maps *maps) +static unsigned int maps__by_address_index(const struct maps *maps, const struct map *map) { - return !maps__first(maps); + struct map **maps_by_address = maps__maps_by_address(maps); + + if (maps__maps_by_address_sorted(maps)) { + struct map **mapp = + bsearch(&map, maps__maps_by_address(maps), maps__nr_maps(maps), + sizeof(*mapp), map__start_cmp); + + if (mapp) + return mapp - maps_by_address; + } else { + for (unsigned int i = 0; i < maps__nr_maps(maps); i++) { + if (RC_CHK_ACCESS(maps_by_address[i]) == RC_CHK_ACCESS(map)) + return i; + } + } + pr_err("Map missing from maps"); + return -1; } -struct maps *maps__new(struct machine *machine) +static unsigned int maps__by_name_index(const struct maps *maps, const struct map *map) { - struct maps *result; - RC_STRUCT(maps) *maps = zalloc(sizeof(*maps)); + struct map **maps_by_name = maps__maps_by_name(maps); + + if (maps__maps_by_name_sorted(maps)) { + struct map **mapp = + bsearch(&map, maps_by_name, maps__nr_maps(maps), + sizeof(*mapp), map__strcmp); + + if (mapp) + return mapp - maps_by_name; + } else { + for (unsigned int i = 0; i < maps__nr_maps(maps); i++) { + if (RC_CHK_ACCESS(maps_by_name[i]) == RC_CHK_ACCESS(map)) + return i; + } + } + pr_err("Map missing from maps"); + return -1; +} - if (ADD_RC_CHK(result, maps)) - maps__init(result, machine); +static int __maps__insert(struct maps *maps, struct map *new) +{ + struct map **maps_by_address = maps__maps_by_address(maps); + struct map **maps_by_name = maps__maps_by_name(maps); + const struct dso *dso = map__dso(new); + unsigned int nr_maps = maps__nr_maps(maps); + unsigned int nr_allocate = RC_CHK_ACCESS(maps)->nr_maps_allocated; + + if (nr_maps + 1 > nr_allocate) { + nr_allocate = !nr_allocate ? 32 : nr_allocate * 2; + + maps_by_address = realloc(maps_by_address, nr_allocate * sizeof(new)); + if (!maps_by_address) + return -ENOMEM; + + maps__set_maps_by_address(maps, maps_by_address); + if (maps_by_name) { + maps_by_name = realloc(maps_by_name, nr_allocate * sizeof(new)); + if (!maps_by_name) { + /* + * If by name fails, just disable by name and it will + * recompute next time it is required. + */ + __maps__free_maps_by_name(maps); + } + maps__set_maps_by_name(maps, maps_by_name); + } + RC_CHK_ACCESS(maps)->nr_maps_allocated = nr_allocate; + } + /* Insert the value at the end. */ + maps_by_address[nr_maps] = map__get(new); + if (maps_by_name) + maps_by_name[nr_maps] = map__get(new); - return result; + nr_maps++; + RC_CHK_ACCESS(maps)->nr_maps = nr_maps; + + /* + * Recompute if things are sorted. If things are inserted in a sorted + * manner, for example by processing /proc/pid/maps, then no + * sorting/resorting will be necessary. + */ + if (nr_maps == 1) { + /* If there's just 1 entry then maps are sorted. */ + maps__set_maps_by_address_sorted(maps, true); + maps__set_maps_by_name_sorted(maps, maps_by_name != NULL); + } else { + /* Sorted if maps were already sorted and this map starts after the last one. */ + maps__set_maps_by_address_sorted(maps, + maps__maps_by_address_sorted(maps) && + map__end(maps_by_address[nr_maps - 2]) <= map__start(new)); + maps__set_maps_by_name_sorted(maps, false); + } + if (map__end(new) < map__start(new)) + RC_CHK_ACCESS(maps)->ends_broken = true; + if (dso && dso->kernel) { + struct kmap *kmap = map__kmap(new); + + if (kmap) + kmap->kmaps = maps; + else + pr_err("Internal error: kernel dso with non kernel map\n"); + } + return 0; } -static void maps__delete(struct maps *maps) +int maps__insert(struct maps *maps, struct map *map) { - maps__exit(maps); - unwind__finish_access(maps); - RC_CHK_FREE(maps); + int ret; + + down_write(maps__lock(maps)); + ret = __maps__insert(maps, map); + up_write(maps__lock(maps)); + return ret; } -struct maps *maps__get(struct maps *maps) +static void __maps__remove(struct maps *maps, struct map *map) { - struct maps *result; + struct map **maps_by_address = maps__maps_by_address(maps); + struct map **maps_by_name = maps__maps_by_name(maps); + unsigned int nr_maps = maps__nr_maps(maps); + unsigned int address_idx; + + /* Slide later mappings over the one to remove */ + address_idx = maps__by_address_index(maps, map); + map__put(maps_by_address[address_idx]); + memmove(&maps_by_address[address_idx], + &maps_by_address[address_idx + 1], + (nr_maps - address_idx - 1) * sizeof(*maps_by_address)); + + if (maps_by_name) { + unsigned int name_idx = maps__by_name_index(maps, map); + + map__put(maps_by_name[name_idx]); + memmove(&maps_by_name[name_idx], + &maps_by_name[name_idx + 1], + (nr_maps - name_idx - 1) * sizeof(*maps_by_name)); + } - if (RC_CHK_GET(result, maps)) - refcount_inc(maps__refcnt(maps)); + --RC_CHK_ACCESS(maps)->nr_maps; +} - return result; +void maps__remove(struct maps *maps, struct map *map) +{ + down_write(maps__lock(maps)); + __maps__remove(maps, map); + up_write(maps__lock(maps)); } -void maps__put(struct maps *maps) +bool maps__empty(struct maps *maps) { - if (maps && refcount_dec_and_test(maps__refcnt(maps))) - maps__delete(maps); - else - RC_CHK_PUT(maps); + return maps__nr_maps(maps) == 0; } int maps__for_each_map(struct maps *maps, int (*cb)(struct map *map, void *data), void *data) { - struct map_rb_node *pos; + bool done = false; int ret = 0; - down_read(maps__lock(maps)); - maps__for_each_entry(maps, pos) { - ret = cb(pos->map, data); - if (ret) - break; + /* See locking/sorting note. */ + while (!done) { + down_read(maps__lock(maps)); + if (maps__maps_by_address_sorted(maps)) { + struct map **maps_by_address = maps__maps_by_address(maps); + unsigned int n = maps__nr_maps(maps); + + for (unsigned int i = 0; i < n; i++) { + struct map *map = maps_by_address[i]; + + ret = cb(map, data); + if (ret) + break; + } + done = true; + } + up_read(maps__lock(maps)); + if (!done) + maps__sort_by_address(maps); } - up_read(maps__lock(maps)); return ret; } void maps__remove_maps(struct maps *maps, bool (*cb)(struct map *map, void *data), void *data) { - struct map_rb_node *pos, *next; - unsigned int start_nr_maps; + struct map **maps_by_address; down_write(maps__lock(maps)); - start_nr_maps = maps__nr_maps(maps); - maps__for_each_entry_safe(maps, pos, next) { - if (cb(pos->map, data)) { - __maps__remove(maps, pos); - --RC_CHK_ACCESS(maps)->nr_maps; - } + maps_by_address = maps__maps_by_address(maps); + for (unsigned int i = 0; i < maps__nr_maps(maps);) { + if (cb(maps_by_address[i], data)) + __maps__remove(maps, maps_by_address[i]); + else + i++; } - if (maps__maps_by_name(maps) && start_nr_maps != maps__nr_maps(maps)) - __maps__free_maps_by_name(maps); - up_write(maps__lock(maps)); } @@ -300,7 +504,7 @@ struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp) /* Ensure map is loaded before using map->map_ip */ if (map != NULL && map__load(map) >= 0) { if (mapp != NULL) - *mapp = map; + *mapp = map; // TODO: map_put on else path when find returns a get. return map__find_symbol(map, map__map_ip(map, addr)); } @@ -348,7 +552,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) if (ams->addr < map__start(ams->ms.map) || ams->addr >= map__end(ams->ms.map)) { if (maps == NULL) return -1; - ams->ms.map = maps__find(maps, ams->addr); + ams->ms.map = maps__find(maps, ams->addr); // TODO: map_get if (ams->ms.map == NULL) return -1; } @@ -393,24 +597,28 @@ size_t maps__fprintf(struct maps *maps, FILE *fp) * Find first map where end > map->start. * Same as find_vma() in kernel. */ -static struct rb_node *first_ending_after(struct maps *maps, const struct map *map) +static unsigned int first_ending_after(struct maps *maps, const struct map *map) { - struct rb_root *root; - struct rb_node *next, *first; + struct map **maps_by_address = maps__maps_by_address(maps); + int low = 0, high = (int)maps__nr_maps(maps) - 1, first = high + 1; + + assert(maps__maps_by_address_sorted(maps)); + if (low <= high && map__end(maps_by_address[0]) > map__start(map)) + return 0; - root = maps__entries(maps); - next = root->rb_node; - first = NULL; - while (next) { - struct map_rb_node *pos = rb_entry(next, struct map_rb_node, rb_node); + while (low <= high) { + int mid = (low + high) / 2; + struct map *pos = maps_by_address[mid]; - if (map__end(pos->map) > map__start(map)) { - first = next; - if (map__start(pos->map) <= map__start(map)) + if (map__end(pos) > map__start(map)) { + first = mid; + if (map__start(pos) <= map__start(map)) { + /* Entry overlaps map. */ break; - next = next->rb_left; + } + high = mid - 1; } else - next = next->rb_right; + low = mid + 1; } return first; } @@ -419,171 +627,249 @@ static struct rb_node *first_ending_after(struct maps *maps, const struct map *m * Adds new to maps, if new overlaps existing entries then the existing maps are * adjusted or removed so that new fits without overlapping any entries. */ -int maps__fixup_overlap_and_insert(struct maps *maps, struct map *new) +static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new) { - - struct rb_node *next; + struct map **maps_by_address; int err = 0; FILE *fp = debug_file(); - down_write(maps__lock(maps)); +sort_again: + if (!maps__maps_by_address_sorted(maps)) + __maps__sort_by_address(maps); - next = first_ending_after(maps, new); - while (next && !err) { - struct map_rb_node *pos = rb_entry(next, struct map_rb_node, rb_node); - next = rb_next(&pos->rb_node); + maps_by_address = maps__maps_by_address(maps); + /* + * Iterate through entries where the end of the existing entry is + * greater-than the new map's start. + */ + for (unsigned int i = first_ending_after(maps, new); i < maps__nr_maps(maps); ) { + struct map *pos = maps_by_address[i]; + struct map *before = NULL, *after = NULL; /* * Stop if current map starts after map->end. * Maps are ordered by start: next will not overlap for sure. */ - if (map__start(pos->map) >= map__end(new)) + if (map__start(pos) >= map__end(new)) break; - if (verbose >= 2) { - - if (use_browser) { - pr_debug("overlapping maps in %s (disable tui for more info)\n", - map__dso(new)->name); - } else { - pr_debug("overlapping maps:\n"); - map__fprintf(new, fp); - map__fprintf(pos->map, fp); - } + if (use_browser) { + pr_debug("overlapping maps in %s (disable tui for more info)\n", + map__dso(new)->name); + } else if (verbose >= 2) { + pr_debug("overlapping maps:\n"); + map__fprintf(new, fp); + map__fprintf(pos, fp); } - rb_erase_init(&pos->rb_node, maps__entries(maps)); /* * Now check if we need to create new maps for areas not * overlapped by the new map: */ - if (map__start(new) > map__start(pos->map)) { - struct map *before = map__clone(pos->map); + if (map__start(new) > map__start(pos)) { + /* Map starts within existing map. Need to shorten the existing map. */ + before = map__clone(pos); if (before == NULL) { err = -ENOMEM; - goto put_map; + goto out_err; } - map__set_end(before, map__start(new)); - err = __maps__insert(maps, before); - if (err) { - map__put(before); - goto put_map; - } if (verbose >= 2 && !use_browser) map__fprintf(before, fp); - map__put(before); } - - if (map__end(new) < map__end(pos->map)) { - struct map *after = map__clone(pos->map); + if (map__end(new) < map__end(pos)) { + /* The new map isn't as long as the existing map. */ + after = map__clone(pos); if (after == NULL) { + map__zput(before); err = -ENOMEM; - goto put_map; + goto out_err; } map__set_start(after, map__end(new)); - map__add_pgoff(after, map__end(new) - map__start(pos->map)); - assert(map__map_ip(pos->map, map__end(new)) == - map__map_ip(after, map__end(new))); - err = __maps__insert(maps, after); - if (err) { - map__put(after); - goto put_map; - } + map__add_pgoff(after, map__end(new) - map__start(pos)); + assert(map__map_ip(pos, map__end(new)) == + map__map_ip(after, map__end(new))); + if (verbose >= 2 && !use_browser) map__fprintf(after, fp); - map__put(after); } -put_map: - map__put(pos->map); - free(pos); + /* + * If adding one entry, for `before` or `after`, we can replace + * the existing entry. If both `before` and `after` are + * necessary than an insert is needed. If the existing entry + * entirely overlaps the existing entry it can just be removed. + */ + if (before) { + map__put(maps_by_address[i]); + maps_by_address[i] = before; + /* Maps are still ordered, go to next one. */ + i++; + if (after) { + __maps__insert(maps, after); + map__put(after); + if (!maps__maps_by_address_sorted(maps)) { + /* + * Sorting broken so invariants don't + * hold, sort and go again. + */ + goto sort_again; + } + /* + * Maps are still ordered, skip after and go to + * next one (terminate loop). + */ + i++; + } + } else if (after) { + map__put(maps_by_address[i]); + maps_by_address[i] = after; + /* Maps are ordered, go to next one. */ + i++; + } else { + __maps__remove(maps, pos); + /* + * Maps are ordered but no need to increase `i` as the + * later maps were moved down. + */ + } + check_invariants(maps); } /* Add the map. */ - err = __maps__insert(maps, new); - up_write(maps__lock(maps)); + __maps__insert(maps, new); +out_err: return err; } -int maps__copy_from(struct maps *maps, struct maps *parent) +int maps__fixup_overlap_and_insert(struct maps *maps, struct map *new) { int err; - struct map_rb_node *rb_node; + down_write(maps__lock(maps)); + err = __maps__fixup_overlap_and_insert(maps, new); + up_write(maps__lock(maps)); + return err; +} + +int maps__copy_from(struct maps *dest, struct maps *parent) +{ + /* Note, if struct map were immutable then cloning could use ref counts. */ + struct map **parent_maps_by_address; + int err = 0; + unsigned int n; + + down_write(maps__lock(dest)); down_read(maps__lock(parent)); - maps__for_each_entry(parent, rb_node) { - struct map *new = map__clone(rb_node->map); + parent_maps_by_address = maps__maps_by_address(parent); + n = maps__nr_maps(parent); + if (maps__empty(dest)) { + /* No existing mappings so just copy from parent to avoid reallocs in insert. */ + unsigned int nr_maps_allocated = RC_CHK_ACCESS(parent)->nr_maps_allocated; + struct map **dest_maps_by_address = + malloc(nr_maps_allocated * sizeof(struct map *)); + struct map **dest_maps_by_name = NULL; - if (new == NULL) { + if (!dest_maps_by_address) err = -ENOMEM; - goto out_unlock; + else { + if (maps__maps_by_name(parent)) { + dest_maps_by_name = + malloc(nr_maps_allocated * sizeof(struct map *)); + } + + RC_CHK_ACCESS(dest)->maps_by_address = dest_maps_by_address; + RC_CHK_ACCESS(dest)->maps_by_name = dest_maps_by_name; + RC_CHK_ACCESS(dest)->nr_maps_allocated = nr_maps_allocated; } - err = unwind__prepare_access(maps, new, NULL); - if (err) - goto out_unlock; + for (unsigned int i = 0; !err && i < n; i++) { + struct map *pos = parent_maps_by_address[i]; + struct map *new = map__clone(pos); - err = maps__insert(maps, new); - if (err) - goto out_unlock; + if (!new) + err = -ENOMEM; + else { + err = unwind__prepare_access(dest, new, NULL); + if (!err) { + dest_maps_by_address[i] = new; + if (dest_maps_by_name) + dest_maps_by_name[i] = map__get(new); + RC_CHK_ACCESS(dest)->nr_maps = i + 1; + } + } + if (err) + map__put(new); + } + maps__set_maps_by_address_sorted(dest, maps__maps_by_address_sorted(parent)); + if (!err) { + RC_CHK_ACCESS(dest)->last_search_by_name_idx = + RC_CHK_ACCESS(parent)->last_search_by_name_idx; + maps__set_maps_by_name_sorted(dest, + dest_maps_by_name && + maps__maps_by_name_sorted(parent)); + } else { + RC_CHK_ACCESS(dest)->last_search_by_name_idx = 0; + maps__set_maps_by_name_sorted(dest, false); + } + } else { + /* Unexpected copying to a maps containing entries. */ + for (unsigned int i = 0; !err && i < n; i++) { + struct map *pos = parent_maps_by_address[i]; + struct map *new = map__clone(pos); - map__put(new); + if (!new) + err = -ENOMEM; + else { + err = unwind__prepare_access(dest, new, NULL); + if (!err) + err = maps__insert(dest, new); + } + map__put(new); + } } - - err = 0; -out_unlock: up_read(maps__lock(parent)); + up_write(maps__lock(dest)); return err; } -struct map *maps__find(struct maps *maps, u64 ip) +static int map__addr_cmp(const void *key, const void *entry) { - struct rb_node *p; - struct map_rb_node *m; - - - down_read(maps__lock(maps)); - - p = maps__entries(maps)->rb_node; - while (p != NULL) { - m = rb_entry(p, struct map_rb_node, rb_node); - if (ip < map__start(m->map)) - p = p->rb_left; - else if (ip >= map__end(m->map)) - p = p->rb_right; - else - goto out; - } + const u64 ip = *(const u64 *)key; + const struct map *map = *(const struct map * const *)entry; - m = NULL; -out: - up_read(maps__lock(maps)); - return m ? m->map : NULL; + if (ip < map__start(map)) + return -1; + if (ip >= map__end(map)) + return 1; + return 0; } -static int map__strcmp(const void *a, const void *b) +struct map *maps__find(struct maps *maps, u64 ip) { - const struct map *map_a = *(const struct map **)a; - const struct map *map_b = *(const struct map **)b; - const struct dso *dso_a = map__dso(map_a); - const struct dso *dso_b = map__dso(map_b); - int ret = strcmp(dso_a->short_name, dso_b->short_name); - - if (ret == 0 && map_a != map_b) { - /* - * Ensure distinct but name equal maps have an order in part to - * aid reference counting. - */ - ret = (int)map__start(map_a) - (int)map__start(map_b); - if (ret == 0) - ret = (int)((intptr_t)map_a - (intptr_t)map_b); + struct map *result = NULL; + bool done = false; + + /* See locking/sorting note. */ + while (!done) { + down_read(maps__lock(maps)); + if (maps__maps_by_address_sorted(maps)) { + struct map **mapp = + bsearch(&ip, maps__maps_by_address(maps), maps__nr_maps(maps), + sizeof(*mapp), map__addr_cmp); + + if (mapp) + result = *mapp; // map__get(*mapp); + done = true; + } + up_read(maps__lock(maps)); + if (!done) + maps__sort_by_address(maps); } - - return ret; + return result; } static int map__strcmp_name(const void *name, const void *b) @@ -593,126 +879,113 @@ static int map__strcmp_name(const void *name, const void *b) return strcmp(name, dso->short_name); } -void __maps__sort_by_name(struct maps *maps) -{ - qsort(maps__maps_by_name(maps), maps__nr_maps(maps), sizeof(struct map *), map__strcmp); -} - -static int map__groups__sort_by_name_from_rbtree(struct maps *maps) -{ - struct map_rb_node *rb_node; - struct map **maps_by_name = realloc(maps__maps_by_name(maps), - maps__nr_maps(maps) * sizeof(struct map *)); - int i = 0; - - if (maps_by_name == NULL) - return -1; - - up_read(maps__lock(maps)); - down_write(maps__lock(maps)); - - RC_CHK_ACCESS(maps)->maps_by_name = maps_by_name; - RC_CHK_ACCESS(maps)->nr_maps_allocated = maps__nr_maps(maps); - - maps__for_each_entry(maps, rb_node) - maps_by_name[i++] = map__get(rb_node->map); - - __maps__sort_by_name(maps); - - up_write(maps__lock(maps)); - down_read(maps__lock(maps)); - - return 0; -} - -static struct map *__maps__find_by_name(struct maps *maps, const char *name) +struct map *maps__find_by_name(struct maps *maps, const char *name) { - struct map **mapp; + struct map *result = NULL; + bool done = false; - if (maps__maps_by_name(maps) == NULL && - map__groups__sort_by_name_from_rbtree(maps)) - return NULL; + /* See locking/sorting note. */ + while (!done) { + unsigned int i; - mapp = bsearch(name, maps__maps_by_name(maps), maps__nr_maps(maps), - sizeof(*mapp), map__strcmp_name); - if (mapp) - return *mapp; - return NULL; -} + down_read(maps__lock(maps)); -struct map *maps__find_by_name(struct maps *maps, const char *name) -{ - struct map_rb_node *rb_node; - struct map *map; - - down_read(maps__lock(maps)); + /* First check last found entry. */ + i = RC_CHK_ACCESS(maps)->last_search_by_name_idx; + if (i < maps__nr_maps(maps) && maps__maps_by_name(maps)) { + struct dso *dso = map__dso(maps__maps_by_name(maps)[i]); + if (dso && strcmp(dso->short_name, name) == 0) { + result = maps__maps_by_name(maps)[i]; // TODO: map__get + done = true; + } + } - if (RC_CHK_ACCESS(maps)->last_search_by_name) { - const struct dso *dso = map__dso(RC_CHK_ACCESS(maps)->last_search_by_name); + /* Second search sorted array. */ + if (!done && maps__maps_by_name_sorted(maps)) { + struct map **mapp = + bsearch(name, maps__maps_by_name(maps), maps__nr_maps(maps), + sizeof(*mapp), map__strcmp_name); - if (strcmp(dso->short_name, name) == 0) { - map = RC_CHK_ACCESS(maps)->last_search_by_name; - goto out_unlock; + if (mapp) { + result = *mapp; // TODO: map__get + i = mapp - maps__maps_by_name(maps); + RC_CHK_ACCESS(maps)->last_search_by_name_idx = i; + } + done = true; } - } - /* - * If we have maps->maps_by_name, then the name isn't in the rbtree, - * as maps->maps_by_name mirrors the rbtree when lookups by name are - * made. - */ - map = __maps__find_by_name(maps, name); - if (map || maps__maps_by_name(maps) != NULL) - goto out_unlock; - - /* Fallback to traversing the rbtree... */ - maps__for_each_entry(maps, rb_node) { - struct dso *dso; - - map = rb_node->map; - dso = map__dso(map); - if (strcmp(dso->short_name, name) == 0) { - RC_CHK_ACCESS(maps)->last_search_by_name = map; - goto out_unlock; + up_read(maps__lock(maps)); + if (!done) { + /* Sort and retry binary search. */ + if (maps__sort_by_name(maps)) { + /* + * Memory allocation failed do linear search + * through address sorted maps. + */ + struct map **maps_by_address; + unsigned int n; + + down_read(maps__lock(maps)); + maps_by_address = maps__maps_by_address(maps); + n = maps__nr_maps(maps); + for (i = 0; i < n; i++) { + struct map *pos = maps_by_address[i]; + struct dso *dso = map__dso(pos); + + if (dso && strcmp(dso->short_name, name) == 0) { + result = pos; // TODO: map__get + break; + } + } + up_read(maps__lock(maps)); + done = true; + } } } - map = NULL; - -out_unlock: - up_read(maps__lock(maps)); - return map; + return result; } struct map *maps__find_next_entry(struct maps *maps, struct map *map) { - struct map_rb_node *rb_node = maps__find_node(maps, map); - struct map_rb_node *next = map_rb_node__next(rb_node); + unsigned int i; + struct map *result = NULL; - if (next) - return next->map; + down_read(maps__lock(maps)); + i = maps__by_address_index(maps, map); + if (i < maps__nr_maps(maps)) + result = maps__maps_by_address(maps)[i]; // TODO: map__get - return NULL; + up_read(maps__lock(maps)); + return result; } void maps__fixup_end(struct maps *maps) { - struct map_rb_node *prev = NULL, *curr; + struct map **maps_by_address; + unsigned int n; down_write(maps__lock(maps)); + if (!maps__maps_by_address_sorted(maps)) + __maps__sort_by_address(maps); - maps__for_each_entry(maps, curr) { - if (prev && (!map__end(prev->map) || map__end(prev->map) > map__start(curr->map))) - map__set_end(prev->map, map__start(curr->map)); + maps_by_address = maps__maps_by_address(maps); + n = maps__nr_maps(maps); + for (unsigned int i = 1; i < n; i++) { + struct map *prev = maps_by_address[i - 1]; + struct map *curr = maps_by_address[i]; - prev = curr; + if (!map__end(prev) || map__end(prev) > map__start(curr)) + map__set_end(prev, map__start(curr)); } /* * We still haven't the actual symbols, so guess the * last map final address. */ - if (curr && !map__end(curr->map)) - map__set_end(curr->map, ~0ULL); + if (n > 0 && !map__end(maps_by_address[n - 1])) + map__set_end(maps_by_address[n - 1], ~0ULL); + + RC_CHK_ACCESS(maps)->ends_broken = false; up_write(maps__lock(maps)); } @@ -723,117 +996,93 @@ void maps__fixup_end(struct maps *maps) */ int maps__merge_in(struct maps *kmaps, struct map *new_map) { - struct map_rb_node *rb_node; - struct rb_node *first; - bool overlaps; - LIST_HEAD(merged); - int err = 0; - - down_read(maps__lock(kmaps)); - first = first_ending_after(kmaps, new_map); - rb_node = first ? rb_entry(first, struct map_rb_node, rb_node) : NULL; - overlaps = rb_node && map__start(rb_node->map) < map__end(new_map); - up_read(maps__lock(kmaps)); + unsigned int first_after_, kmaps__nr_maps; + struct map **kmaps_maps_by_address; + struct map **merged_maps_by_address; + unsigned int merged_nr_maps_allocated; + + /* First try under a read lock. */ + while (true) { + down_read(maps__lock(kmaps)); + if (maps__maps_by_address_sorted(kmaps)) + break; - if (!overlaps) - return maps__insert(kmaps, new_map); + up_read(maps__lock(kmaps)); - maps__for_each_entry(kmaps, rb_node) { - struct map *old_map = rb_node->map; + /* First after binary search requires sorted maps. Sort and try again. */ + maps__sort_by_address(kmaps); + } + first_after_ = first_ending_after(kmaps, new_map); + kmaps_maps_by_address = maps__maps_by_address(kmaps); - /* no overload with this one */ - if (map__end(new_map) < map__start(old_map) || - map__start(new_map) >= map__end(old_map)) - continue; + if (first_after_ >= maps__nr_maps(kmaps) || + map__start(kmaps_maps_by_address[first_after_]) >= map__end(new_map)) { + /* No overlap so regular insert suffices. */ + up_read(maps__lock(kmaps)); + return maps__insert(kmaps, new_map); + } + up_read(maps__lock(kmaps)); - if (map__start(new_map) < map__start(old_map)) { - /* - * |new...... - * |old.... - */ - if (map__end(new_map) < map__end(old_map)) { - /* - * |new......| -> |new..| - * |old....| -> |old....| - */ - map__set_end(new_map, map__start(old_map)); - } else { - /* - * |new.............| -> |new..| |new..| - * |old....| -> |old....| - */ - struct map_list_node *m = map_list_node__new(); + /* Plain insert with a read-lock failed, try again now with the write lock. */ + down_write(maps__lock(kmaps)); + if (!maps__maps_by_address_sorted(kmaps)) + __maps__sort_by_address(kmaps); + + first_after_ = first_ending_after(kmaps, new_map); + kmaps_maps_by_address = maps__maps_by_address(kmaps); + kmaps__nr_maps = maps__nr_maps(kmaps); + + if (first_after_ >= kmaps__nr_maps || + map__start(kmaps_maps_by_address[first_after_]) >= map__end(new_map)) { + /* No overlap so regular insert suffices. */ + int ret = __maps__insert(kmaps, new_map); + up_write(maps__lock(kmaps)); + return ret; + } + /* Array to merge into, possibly 1 more for the sake of new_map. */ + merged_nr_maps_allocated = RC_CHK_ACCESS(kmaps)->nr_maps_allocated; + if (kmaps__nr_maps + 1 == merged_nr_maps_allocated) + merged_nr_maps_allocated++; + + merged_maps_by_address = malloc(merged_nr_maps_allocated * sizeof(*merged_maps_by_address)); + if (!merged_maps_by_address) { + up_write(maps__lock(kmaps)); + return -ENOMEM; + } + maps__set_maps_by_address(kmaps, merged_maps_by_address); + maps__set_maps_by_address_sorted(kmaps, true); + zfree(maps__maps_by_name_addr(kmaps)); + maps__set_maps_by_name_sorted(kmaps, true); + maps__set_nr_maps_allocated(kmaps, merged_nr_maps_allocated); - if (!m) { - err = -ENOMEM; - goto out; - } + /* Copy entries before the new_map that can't overlap. */ + for (unsigned int i = 0; i < first_after_; i++) + merged_maps_by_address[i] = map__get(kmaps_maps_by_address[i]); - m->map = map__clone(new_map); - if (!m->map) { - free(m); - err = -ENOMEM; - goto out; - } + maps__set_nr_maps(kmaps, first_after_); - map__set_end(m->map, map__start(old_map)); - list_add_tail(&m->node, &merged); - map__add_pgoff(new_map, map__end(old_map) - map__start(new_map)); - map__set_start(new_map, map__end(old_map)); - } - } else { - /* - * |new...... - * |old.... - */ - if (map__end(new_map) < map__end(old_map)) { - /* - * |new..| -> x - * |old.........| -> |old.........| - */ - map__put(new_map); - new_map = NULL; - break; - } else { - /* - * |new......| -> |new...| - * |old....| -> |old....| - */ - map__add_pgoff(new_map, map__end(old_map) - map__start(new_map)); - map__set_start(new_map, map__end(old_map)); - } - } - } + /* Add the new map, it will be split when the later overlapping mappings are added. */ + __maps__insert(kmaps, new_map); -out: - while (!list_empty(&merged)) { - struct map_list_node *old_node; + /* Insert mappings after new_map, splitting new_map in the process. */ + for (unsigned int i = first_after_; i < kmaps__nr_maps; i++) + __maps__fixup_overlap_and_insert(kmaps, kmaps_maps_by_address[i]); - old_node = list_entry(merged.next, struct map_list_node, node); - list_del_init(&old_node->node); - if (!err) - err = maps__insert(kmaps, old_node->map); - map__put(old_node->map); - free(old_node); - } + /* Copy the maps from merged into kmaps. */ + for (unsigned int i = 0; i < kmaps__nr_maps; i++) + map__zput(kmaps_maps_by_address[i]); - if (new_map) { - if (!err) - err = maps__insert(kmaps, new_map); - map__put(new_map); - } - return err; + free(kmaps_maps_by_address); + up_write(maps__lock(kmaps)); + return 0; } void maps__load_first(struct maps *maps) { - struct map_rb_node *first; - down_read(maps__lock(maps)); - first = maps__first(maps); - if (first) - map__load(first->map); + if (maps__nr_maps(maps) > 0) + map__load(maps__maps_by_address(maps)[0]); up_read(maps__lock(maps)); } diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index d836d04c9402..df9dd5a0e3c0 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -25,21 +25,56 @@ static inline struct map_list_node *map_list_node__new(void) return malloc(sizeof(struct map_list_node)); } -struct map *maps__find(struct maps *maps, u64 addr); +/* + * Locking/sorting note: + * + * Sorting is done with the write lock, iteration and binary searching happens + * under the read lock requiring being sorted. There is a race between sorting + * releasing the write lock and acquiring the read lock for iteration/searching + * where another thread could insert and break the sorting of the maps. In + * practice inserting maps should be rare meaning that the race shouldn't lead + * to live lock. Removal of maps doesn't break being sorted. + */ DECLARE_RC_STRUCT(maps) { - struct rb_root entries; struct rw_semaphore lock; - struct machine *machine; - struct map *last_search_by_name; + /** + * @maps_by_address: array of maps sorted by their starting address if + * maps_by_address_sorted is true. + */ + struct map **maps_by_address; + /** + * @maps_by_name: optional array of maps sorted by their dso name if + * maps_by_name_sorted is true. + */ struct map **maps_by_name; - refcount_t refcnt; - unsigned int nr_maps; - unsigned int nr_maps_allocated; + struct machine *machine; #ifdef HAVE_LIBUNWIND_SUPPORT - void *addr_space; + void *addr_space; const struct unwind_libunwind_ops *unwind_libunwind_ops; #endif + refcount_t refcnt; + /** + * @nr_maps: number of maps_by_address, and possibly maps_by_name, + * entries that contain maps. + */ + unsigned int nr_maps; + /** + * @nr_maps_allocated: number of entries in maps_by_address and possibly + * maps_by_name. + */ + unsigned int nr_maps_allocated; + /** + * @last_search_by_name_idx: cache of last found by name entry's index + * as frequent searches for the same dso name are common. + */ + unsigned int last_search_by_name_idx; + /** @maps_by_address_sorted: is maps_by_address sorted. */ + bool maps_by_address_sorted; + /** @maps_by_name_sorted: is maps_by_name sorted. */ + bool maps_by_name_sorted; + /** @ends_broken: does the map contain a map where end values are unset/unsorted? */ + bool ends_broken; }; #define KMAP_NAME_LEN 256 @@ -102,6 +137,7 @@ size_t maps__fprintf(struct maps *maps, FILE *fp); int maps__insert(struct maps *maps, struct map *map); void maps__remove(struct maps *maps, struct map *map); +struct map *maps__find(struct maps *maps, u64 addr); struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp); struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, struct map **mapp); @@ -117,8 +153,6 @@ struct map *maps__find_next_entry(struct maps *maps, struct map *map); int maps__merge_in(struct maps *kmaps, struct map *new_map); -void __maps__sort_by_name(struct maps *maps); - void maps__fixup_end(struct maps *maps); void maps__load_first(struct maps *maps); From patchwork Fri Feb 2 06:15:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195584 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp237650dyc; Thu, 1 Feb 2024 22:16:51 -0800 (PST) X-Google-Smtp-Source: AGHT+IHFIcA8aTjEIxx9IO2gefsuhUDL9mQcoyjAwgJGOO4itBvMpFb5p6iyFd9OOFW5271YU9zc X-Received: by 2002:aa7:d1ce:0:b0:55f:c940:a949 with SMTP id g14-20020aa7d1ce000000b0055fc940a949mr2004239edp.13.1706854610775; Thu, 01 Feb 2024 22:16:50 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854610; cv=pass; d=google.com; s=arc-20160816; b=l9sfPONVm+8JyisqJZZMd84Obw0UIFNquaZrZWfUztKgHkuqF5ZjMYl9SoksydxHQ+ VsmwoHXmfw5kkopyNGOp0p6VCuMC87+rQNyeOcCOY4XBToeM/4U0fTOhJ8K2olwb69B2 1co8kaxfX96XidtlbjfqjHPv3VVTnmmZX7D1Q5cjwiXRwmq8nuRoNF5EEOMPwIRc27Ar Z7DMvIxvrnmclwMpMRDOonKQhuullZ8ondQdRHbYoH9vii+NyM1izjo72Q6sTZfpYu7i rvo2yDSZyUDhIS/cAfTBkxa0Zy9aMWZcg27rwhJI63wYAIty1ue5C/hjTJIAUpZAI/ds WONA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=Ns6s7UIGkTM/nycvAWwyFQvgVrl7UVyKC0csznO8c+s=; fh=Yh9wtvCgrqaKKrjgR2SmOGwKTwOc6PaTo08BlNmIt3M=; b=SeryKA4913GvpwFMeNT+S7/NlYLUezuGPChy3EsFxZk4InBYiMAlXSohpFD8S2VdoN 5Jf+a0tC1p3q752GaUF9EoL5unP0XF93bACK8Wpi8Rct1eWzX9H5ar7gED9RiGe2SL2P ddk8kAWD2iQhcxvVXoiyYu0vNl7a7WN1AQFj3XiLfmTOKb2+OmJuzG2pjfM/YGpakngM IvUgtm2y7VjnBNQi3N8ewhDFoKvYAYKSDjqeBUAMRsvmHl9rjd69eJI2rjq5b0vxv5Im LiCreSV3lVFsYWC/f3U4wH4L/tpiIy6vgaz27+PG5FSwcvsyETLKYWRZ3rkFun56At27 74TA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=MSIZ9SL2; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49241-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49241-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCWENWBwQphCgo2F6WQpQvVAqOJRQe9+SZdrz9AWm8B1Qx7eRSx/Dhe7lbTQJj5mN3FUQE1AMtJa5IXZ+wKa5DtF365o7Q== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id t6-20020a05640203c600b0055fb593905fsi529374edw.122.2024.02.01.22.16.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:16:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49241-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=MSIZ9SL2; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49241-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49241-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 am.mirrors.kernel.org (Postfix) with ESMTPS id 3B0941F228E4 for ; Fri, 2 Feb 2024 06:16:50 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B18C417BDD; Fri, 2 Feb 2024 06:15:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="MSIZ9SL2" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 F22601755A for ; Fri, 2 Feb 2024 06:15:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854555; cv=none; b=gLkgwkD0B2eew5QI1/1Uh76V00kcHyEHoaYOeks56z+h1fyn6rdSUjCc/ZlsIutae6roj1bEvNXkXHOR0Z4sUt4fy2bnbsad00oDi3S34dynixyCjc+1x++4oQEmXi3BXiLIwvA08u/qr4kKhCMRhDH6fgSZcgKNxCP3XkxRjj0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854555; c=relaxed/simple; bh=Y96V0rvU+Ma2laWtDGnXqBdJjwnDCvtjHq78CaW9p78=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=nNwigpLiZJi4i2fk7jlWJJ1eJ19KFrZVtzwvw5YaRNbxjx0N2G3XCr04QI6/4jnTVEjM38ZT0xRcCNKAw/CKRxzYj54/AtAHgby93tY2r4MOEjfxS0sAPNVQ3w+ZT2qY7o/GZylkkPRk7euRXx8beAZFK73WRqUQEgZ24EPZqCQ= 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=MSIZ9SL2; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60411f95c44so23825877b3.1 for ; Thu, 01 Feb 2024 22:15:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854551; x=1707459351; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=Ns6s7UIGkTM/nycvAWwyFQvgVrl7UVyKC0csznO8c+s=; b=MSIZ9SL2BYZSGMeGKbhFO9CTLJRQXzuLvnJ2UW184DJXVDhtOXnZuiE9K71aBpoHIz yQtnm/kLzT39fSSZVSps8VpSV/8KWdzETPsoedTyKp9Pc9loQKkzb5hbFQmgdNOCXzXS j22KAmVTpbNNJ4ySreMjj7lFr6zl37ZVXcTdACnTEliETRz534ctaZj6BwHU5r5Qkn+X 4ug7fdzeQYxvLMc9Cgg5WU8bdQQx7k0II/ShTsSTYrr2Om8LJZQGO4WUVk44HPHgi+Hu QnzmlkdSzNEqwLrz8aEVwUF2ZEZi0wEAWMSX70BmkqMvKh9IMkzz7nfL7jUQR+yWcPqn 2sFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854551; x=1707459351; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Ns6s7UIGkTM/nycvAWwyFQvgVrl7UVyKC0csznO8c+s=; b=bzZDVlsrV6MxYTnmIlrEgtWS5N8Yuu+57HONUFgMr/rbS9A8C/SGqnlnd7K6BXgKHp /9mWqAS74wHEJDbypk35Lvr0+ou6K79LbhRMff04l6E7okAwfmZsjIpK8329zK+pm26o uMP+RrW/ryeFF7DLl8G3XQkT+ya7E98AKzXRoHXLOocajmHxL7M8DLRFn4TaKVrDhyzz ZQ85iZAqmu0IkTsOwz5Oybu0cJbfpH5E67DpLGbCs3AObLHf1RnxEMbnzWXVzpp6nd0I tFNxgan95dcO13bNvyTBS9Ul6XHCrbnaO5MsdsU78QxqqCEG/9YNx7MSqk4zTxmpWHjg 1gsw== X-Gm-Message-State: AOJu0YzWyyilGuTvjC4ueMVkoGVGBOP+EexOPHJVnV+C0iVYpFmkx1G8 pwiwkL5e4s5FdN5Sc2zDkAQQaWODGYivCbDWf8Br2uUIcus+m1DuDq/pvaWI8dUfBB125HIfwPN OpJPbNQ== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:690c:19:b0:5ee:d5ed:5f70 with SMTP id bc25-20020a05690c001900b005eed5ed5f70mr1172776ywb.9.1706854551036; Thu, 01 Feb 2024 22:15:51 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:09 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-3-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 02/25] perf maps: Get map before returning in maps__find From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766780181976095 X-GMAIL-MSGID: 1789766780181976095 Finding a map is done under a lock, returning the map without a reference count means it can be removed without notice and causing uses after free. Grab a reference count to the map within the lock region and return this. Fix up locations that need a map__put following this. Signed-off-by: Ian Rogers --- tools/perf/arch/x86/tests/dwarf-unwind.c | 1 + tools/perf/tests/vmlinux-kallsyms.c | 5 ++--- tools/perf/util/bpf-event.c | 1 + tools/perf/util/event.c | 4 ++-- tools/perf/util/machine.c | 22 ++++++++-------------- tools/perf/util/maps.c | 17 ++++++++++------- tools/perf/util/symbol.c | 3 ++- 7 files changed, 26 insertions(+), 27 deletions(-) diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c index 5bfec3345d59..c05c0a85dad4 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -34,6 +34,7 @@ static int sample_ustack(struct perf_sample *sample, } stack_size = map__end(map) - sp; + map__put(map); stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; memcpy(buf, (void *) sp, stack_size); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 822f893e67d5..e808e6fc8f76 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -151,10 +151,8 @@ static int test__vmlinux_matches_kallsyms_cb2(struct map *map, void *data) u64 mem_end = map__unmap_ip(args->vmlinux_map, map__end(map)); pair = maps__find(args->kallsyms.kmaps, mem_start); - if (pair == NULL || map__priv(pair)) - return 0; - if (map__start(pair) == mem_start) { + if (pair != NULL && !map__priv(pair) && map__start(pair) == mem_start) { struct dso *dso = map__dso(map); if (!args->header_printed) { @@ -170,6 +168,7 @@ static int test__vmlinux_matches_kallsyms_cb2(struct map *map, void *data) pr_info(" %s\n", dso->name); map__set_priv(pair, 1); } + map__put(pair); return 0; } diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 3573e0b7ef3e..83709146a48a 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -63,6 +63,7 @@ static int machine__process_bpf_event_load(struct machine *machine, dso->bpf_prog.id = id; dso->bpf_prog.sub_id = i; dso->bpf_prog.env = env; + map__put(map); } } return 0; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 68f45e9e63b6..198903157f9e 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -511,7 +511,7 @@ size_t perf_event__fprintf_text_poke(union perf_event *event, struct machine *ma struct addr_location al; addr_location__init(&al); - al.map = map__get(maps__find(machine__kernel_maps(machine), tp->addr)); + al.map = maps__find(machine__kernel_maps(machine), tp->addr); if (al.map && map__load(al.map) >= 0) { al.addr = map__map_ip(al.map, tp->addr); al.sym = map__find_symbol(al.map, al.addr); @@ -641,7 +641,7 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, return NULL; } al->maps = maps__get(maps); - al->map = map__get(maps__find(maps, al->addr)); + al->map = maps__find(maps, al->addr); if (al->map != NULL) { /* * Kernel maps might be changed when loading symbols so loading diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index b397a769006f..e8eb9f0b073f 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -896,7 +896,6 @@ static int machine__process_ksymbol_register(struct machine *machine, struct symbol *sym; struct dso *dso; struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); - bool put_map = false; int err = 0; if (!map) { @@ -913,12 +912,6 @@ static int machine__process_ksymbol_register(struct machine *machine, err = -ENOMEM; goto out; } - /* - * The inserted map has a get on it, we need to put to release - * the reference count here, but do it after all accesses are - * done. - */ - put_map = true; if (event->ksymbol.ksym_type == PERF_RECORD_KSYMBOL_TYPE_OOL) { dso->binary_type = DSO_BINARY_TYPE__OOL; dso->data.file_size = event->ksymbol.len; @@ -952,8 +945,7 @@ static int machine__process_ksymbol_register(struct machine *machine, } dso__insert_symbol(dso, sym); out: - if (put_map) - map__put(map); + map__put(map); return err; } @@ -977,7 +969,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine, if (sym) dso__delete_symbol(dso, sym); } - + map__put(map); return 0; } @@ -1005,11 +997,11 @@ int machine__process_text_poke(struct machine *machine, union perf_event *event, perf_event__fprintf_text_poke(event, machine, stdout); if (!event->text_poke.new_len) - return 0; + goto out; if (cpumode != PERF_RECORD_MISC_KERNEL) { pr_debug("%s: unsupported cpumode - ignoring\n", __func__); - return 0; + goto out; } if (dso) { @@ -1032,7 +1024,8 @@ int machine__process_text_poke(struct machine *machine, union perf_event *event, pr_debug("Failed to find kernel text poke address map for %#" PRI_lx64 "\n", event->text_poke.addr); } - +out: + map__put(map); return 0; } @@ -1300,9 +1293,10 @@ static int machine__map_x86_64_entry_trampolines_cb(struct map *map, void *data) return 0; dest_map = maps__find(args->kmaps, map__pgoff(map)); - if (dest_map != map) + if (RC_CHK_ACCESS(dest_map) != RC_CHK_ACCESS(map)) map__set_pgoff(map, map__map_ip(dest_map, map__pgoff(map))); + map__put(dest_map); args->found = true; return 0; } diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 2fd81e2d622e..252a3b1f8f81 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -500,15 +500,18 @@ void maps__remove_maps(struct maps *maps, bool (*cb)(struct map *map, void *data struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp) { struct map *map = maps__find(maps, addr); + struct symbol *result = NULL; /* Ensure map is loaded before using map->map_ip */ if (map != NULL && map__load(map) >= 0) { - if (mapp != NULL) - *mapp = map; // TODO: map_put on else path when find returns a get. - return map__find_symbol(map, map__map_ip(map, addr)); - } + if (mapp) + *mapp = map; - return NULL; + result = map__find_symbol(map, map__map_ip(map, addr)); + if (!mapp) + map__put(map); + } + return result; } struct maps__find_symbol_by_name_args { @@ -552,7 +555,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) if (ams->addr < map__start(ams->ms.map) || ams->addr >= map__end(ams->ms.map)) { if (maps == NULL) return -1; - ams->ms.map = maps__find(maps, ams->addr); // TODO: map_get + ams->ms.map = maps__find(maps, ams->addr); if (ams->ms.map == NULL) return -1; } @@ -862,7 +865,7 @@ struct map *maps__find(struct maps *maps, u64 ip) sizeof(*mapp), map__addr_cmp); if (mapp) - result = *mapp; // map__get(*mapp); + result = map__get(*mapp); done = true; } up_read(maps__lock(maps)); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index be212ba157dc..1710b89e207c 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -757,7 +757,6 @@ static int dso__load_all_kallsyms(struct dso *dso, const char *filename) static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) { - struct map *curr_map; struct symbol *pos; int count = 0; struct rb_root_cached old_root = dso->symbols; @@ -770,6 +769,7 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) *root = RB_ROOT_CACHED; while (next) { + struct map *curr_map; struct dso *curr_map_dso; char *module; @@ -796,6 +796,7 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) pos->end -= map__start(curr_map) - map__pgoff(curr_map); symbols__insert(&curr_map_dso->symbols, pos); ++count; + map__put(curr_map); } /* Symbols have been adjusted */ From patchwork Fri Feb 2 06:15:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195585 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp237691dyc; Thu, 1 Feb 2024 22:16:55 -0800 (PST) X-Google-Smtp-Source: AGHT+IE8O+7iGQ6h0Q5ZS5q7F8Q1LbjVHSe5UieA9lrexE7FWXyoG0LGd1tdJQWXDIQdHIG9+wEP X-Received: by 2002:a05:6122:270f:b0:4bd:6486:16fc with SMTP id ej15-20020a056122270f00b004bd648616fcmr4568854vkb.6.1706854615606; Thu, 01 Feb 2024 22:16:55 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854615; cv=pass; d=google.com; s=arc-20160816; b=qzB//LqBvNjYsi6LADLhzH5e8BNOefhrB6sFVbrjIPSKiAJXDCmygWAuoihJTHNBVN w6EoudltrIu8qffXlwPFTCip0AsOhj+79lRvbPWSa4CE6mz6B1wYHqWCU0nHLPcdGrl1 sln/dlO5bQvVPoAFvloQnF47oaZOqwQruAd/VW/1WBfPor8ecGPOTFtDyx9XQWVg3SRX Tk/ChCVScmBiQOKHflvXLpCd29fhCZyBk/UN17pU+PjYEFiYXgNewzuzMTzZ7lTIFF10 UhaRiAtFT5bJiiP78lN5HPp9DM7LTmGZ40dS4ORPYwgigJzt7laYhGPjvcZSohtkGzqM XroA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=v+u9iEAq0iCqu7yfngDUriNlQosa5LnNT/PlXHwuCTs=; fh=rXDPq/tuEA94yPRDJ0iBlWImNx/VNixPTkJzFveysjE=; b=G2udiK8rdS8ypffq1AJ+KN4TBfc5l24f13V7YCFeJXNA6MN8FPXXgyBm9y5BMNAUuw 92GwBEl3mxPhNYDf3tQ7JQibeN9BCTmBGMoVCfx7VwN3LsAiOMsUeSKGzEXLfNBOYrsu +vp8Oy+OfNV4vOPpObzhbHxjXuVKB9y8wh2wdbS1w6SxfB6aCby2Cdp0Gm5AEUC9abCu CSETOYks8dIQKOw6cjTTfaGfLZpvMDkZV1RuxC2D+yKm4V+Kt9odtodUou58RcfmYh2d 4MlT+7l6/mpg6mU4S8MbGWLF92EBgvGYevYlSVRx/u/uBpToCYGLQGiqjgcKf5Zy4idF XT0w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=zkts1HOe; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49242-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49242-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCWg9phLZfJnD/7QZpIM3323q6K7NCozHLSYRxK17ydHNxAHObXGmAQF1KFFCkiv6fEndIOR2leqoIZbEkruStz0CAFryg== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id k9-20020a0cebc9000000b0068c507c1d46si1260686qvq.419.2024.02.01.22.16.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:16:55 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49242-ouuuleilei=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; dkim=pass header.i=@google.com header.s=20230601 header.b=zkts1HOe; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49242-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49242-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 564381C21AA9 for ; Fri, 2 Feb 2024 06:16:55 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 52C2F17C70; Fri, 2 Feb 2024 06:16:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="zkts1HOe" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 5504217549 for ; Fri, 2 Feb 2024 06:15:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854556; cv=none; b=mIZbSH9gcMad8fkRG4G59+BU4oXZgxnnZTA46aPJhpnEPUsaqcOmN3lwyTgbbxjWFFtjdLPKq0SwlYIIHLdeWCbr9kyZu0KeWdbU4fbIneV/qVBWzDIPHKnN6uDz3+Ju53DOp966bxuHBn2UJLUpp4ibFY2p3UF+sha4YCF4LJw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854556; c=relaxed/simple; bh=2j1qjZFTeJGHeOMFeX3LjyFdA0NCYp4OZGkvalboIXM=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=gbrGBWWLzgAdXcMZr3OSfYMF1ZaFs3AwvSXrY0TXwqJ0C1K5UuY4zJfYW7NIVYrcugH1hNZwV8bW7KoUiRK1bN8gVR0Pk3qGYeDkDWAsi8Dr93/5KIcQzZD1KzqOzenXCScjUYvOIzBcRoI/PubC7vZJGeFFkPTk2ivgB8l7514= 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=zkts1HOe; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6040aaa4e79so28874117b3.3 for ; Thu, 01 Feb 2024 22:15:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854553; x=1707459353; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=v+u9iEAq0iCqu7yfngDUriNlQosa5LnNT/PlXHwuCTs=; b=zkts1HOeRUJyXCo1yh1SbJNjcbiyEpnCiNMYmBZl8RkkwLmsErP1wLMNbUGpou5j5m GUs1F2T3Acs6HaDw+QNlh++8YlO/KHLPKp3gIr4hVtXLzcCO3M30IBgm3Aa2EfeNRpXe KtGdd2ls0PyMpmHDeo9SeXtfORL/H5CKUhZsfsTZIY1byXlzLGfZRVHcYXMWodV2K2LW plU7Ke0/hNFMiczV+xOvZ7tlcPhklnxcyRbhRBpuh9kNxAWP8CXSBogpoqI0Rrfay7yv C3NJI42//3Y39ChvAsAr15FBbM4p7WDX+zSVTvjUZT2eQMiil8e38e2OvZj3WjVkai3S Vv0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854553; x=1707459353; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=v+u9iEAq0iCqu7yfngDUriNlQosa5LnNT/PlXHwuCTs=; b=K65H7zVL995o1TFPpFFhpThCD8nh/NHrKCpP+PUt26J6avK4tm6T+dWks2r2tDo9Pp 1x09z8IamvLddL6K55DBVNWKh6dbMt/iEjlC+OMFqfxPSJRueuaBagyRjb2mVRCxffOA DgKc63V388gG/JyGxXI8xbGfN54hasnBNCBxkJ9iOMIYW1F85cAWQH2CcYv0ea7yN7I/ B68woNGXj9H1eIYqSo/Km6Zu6h2zD6Bb8z8jnuxo/3VfjoAvLbmqVrDjPAHtabXOtbOD 3tSSyFGzagKlFTihGLZjRlm6tfp4jcyHQkXGG+Xelqes4lkhq3Kom9wPBwclkASX3PE3 61UA== X-Gm-Message-State: AOJu0YzcsLQMFdCamLGbV7+vILWBzpOQVNjntnMi+ls7ZSj6+VTPx4MN qCGLXIAP667fMmF2IJN5gUNoPKintn8cV0+ELoa/VQTlrglpHDE+qQ4HIQIfLM/hHXNsMuPDJZd kxE+TFQ== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:260c:b0:dc2:3426:c9ee with SMTP id dw12-20020a056902260c00b00dc23426c9eemr67227ybb.11.1706854553371; Thu, 01 Feb 2024 22:15:53 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:10 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-4-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 03/25] perf maps: Get map before returning in maps__find_by_name From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766785438429420 X-GMAIL-MSGID: 1789766785438429420 Finding a map is done under a lock, returning the map without a reference count means it can be removed without notice and causing uses after free. Grab a reference count to the map within the lock region and return this. Fix up locations that need a map__put following this. Also fix some reference counted pointer comparisons. Signed-off-by: Ian Rogers --- tools/perf/tests/vmlinux-kallsyms.c | 5 +++-- tools/perf/util/machine.c | 6 ++++-- tools/perf/util/maps.c | 6 +++--- tools/perf/util/probe-event.c | 1 + tools/perf/util/symbol-elf.c | 4 +++- tools/perf/util/symbol.c | 18 +++++++++++------- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index e808e6fc8f76..fecbf851bb2e 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -131,9 +131,10 @@ static int test__vmlinux_matches_kallsyms_cb1(struct map *map, void *data) struct map *pair = maps__find_by_name(args->kallsyms.kmaps, (dso->kernel ? dso->short_name : dso->name)); - if (pair) + if (pair) { map__set_priv(pair, 1); - else { + map__put(pair); + } else { if (!args->header_printed) { pr_info("WARN: Maps only in vmlinux:\n"); args->header_printed = true; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index e8eb9f0b073f..7031f6fddcae 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1537,8 +1537,10 @@ static int maps__set_module_path(struct maps *maps, const char *path, struct kmo return 0; long_name = strdup(path); - if (long_name == NULL) + if (long_name == NULL) { + map__put(map); return -ENOMEM; + } dso = map__dso(map); dso__set_long_name(dso, long_name, true); @@ -1552,7 +1554,7 @@ static int maps__set_module_path(struct maps *maps, const char *path, struct kmo dso->symtab_type++; dso->comp = m->comp; } - + map__put(map); return 0; } diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 252a3b1f8f81..489072bebb5b 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -899,7 +899,7 @@ struct map *maps__find_by_name(struct maps *maps, const char *name) struct dso *dso = map__dso(maps__maps_by_name(maps)[i]); if (dso && strcmp(dso->short_name, name) == 0) { - result = maps__maps_by_name(maps)[i]; // TODO: map__get + result = map__get(maps__maps_by_name(maps)[i]); done = true; } } @@ -911,7 +911,7 @@ struct map *maps__find_by_name(struct maps *maps, const char *name) sizeof(*mapp), map__strcmp_name); if (mapp) { - result = *mapp; // TODO: map__get + result = map__get(*mapp); i = mapp - maps__maps_by_name(maps); RC_CHK_ACCESS(maps)->last_search_by_name_idx = i; } @@ -936,7 +936,7 @@ struct map *maps__find_by_name(struct maps *maps, const char *name) struct dso *dso = map__dso(pos); if (dso && strcmp(dso->short_name, name) == 0) { - result = pos; // TODO: map__get + result = map__get(pos); break; } } diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a1a796043691..be71abe8b9b0 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -358,6 +358,7 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) map = maps__find_by_name(machine__kernel_maps(host_machine), module_name); if (map) { dso = map__dso(map); + map__put(map); goto found; } pr_debug("Failed to find module %s.\n", module); diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 4b934ed3bfd1..5990e3fabdb5 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1470,8 +1470,10 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, dso__set_loaded(curr_dso); *curr_mapp = curr_map; *curr_dsop = curr_dso; - } else + } else { *curr_dsop = map__dso(curr_map); + map__put(curr_map); + } return 0; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 1710b89e207c..0785a54e832e 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -814,7 +814,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, struct map *initial_map) { struct machine *machine; - struct map *curr_map = initial_map; + struct map *curr_map = map__get(initial_map); struct symbol *pos; int count = 0, moved = 0; struct rb_root_cached *root = &dso->symbols; @@ -858,13 +858,14 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, dso__set_loaded(curr_map_dso); } + map__zput(curr_map); curr_map = maps__find_by_name(kmaps, module); if (curr_map == NULL) { pr_debug("%s/proc/{kallsyms,modules} " "inconsistency while looking " "for \"%s\" module!\n", machine->root_dir, module); - curr_map = initial_map; + curr_map = map__get(initial_map); goto discard_symbol; } curr_map_dso = map__dso(curr_map); @@ -888,7 +889,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, * symbols at this point. */ goto discard_symbol; - } else if (curr_map != initial_map) { + } else if (!RC_CHK_EQUAL(curr_map, initial_map)) { char dso_name[PATH_MAX]; struct dso *ndso; @@ -899,7 +900,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, } if (count == 0) { - curr_map = initial_map; + map__zput(curr_map); + curr_map = map__get(initial_map); goto add_symbol; } @@ -913,6 +915,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, kernel_range++); ndso = dso__new(dso_name); + map__zput(curr_map); if (ndso == NULL) return -1; @@ -926,6 +929,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, map__set_mapping_type(curr_map, MAPPING_TYPE__IDENTITY); if (maps__insert(kmaps, curr_map)) { + map__zput(curr_map); dso__put(ndso); return -1; } @@ -936,7 +940,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, pos->end -= delta; } add_symbol: - if (curr_map != initial_map) { + if (!RC_CHK_EQUAL(curr_map, initial_map)) { struct dso *curr_map_dso = map__dso(curr_map); rb_erase_cached(&pos->rb_node, root); @@ -951,12 +955,12 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, symbol__delete(pos); } - if (curr_map != initial_map && + if (!RC_CHK_EQUAL(curr_map, initial_map) && dso->kernel == DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(maps__machine(kmaps))) { dso__set_loaded(map__dso(curr_map)); } - + map__put(curr_map); return count + moved; } From patchwork Fri Feb 2 06:15:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195586 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp237735dyc; Thu, 1 Feb 2024 22:17:02 -0800 (PST) X-Google-Smtp-Source: AGHT+IHzZDnQZty6bWBoWai2ac94+TrcFxI/TexekJc7Si/urnCJvZHIvVbcL8dZiAef/B2HbRHv X-Received: by 2002:a05:6870:8a27:b0:219:177e:c98b with SMTP id p39-20020a0568708a2700b00219177ec98bmr1041610oaq.27.1706854622261; Thu, 01 Feb 2024 22:17:02 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854622; cv=pass; d=google.com; s=arc-20160816; b=M2XXZevvoIASYGqwuIjdRw0BrX4ZzVy8mEDuLF8JC7usBZL421kP2A6kSc0pBiMH0b 5pf/mCpsZYBLUY6s+b4DktyGvfu0oTW1mTD1AyhsRVJmd19SlQc2/323KoSiGLZ1d2s8 +5DlwJscdmp++OypctpkjznrboqesUAKcX+KXiYp+p6PwotikXaIXUU/74VvsCkx9oGO 0HuAst9gF16MeF1fCoglhWsBJd+xpLg/NVQOqN+9oqlxH/2txHOfBrCkFlNDSU+4Y5pB GYlYa+vtfyzSYH3Auet+nyr6TYsqAzTEAsF9d+gWN9orjAL4qZPYUz6KBInZf4CetpU0 KDVA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=J1NDzPJDQoypR+FtlykBmPEdE/4vIPaLTqPNnIbkP3o=; fh=WXZGoovQuGcsZ0DDqaxQRv8c2+/t3FwLaGwewWn3FsY=; b=oVPDkP0MdIGzcNqXQvboVfzEoIp+GPH70lGwdco7h9czAuTdAEYLdcCjC1BvqtF8p4 aPQ1gmvAl0t3Duq1toES6+IlAXHAvLXYS0hTK5AYiHzvJTsmRhnGUQbT7wdzdXtTtqks 0YpDhlMLD5feSInPdB0Kh8jUaYIHunJmq+yu1f4BCEd0F/5pf0DpXExTNUl9H13+tyZ0 nTradmSV8yi4hBdO3/JlG6KL1dNBM9CTlTfQEXUyBLsLJtreg0LKe9ay0HIf1jlRzvOu IPL1OFwwTouO4jfZxwbwQDuIgdmSzTXeAR9Z/wZ30lWI0b0QcAbhTiWhJczBWbIzZ/Nx +myg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=KoIRlQsK; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49243-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49243-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCXfUngW7IpvyMxO3cFm0dF/5Xs/XGra1Dc0BU76ypz8vcrAKogb5VcZnPziV/i3IL6toYS9aC3epFGr0JlUq6gnDqmsuw== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id v17-20020a63f851000000b005d8c0939d3fsi1027341pgj.902.2024.02.01.22.17.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:17:02 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49243-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=KoIRlQsK; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49243-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49243-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 078AA28D572 for ; Fri, 2 Feb 2024 06:17:02 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3869B1755E; Fri, 2 Feb 2024 06:16:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="KoIRlQsK" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.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 8BE6A1774A for ; Fri, 2 Feb 2024 06:15:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854558; cv=none; b=FPKN5D51Iu5gX7qoe3R9Rs9dYJfw/k+vvElyU3VS+jfhJyyil9/wu8k860r12AKxLN03aDsFqcDXQ54awgBxPrCjGm6mZuj3jC1tFpsVGxYHcjPYK6a8pm3RMypHEt37z8/qgutQba+9p31J6uKYC+neVvlYVQz9Ncl5dHXccRI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854558; c=relaxed/simple; bh=DaB8vTdXvQNZKpQ3zmCJbz1kO9aEvxkRfoyVK91CF/8=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=Nb+LC4y33YBd8F+s7IuydGIGmbIwi5Iqv7JP+q1IzIZMED6j4YRHQec5Ayp94mrRKDVQ4kjIms4Nqw0H4GvUzKM5pFI9zauOmZOeL8+s7VHdTrMlW6wcUDvcRdFXPhBGfPIxV+mn83699xReVx2nhY/6h8kJ9mT6DELeA4B7DAU= 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=KoIRlQsK; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc6c2643a07so3113978276.3 for ; Thu, 01 Feb 2024 22:15:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854555; x=1707459355; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=J1NDzPJDQoypR+FtlykBmPEdE/4vIPaLTqPNnIbkP3o=; b=KoIRlQsKE20SUL48lWyZvfQmqDsCbSlEExODvgMfICbWuHk4PjCORHQecoj3iv8baa l0PxQihrApQi8ZY4jJ8glRfBnTwE1oRdBp4JshMO+mqxvUij2RdFnY5wNOh0mcg95Fje Eza60cebkrHbcIDkOnleMalvGl1aUTsYi0/FNb/s7fV7C2baAP1wFZy+VZJeuL9t+Sbo JCacnOfh3CQIN8AaL9Jr1dERw+sE4g+xWR23qb+e1pHZvqNt5Y1Djz07mF3EQFUkkVl+ sFH025fVuUcVtCdVhIyknPFz+CKJXAbOH25aRSFoKcHTqBt/Jj41h5GEzBhKMAebUige JNAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854555; x=1707459355; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=J1NDzPJDQoypR+FtlykBmPEdE/4vIPaLTqPNnIbkP3o=; b=RBOCv1WL7L9uZCdQYN4VfvV1vnVb0Fga5UwQLhE3WWPtaoQDDEIe7wyjBBhEV4V6KB uwAk5asJGNKVGf99weLTREgV30Lg+XDX3qLrEPsZ3H7kJwxcjJHgYeVblEPoKlNejhmK VaNhdn2eBHd4PxJbVWoN6OHkukWv+ENoFOm5clIYIFAii6lAFLw3CtkdTIXNJZdq9A/P t3dVLKzzXwSQR7LCgqo+lFOEpoVLls9PArpJrifgjjoV0OudDKhE6ktMkfuSUNZKThw5 zgUqia/eFI5u1mC4uwCBfjH8MmBz8PkGCPZJBaR7Xc/nrnfZcBHt/Uu+NjPss1fjBd9q c05g== X-Gm-Message-State: AOJu0YwKQrCnXKeDBFqS3ND0W3aKN0bKNYMMf728c8/1kpGdLli3jMur hm4G5TQZhZNNTorqOntq/1g6AY6PEaq2ABidjDh21JS/Q9JbUf5LJApu5QQzkF6Z2qPAzCC9FUv lmxuMHg== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:f0a:b0:dc6:d3c0:ebe0 with SMTP id et10-20020a0569020f0a00b00dc6d3c0ebe0mr1158215ybb.0.1706854555663; Thu, 01 Feb 2024 22:15:55 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:11 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-5-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 04/25] perf maps: Get map before returning in maps__find_next_entry From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766792817544989 X-GMAIL-MSGID: 1789766792817544989 Finding a map is done under a lock, returning the map without a reference count means it can be removed without notice and causing uses after free. Grab a reference count to the map within the lock region and return this. Fix up locations that need a map__put following this. Signed-off-by: Ian Rogers --- tools/perf/util/machine.c | 4 +++- tools/perf/util/maps.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 7031f6fddcae..4911734411b5 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1761,8 +1761,10 @@ int machine__create_kernel_maps(struct machine *machine) struct map *next = maps__find_next_entry(machine__kernel_maps(machine), machine__kernel_map(machine)); - if (next) + if (next) { machine__set_kernel_mmap(machine, start, map__start(next)); + map__put(next); + } } out_put: diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 489072bebb5b..75e85c0e04bc 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -956,7 +956,7 @@ struct map *maps__find_next_entry(struct maps *maps, struct map *map) down_read(maps__lock(maps)); i = maps__by_address_index(maps, map); if (i < maps__nr_maps(maps)) - result = maps__maps_by_address(maps)[i]; // TODO: map__get + result = map__get(maps__maps_by_address(maps)[i]); up_read(maps__lock(maps)); return result; From patchwork Fri Feb 2 06:15:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195587 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp237953dyc; Thu, 1 Feb 2024 22:17:38 -0800 (PST) X-Google-Smtp-Source: AGHT+IF1lkArosFUeL4eKI3dzL5KRTgx8mfQYdkpH9Fzj3sK0d0vgm+4Sn+gU7favcAXl/KtLK4U X-Received: by 2002:ad4:4390:0:b0:68c:4058:7383 with SMTP id s16-20020ad44390000000b0068c40587383mr2172863qvr.5.1706854658657; Thu, 01 Feb 2024 22:17:38 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854658; cv=pass; d=google.com; s=arc-20160816; b=MNBpby0zoZkzg+A1An2/hMubHfVS/GsE3pg0ayjyL9DVXYxPxV4M3E7y+Gg2BvyHUK jCrXwjr5+wB2OOn24MeIWpvZzUx6fnnmc1dqxYnmPQsHaJhLTMMgjwmPOGkvg7Pdr9yv GbpdLuHHcU5AIi8UMEHwpfBy18ve5gX3j0JAva+9KthygTyVmFSb83pRipI38Ub6O127 7tS/S1MZrudO43xTww4bHYpLaa28eRldwIOPILuXrGFC8M3ff1k34BEKXIjGUdW4hgpC T6VcbxVJzRSbmmdn5+GY4Ow34tTJAR4VifpV1ijS3L91i4ie92p4wKST9AJx2N02qk/f HKaA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=7amT2XNnuFH4XehBpDI+JYPmF5G9UAykcEoNfxCnIz8=; fh=4gMlUFhMSF0Cxv3+vdX8BybxaRgEEoLC8flibRrKHlI=; b=AL9rpCaS1amwGNcq/IoAvj6gg7SGTbD6RdjYYPPka09PukX5I+YXLEcXqPnHB3J5Rn 9IFOzuvvuazX1pwdRqZ2+e3hELyatjGFRHv6EnRwVR+YPZiiCm5c2ZA0exz9rjySTiJR E1a47BRgFe9SofPEhygK80QL5A5q8AzurMbrwVOjcNBiPbU8srkV/frhvnpMY1o8HSXg ze1wwET/2Nq1YhKoyC+liquHuzgWy5izwVxmhsyIxX9h+AAZIYcFTAdEch1ES8ymFNxy jNBQkFMlKCCAtBFN7DIwzjt50PQ5kwGNjGEMwOQ442bpOuvephH3MJRluTxVwR5wj62w MDpg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=D6ipLicD; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49244-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49244-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCU6/bt1W+5kcyGaezhFwojQBkiNTOkWcbvCHqM6jYHp9Hf68ywEGmWRC964vpHfPzkbNvP8gpGzMb/vVcg0go12B1zB8w== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id t18-20020a05621405d200b00688883e7b6dsi1330188qvz.436.2024.02.01.22.17.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:17:38 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49244-ouuuleilei=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; dkim=pass header.i=@google.com header.s=20230601 header.b=D6ipLicD; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49244-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49244-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 63AF51C21874 for ; Fri, 2 Feb 2024 06:17:38 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 749FD1862F; Fri, 2 Feb 2024 06:16:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="D6ipLicD" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 CEFDD17BB2 for ; Fri, 2 Feb 2024 06:15:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854560; cv=none; b=epWm7dnyj/w8CocFkwF7ogjMX9LX+DnMvLy8mgK3SRcrKph/zyOqHcpulgeV0W2e7S0UGGv2gTuyme4UDbWO+7xBPUGaOYMnfvbe1hi6OE4nhU9M52rrEPFHhPUPaj3ar1wR3Ewuqmr6tiF6itvzvGianBnqYpfM/VPHfGdyGNA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854560; c=relaxed/simple; bh=9njMxvYtK5Kc82xrNh5zRgQJtlXBSYtihaT2tlm73O8=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=CFwGh3iV9dpUwLOt8OSxn7y75qku6wl62bE1682aYWouCz3e9a5fAXJ6emLdBqa1E/+oJ+9v52GmCf5IchtwrEMxSwmIg9Vwh3MS/OmqnUU4c5MlKkA1qEJoi3QZlbMV4ijMsQ3IVHGCoHd2YmE1BH8AE7yvY8F8/mybVj6Dvjs= 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=D6ipLicD; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-5efe82b835fso35157237b3.0 for ; Thu, 01 Feb 2024 22:15:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854558; x=1707459358; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=7amT2XNnuFH4XehBpDI+JYPmF5G9UAykcEoNfxCnIz8=; b=D6ipLicDghE7Fa9L5l2GWK2NYk3qTgQw27tX+8cSmiImXYYNphArIHepai6OXuRJLJ V4qAv1pQB2pz9rjh3fMQKfeWAmjgacP3wPNvvVfjGtmv+UD2bZ0ANm8M4yesbHOtrKUr Sl9uKkWjSc8OMkqJUY73ugyBBVxE5mR4vtbFUYuJQzJrdK85lZOeLAB0hO1LcxdDJtQn MyMLIPLRECruM729KibrQGNDmHJ7vXEhOknGP8D0YUNYNO+nRQC7CkV5gtZWQCf2zBOr EbUgrYgyzziL65MlwWy11QrGvzwi8V9oPw61mTNbZZ3raoHQ+qCp0eXl5YR03cchUitr WGkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854558; x=1707459358; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7amT2XNnuFH4XehBpDI+JYPmF5G9UAykcEoNfxCnIz8=; b=kdq6gjkFDIQvuxZ4ExvNi94QeLE7JfY5n0ivddlSXK4thqYmx7guPpCfOfDeYuo+hf G8Mhv3lVy6q2vXQESJMZk+1jXPrUlsjorKtVM1YD1c9Klnp53qET9tGtKi4p2HUpiRPF Rf8V/lnKXOZWV1f7Pu+8BxFOn+H2Mb8o2YiL5pSRtc/OhdSJiSbNOZTNs0J7L5xdcd0W ozjj5NV4wFOsB2nOyf2BOZUk17wLIIsdDP3Mk7YNDkYazPVSXMToy9ZMOTX4L3R9OMah +SA1dGnPyrcV1dTRQOWFSlnQcESIOgW2DZd6vaN3L6LsnnJQFDFMooH5sTUxCxVrQRF5 FwEw== X-Gm-Message-State: AOJu0Yw5SMSt/EXXz1LEwneWkc/Lfjcrw06c8ZB8bodoyPOG+wORaPqa M2JGEnabzoAw6uxkcUCP2bjssXfkiG2FD4t+Ue83Bc1AFrSS0JPjk54J3uqtSdxURBitGydG7X/ M8FaUPQ== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a81:9b53:0:b0:5d3:40f3:56bf with SMTP id s80-20020a819b53000000b005d340f356bfmr1524171ywg.1.1706854558039; Thu, 01 Feb 2024 22:15:58 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:12 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-6-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 05/25] perf maps: Hide maps internals From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766830709637184 X-GMAIL-MSGID: 1789766830709637184 Move the struct into the C file. Add maps__equal to work around exposing the struct for reference count checking. Add accessors for the unwind_libunwind_ops. Move maps_list_node to its only use in symbol.c. Signed-off-by: Ian Rogers --- tools/perf/tests/thread-maps-share.c | 8 +- tools/perf/util/callchain.c | 2 +- tools/perf/util/maps.c | 96 +++++++++++++++++++++++ tools/perf/util/maps.h | 97 +++--------------------- tools/perf/util/symbol.c | 10 +++ tools/perf/util/thread.c | 2 +- tools/perf/util/unwind-libunwind-local.c | 2 +- tools/perf/util/unwind-libunwind.c | 7 +- 8 files changed, 123 insertions(+), 101 deletions(-) diff --git a/tools/perf/tests/thread-maps-share.c b/tools/perf/tests/thread-maps-share.c index 7fa6f7c568e2..e9ecd30a5c05 100644 --- a/tools/perf/tests/thread-maps-share.c +++ b/tools/perf/tests/thread-maps-share.c @@ -46,9 +46,9 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 4); /* test the maps pointer is shared */ - TEST_ASSERT_VAL("maps don't match", RC_CHK_EQUAL(maps, thread__maps(t1))); - TEST_ASSERT_VAL("maps don't match", RC_CHK_EQUAL(maps, thread__maps(t2))); - TEST_ASSERT_VAL("maps don't match", RC_CHK_EQUAL(maps, thread__maps(t3))); + TEST_ASSERT_VAL("maps don't match", maps__equal(maps, thread__maps(t1))); + TEST_ASSERT_VAL("maps don't match", maps__equal(maps, thread__maps(t2))); + TEST_ASSERT_VAL("maps don't match", maps__equal(maps, thread__maps(t3))); /* * Verify the other leader was created by previous call. @@ -73,7 +73,7 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s other_maps = thread__maps(other); TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(other_maps)), 2); - TEST_ASSERT_VAL("maps don't match", RC_CHK_EQUAL(other_maps, thread__maps(other_leader))); + TEST_ASSERT_VAL("maps don't match", maps__equal(other_maps, thread__maps(other_leader))); /* release thread group */ thread__put(t3); diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 8262f69118db..7517d16c02ec 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1157,7 +1157,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node * if (al->map == NULL) goto out; } - if (RC_CHK_EQUAL(al->maps, machine__kernel_maps(machine))) { + if (maps__equal(al->maps, machine__kernel_maps(machine))) { if (machine__is_host(machine)) { al->cpumode = PERF_RECORD_MISC_KERNEL; al->level = 'k'; diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 75e85c0e04bc..c3d91e5e9cae 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -6,9 +6,63 @@ #include "dso.h" #include "map.h" #include "maps.h" +#include "rwsem.h" #include "thread.h" #include "ui/ui.h" #include "unwind.h" +#include + +/* + * Locking/sorting note: + * + * Sorting is done with the write lock, iteration and binary searching happens + * under the read lock requiring being sorted. There is a race between sorting + * releasing the write lock and acquiring the read lock for iteration/searching + * where another thread could insert and break the sorting of the maps. In + * practice inserting maps should be rare meaning that the race shouldn't lead + * to live lock. Removal of maps doesn't break being sorted. + */ + +DECLARE_RC_STRUCT(maps) { + struct rw_semaphore lock; + /** + * @maps_by_address: array of maps sorted by their starting address if + * maps_by_address_sorted is true. + */ + struct map **maps_by_address; + /** + * @maps_by_name: optional array of maps sorted by their dso name if + * maps_by_name_sorted is true. + */ + struct map **maps_by_name; + struct machine *machine; +#ifdef HAVE_LIBUNWIND_SUPPORT + void *addr_space; + const struct unwind_libunwind_ops *unwind_libunwind_ops; +#endif + refcount_t refcnt; + /** + * @nr_maps: number of maps_by_address, and possibly maps_by_name, + * entries that contain maps. + */ + unsigned int nr_maps; + /** + * @nr_maps_allocated: number of entries in maps_by_address and possibly + * maps_by_name. + */ + unsigned int nr_maps_allocated; + /** + * @last_search_by_name_idx: cache of last found by name entry's index + * as frequent searches for the same dso name are common. + */ + unsigned int last_search_by_name_idx; + /** @maps_by_address_sorted: is maps_by_address sorted. */ + bool maps_by_address_sorted; + /** @maps_by_name_sorted: is maps_by_name sorted. */ + bool maps_by_name_sorted; + /** @ends_broken: does the map contain a map where end values are unset/unsorted? */ + bool ends_broken; +}; static void check_invariants(const struct maps *maps __maybe_unused) { @@ -118,6 +172,43 @@ static void maps__set_maps_by_name_sorted(struct maps *maps, bool value) RC_CHK_ACCESS(maps)->maps_by_name_sorted = value; } +struct machine *maps__machine(const struct maps *maps) +{ + return RC_CHK_ACCESS(maps)->machine; +} + +unsigned int maps__nr_maps(const struct maps *maps) +{ + return RC_CHK_ACCESS(maps)->nr_maps; +} + +refcount_t *maps__refcnt(struct maps *maps) +{ + return &RC_CHK_ACCESS(maps)->refcnt; +} + +#ifdef HAVE_LIBUNWIND_SUPPORT +void *maps__addr_space(const struct maps *maps) +{ + return RC_CHK_ACCESS(maps)->addr_space; +} + +void maps__set_addr_space(struct maps *maps, void *addr_space) +{ + RC_CHK_ACCESS(maps)->addr_space = addr_space; +} + +const struct unwind_libunwind_ops *maps__unwind_libunwind_ops(const struct maps *maps) +{ + return RC_CHK_ACCESS(maps)->unwind_libunwind_ops; +} + +void maps__set_unwind_libunwind_ops(struct maps *maps, const struct unwind_libunwind_ops *ops) +{ + RC_CHK_ACCESS(maps)->unwind_libunwind_ops = ops; +} +#endif + static struct rw_semaphore *maps__lock(struct maps *maps) { /* @@ -453,6 +544,11 @@ bool maps__empty(struct maps *maps) return maps__nr_maps(maps) == 0; } +bool maps__equal(struct maps *a, struct maps *b) +{ + return RC_CHK_EQUAL(a, b); +} + int maps__for_each_map(struct maps *maps, int (*cb)(struct map *map, void *data), void *data) { bool done = false; diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index df9dd5a0e3c0..4bcba136ffe5 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -3,80 +3,15 @@ #define __PERF_MAPS_H #include -#include #include #include #include -#include "rwsem.h" -#include struct ref_reloc_sym; struct machine; struct map; struct maps; -struct map_list_node { - struct list_head node; - struct map *map; -}; - -static inline struct map_list_node *map_list_node__new(void) -{ - return malloc(sizeof(struct map_list_node)); -} - -/* - * Locking/sorting note: - * - * Sorting is done with the write lock, iteration and binary searching happens - * under the read lock requiring being sorted. There is a race between sorting - * releasing the write lock and acquiring the read lock for iteration/searching - * where another thread could insert and break the sorting of the maps. In - * practice inserting maps should be rare meaning that the race shouldn't lead - * to live lock. Removal of maps doesn't break being sorted. - */ - -DECLARE_RC_STRUCT(maps) { - struct rw_semaphore lock; - /** - * @maps_by_address: array of maps sorted by their starting address if - * maps_by_address_sorted is true. - */ - struct map **maps_by_address; - /** - * @maps_by_name: optional array of maps sorted by their dso name if - * maps_by_name_sorted is true. - */ - struct map **maps_by_name; - struct machine *machine; -#ifdef HAVE_LIBUNWIND_SUPPORT - void *addr_space; - const struct unwind_libunwind_ops *unwind_libunwind_ops; -#endif - refcount_t refcnt; - /** - * @nr_maps: number of maps_by_address, and possibly maps_by_name, - * entries that contain maps. - */ - unsigned int nr_maps; - /** - * @nr_maps_allocated: number of entries in maps_by_address and possibly - * maps_by_name. - */ - unsigned int nr_maps_allocated; - /** - * @last_search_by_name_idx: cache of last found by name entry's index - * as frequent searches for the same dso name are common. - */ - unsigned int last_search_by_name_idx; - /** @maps_by_address_sorted: is maps_by_address sorted. */ - bool maps_by_address_sorted; - /** @maps_by_name_sorted: is maps_by_name sorted. */ - bool maps_by_name_sorted; - /** @ends_broken: does the map contain a map where end values are unset/unsorted? */ - bool ends_broken; -}; - #define KMAP_NAME_LEN 256 struct kmap { @@ -100,36 +35,22 @@ static inline void __maps__zput(struct maps **map) #define maps__zput(map) __maps__zput(&map) +bool maps__equal(struct maps *a, struct maps *b); + /* Iterate over map calling cb for each entry. */ int maps__for_each_map(struct maps *maps, int (*cb)(struct map *map, void *data), void *data); /* Iterate over map removing an entry if cb returns true. */ void maps__remove_maps(struct maps *maps, bool (*cb)(struct map *map, void *data), void *data); -static inline struct machine *maps__machine(struct maps *maps) -{ - return RC_CHK_ACCESS(maps)->machine; -} - -static inline unsigned int maps__nr_maps(const struct maps *maps) -{ - return RC_CHK_ACCESS(maps)->nr_maps; -} - -static inline refcount_t *maps__refcnt(struct maps *maps) -{ - return &RC_CHK_ACCESS(maps)->refcnt; -} +struct machine *maps__machine(const struct maps *maps); +unsigned int maps__nr_maps(const struct maps *maps); +refcount_t *maps__refcnt(struct maps *maps); #ifdef HAVE_LIBUNWIND_SUPPORT -static inline void *maps__addr_space(struct maps *maps) -{ - return RC_CHK_ACCESS(maps)->addr_space; -} - -static inline const struct unwind_libunwind_ops *maps__unwind_libunwind_ops(const struct maps *maps) -{ - return RC_CHK_ACCESS(maps)->unwind_libunwind_ops; -} +void *maps__addr_space(const struct maps *maps); +void maps__set_addr_space(struct maps *maps, void *addr_space); +const struct unwind_libunwind_ops *maps__unwind_libunwind_ops(const struct maps *maps); +void maps__set_unwind_libunwind_ops(struct maps *maps, const struct unwind_libunwind_ops *ops); #endif size_t maps__fprintf(struct maps *maps, FILE *fp); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 0785a54e832e..35975189999b 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -63,6 +63,16 @@ struct symbol_conf symbol_conf = { .res_sample = 0, }; +struct map_list_node { + struct list_head node; + struct map *map; +}; + +static struct map_list_node *map_list_node__new(void) +{ + return malloc(sizeof(struct map_list_node)); +} + static enum dso_binary_type binary_type_symtab[] = { DSO_BINARY_TYPE__KALLSYMS, DSO_BINARY_TYPE__GUEST_KALLSYMS, diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 89c47a5098e2..c59ab4d79163 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -383,7 +383,7 @@ static int thread__clone_maps(struct thread *thread, struct thread *parent, bool if (thread__pid(thread) == thread__pid(parent)) return thread__prepare_access(thread); - if (RC_CHK_EQUAL(thread__maps(thread), thread__maps(parent))) { + if (maps__equal(thread__maps(thread), thread__maps(parent))) { pr_debug("broken map groups on thread %d/%d parent %d/%d\n", thread__pid(thread), thread__tid(thread), thread__pid(parent), thread__tid(parent)); diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index dac536e28360..6a5ac0faa6f4 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -706,7 +706,7 @@ static int _unwind__prepare_access(struct maps *maps) { void *addr_space = unw_create_addr_space(&accessors, 0); - RC_CHK_ACCESS(maps)->addr_space = addr_space; + maps__set_addr_space(maps, addr_space); if (!addr_space) { pr_err("unwind: Can't create unwind address space.\n"); return -ENOMEM; diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 76cd63de80a8..2728eb4f13ea 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -12,11 +12,6 @@ struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops; struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops; struct unwind_libunwind_ops __weak *arm64_unwind_libunwind_ops; -static void unwind__register_ops(struct maps *maps, struct unwind_libunwind_ops *ops) -{ - RC_CHK_ACCESS(maps)->unwind_libunwind_ops = ops; -} - int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized) { const char *arch; @@ -60,7 +55,7 @@ int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized return 0; } out_register: - unwind__register_ops(maps, ops); + maps__set_unwind_libunwind_ops(maps, ops); err = maps__unwind_libunwind_ops(maps)->prepare_access(maps); if (initialized) From patchwork Fri Feb 2 06:15:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195590 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp238273dyc; Thu, 1 Feb 2024 22:18:31 -0800 (PST) X-Google-Smtp-Source: AGHT+IG0hUdo+DtdbLABZLI3E1AFjSZnZ/kxLGxBwJKyvQFP6MnJCbYr+NKxqAbahhSWjAp5nxDp X-Received: by 2002:a17:903:26d5:b0:1d9:4643:65b6 with SMTP id jg21-20020a17090326d500b001d9464365b6mr4610911plb.1.1706854710990; Thu, 01 Feb 2024 22:18:30 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854710; cv=pass; d=google.com; s=arc-20160816; b=NzAG3zD84zEbpbXSByjkjZvq/odOSQVRjYPd8Q1FeDMGQ7WLy8pm0NDvphMPFtaopH XvJ1Hfj12Mp6Vdps5GXjiflP+zPR1/Dm0Xi+ghcrmHEXlljqmKjdnLZcFWnpTCPeFnzJ A7BvvsBcBdnBm3N8z4/Wey3DZwz+nLx+tQGP06Cw9a6y+5yhethgMUB7oCzJXAUtyuZc ggjTSjohPnXXDP8F0vjptWeT97HUp76pMMyCagcZ0VjfT+deUG0Evs/3TSAFufea3AW0 6rvINlAuQ+MVJkNlF5OY0ItqT8oQ4KBIhngbS64V2HMvcv0ucQeHIisMwGP+eP+UkFlT JpUw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=GtgvpFVCeAxfBLC1ay05GLymu1fr0pRRLiLlSBt0YmA=; fh=Z5uDtJ7TF8lLsPqyJwjdCUqFuoldmpyTG5yAYwTTu4w=; b=hSnOy2ZCG6Bf0czjpCOwGOKUojpoLp+mbsBBHFDAJdnA45puOFBrn1haIipKeivawS SDC2See/oTeujlRmOLEbDn83A62AwxcfuFDEflICu+bkKkSd59Q78WsvWN0mfFBq477I fcTbJDzudPHvQyb6ZTTmSDkFREXAW3Rm8TIHKm72w8OVcxiEGrVIsNHQxcbvBDnKmp2w RoYUZBwqX2wHMAKo/NQnM4A5k8CGIN4mb7b9aSPGtGmLrBHvrTXOncJdNyfrKSYkwCjp qYNSANT8O6iU7aRNfBhmGKDIqc7QVqMuEomSa4WMvj3Bn7WmEVDTljKtCOD+L/h15hDt OJcg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=SmQziLbY; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49245-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49245-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCV1d/lFdTpyMbedgl7L6iCVLsXzUSBbQvwP3NEZ0r5QgzyluV0UlAzy4P4nMQEU98OlvovsdAOYXm6ZfknevrPsrCusQg== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id d6-20020a170903230600b001d70fef0d09si1257368plh.52.2024.02.01.22.18.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:18:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49245-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=SmQziLbY; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49245-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49245-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 sv.mirrors.kernel.org (Postfix) with ESMTPS id E43DA284ADE for ; Fri, 2 Feb 2024 06:17:33 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0335E18627; Fri, 2 Feb 2024 06:16:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="SmQziLbY" Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.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 380C81755A for ; Fri, 2 Feb 2024 06:16:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854562; cv=none; b=kRyxsgiaxfXyPkKrHBLzHj+y6WieYDA2lROi4vTcUToVH/rqBCWOn54G0tZPTmxBzTbfT+EoQbkcrbm+4JB4lIsnADCbT36JbakFe9cTHiIPgcDNnQG8+cQPZwGe7kfjkqvWEbEr0JOmAdWIB1DOpWVciHUfiN3nul7Y9DJwEhg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854562; c=relaxed/simple; bh=8s9pvXR/dJ4oS1alnHLZ3B/RdRusn7pUE+bkSp22vOk=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=YwNtFzcR5EJgmUcIyEV6thWf4iz4ku7yiLHZ9o5t/cxAXBk4YW33cfWDtoytrwV1Dxi5zQk1VVu8PsiK57iXX3hjdrxLO+mimKuVxktNQODVvMVz+todphWRNHzy5krHuIisjO3jxz9+ze/yw06lCuoViOO52+2/M9sHxed15xU= 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=SmQziLbY; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dc6ade10cb8so1005120276.0 for ; Thu, 01 Feb 2024 22:16:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854560; x=1707459360; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=GtgvpFVCeAxfBLC1ay05GLymu1fr0pRRLiLlSBt0YmA=; b=SmQziLbYIXp3B16LvdMb/KufFnTDnU6wkgdxeaYTnlSpdH1hXEVaHzerxvqGhYspyV oo4stUf8s+SqXnRBKacAzX11GwcHYNHdO76K6Je+MjHEyJNFjs5c7fPn8a1mcmCsWSwK bobU5hnJuERN8LNTVMR0wwbZrUVQBeHSSh7ZR7qcwqB/9PBjNwwYGg8HRXYQmQBH1YT1 gSDxU8AxtkQF7mqzu18HyDfspkMsXrpCy2FiMzCmpozpqrC1gkOHgnyOuUp69jjLoqab 2QugJrXocAPCdctGM1RPcDPBz9C24N8R1AEnPGQVVjgvGu9J7hw4pvUMKQWo/jdw6B7G o/3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854560; x=1707459360; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=GtgvpFVCeAxfBLC1ay05GLymu1fr0pRRLiLlSBt0YmA=; b=aqer77izX3NdPQ/+iedy26nBhCxkbIzftNoPkN5rcUDUHHV/xr7CQFfbnE7h3ASF5A KqAVuI16bkPhJTFIXviajNM+vKowet7zwfLQgFvwMEJlbX6f9kqfVlIFf81KInW2xqK/ Z3u9NhtQASxOJZhIhZ23OreOz9ofPeN7kK0aOu4CRRGIxLlxJrg94Pz0wYPMl9SncsP0 H3WNFEid7p61Ep6jF1U5LUMcwBy3Zafs13yg/5n/rNhEEfW3s3nBaI/qNs5Fx6yFwdkq 32gwv5dZAvyFO5AYNOwh6mWbsz7Yqwj5/n5zRM0XRoOcgR26P2B34d3/Qh4154fdZIW7 P0Dg== X-Gm-Message-State: AOJu0Ywn83lFTkvz19hfTvSN5fUxukiTzXheKx/sjOaDCefbjLBKRiAW KZ/+CCyURldaOkFl4NrVjmBTrmt33o9vebZfZpecFYEQpi4+UKEI5QTBbuwUlpvB0b+2GHoiHpN M/9+0bQ== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a25:b28c:0:b0:dc6:ddb9:14ad with SMTP id k12-20020a25b28c000000b00dc6ddb914admr242339ybj.0.1706854560075; Thu, 01 Feb 2024 22:16:00 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:13 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-7-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 06/25] perf maps: Locking tidy up of nr_maps From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766885737958820 X-GMAIL-MSGID: 1789766885737958820 After this change maps__nr_maps is only used by tests, existing users are migrated to maps__empty. Compute maps__empty under the read lock. Signed-off-by: Ian Rogers --- tools/perf/util/machine.c | 2 +- tools/perf/util/maps.c | 10 ++++++++-- tools/perf/util/maps.h | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 4911734411b5..3da92f18814a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -440,7 +440,7 @@ static struct thread *findnew_guest_code(struct machine *machine, return NULL; /* Assume maps are set up if there are any */ - if (maps__nr_maps(thread__maps(thread))) + if (!maps__empty(thread__maps(thread))) return thread; host_thread = machine__find_thread(host_machine, -1, pid); diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index c3d91e5e9cae..d5db1f284dad 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -541,7 +541,13 @@ void maps__remove(struct maps *maps, struct map *map) bool maps__empty(struct maps *maps) { - return maps__nr_maps(maps) == 0; + bool res; + + down_read(maps__lock(maps)); + res = maps__nr_maps(maps) == 0; + up_read(maps__lock(maps)); + + return res; } bool maps__equal(struct maps *a, struct maps *b) @@ -865,7 +871,7 @@ int maps__copy_from(struct maps *dest, struct maps *parent) parent_maps_by_address = maps__maps_by_address(parent); n = maps__nr_maps(parent); - if (maps__empty(dest)) { + if (maps__nr_maps(dest) == 0) { /* No existing mappings so just copy from parent to avoid reallocs in insert. */ unsigned int nr_maps_allocated = RC_CHK_ACCESS(parent)->nr_maps_allocated; struct map **dest_maps_by_address = diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index 4bcba136ffe5..d9aa62ed968a 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -43,8 +43,8 @@ int maps__for_each_map(struct maps *maps, int (*cb)(struct map *map, void *data) void maps__remove_maps(struct maps *maps, bool (*cb)(struct map *map, void *data), void *data); struct machine *maps__machine(const struct maps *maps); -unsigned int maps__nr_maps(const struct maps *maps); -refcount_t *maps__refcnt(struct maps *maps); +unsigned int maps__nr_maps(const struct maps *maps); /* Test only. */ +refcount_t *maps__refcnt(struct maps *maps); /* Test only. */ #ifdef HAVE_LIBUNWIND_SUPPORT void *maps__addr_space(const struct maps *maps); From patchwork Fri Feb 2 06:15:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195588 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp238139dyc; Thu, 1 Feb 2024 22:18:07 -0800 (PST) X-Google-Smtp-Source: AGHT+IGaH8YRkiKCOwpVErUfK4uJOk2z29mp6IQMF9AzlVqVF8LG1Z9sjmAVL4RDJDtmJkXo+tyT X-Received: by 2002:a25:4d86:0:b0:dbd:b081:9663 with SMTP id a128-20020a254d86000000b00dbdb0819663mr3987704ybb.41.1706854687683; Thu, 01 Feb 2024 22:18:07 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854687; cv=pass; d=google.com; s=arc-20160816; b=qdnShk2GEtpt+4HIspwOs8azxwNXjvGKL2WXlmuHZkjj/HD7hrSnZdQFLaWWuFt7Bd 90gWLjdOyi4ojKXahComIuYe6tawORqKe3bDai5O86R2PEnntV69t5ay0qKLnNs1/DcO FVbn3GvBsUbVr4NjajbwUYwQ/S5q0UhwAE3i+mBCbWesBdUqV2Sbj7sMEcWIi8vq8Pjx 0pM8dhb8/ZUWS3GnFQGv0dyMGndK3nmMZRep5DaEk+NXnZBReTNYIFRDGTPOU3oCO2yh SKGlBffi7OrX2NDaCVTIfvVpms4VA8dstqJV5GNdgWL56hPpfoUu9y2U3/gniYsPituR 0KFw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=LraddYkgLopGo/nY223hQ1nvCnHwVQlgNAwJab4EqVs=; fh=tf8/6fR3mUax22U1VTDKUKn7BZDG7B7+NDzvexAAABg=; b=Shj7BYJisM/mOTtcJulqKWpkCVAvBG9xkM6GNkKh8X0fWNq1DUcJjp9wjJHjMbmfKc euCWAXElhdHOjDA+BlY3TLMifICiD2ZgqWlPqNs0uW40JQ2UufcGTQjmDVS0G5qCm1gj HLHhWjFcnwriCWk/A1Vm+Y6ZSiZPccASZUlsDZas1TWAiNgbBV/E0Pa37KtiAPjowBMS R9WeTnsj1Ys6cOlc8l4bx011/SWlBNN4j65upyGwmRKs+nq3kMXNdsZtAfG6rzJuQ66H AJ8OwSP1IWQTvqOL/8p18Pe+2WG6ukDKtVcKcBy3D760bvvUJ83FhP87b24nYdhypoPG Yq1w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=dv2Ugu5P; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49246-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49246-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCWCa5FrN2gUGyTRFvIImOOPHfUyNwWcbNqmJ0VlcHJioZGQ2K/h2vBt/FHVqboarLIyblnB+Qa6EstC/uLbs+kfRJoHZQ== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id t5-20020ac85885000000b0042a2ddc3e33si1281937qta.190.2024.02.01.22.18.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:18:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49246-ouuuleilei=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; dkim=pass header.i=@google.com header.s=20230601 header.b=dv2Ugu5P; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49246-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49246-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 69F931C22F64 for ; Fri, 2 Feb 2024 06:18:07 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C064A18E0E; Fri, 2 Feb 2024 06:16:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dv2Ugu5P" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.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 A77401804A for ; Fri, 2 Feb 2024 06:16:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854565; cv=none; b=gezea+x/1MZ/IhisqVgy34mzqDQrVcyA8SyVVy3ZFgBsEMZJBvYu44hOkEfwFUI/SSxTMTbDwjCVIDuKLgIug7WxuEGRx1BSnyvQ7FSrWXMn/7BrIMAJQ91ojz5R+l59V9VhR7IIfHMS3l99uv8TjiHD2LVKWsFfInR0ANpd7Uw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854565; c=relaxed/simple; bh=d+RnTUEfwRnwl1k4HqM68WIpaWnlwVSPB0IEcqxt+IA=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=erkATe86YXbjRwPMmN8IY2FG8nYF6m9F4kGjCwiKs1NANfoOWHlXXacCYW0wBovKeWAVafmlDxt/rc/sAP+0hjB/VDHJJb2svaln9IGQVHyzQPSSmh5g9WqHhboRGl2Z1L+iDUkU4I9KXtG5MD32cfnCwnd35oVVb1wn3p90ndE= 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=dv2Ugu5P; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc6531fa07fso2222204276.2 for ; Thu, 01 Feb 2024 22:16:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854562; x=1707459362; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=LraddYkgLopGo/nY223hQ1nvCnHwVQlgNAwJab4EqVs=; b=dv2Ugu5P3vz4vmYhJAzQlFCywEkPQq09kHqPTe36/H297QlgXoDHSv6Ik8/P/WDRbq ObqMO1EG8FTIe63zt/wQzH5qxtPk9ylSF7q6csc/dC3BBy+UuyaiclIppgaPxKw7yU1J EWipglViGhLA9fDL/WoDthXzxuYwHccDA2Efceo7vn4Kz4OtUmsLVhWfVJDEbiPH3v2z LIc47iUbjBJShYQPLW7OH+xnNXLdgQ8f3JdTyHg/UvscpTmV7v3JMyuiMUGEdzMrX0Gv xHqCG7ywc36/LdnVT1t2xnsp0cNWij+S4Q39MZkYsuy7dy0ql/Kuc5XLjg7nm0+HiJ+C NnAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854562; x=1707459362; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=LraddYkgLopGo/nY223hQ1nvCnHwVQlgNAwJab4EqVs=; b=lCdsSX1Gj1YRsuTvobJRfxZPFcMWQHznqhEhJPdtbW36b9biZmndZT86mnjefCbRAX QkGw3NMGcGSpGffQnsmNB2KSAWy2RYgSEdY2s27LPOwTnMNYlldc6OjlNWHdIJffutWC sKy6fD501xrhDXEhUz0dLZAq8Bvp3nqVUU4u2tAdFUC0fhJNtsiR1zlcmTPH/JTjwM0h OnOzz7wRbtQsPHROxH5u2QUZb7Qr4ez8WjhuETtNmhNTR1EIsUzLHhI8ilf1PMMuRYEm TGLUO4EDuWosc0lX3qMWfJzxYkfdUeTgrDVHyruqEQGDpe6pw4zCFnHv0JXvk95qZMFt OnnA== X-Gm-Message-State: AOJu0Yy5zTQID2fRGkrtBqR2aDXFozQinb5RV6EWzfl5Zwz9gCBrPR6j oY1JhLt3m4d5O1P3PFl05zGqOXu8n3KsFb1JTFRS27GRzkqCTqvN8FbE6VrL9ZFbD+IgHkXnhXT Qk3Fy7g== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:2306:b0:dc2:5130:198f with SMTP id do6-20020a056902230600b00dc25130198fmr67402ybb.5.1706854562551; Thu, 01 Feb 2024 22:16:02 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:14 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-8-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 07/25] perf dso: Reorder variables to save space in struct dso From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766860696181982 X-GMAIL-MSGID: 1789766860696181982 Save 40 bytes and move from 8 to 7 cache lines. Make variable dwfl dependent on being a powerpc build. Squeeze bits of int/enum types when appropriate. Remove holes/padding by reordering variables. Before: ``` struct dso { struct mutex lock; /* 0 40 */ struct list_head node; /* 40 16 */ struct rb_node rb_node __attribute__((__aligned__(8))); /* 56 24 */ /* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */ struct rb_root * root; /* 80 8 */ struct rb_root_cached symbols; /* 88 16 */ struct symbol * * symbol_names; /* 104 8 */ size_t symbol_names_len; /* 112 8 */ struct rb_root_cached inlined_nodes; /* 120 16 */ /* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */ struct rb_root_cached srclines; /* 136 16 */ struct { u64 addr; /* 152 8 */ struct symbol * symbol; /* 160 8 */ } last_find_result; /* 152 16 */ void * a2l; /* 168 8 */ char * symsrc_filename; /* 176 8 */ unsigned int a2l_fails; /* 184 4 */ enum dso_space_type kernel; /* 188 4 */ /* --- cacheline 3 boundary (192 bytes) --- */ _Bool is_kmod; /* 192 1 */ /* XXX 3 bytes hole, try to pack */ enum dso_swap_type needs_swap; /* 196 4 */ enum dso_binary_type symtab_type; /* 200 4 */ enum dso_binary_type binary_type; /* 204 4 */ enum dso_load_errno load_errno; /* 208 4 */ u8 adjust_symbols:1; /* 212: 0 1 */ u8 has_build_id:1; /* 212: 1 1 */ u8 header_build_id:1; /* 212: 2 1 */ u8 has_srcline:1; /* 212: 3 1 */ u8 hit:1; /* 212: 4 1 */ u8 annotate_warned:1; /* 212: 5 1 */ u8 auxtrace_warned:1; /* 212: 6 1 */ u8 short_name_allocated:1; /* 212: 7 1 */ u8 long_name_allocated:1; /* 213: 0 1 */ u8 is_64_bit:1; /* 213: 1 1 */ /* XXX 6 bits hole, try to pack */ _Bool sorted_by_name; /* 214 1 */ _Bool loaded; /* 215 1 */ u8 rel; /* 216 1 */ /* XXX 7 bytes hole, try to pack */ struct build_id bid; /* 224 32 */ /* --- cacheline 4 boundary (256 bytes) --- */ u64 text_offset; /* 256 8 */ u64 text_end; /* 264 8 */ const char * short_name; /* 272 8 */ const char * long_name; /* 280 8 */ u16 long_name_len; /* 288 2 */ u16 short_name_len; /* 290 2 */ /* XXX 4 bytes hole, try to pack */ void * dwfl; /* 296 8 */ struct auxtrace_cache * auxtrace_cache; /* 304 8 */ int comp; /* 312 4 */ /* XXX 4 bytes hole, try to pack */ /* --- cacheline 5 boundary (320 bytes) --- */ struct { struct rb_root cache; /* 320 8 */ int fd; /* 328 4 */ int status; /* 332 4 */ u32 status_seen; /* 336 4 */ /* XXX 4 bytes hole, try to pack */ u64 file_size; /* 344 8 */ struct list_head open_entry; /* 352 16 */ u64 elf_base_addr; /* 368 8 */ u64 debug_frame_offset; /* 376 8 */ /* --- cacheline 6 boundary (384 bytes) --- */ u64 eh_frame_hdr_addr; /* 384 8 */ u64 eh_frame_hdr_offset; /* 392 8 */ } data; /* 320 80 */ struct { u32 id; /* 400 4 */ u32 sub_id; /* 404 4 */ struct perf_env * env; /* 408 8 */ } bpf_prog; /* 400 16 */ union { void * priv; /* 416 8 */ u64 db_id; /* 416 8 */ }; /* 416 8 */ struct nsinfo * nsinfo; /* 424 8 */ struct dso_id id; /* 432 24 */ /* --- cacheline 7 boundary (448 bytes) was 8 bytes ago --- */ refcount_t refcnt; /* 456 4 */ char name[]; /* 460 0 */ /* size: 464, cachelines: 8, members: 49 */ /* sum members: 440, holes: 4, sum holes: 18 */ /* sum bitfield members: 10 bits, bit holes: 1, sum bit holes: 6 bits */ /* padding: 4 */ /* forced alignments: 1 */ /* last cacheline: 16 bytes */ } __attribute__((__aligned__(8))); ``` After: ``` struct dso { struct mutex lock; /* 0 40 */ struct list_head node; /* 40 16 */ struct rb_node rb_node __attribute__((__aligned__(8))); /* 56 24 */ /* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */ struct rb_root * root; /* 80 8 */ struct rb_root_cached symbols; /* 88 16 */ struct symbol * * symbol_names; /* 104 8 */ size_t symbol_names_len; /* 112 8 */ struct rb_root_cached inlined_nodes; /* 120 16 */ /* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */ struct rb_root_cached srclines; /* 136 16 */ struct { u64 addr; /* 152 8 */ struct symbol * symbol; /* 160 8 */ } last_find_result; /* 152 16 */ struct build_id bid; /* 168 32 */ /* --- cacheline 3 boundary (192 bytes) was 8 bytes ago --- */ u64 text_offset; /* 200 8 */ u64 text_end; /* 208 8 */ const char * short_name; /* 216 8 */ const char * long_name; /* 224 8 */ void * a2l; /* 232 8 */ char * symsrc_filename; /* 240 8 */ struct nsinfo * nsinfo; /* 248 8 */ /* --- cacheline 4 boundary (256 bytes) --- */ struct auxtrace_cache * auxtrace_cache; /* 256 8 */ union { void * priv; /* 264 8 */ u64 db_id; /* 264 8 */ }; /* 264 8 */ struct { struct perf_env * env; /* 272 8 */ u32 id; /* 280 4 */ u32 sub_id; /* 284 4 */ } bpf_prog; /* 272 16 */ struct { struct rb_root cache; /* 288 8 */ struct list_head open_entry; /* 296 16 */ u64 file_size; /* 312 8 */ /* --- cacheline 5 boundary (320 bytes) --- */ u64 elf_base_addr; /* 320 8 */ u64 debug_frame_offset; /* 328 8 */ u64 eh_frame_hdr_addr; /* 336 8 */ u64 eh_frame_hdr_offset; /* 344 8 */ int fd; /* 352 4 */ int status; /* 356 4 */ u32 status_seen; /* 360 4 */ } data; /* 288 80 */ /* XXX last struct has 4 bytes of padding */ struct dso_id id; /* 368 24 */ /* --- cacheline 6 boundary (384 bytes) was 8 bytes ago --- */ unsigned int a2l_fails; /* 392 4 */ int comp; /* 396 4 */ refcount_t refcnt; /* 400 4 */ enum dso_load_errno load_errno; /* 404 4 */ u16 long_name_len; /* 408 2 */ u16 short_name_len; /* 410 2 */ enum dso_binary_type symtab_type:8; /* 412: 0 4 */ enum dso_binary_type binary_type:8; /* 412: 8 4 */ enum dso_space_type kernel:2; /* 412:16 4 */ enum dso_swap_type needs_swap:2; /* 412:18 4 */ /* Bitfield combined with next fields */ _Bool is_kmod:1; /* 414: 4 1 */ u8 adjust_symbols:1; /* 414: 5 1 */ u8 has_build_id:1; /* 414: 6 1 */ u8 header_build_id:1; /* 414: 7 1 */ u8 has_srcline:1; /* 415: 0 1 */ u8 hit:1; /* 415: 1 1 */ u8 annotate_warned:1; /* 415: 2 1 */ u8 auxtrace_warned:1; /* 415: 3 1 */ u8 short_name_allocated:1; /* 415: 4 1 */ u8 long_name_allocated:1; /* 415: 5 1 */ u8 is_64_bit:1; /* 415: 6 1 */ /* XXX 1 bit hole, try to pack */ _Bool sorted_by_name; /* 416 1 */ _Bool loaded; /* 417 1 */ u8 rel; /* 418 1 */ char name[]; /* 419 0 */ /* size: 424, cachelines: 7, members: 48 */ /* sum members: 415 */ /* sum bitfield members: 31 bits, bit holes: 1, sum bit holes: 1 bits */ /* padding: 5 */ /* paddings: 1, sum paddings: 4 */ /* forced alignments: 1 */ /* last cacheline: 40 bytes */ } __attribute__((__aligned__(8))); ``` Signed-off-by: Ian Rogers --- tools/perf/util/dso.h | 84 +++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index ce9f3849a773..33a41bcea335 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -160,66 +160,66 @@ struct dso { u64 addr; struct symbol *symbol; } last_find_result; - void *a2l; - char *symsrc_filename; - unsigned int a2l_fails; - enum dso_space_type kernel; - bool is_kmod; - enum dso_swap_type needs_swap; - enum dso_binary_type symtab_type; - enum dso_binary_type binary_type; - enum dso_load_errno load_errno; - u8 adjust_symbols:1; - u8 has_build_id:1; - u8 header_build_id:1; - u8 has_srcline:1; - u8 hit:1; - u8 annotate_warned:1; - u8 auxtrace_warned:1; - u8 short_name_allocated:1; - u8 long_name_allocated:1; - u8 is_64_bit:1; - bool sorted_by_name; - bool loaded; - u8 rel; struct build_id bid; u64 text_offset; u64 text_end; const char *short_name; const char *long_name; - u16 long_name_len; - u16 short_name_len; + void *a2l; + char *symsrc_filename; +#if defined(__powerpc__) void *dwfl; /* DWARF debug info */ +#endif + struct nsinfo *nsinfo; struct auxtrace_cache *auxtrace_cache; - int comp; - + union { /* Tool specific area */ + void *priv; + u64 db_id; + }; + /* bpf prog information */ + struct { + struct perf_env *env; + u32 id; + u32 sub_id; + } bpf_prog; /* dso data file */ struct { struct rb_root cache; - int fd; - int status; - u32 status_seen; - u64 file_size; struct list_head open_entry; + u64 file_size; u64 elf_base_addr; u64 debug_frame_offset; u64 eh_frame_hdr_addr; u64 eh_frame_hdr_offset; + int fd; + int status; + u32 status_seen; } data; - /* bpf prog information */ - struct { - u32 id; - u32 sub_id; - struct perf_env *env; - } bpf_prog; - - union { /* Tool specific area */ - void *priv; - u64 db_id; - }; - struct nsinfo *nsinfo; struct dso_id id; + unsigned int a2l_fails; + int comp; refcount_t refcnt; + enum dso_load_errno load_errno; + u16 long_name_len; + u16 short_name_len; + enum dso_binary_type symtab_type:8; + enum dso_binary_type binary_type:8; + enum dso_space_type kernel:2; + enum dso_swap_type needs_swap:2; + bool is_kmod:1; + u8 adjust_symbols:1; + u8 has_build_id:1; + u8 header_build_id:1; + u8 has_srcline:1; + u8 hit:1; + u8 annotate_warned:1; + u8 auxtrace_warned:1; + u8 short_name_allocated:1; + u8 long_name_allocated:1; + u8 is_64_bit:1; + bool sorted_by_name; + bool loaded; + u8 rel; char name[]; }; From patchwork Fri Feb 2 06:15:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195589 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp238269dyc; Thu, 1 Feb 2024 22:18:30 -0800 (PST) X-Google-Smtp-Source: AGHT+IF9+8mXmjQeQJybrQGe/wX2CtEYNJ8bEGZclicboK8aYBtLXnv+1tMz0QDsE7HHXPUUzkFW X-Received: by 2002:aa7:c0cd:0:b0:55f:eae0:17ec with SMTP id j13-20020aa7c0cd000000b0055feae017ecmr799320edp.22.1706854710554; Thu, 01 Feb 2024 22:18:30 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854710; cv=pass; d=google.com; s=arc-20160816; b=GhUtT+u3/MOBuSrKCM0R2cOQSNvkMdXcHqp70xIk1nf7AlppT+1TvEwlVl1EMkpzvy 6tAil9sjBpuP4TVW+WGe9/eFsKDmPCUxMT8IUd/3TAWpvpi7DonUKdUXK2eJK6E7vEaP 8CgzJ0w3on+gwzEvhDjZfk+8wPzAy38PcHEAVsJzmVaBzhfKhtJTW/yGty9rXwLQwfqy 501dFNtQwmr1anyLlvWA3nBlmsR2cqPessy3J1gLnrjXBgoFq4twNELyBlB44nLwJroB UGTovKU/mQisjGasbI3PpwnBupbHCexbs4PDMIO4Y3PF4msPLS83gu4NQe8mHrFdvxnn MoBA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=tJud4au3Z9PjBuOB/8R+QNGS64GphjM5sRn/EZb5fRM=; fh=nSG3W/6vzARscgUZP2fyq4aQ4tt9BizlnOUuAruEN+0=; b=PZAvF6ufPOtQO/sXntF6cxMsTQ8C7iCc7TOY4gAgzu161p/nwjIVV51rYMEZAJPfbX 64lx7Hh0xy6/1DO7EyJoBCOwp4vS7HpFvhnoqD05OIuju0m+nFD0c5g+p+B4wkhgtvjv VKWIichaYrGmS+NQ+yzDzxtEv4U7EzrLsiSbUHLa4i5VuyWo9aLLxEd2yZwhmLqNSEUv 0PwUa5AiUXVSbDypa3acKSYVx9wzw9ydVpxwZ0VJBImDebtRoKzjEITyJ7ubJmISeBpR 4DhyQkSv+cnsxatO0vVeHDdb7GqOKFfj3fHCrK3rkkv/FLgbG2BtwnntlgNACHCpup6q jxjA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=bwIKQ4lO; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49248-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49248-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCV74A3vYD6f1bEygC1Ur0eQOYeuVURtpegLCVC79Nz+vpAwM1l9oOm6PTzUzNXv5JDR2r/VrM2rnohcX817KrO6+aV98w== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id r6-20020a50c006000000b0055d0a061200si521838edb.21.2024.02.01.22.18.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:18:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49248-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=bwIKQ4lO; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49248-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49248-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 am.mirrors.kernel.org (Postfix) with ESMTPS id 00DF01F23664 for ; Fri, 2 Feb 2024 06:18:30 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BA8B81A27E; Fri, 2 Feb 2024 06:16:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="bwIKQ4lO" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 3588618651 for ; Fri, 2 Feb 2024 06:16:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854571; cv=none; b=IY10Yr05jNfhVm7FJK9tQ2gskENBtech51/feaaObXCrmPt8jUmBkoVkc2cTN8ap3kgI4w1zLSlODaE5JCLszjCfWpo7oM0aSD5kAksNlBheuzzz0ll+Of0Bv/1uqtrKPIActQUugYz19JTzIENnMQHUxLk/VK5ff6xFE0w8ljs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854571; c=relaxed/simple; bh=BXiX9gzQs5k0E5V5XLiwe7g8s/r2aLi/zeI/x5SxZBA=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=CVGx9ZnVMXYmRo57ZbqZDB3XigrS+xH9KfyIIcdkLNZyVBm27yNTRbDudgLi/z9p4bQPBmUTb17NuKCKDHrOyipRwTkefvrt4jXJZGL1qYJuiQ0uajave0wrn4csdv6sGQWXaZsaLmGhfFLPXVgosbom3lNU98JocPXLTe0mznM= 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=bwIKQ4lO; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60402c8d651so28172417b3.3 for ; Thu, 01 Feb 2024 22:16:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854567; x=1707459367; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=tJud4au3Z9PjBuOB/8R+QNGS64GphjM5sRn/EZb5fRM=; b=bwIKQ4lOnlXCNbe+z4MZSVuDTdCQLKCcoWXtOf/mVaHtk6rKX+hW4+Pp2KygBDj0fc MBiqGQj6DEn9O0GZbgh8mlw+fGkwArNnZOZnN108ePq5b8tpcCiRo60+d0HE3+vU6+it wBglhEb+W6MqKDlqff1QfYe9piq4qUwGYOU51yG2GbYK9Y663A7TjxCb24ROcLv0LtoC btqLaggyRUqBW7A/VcXIRtV00DSi1rWPKq9gcFrzwQsxV6NK7O0JOr1YLBYomP9B1gaG AZHWkWLGehH7DPT+a09klMs3dIq5xBUd9rRIosL598TyECrz72EPeraE1Btj5SIYZZEU M0GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854567; x=1707459367; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tJud4au3Z9PjBuOB/8R+QNGS64GphjM5sRn/EZb5fRM=; b=bZ4l37S6FPQCCDX1mZ5PoLaQF/R5VvIs/rEfOz5Yqp4p1o3J99X/8oazn06g6st6EK 0hGFX5mDd0KQKyFwblRCP6P1N7kcDPeYiruVSFc4MisJeuyyjK2cKTj6HKytmBEbPtPY pyLhUE2YuZvxH2/iD+/ndV1afvKClCnO2+QAUdMxXHd+/zlimTy1cu7xlUBnwQbjoNiV H/9auBTyDrg52k2P/gsrwnHpUrO1oLscfWEOLgr1pCZUXGc86SzdZ3gNI+TrXneJUOqa InKcuIpkuKEhPAwN4bL41/czgENoKiEcN7qrHAa3Kty9jbQ7wtSaodQ4lkhGYzVAY9u6 gIPA== X-Gm-Message-State: AOJu0YzkpH0nuwuNvBqoaMyFsaMROZBp3mkqZaFx18ia0RI1Nvf6USjT RI7Hmkwr0MkTb42iFGnXNdLBR2bpF3s5LPDByu4K/nkgHS0J6HRpBYc4nl00Qpm71SS2phE9Hzs lVog6DQ== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a81:9a47:0:b0:5fb:5605:494a with SMTP id r68-20020a819a47000000b005fb5605494amr777271ywg.7.1706854567242; Thu, 01 Feb 2024 22:16:07 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:16 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-10-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 09/25] perf trace: Ignore thread hashing in summary From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766885182470103 X-GMAIL-MSGID: 1789766885182470103 Commit 91e467bc568f ("perf machine: Use hashtable for machine threads") made the iteration of thread tids unordered. The perf trace --summary output sorts and prints each hash bucket, rather than all threads globally. Change this behavior by turn all threads into a list, sort the list by number of trace events then by tids, finally print the list. This also allows the rbtree in threads to be not accessed outside of machine. Signed-off-by: Ian Rogers --- tools/perf/builtin-trace.c | 41 +++++++++++++++++++++---------------- tools/perf/util/rb_resort.h | 5 ----- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 109b8e64fe69..90eaff8c0f6e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -4312,34 +4313,38 @@ static unsigned long thread__nr_events(struct thread_trace *ttrace) return ttrace ? ttrace->nr_events : 0; } -DEFINE_RESORT_RB(threads, - (thread__nr_events(thread__priv(a->thread)) < - thread__nr_events(thread__priv(b->thread))), - struct thread *thread; -) +static int trace_nr_events_cmp(void *priv __maybe_unused, + const struct list_head *la, + const struct list_head *lb) { - entry->thread = rb_entry(nd, struct thread_rb_node, rb_node)->thread; + struct thread_list *a = list_entry(la, struct thread_list, list); + struct thread_list *b = list_entry(lb, struct thread_list, list); + unsigned long a_nr_events = thread__nr_events(thread__priv(a->thread)); + unsigned long b_nr_events = thread__nr_events(thread__priv(b->thread)); + + if (a_nr_events != b_nr_events) + return a_nr_events < b_nr_events ? -1 : 1; + + /* Identical number of threads, place smaller tids first. */ + return thread__tid(a->thread) < thread__tid(b->thread) + ? -1 + : (thread__tid(a->thread) > thread__tid(b->thread) ? 1 : 0); } static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp) { size_t printed = trace__fprintf_threads_header(fp); - struct rb_node *nd; - int i; - - for (i = 0; i < THREADS__TABLE_SIZE; i++) { - DECLARE_RESORT_RB_MACHINE_THREADS(threads, trace->host, i); + LIST_HEAD(threads); - if (threads == NULL) { - fprintf(fp, "%s", "Error sorting output by nr_events!\n"); - return 0; - } + if (machine__thread_list(trace->host, &threads) == 0) { + struct thread_list *pos; - resort_rb__for_each_entry(nd, threads) - printed += trace__fprintf_thread(fp, threads_entry->thread, trace); + list_sort(NULL, &threads, trace_nr_events_cmp); - resort_rb__delete(threads); + list_for_each_entry(pos, &threads, list) + printed += trace__fprintf_thread(fp, pos->thread, trace); } + thread_list__delete(&threads); return printed; } diff --git a/tools/perf/util/rb_resort.h b/tools/perf/util/rb_resort.h index 376e86cb4c3c..d927a0d25052 100644 --- a/tools/perf/util/rb_resort.h +++ b/tools/perf/util/rb_resort.h @@ -143,9 +143,4 @@ struct __name##_sorted *__name = __name##_sorted__new DECLARE_RESORT_RB(__name)(&__ilist->rblist.entries.rb_root, \ __ilist->rblist.nr_entries) -/* For 'struct machine->threads' */ -#define DECLARE_RESORT_RB_MACHINE_THREADS(__name, __machine, hash_bucket) \ - DECLARE_RESORT_RB(__name)(&__machine->threads[hash_bucket].entries.rb_root, \ - __machine->threads[hash_bucket].nr) - #endif /* _PERF_RESORT_RB_H_ */ From patchwork Fri Feb 2 06:15:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195592 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp238378dyc; Thu, 1 Feb 2024 22:18:46 -0800 (PST) X-Google-Smtp-Source: AGHT+IGml3nOvyOmFwDv10DHrW/yHJc+gkyHvsHmRxgx0YYo/2p64AiAOmJuXKWsxnmerIRxlyEy X-Received: by 2002:a05:6402:60c:b0:55f:fb25:47d9 with SMTP id n12-20020a056402060c00b0055ffb2547d9mr181361edv.8.1706854726093; Thu, 01 Feb 2024 22:18:46 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854726; cv=pass; d=google.com; s=arc-20160816; b=amUOjBq5eFwSOVDFh8u8VCwE1uzMQTt/L8G9O0IHmC6iRKR84BWo6r0ek92UYQSclL vsGnmRDZiOyyDeZ/BuZg12VLAbyBPY79FOhlFXwCPy+x0xv5cGXxLY0gDvoSdpSNxjgS aCquvBWN4yyHB1BRCi3utgK4N+ZkNKz/oAmTJC1wvbojihGaPXsww1GFlA6dmoeKl13u QRkI/QvyJCHHBaz7DcplPtsN2ShuoUzPwWnsxFHj6uWBrUx7y+xm3L9ON457OGSU4JCi L6lqgIxle/8SVPUbX0bIJ0H7gWNlKJTpVOh5eKhklqrHRsGzwsLY4en1XxOqZDY+2HKQ dTaQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=T6mw7Xtg2kK14DjlLq7BifI7GtEprdY4uQDlUS0jAeg=; fh=MhwT2GNwnNIrP/ygJRZ+ekreoUwJXnk7cjoa/hv47rY=; b=C5/Xmornkx0CGvdGCbkUuXr09zb87CLn8+al0QO6dMluSGY0UBFPAhvxmCseGv/Qu2 D1P0Pi+0LqMhvf2ZpAHtjleetCDGUlPYiXkZZInUK+Bjeu8Lpji4ljg6QLQUUBJvpF+q 4wPFJWXobpUQdCZEMP43627n7jgOKWsbRxFNqtwDwjHde11P9yZCiKnIbQ1hgj9cSo9H dI7vWlow5L635jmAHvD62guHalRIxISi4UpY1JJnDDccSVk2OpAnAV5BW08DA3guSZg5 rP5+mB6kDeRUIFCHBlEyZIDJn2nOY2C2IV+T1prZHdTBJRIdHd5xBsYfpqAIR29XXj/Y aR6A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b="Je2mC/DA"; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49249-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49249-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCXQNMwvQHgKA5xxJ0dufOcVhVWTY9sFgWun5tk7Ck5s0xPWVToGAK56saoohhP1u4vvfzY4kVK6MC03G+GCez4nxS8cJg== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id w12-20020aa7da4c000000b0055fed500e30si352161eds.677.2024.02.01.22.18.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:18:46 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49249-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b="Je2mC/DA"; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49249-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49249-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 am.mirrors.kernel.org (Postfix) with ESMTPS id 852C01F23F94 for ; Fri, 2 Feb 2024 06:18:45 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EF0FA1B270; Fri, 2 Feb 2024 06:16:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Je2mC/DA" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.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 B044218B02 for ; Fri, 2 Feb 2024 06:16:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854573; cv=none; b=NoA7qR4Sak328Z5hWwRlV75K+B3mThYv2v7TKlD7nSvL9Pa8QEY89c2EUwWxVnZF/7C0eem9dtiW92SvFTh1CDY67bNpuqlwXCLT2siHG89WXwF8bZw+1PiTI5bCebhYjQ/tR7MaxcYjRwe3US4IayyzQXS6n+E/94v6+PYBKa8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854573; c=relaxed/simple; bh=ar+h6lW4xcIxzdvZbvzL64J6bTCD6UFYPdk5Pkaa3hQ=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=UIqrtOOsUsfMbXY+Ao2E/8oBBD2LQbxIagNxL8W0jaKS6Pl2Lnx27G6xB5PQmRrfvjykdHR31TRvTz1eh/jI39N/EHIuAPeDFfpng1xZ0hsnDQMKHhvQyV9SdGouaR85lBTOD0trME0s/ULEL9qHtPLpoyr1Zq5PuRqK2MLpCEY= 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=Je2mC/DA; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dbf216080f5so2808220276.1 for ; Thu, 01 Feb 2024 22:16:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854569; x=1707459369; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=T6mw7Xtg2kK14DjlLq7BifI7GtEprdY4uQDlUS0jAeg=; b=Je2mC/DAC2JRCwzcJ0s2U7AOMAmBnasb8Q9UaAHRZYVygUsjlY4K1qjORCYDwuZYvD +H1Z4IP9up/JYHyF6gbEpI9nB3cSCljk6baIlOyjBdwBWqeYHxiCnDul7Wz/jPRbJxUH A+norGsWQ2abTjukx1Fv5UbzYro0fvODMt6x7xcm4K/QHmyTLVMyVZ7cVq/4IQV08SZ0 2Jz0PKhUSeMS+S4XpCLDGi8LE/Xx4BLf8iGg9a9jousQuIWNZVWALSXrl5dU7eXOHPV4 pIfSB8fA8CGKwHLyOSru8Nzy9qG6wMSUzj6frKi3roaz0jMULape9c1T0LRKuWZwtPDZ lWPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854569; x=1707459369; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=T6mw7Xtg2kK14DjlLq7BifI7GtEprdY4uQDlUS0jAeg=; b=dqs9vLrKEvSqgUlnihW4CLseYDZylDu2J/LMNjfLVE7adIZ73QERPPeZ/CUQcEivZD uEeYPPY8pjdxFNPchIANmExLTi0zxpY2/UZp7yjsAshdt49HB1+DWXqih/nG9ZUICVfr B0/VpN3qxiVjO17BbYpPwDq/9+q7jvIWcCkH+iogKJOj7f361fdlM9+09bKbZLhHIP41 zHem2rvrO5MPs4FLtJPXJ/si1DtKksJAsrrAQYx7/0raZrjv4c6ae7QHJkiFGOeeuBRg opofFyHgY42ETNdg2wsLwOvzPSBXZoiYmTmByTlC1Z8eAT5Bj1rtE+BHxFR6c/Vhz+H1 iI3w== X-Gm-Message-State: AOJu0YyLRGL2gf1cL47hd1u5WqWvR21amhzMweNZcsKNhiHaN/ZotMVc cex/bbtPeOtlg54Cncxo1dGj4Xqe08eoLrnP//qSQb0peDDkRDFaLw+12tPEG91bwhfo7DyE86V My/DTqA== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:2186:b0:dc2:466a:23c4 with SMTP id dl6-20020a056902218600b00dc2466a23c4mr375837ybb.4.1706854569681; Thu, 01 Feb 2024 22:16:09 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:17 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-11-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 10/25] perf machine: Move fprintf to for_each loop and a callback From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766900867029469 X-GMAIL-MSGID: 1789766900867029469 Avoid exposing the threads data structure by switching to the callback machine__for_each_thread approach. machine__fprintf is only used in tests and verbose >3 output so don't turn to list and sort. Add machine__threads_nr to be refactored later. Note, all existing *_fprintf routines ignore fprintf errors. Signed-off-by: Ian Rogers --- tools/perf/util/machine.c | 43 ++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 7872ce92c9fc..e072b2115b64 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1113,29 +1113,40 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp) return printed; } -size_t machine__fprintf(struct machine *machine, FILE *fp) +struct machine_fprintf_cb_args { + FILE *fp; + size_t printed; +}; + +static int machine_fprintf_cb(struct thread *thread, void *data) { - struct rb_node *nd; - size_t ret; - int i; + struct machine_fprintf_cb_args *args = data; - for (i = 0; i < THREADS__TABLE_SIZE; i++) { - struct threads *threads = &machine->threads[i]; + /* TODO: handle fprintf errors. */ + args->printed += thread__fprintf(thread, args->fp); + return 0; +} - down_read(&threads->lock); +static size_t machine__threads_nr(const struct machine *machine) +{ + size_t nr = 0; - ret = fprintf(fp, "Threads: %u\n", threads->nr); + for (int i = 0; i < THREADS__TABLE_SIZE; i++) + nr += machine->threads[i].nr; - for (nd = rb_first_cached(&threads->entries); nd; - nd = rb_next(nd)) { - struct thread *pos = rb_entry(nd, struct thread_rb_node, rb_node)->thread; + return nr; +} - ret += thread__fprintf(pos, fp); - } +size_t machine__fprintf(struct machine *machine, FILE *fp) +{ + struct machine_fprintf_cb_args args = { + .fp = fp, + .printed = 0, + }; + size_t ret = fprintf(fp, "Threads: %zu\n", machine__threads_nr(machine)); - up_read(&threads->lock); - } - return ret; + machine__for_each_thread(machine, machine_fprintf_cb, &args); + return ret + args.printed; } static struct dso *machine__get_kernel(struct machine *machine) From patchwork Fri Feb 2 06:15:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195594 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp238666dyc; Thu, 1 Feb 2024 22:19:29 -0800 (PST) X-Google-Smtp-Source: AGHT+IGEaVPNeGhvLqdiReX8iokKfyWR+TWo9/L8TqYRs8zv+eFQbq4kC9XpGB5rNvbsDTjzGmNu X-Received: by 2002:a17:907:762d:b0:a36:c478:32c9 with SMTP id jy13-20020a170907762d00b00a36c47832c9mr836820ejc.1.1706854769663; Thu, 01 Feb 2024 22:19:29 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854769; cv=pass; d=google.com; s=arc-20160816; b=NHZbX5y0XmWon5PwUurIqdX3Sg+ruN6ETkgTa8770xILHUY8rKXqSONqmaVKL52VHp z3orYqqOpFdcEUYreGyFse9dB6jLoB2VNbFkUazoIqGsahC26ag/78B5P6clIphq5vpu cxKFFlT9y3FjEe3CeKXe0zBs4ZxpVoJpnRM/1r9bsuE30dZOQPGbyQ02yBLdbJazgXLr WHZz9HVUu5Y0PGiloI68fJPXro6HUE0hy5uo2sY2xRWSzfN0g/8R/o2neC0fwUQvN6IJ G89UdwjueT16LH8FFvWhPvFw8krhH2QPJ5+zhMX26Z/tdvg2M7MRtNae/jNGXGjZ07EO 8oXQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=gjBb7mb7ox08+Ftzctm2JAkXgywmsYxBt1hXHxYt4so=; fh=TFQPe/iTX8FzNK6HE1OUQnYkjNtkatefDXGcCJcDu9Y=; b=t0c3p8aMD9mzkxe7QcUHikycsg/jaHtv7aUiYFVtjWvdw9nZc/6QXnkbTEdUR+DJXk 2zVxFbjEfL5yWpqX8CkoB45OExdDXaB8d7JtDl01cC9O3J/cGwJH+5clG+PKS0jOtKlN ILQBxV5IzQeSaNg6md1A2cSMZMpK/NIOo63zjxaMnSQKPFuxre8iV96BT94K/47FHBhU o1367tMgA8It8XdMqj80w24hg3nuKNneBxuCL7D/yvSg7PjgIqu9mb0GNyGnaslfPGwa AeCdGwqtxRu3229FrNghNylSgUjSIBylG57tlvTVtRuYtILi+ndvzG0re9x1zOKIn83d YD5g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=AramTbs0; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49250-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49250-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCWTZluoEqMw7IbQVUEDHhsC3rkcuLQAfTXAn2/9eQlGGHxJTEksfUFfW+naQn8PZ6wYOkfzw+bluKpDl7xan5LbNNCf5g== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id i19-20020a170906115300b00a36600d8ed0si467277eja.658.2024.02.01.22.19.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:19:29 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49250-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=AramTbs0; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49250-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49250-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 am.mirrors.kernel.org (Postfix) with ESMTPS id E942A1F257DE for ; Fri, 2 Feb 2024 06:19:28 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 20C673A1C3; Fri, 2 Feb 2024 06:16:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AramTbs0" Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.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 E21BB18E27 for ; Fri, 2 Feb 2024 06:16:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854575; cv=none; b=dxnJwwCXfwk8cbzlII+/qmhOxGhjGjxwPvyzLsKtrrBqgoBkBftz5xTy5ad/ar2K44As9ukvpy42Mt+GruvJbAZrWKl/o3Dq+SBHI+RU0fCe+M1jw4BdEoHHuze9tk2iagHxbzNANS7hsXU2iASXccQaB4D/116dtwa2937iia8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854575; c=relaxed/simple; bh=SzsNpaTZGopdbxFhW2AWrU/kwxHBK15G+VrTpqY4HM4=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=iZo6iipAlowPHL+4XhVYPO//c8SOpQxdGWE8gae2X7XT83vd38FHJIpL1onx1zqsR9bJXVhDkBt4QBv3x3pqC1yLk0q4feDEIpKnBJnxzKSUmRNG5DCwYOO8owGGfMs8j9vomK+6lm4mHlI6ovEyHtr49mSkucLIxasw17JpEys= 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=AramTbs0; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dc6e6bc4aa3so1026152276.0 for ; Thu, 01 Feb 2024 22:16:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854572; x=1707459372; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=gjBb7mb7ox08+Ftzctm2JAkXgywmsYxBt1hXHxYt4so=; b=AramTbs00GCrGfkHwaX62j4gVHjdY7NcPUH6dueexYrU43hD/9TKDiCXUSrlWhQfsP IQTJTOgzAlUdWC7vl2g4z2Dvqoffsn0N9cyFxz3gEU4/GcX97phK4YtnUL8Eoz7wPSCI FZysl9EzIBp+LwAm22CrgexlzLBnxOx6aACYebDdYXwA39+zFURfzqVa/oiG43dOHPiT YexwWrUeQN/RP4Y7v5/VgmcM0hO2eMsvNEbpN50Fq8Vn1+owFDoORv/p9aQ9AT39uc/x LbgiNKXjqV0KO9SZExMEcn0vow/FlmOlYTGKz4eY/dMhmQx98AcWnokhUB92D1Ml8TvD t23g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854572; x=1707459372; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gjBb7mb7ox08+Ftzctm2JAkXgywmsYxBt1hXHxYt4so=; b=Oh9b3hmEP9SsKJVDnzFd5z+LjRLJ1yt7yrjA5XTGpTaaEw1Rr6+ac7pzP1bfH/y1Q/ +DqxizfAkB62KWlLGj35Xx4kSaIqZE2MxPJJantl1d8SSZZNY3pZEh4TQkme+YHgg2MN JsuEdjwm3WZoCHnlz3k+igovAxfm/v9LH79ZSYQsQJR8QUUIqftRY1i//7LfVheyl5wh XQaz3fhMC4qV2MpmJwqXyctzhFvCR6ChNz/pTtjCX3QtHwttiWBDZMREmnPRECuVkpYO Ao/ogFA5ylsdfaWtb+2XQKryrDXlGSEmVh6ub2OA+2K1vh7e/SJlvNJtqU9aHbMcD5qm rTQA== X-Gm-Message-State: AOJu0YwqL8SU9OhHnl6mVdcljy5xvB/oQLy4ueWcz2AAzNvWlcuStIoW QgM4TbM1Ur3eRWa9tDiauKcS93bRAy9NoXx/KCETQctu7/y2PYD37goaxXHFBHAm+bDOwZZQiSb Y9ODD3w== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:138f:b0:dc6:dd74:de68 with SMTP id x15-20020a056902138f00b00dc6dd74de68mr97071ybu.12.1706854571767; Thu, 01 Feb 2024 22:16:11 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:18 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-12-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 11/25] perf threads: Move threads to its own files From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766946953659230 X-GMAIL-MSGID: 1789766946953659230 Move threads out of machine and move thread_rb_node into the C file. This hides the implementation of threads from the rest of the code allowing for it to be refactored. Locking discipline is tightened up in this change. Signed-off-by: Ian Rogers --- tools/perf/util/Build | 1 + tools/perf/util/bpf_lock_contention.c | 8 +- tools/perf/util/machine.c | 287 ++++---------------------- tools/perf/util/machine.h | 20 +- tools/perf/util/thread.c | 2 +- tools/perf/util/thread.h | 6 - tools/perf/util/threads.c | 244 ++++++++++++++++++++++ tools/perf/util/threads.h | 35 ++++ 8 files changed, 325 insertions(+), 278 deletions(-) create mode 100644 tools/perf/util/threads.c create mode 100644 tools/perf/util/threads.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 8027f450fa3e..a0e8cd68d490 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -71,6 +71,7 @@ perf-y += ordered-events.o perf-y += namespaces.o perf-y += comm.o perf-y += thread.o +perf-y += threads.o perf-y += thread_map.o perf-y += parse-events-flex.o perf-y += parse-events-bison.o diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index 31ff19afc20c..3992c8a9fd96 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -210,7 +210,7 @@ static const char *lock_contention_get_name(struct lock_contention *con, /* do not update idle comm which contains CPU number */ if (pid) { - struct thread *t = __machine__findnew_thread(machine, /*pid=*/-1, pid); + struct thread *t = machine__findnew_thread(machine, /*pid=*/-1, pid); if (t == NULL) return name; @@ -302,9 +302,9 @@ int lock_contention_read(struct lock_contention *con) return -1; if (con->aggr_mode == LOCK_AGGR_TASK) { - struct thread *idle = __machine__findnew_thread(machine, - /*pid=*/0, - /*tid=*/0); + struct thread *idle = machine__findnew_thread(machine, + /*pid=*/0, + /*tid=*/0); thread__set_comm(idle, "swapper", /*timestamp=*/0); } diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index e072b2115b64..e668a97255f8 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -43,9 +43,6 @@ #include #include -static void __machine__remove_thread(struct machine *machine, struct thread_rb_node *nd, - struct thread *th, bool lock); - static struct dso *machine__kernel_dso(struct machine *machine) { return map__dso(machine->vmlinux_map); @@ -58,35 +55,6 @@ static void dsos__init(struct dsos *dsos) init_rwsem(&dsos->lock); } -static void machine__threads_init(struct machine *machine) -{ - int i; - - for (i = 0; i < THREADS__TABLE_SIZE; i++) { - struct threads *threads = &machine->threads[i]; - threads->entries = RB_ROOT_CACHED; - init_rwsem(&threads->lock); - threads->nr = 0; - threads->last_match = NULL; - } -} - -static int thread_rb_node__cmp_tid(const void *key, const struct rb_node *nd) -{ - int to_find = (int) *((pid_t *)key); - - return to_find - (int)thread__tid(rb_entry(nd, struct thread_rb_node, rb_node)->thread); -} - -static struct thread_rb_node *thread_rb_node__find(const struct thread *th, - struct rb_root *tree) -{ - pid_t to_find = thread__tid(th); - struct rb_node *nd = rb_find(&to_find, tree, thread_rb_node__cmp_tid); - - return rb_entry(nd, struct thread_rb_node, rb_node); -} - static int machine__set_mmap_name(struct machine *machine) { if (machine__is_host(machine)) @@ -120,7 +88,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) RB_CLEAR_NODE(&machine->rb_node); dsos__init(&machine->dsos); - machine__threads_init(machine); + threads__init(&machine->threads); machine->vdso_info = NULL; machine->env = NULL; @@ -221,27 +189,11 @@ static void dsos__exit(struct dsos *dsos) void machine__delete_threads(struct machine *machine) { - struct rb_node *nd; - int i; - - for (i = 0; i < THREADS__TABLE_SIZE; i++) { - struct threads *threads = &machine->threads[i]; - down_write(&threads->lock); - nd = rb_first_cached(&threads->entries); - while (nd) { - struct thread_rb_node *trb = rb_entry(nd, struct thread_rb_node, rb_node); - - nd = rb_next(nd); - __machine__remove_thread(machine, trb, trb->thread, false); - } - up_write(&threads->lock); - } + threads__remove_all_threads(&machine->threads); } void machine__exit(struct machine *machine) { - int i; - if (machine == NULL) return; @@ -254,12 +206,7 @@ void machine__exit(struct machine *machine) zfree(&machine->current_tid); zfree(&machine->kallsyms_filename); - machine__delete_threads(machine); - for (i = 0; i < THREADS__TABLE_SIZE; i++) { - struct threads *threads = &machine->threads[i]; - - exit_rwsem(&threads->lock); - } + threads__exit(&machine->threads); } void machine__delete(struct machine *machine) @@ -526,7 +473,7 @@ static void machine__update_thread_pid(struct machine *machine, if (thread__pid(th) == thread__tid(th)) return; - leader = __machine__findnew_thread(machine, thread__pid(th), thread__pid(th)); + leader = machine__findnew_thread(machine, thread__pid(th), thread__pid(th)); if (!leader) goto out_err; @@ -560,160 +507,55 @@ static void machine__update_thread_pid(struct machine *machine, goto out_put; } -/* - * Front-end cache - TID lookups come in blocks, - * so most of the time we dont have to look up - * the full rbtree: - */ -static struct thread* -__threads__get_last_match(struct threads *threads, struct machine *machine, - int pid, int tid) -{ - struct thread *th; - - th = threads->last_match; - if (th != NULL) { - if (thread__tid(th) == tid) { - machine__update_thread_pid(machine, th, pid); - return thread__get(th); - } - thread__put(threads->last_match); - threads->last_match = NULL; - } - - return NULL; -} - -static struct thread* -threads__get_last_match(struct threads *threads, struct machine *machine, - int pid, int tid) -{ - struct thread *th = NULL; - - if (perf_singlethreaded) - th = __threads__get_last_match(threads, machine, pid, tid); - - return th; -} - -static void -__threads__set_last_match(struct threads *threads, struct thread *th) -{ - thread__put(threads->last_match); - threads->last_match = thread__get(th); -} - -static void -threads__set_last_match(struct threads *threads, struct thread *th) -{ - if (perf_singlethreaded) - __threads__set_last_match(threads, th); -} - /* * Caller must eventually drop thread->refcnt returned with a successful * lookup/new thread inserted. */ -static struct thread *____machine__findnew_thread(struct machine *machine, - struct threads *threads, - pid_t pid, pid_t tid, - bool create) +static struct thread *__machine__findnew_thread(struct machine *machine, + pid_t pid, + pid_t tid, + bool create) { - struct rb_node **p = &threads->entries.rb_root.rb_node; - struct rb_node *parent = NULL; - struct thread *th; - struct thread_rb_node *nd; - bool leftmost = true; + struct thread *th = threads__find(&machine->threads, tid); + bool created; - th = threads__get_last_match(threads, machine, pid, tid); - if (th) + if (th) { + machine__update_thread_pid(machine, th, pid); return th; - - while (*p != NULL) { - parent = *p; - th = rb_entry(parent, struct thread_rb_node, rb_node)->thread; - - if (thread__tid(th) == tid) { - threads__set_last_match(threads, th); - machine__update_thread_pid(machine, th, pid); - return thread__get(th); - } - - if (tid < thread__tid(th)) - p = &(*p)->rb_left; - else { - p = &(*p)->rb_right; - leftmost = false; - } } - if (!create) return NULL; - th = thread__new(pid, tid); - if (th == NULL) - return NULL; - - nd = malloc(sizeof(*nd)); - if (nd == NULL) { - thread__put(th); - return NULL; - } - nd->thread = th; - - rb_link_node(&nd->rb_node, parent, p); - rb_insert_color_cached(&nd->rb_node, &threads->entries, leftmost); - /* - * We have to initialize maps separately after rb tree is updated. - * - * The reason is that we call machine__findnew_thread within - * thread__init_maps to find the thread leader and that would screwed - * the rb tree. - */ - if (thread__init_maps(th, machine)) { - pr_err("Thread init failed thread %d\n", pid); - rb_erase_cached(&nd->rb_node, &threads->entries); - RB_CLEAR_NODE(&nd->rb_node); - free(nd); - thread__put(th); - return NULL; - } - /* - * It is now in the rbtree, get a ref - */ - threads__set_last_match(threads, th); - ++threads->nr; - - return thread__get(th); -} + th = threads__findnew(&machine->threads, pid, tid, &created); + if (created) { + /* + * We have to initialize maps separately after rb tree is + * updated. + * + * The reason is that we call machine__findnew_thread within + * thread__init_maps to find the thread leader and that would + * screwed the rb tree. + */ + if (thread__init_maps(th, machine)) { + pr_err("Thread init failed thread %d\n", pid); + threads__remove(&machine->threads, th); + thread__put(th); + return NULL; + } + } else + machine__update_thread_pid(machine, th, pid); -struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid) -{ - return ____machine__findnew_thread(machine, machine__threads(machine, tid), pid, tid, true); + return th; } -struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, - pid_t tid) +struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid) { - struct threads *threads = machine__threads(machine, tid); - struct thread *th; - - down_write(&threads->lock); - th = __machine__findnew_thread(machine, pid, tid); - up_write(&threads->lock); - return th; + return __machine__findnew_thread(machine, pid, tid, /*create=*/true); } -struct thread *machine__find_thread(struct machine *machine, pid_t pid, - pid_t tid) +struct thread *machine__find_thread(struct machine *machine, pid_t pid, pid_t tid) { - struct threads *threads = machine__threads(machine, tid); - struct thread *th; - - down_read(&threads->lock); - th = ____machine__findnew_thread(machine, threads, pid, tid, false); - up_read(&threads->lock); - return th; + return __machine__findnew_thread(machine, pid, tid, /*create=*/false); } /* @@ -1127,23 +969,13 @@ static int machine_fprintf_cb(struct thread *thread, void *data) return 0; } -static size_t machine__threads_nr(const struct machine *machine) -{ - size_t nr = 0; - - for (int i = 0; i < THREADS__TABLE_SIZE; i++) - nr += machine->threads[i].nr; - - return nr; -} - size_t machine__fprintf(struct machine *machine, FILE *fp) { struct machine_fprintf_cb_args args = { .fp = fp, .printed = 0, }; - size_t ret = fprintf(fp, "Threads: %zu\n", machine__threads_nr(machine)); + size_t ret = fprintf(fp, "Threads: %zu\n", threads__nr(&machine->threads)); machine__for_each_thread(machine, machine_fprintf_cb, &args); return ret + args.printed; @@ -2069,36 +1901,9 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event return 0; } -static void __machine__remove_thread(struct machine *machine, struct thread_rb_node *nd, - struct thread *th, bool lock) -{ - struct threads *threads = machine__threads(machine, thread__tid(th)); - - if (!nd) - nd = thread_rb_node__find(th, &threads->entries.rb_root); - - if (threads->last_match && RC_CHK_EQUAL(threads->last_match, th)) - threads__set_last_match(threads, NULL); - - if (lock) - down_write(&threads->lock); - - BUG_ON(refcount_read(thread__refcnt(th)) == 0); - - thread__put(nd->thread); - rb_erase_cached(&nd->rb_node, &threads->entries); - RB_CLEAR_NODE(&nd->rb_node); - --threads->nr; - - free(nd); - - if (lock) - up_write(&threads->lock); -} - void machine__remove_thread(struct machine *machine, struct thread *th) { - return __machine__remove_thread(machine, NULL, th, true); + return threads__remove(&machine->threads, th); } int machine__process_fork_event(struct machine *machine, union perf_event *event, @@ -3232,23 +3037,7 @@ int machine__for_each_thread(struct machine *machine, int (*fn)(struct thread *thread, void *p), void *priv) { - struct threads *threads; - struct rb_node *nd; - int rc = 0; - int i; - - for (i = 0; i < THREADS__TABLE_SIZE; i++) { - threads = &machine->threads[i]; - for (nd = rb_first_cached(&threads->entries); nd; - nd = rb_next(nd)) { - struct thread_rb_node *trb = rb_entry(nd, struct thread_rb_node, rb_node); - - rc = fn(trb->thread, priv); - if (rc != 0) - return rc; - } - } - return rc; + return threads__for_each_thread(&machine->threads, fn, priv); } int machines__for_each_thread(struct machines *machines, diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index b738ce84817b..e28c787616fe 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -7,6 +7,7 @@ #include "maps.h" #include "dsos.h" #include "rwsem.h" +#include "threads.h" struct addr_location; struct branch_stack; @@ -28,16 +29,6 @@ extern const char *ref_reloc_sym_names[]; struct vdso_info; -#define THREADS__TABLE_BITS 8 -#define THREADS__TABLE_SIZE (1 << THREADS__TABLE_BITS) - -struct threads { - struct rb_root_cached entries; - struct rw_semaphore lock; - unsigned int nr; - struct thread *last_match; -}; - struct machine { struct rb_node rb_node; pid_t pid; @@ -48,7 +39,7 @@ struct machine { char *root_dir; char *mmap_name; char *kallsyms_filename; - struct threads threads[THREADS__TABLE_SIZE]; + struct threads threads; struct vdso_info *vdso_info; struct perf_env *env; struct dsos dsos; @@ -69,12 +60,6 @@ struct machine { bool trampolines_mapped; }; -static inline struct threads *machine__threads(struct machine *machine, pid_t tid) -{ - /* Cast it to handle tid == -1 */ - return &machine->threads[(unsigned int)tid % THREADS__TABLE_SIZE]; -} - /* * The main kernel (vmlinux) map */ @@ -220,7 +205,6 @@ bool machine__is(struct machine *machine, const char *arch); bool machine__normalized_is(struct machine *machine, const char *arch); int machine__nr_cpus_avail(struct machine *machine); -struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid); struct dso *machine__findnew_dso_id(struct machine *machine, const char *filename, struct dso_id *id); diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index c59ab4d79163..1aa8962dcf52 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -26,7 +26,7 @@ int thread__init_maps(struct thread *thread, struct machine *machine) if (pid == thread__tid(thread) || pid == -1) { thread__set_maps(thread, maps__new(machine)); } else { - struct thread *leader = __machine__findnew_thread(machine, pid, pid); + struct thread *leader = machine__findnew_thread(machine, pid, pid); if (leader) { thread__set_maps(thread, maps__get(thread__maps(leader))); diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 0df775b5c110..4b8f3e9e513b 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -3,7 +3,6 @@ #define __PERF_THREAD_H #include -#include #include #include #include @@ -30,11 +29,6 @@ struct lbr_stitch { struct callchain_cursor_node *prev_lbr_cursor; }; -struct thread_rb_node { - struct rb_node rb_node; - struct thread *thread; -}; - DECLARE_RC_STRUCT(thread) { /** @maps: mmaps associated with this thread. */ struct maps *maps; diff --git a/tools/perf/util/threads.c b/tools/perf/util/threads.c new file mode 100644 index 000000000000..d984ec939c7b --- /dev/null +++ b/tools/perf/util/threads.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "threads.h" +#include "machine.h" +#include "thread.h" + +struct thread_rb_node { + struct rb_node rb_node; + struct thread *thread; +}; + +static struct threads_table_entry *threads__table(struct threads *threads, pid_t tid) +{ + /* Cast it to handle tid == -1 */ + return &threads->table[(unsigned int)tid % THREADS__TABLE_SIZE]; +} + +void threads__init(struct threads *threads) +{ + for (int i = 0; i < THREADS__TABLE_SIZE; i++) { + struct threads_table_entry *table = &threads->table[i]; + + table->entries = RB_ROOT_CACHED; + init_rwsem(&table->lock); + table->nr = 0; + table->last_match = NULL; + } +} + +void threads__exit(struct threads *threads) +{ + threads__remove_all_threads(threads); + for (int i = 0; i < THREADS__TABLE_SIZE; i++) { + struct threads_table_entry *table = &threads->table[i]; + + exit_rwsem(&table->lock); + } +} + +size_t threads__nr(struct threads *threads) +{ + size_t nr = 0; + + for (int i = 0; i < THREADS__TABLE_SIZE; i++) { + struct threads_table_entry *table = &threads->table[i]; + + down_read(&table->lock); + nr += table->nr; + up_read(&table->lock); + } + return nr; +} + +/* + * Front-end cache - TID lookups come in blocks, + * so most of the time we dont have to look up + * the full rbtree: + */ +static struct thread *__threads_table_entry__get_last_match(struct threads_table_entry *table, + pid_t tid) +{ + struct thread *th, *res = NULL; + + th = table->last_match; + if (th != NULL) { + if (thread__tid(th) == tid) + res = thread__get(th); + } + return res; +} + +static void __threads_table_entry__set_last_match(struct threads_table_entry *table, + struct thread *th) +{ + thread__put(table->last_match); + table->last_match = thread__get(th); +} + +static void threads_table_entry__set_last_match(struct threads_table_entry *table, + struct thread *th) +{ + down_write(&table->lock); + __threads_table_entry__set_last_match(table, th); + up_write(&table->lock); +} + +struct thread *threads__find(struct threads *threads, pid_t tid) +{ + struct threads_table_entry *table = threads__table(threads, tid); + struct rb_node **p; + struct thread *res = NULL; + + down_read(&table->lock); + res = __threads_table_entry__get_last_match(table, tid); + if (res) + return res; + + p = &table->entries.rb_root.rb_node; + while (*p != NULL) { + struct rb_node *parent = *p; + struct thread *th = rb_entry(parent, struct thread_rb_node, rb_node)->thread; + + if (thread__tid(th) == tid) { + res = thread__get(th); + break; + } + + if (tid < thread__tid(th)) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + up_read(&table->lock); + if (res) + threads_table_entry__set_last_match(table, res); + return res; +} + +struct thread *threads__findnew(struct threads *threads, pid_t pid, pid_t tid, bool *created) +{ + struct threads_table_entry *table = threads__table(threads, tid); + struct rb_node **p; + struct rb_node *parent = NULL; + struct thread *res = NULL; + struct thread_rb_node *nd; + bool leftmost = true; + + *created = false; + down_write(&table->lock); + p = &table->entries.rb_root.rb_node; + while (*p != NULL) { + struct thread *th; + + parent = *p; + th = rb_entry(parent, struct thread_rb_node, rb_node)->thread; + + if (thread__tid(th) == tid) { + __threads_table_entry__set_last_match(table, th); + res = thread__get(th); + goto out_unlock; + } + + if (tid < thread__tid(th)) + p = &(*p)->rb_left; + else { + leftmost = false; + p = &(*p)->rb_right; + } + } + nd = malloc(sizeof(*nd)); + if (nd == NULL) + goto out_unlock; + res = thread__new(pid, tid); + if (!res) + free(nd); + else { + *created = true; + nd->thread = thread__get(res); + rb_link_node(&nd->rb_node, parent, p); + rb_insert_color_cached(&nd->rb_node, &table->entries, leftmost); + ++table->nr; + __threads_table_entry__set_last_match(table, res); + } +out_unlock: + up_write(&table->lock); + return res; +} + +void threads__remove_all_threads(struct threads *threads) +{ + for (int i = 0; i < THREADS__TABLE_SIZE; i++) { + struct threads_table_entry *table = &threads->table[i]; + struct rb_node *nd; + + down_write(&table->lock); + __threads_table_entry__set_last_match(table, NULL); + nd = rb_first_cached(&table->entries); + while (nd) { + struct thread_rb_node *trb = rb_entry(nd, struct thread_rb_node, rb_node); + + nd = rb_next(nd); + thread__put(trb->thread); + rb_erase_cached(&trb->rb_node, &table->entries); + RB_CLEAR_NODE(&trb->rb_node); + --table->nr; + + free(trb); + } + assert(table->nr == 0); + up_write(&table->lock); + } +} + +void threads__remove(struct threads *threads, struct thread *thread) +{ + struct rb_node **p; + struct threads_table_entry *table = threads__table(threads, thread__tid(thread)); + pid_t tid = thread__tid(thread); + + down_write(&table->lock); + if (table->last_match && RC_CHK_EQUAL(table->last_match, thread)) + __threads_table_entry__set_last_match(table, NULL); + + p = &table->entries.rb_root.rb_node; + while (*p != NULL) { + struct rb_node *parent = *p; + struct thread_rb_node *nd = rb_entry(parent, struct thread_rb_node, rb_node); + struct thread *th = nd->thread; + + if (RC_CHK_EQUAL(th, thread)) { + thread__put(nd->thread); + rb_erase_cached(&nd->rb_node, &table->entries); + RB_CLEAR_NODE(&nd->rb_node); + --table->nr; + free(nd); + break; + } + + if (tid < thread__tid(th)) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + up_write(&table->lock); +} + +int threads__for_each_thread(struct threads *threads, + int (*fn)(struct thread *thread, void *data), + void *data) +{ + for (int i = 0; i < THREADS__TABLE_SIZE; i++) { + struct threads_table_entry *table = &threads->table[i]; + struct rb_node *nd; + + for (nd = rb_first_cached(&table->entries); nd; nd = rb_next(nd)) { + struct thread_rb_node *trb = rb_entry(nd, struct thread_rb_node, rb_node); + int rc = fn(trb->thread, data); + + if (rc != 0) + return rc; + } + } + return 0; + +} diff --git a/tools/perf/util/threads.h b/tools/perf/util/threads.h new file mode 100644 index 000000000000..ed67de627578 --- /dev/null +++ b/tools/perf/util/threads.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_THREADS_H +#define __PERF_THREADS_H + +#include +#include "rwsem.h" + +struct thread; + +#define THREADS__TABLE_BITS 8 +#define THREADS__TABLE_SIZE (1 << THREADS__TABLE_BITS) + +struct threads_table_entry { + struct rb_root_cached entries; + struct rw_semaphore lock; + unsigned int nr; + struct thread *last_match; +}; + +struct threads { + struct threads_table_entry table[THREADS__TABLE_SIZE]; +}; + +void threads__init(struct threads *threads); +void threads__exit(struct threads *threads); +size_t threads__nr(struct threads *threads); +struct thread *threads__find(struct threads *threads, pid_t tid); +struct thread *threads__findnew(struct threads *threads, pid_t pid, pid_t tid, bool *created); +void threads__remove_all_threads(struct threads *threads); +void threads__remove(struct threads *threads, struct thread *thread); +int threads__for_each_thread(struct threads *threads, + int (*fn)(struct thread *thread, void *data), + void *data); + +#endif /* __PERF_THREADS_H */ From patchwork Fri Feb 2 06:15:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195593 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp238570dyc; Thu, 1 Feb 2024 22:19:11 -0800 (PST) X-Google-Smtp-Source: AGHT+IGwTy+zlbEq945jI4jifiiexYefqqA26m6T3dGgmqM7m65NVUYpFTBqa9LeOinf3aysm33k X-Received: by 2002:a05:6214:21c9:b0:682:59:2338 with SMTP id d9-20020a05621421c900b0068200592338mr1208404qvh.59.1706854751093; Thu, 01 Feb 2024 22:19:11 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854751; cv=pass; d=google.com; s=arc-20160816; b=YawGYd53rsDGviLg0l1nw7zejeQ0MJUezKMcDC02hIlEaxC76LOhCBrH5B43spy369 wSPIVGQ9qfm1mTp6DqM6pqW6PcoK+W7qtBOSbsAy5idrY50P+9NQ38TKYAe21mamaNuH W7F0Brzn5s5a3jsZlkvCu5Z/+rBRcDBHWLe0DzXVk/+WPnHVCw8HTWR0PM25bRvWhZrB QVJmCgy1ZeFzV2CviTt1J+Sp7JoLIYUJnU/7nTrhdE7V/wFJAYeDWVPcda+doB7O1sXj kw5O1QOGg+UBf4aU6o87ZHSlVBkYIjJW0g01dWdJ1QJeQYHLiivElFYggOiOhZ+65xqV z7Vg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=r8cuyus4waavntWUzMcbs7+5xI+OsCPQ5CRbneZJkcA=; fh=33qFiZhzca3PRgUAF1AdrpnfKVg6sDsiQU4xfYabzPk=; b=ZHyzqsY4MtD3tRCpjKrKPcp18D1dDwvEwExNcc2oDucbEqJP6MS++4LcLy4W5A4NiT HMvDdrTxy3+VY3Vq7rS2RSQTYsqMTZV9rJQNvPMRC0po4lfjO3I0x2iW2hTtB6iiFoKE SaYtsk5yOlZz0HFtgg/bz86CwgBrFbvWonjCWMJUKUwqHYNymEXhwcUpdvSy1L3G6747 aFQ42LuO6qjNwmCnqzgvPQna+V8GWYZe9PsjqmQcs9KDr6ciJIw8KSxvZZzjXUnXT5W5 RindoWeQGMsv7pcHabVgF0CH8wro8qmjJKlMS3dEaWYwePW08D6zBl2lh6zxm0I97owi 0aKg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=LqWkOEnn; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49251-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49251-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCVS3U622GKnaMPUBJ0tj0YC/jcEbBNiMpctsRe0yo/g1k2lh9jtEBHtDrYS0m43kLFl1rFdLT5ECPKAtssKi6xy8OXRmA== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id cz3-20020a056214088300b006816c71f3fasi1298146qvb.104.2024.02.01.22.19.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:19:11 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49251-ouuuleilei=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; dkim=pass header.i=@google.com header.s=20230601 header.b=LqWkOEnn; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49251-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49251-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 CF9921C2469D for ; Fri, 2 Feb 2024 06:19:10 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1387229420; Fri, 2 Feb 2024 06:16:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="LqWkOEnn" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.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 100DC1AACA for ; Fri, 2 Feb 2024 06:16:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854576; cv=none; b=YnCP13zeaV/+QryXIYieaa0sNXfHkAu7J97oHJWfKfNQfnroDVzH53IWHPJuNcCe5FnQPrqR/04pC0a0/LKvQ5ciwlpsnD0wTqJ66JZ7Ewh1hc+m0IN66O/1tgwOfEEdahPXf/bjW0FyKIeF5gTc6AAZN/dkAYj34VH2FA5BorA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854576; c=relaxed/simple; bh=vS3HQqPNbnCSG6H0mLijqDfI30W+eyfGf7Du2zJBBGI=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=nR8hg9EOztzWSXcj7piQdfsbHD8jzpsYys5psadj6S1KbqwpKdbAco+p3tC2op8d9yOWIEMR1BzVfmt+yZDCwR83569ybJt7GWfoC3Y1RKS4SEUrqiPqhE2qsM+4t4peRCFfih7ALaBB+nHhIOXazjVzZco/oNGDvAORq4YFpIk= 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=LqWkOEnn; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc657e9bdc4so2429413276.0 for ; Thu, 01 Feb 2024 22:16:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854574; x=1707459374; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=r8cuyus4waavntWUzMcbs7+5xI+OsCPQ5CRbneZJkcA=; b=LqWkOEnnZ/TIfV4hGMcpYhLQBD888gwe4X3PrdMFKQlUgDPXmhvmTZ6dQcrUNP5UJN vrSF9+kl9dF0P3icPObwZ9C6qPgmTCbG+P4l9z5lbxsM9JMQ7tOyZ0R+WPkazYrQaITs 15rrg1flN2Lv8oKroAjyaL6GldCzCAaywPeVOiF1tqujFPo70GfuAn7nb/MqzN7HxmLV pLQ8C2y/pDZsF+ejWNOSc9hJIk5OyWc1grbkmgMD+TuEOZDl0IaMHuJ5GUqCYzVzEmHJ mv13VhHg1+dTEfUjvHnk71Ml6B1PwaTlPcT9YdNBf2SxT2LYrVIbzQzAQcsulzc35mP5 7ZLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854574; x=1707459374; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=r8cuyus4waavntWUzMcbs7+5xI+OsCPQ5CRbneZJkcA=; b=Bl+T2c4wp7Jpwac6vdrgSjAgA7NaIDMHrMvfjV4qHbLcFVqfV8enJWWFeH9VFQlD+F q2p3eblryV/8VZ5IpKReALAQEy/6/zos5mDwO1vqTCObBMXcDRXPaJnQ762x3aydm0ES 5Nktg2u5XZiOt5NntpeExQzzL/wjSZ3Jyfj/JvCeSEaxh+i+o2Vb6wj7aeijxhSa4pWf XPfj9bJOn0ihEGyMrW9/QIGQ+wlwFrCStjqBd4e8N3ugPsnV2wJK6A5uzoIWaNuG+GtQ nVGVnk0wJ25YRotdSahA5LZKVWY+I2KDVM40fwaG5TcB6ztuZ+TdSWHezDVYJg368VZI Qljw== X-Gm-Message-State: AOJu0Ywqp2Z5YNS1qZKoZcLQLXoIo6LVOgS0aVHawtWDfUS77BQ+OZ8J mGvBTkOpGlW47d1xpWkc8pVgOb7ahoh8cxnv6pvzb0ixTMRIFa6u6C2nEe8QsYHhI7RLl13pS+j iN7EP7w== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:108d:b0:dc6:d9eb:6422 with SMTP id v13-20020a056902108d00b00dc6d9eb6422mr67423ybu.10.1706854574065; Thu, 01 Feb 2024 22:16:14 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:19 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-13-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 12/25] perf threads: Switch from rbtree to hashmap From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766927203525219 X-GMAIL-MSGID: 1789766927203525219 The rbtree provides a sorting on entries but this is unused. Switch to using hashmap for O(1) rather than O(log n) find/insert/remove complexity. Signed-off-by: Ian Rogers --- tools/perf/util/threads.c | 146 ++++++++++++-------------------------- tools/perf/util/threads.h | 6 +- 2 files changed, 47 insertions(+), 105 deletions(-) diff --git a/tools/perf/util/threads.c b/tools/perf/util/threads.c index d984ec939c7b..55923be53180 100644 --- a/tools/perf/util/threads.c +++ b/tools/perf/util/threads.c @@ -3,25 +3,30 @@ #include "machine.h" #include "thread.h" -struct thread_rb_node { - struct rb_node rb_node; - struct thread *thread; -}; - static struct threads_table_entry *threads__table(struct threads *threads, pid_t tid) { /* Cast it to handle tid == -1 */ return &threads->table[(unsigned int)tid % THREADS__TABLE_SIZE]; } +static size_t key_hash(long key, void *ctx __maybe_unused) +{ + /* The table lookup removes low bit entropy, but this is just ignored here. */ + return key; +} + +static bool key_equal(long key1, long key2, void *ctx __maybe_unused) +{ + return key1 == key2; +} + void threads__init(struct threads *threads) { for (int i = 0; i < THREADS__TABLE_SIZE; i++) { struct threads_table_entry *table = &threads->table[i]; - table->entries = RB_ROOT_CACHED; + hashmap__init(&table->shard, key_hash, key_equal, NULL); init_rwsem(&table->lock); - table->nr = 0; table->last_match = NULL; } } @@ -32,6 +37,7 @@ void threads__exit(struct threads *threads) for (int i = 0; i < THREADS__TABLE_SIZE; i++) { struct threads_table_entry *table = &threads->table[i]; + hashmap__clear(&table->shard); exit_rwsem(&table->lock); } } @@ -44,7 +50,7 @@ size_t threads__nr(struct threads *threads) struct threads_table_entry *table = &threads->table[i]; down_read(&table->lock); - nr += table->nr; + nr += hashmap__size(&table->shard); up_read(&table->lock); } return nr; @@ -86,28 +92,13 @@ static void threads_table_entry__set_last_match(struct threads_table_entry *tabl struct thread *threads__find(struct threads *threads, pid_t tid) { struct threads_table_entry *table = threads__table(threads, tid); - struct rb_node **p; - struct thread *res = NULL; + struct thread *res; down_read(&table->lock); res = __threads_table_entry__get_last_match(table, tid); - if (res) - return res; - - p = &table->entries.rb_root.rb_node; - while (*p != NULL) { - struct rb_node *parent = *p; - struct thread *th = rb_entry(parent, struct thread_rb_node, rb_node)->thread; - - if (thread__tid(th) == tid) { - res = thread__get(th); - break; - } - - if (tid < thread__tid(th)) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; + if (!res) { + if (hashmap__find(&table->shard, tid, &res)) + res = thread__get(res); } up_read(&table->lock); if (res) @@ -118,49 +109,25 @@ struct thread *threads__find(struct threads *threads, pid_t tid) struct thread *threads__findnew(struct threads *threads, pid_t pid, pid_t tid, bool *created) { struct threads_table_entry *table = threads__table(threads, tid); - struct rb_node **p; - struct rb_node *parent = NULL; struct thread *res = NULL; - struct thread_rb_node *nd; - bool leftmost = true; *created = false; down_write(&table->lock); - p = &table->entries.rb_root.rb_node; - while (*p != NULL) { - struct thread *th; - - parent = *p; - th = rb_entry(parent, struct thread_rb_node, rb_node)->thread; - - if (thread__tid(th) == tid) { - __threads_table_entry__set_last_match(table, th); - res = thread__get(th); - goto out_unlock; - } - - if (tid < thread__tid(th)) - p = &(*p)->rb_left; - else { - leftmost = false; - p = &(*p)->rb_right; - } - } - nd = malloc(sizeof(*nd)); - if (nd == NULL) - goto out_unlock; res = thread__new(pid, tid); - if (!res) - free(nd); - else { - *created = true; - nd->thread = thread__get(res); - rb_link_node(&nd->rb_node, parent, p); - rb_insert_color_cached(&nd->rb_node, &table->entries, leftmost); - ++table->nr; - __threads_table_entry__set_last_match(table, res); + if (res) { + if (hashmap__add(&table->shard, tid, res)) { + /* Add failed. Assume a race so find other entry. */ + thread__put(res); + res = NULL; + if (hashmap__find(&table->shard, tid, &res)) + res = thread__get(res); + } else { + res = thread__get(res); + *created = true; + } + if (res) + __threads_table_entry__set_last_match(table, res); } -out_unlock: up_write(&table->lock); return res; } @@ -169,57 +136,32 @@ void threads__remove_all_threads(struct threads *threads) { for (int i = 0; i < THREADS__TABLE_SIZE; i++) { struct threads_table_entry *table = &threads->table[i]; - struct rb_node *nd; + struct hashmap_entry *cur, *tmp; + size_t bkt; down_write(&table->lock); __threads_table_entry__set_last_match(table, NULL); - nd = rb_first_cached(&table->entries); - while (nd) { - struct thread_rb_node *trb = rb_entry(nd, struct thread_rb_node, rb_node); - - nd = rb_next(nd); - thread__put(trb->thread); - rb_erase_cached(&trb->rb_node, &table->entries); - RB_CLEAR_NODE(&trb->rb_node); - --table->nr; + hashmap__for_each_entry_safe((&table->shard), cur, tmp, bkt) { + struct thread *old_value; - free(trb); + hashmap__delete(&table->shard, cur->key, /*old_key=*/NULL, &old_value); + thread__put(old_value); } - assert(table->nr == 0); up_write(&table->lock); } } void threads__remove(struct threads *threads, struct thread *thread) { - struct rb_node **p; struct threads_table_entry *table = threads__table(threads, thread__tid(thread)); - pid_t tid = thread__tid(thread); + struct thread *old_value; down_write(&table->lock); if (table->last_match && RC_CHK_EQUAL(table->last_match, thread)) __threads_table_entry__set_last_match(table, NULL); - p = &table->entries.rb_root.rb_node; - while (*p != NULL) { - struct rb_node *parent = *p; - struct thread_rb_node *nd = rb_entry(parent, struct thread_rb_node, rb_node); - struct thread *th = nd->thread; - - if (RC_CHK_EQUAL(th, thread)) { - thread__put(nd->thread); - rb_erase_cached(&nd->rb_node, &table->entries); - RB_CLEAR_NODE(&nd->rb_node); - --table->nr; - free(nd); - break; - } - - if (tid < thread__tid(th)) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } + hashmap__delete(&table->shard, thread__tid(thread), /*old_key=*/NULL, &old_value); + thread__put(old_value); up_write(&table->lock); } @@ -229,11 +171,11 @@ int threads__for_each_thread(struct threads *threads, { for (int i = 0; i < THREADS__TABLE_SIZE; i++) { struct threads_table_entry *table = &threads->table[i]; - struct rb_node *nd; + struct hashmap_entry *cur; + size_t bkt; - for (nd = rb_first_cached(&table->entries); nd; nd = rb_next(nd)) { - struct thread_rb_node *trb = rb_entry(nd, struct thread_rb_node, rb_node); - int rc = fn(trb->thread, data); + hashmap__for_each_entry((&table->shard), cur, bkt) { + int rc = fn((struct thread *)cur->pvalue, data); if (rc != 0) return rc; diff --git a/tools/perf/util/threads.h b/tools/perf/util/threads.h index ed67de627578..d03bd91a7769 100644 --- a/tools/perf/util/threads.h +++ b/tools/perf/util/threads.h @@ -2,7 +2,7 @@ #ifndef __PERF_THREADS_H #define __PERF_THREADS_H -#include +#include "hashmap.h" #include "rwsem.h" struct thread; @@ -11,9 +11,9 @@ struct thread; #define THREADS__TABLE_SIZE (1 << THREADS__TABLE_BITS) struct threads_table_entry { - struct rb_root_cached entries; + /* Key is tid, value is struct thread. */ + struct hashmap shard; struct rw_semaphore lock; - unsigned int nr; struct thread *last_match; }; From patchwork Fri Feb 2 06:15:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195596 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp238874dyc; Thu, 1 Feb 2024 22:20:01 -0800 (PST) X-Google-Smtp-Source: AGHT+IFJpb9QmMxEM1xlTdeukHAmD4Ho8yyM3rFm6H5aK81eOZePgJXfBjkFqmhX89QYHXj+mzCh X-Received: by 2002:a05:6808:1528:b0:3be:a790:3456 with SMTP id u40-20020a056808152800b003bea7903456mr8607976oiw.21.1706854798764; Thu, 01 Feb 2024 22:19:58 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854798; cv=pass; d=google.com; s=arc-20160816; b=nQ6UmMm9XJfu+i8BxIiEJzNSBqIomu004KSSQ0e054qV4Grk7tqSuYCdcgTd8FBo+k TpslFibDnPn4mzlNxoqFjRZPdCUTZPrkpwvwku9eKZoiE+MOHBs1qJ1qzqbx30qjyQ6R ravBeZUc04W1SCtMVTzlUvC+s1hXFYAUvY5FGI6+u3YqyMwbXqYJrH0HTOdarguxVAuw GAZ407/l/Eg8ZbcVwEMrtueQut3vbZqkEUrdqHE6DMnuZj/ymy2zcjv7XPayUbuQSGon ZJcTRNELB+cLxW0/V7uscJluVF6mcpcIxMXHblzXh6JXecrPa+gPnUVZhtvGppf0ivcA qEkw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=Rt20z4T5VPT3LRcytD9SJzsjA7tToX3uHX4SxOAPIZ4=; fh=yIzt92Mi0+yF5NODp+htzBAg/ItYvj75LZzmw6qaOnk=; b=iTrEwL8raUbEEAHKgukPK+qb2/u9WCaoo2hFBNy85s6q7kKOdef0Sf0GA5oVog1vFa tbuSu5qCDt4TMXvu+mRARyYIolG6AxAqrMmXlfX3q+MfiEpeReSti0TEaR97joV9MXAx w3eq76Jl312ivJl0tVQgmd6QDEbvh0vL2WpazNAP0bOWQbruFd/lEr+XCbha6N0k1boE QT+dOkT/+8qcQnhTawwCvztrhnGdmc8o2b9VGZNUGRX1zwqa6fAzGj801sIeU41V0q6z PJ0ca6ZwPPhV5XkuJ0R8mla9MFCYxBltkYNslUVlXYvT0lPyB2LCBp1XByNHUs/+QtzB YtCQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=gtwdmomx; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49252-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49252-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCV18qzuUnHlQZYtBqiFKxBNq0VNCfzdimS8iLMyQPz6rn24+/i6AicGjsXcz9NAJaktxI8CdggJXzhtN9w0uTESacU0jA== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id i16-20020a635410000000b005b91536981csi1118557pgb.11.2024.02.01.22.19.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:19:58 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49252-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=gtwdmomx; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49252-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49252-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 15FFD28489A for ; Fri, 2 Feb 2024 06:19:22 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 800A63986E; Fri, 2 Feb 2024 06:16:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="gtwdmomx" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 7C8751AAD2 for ; Fri, 2 Feb 2024 06:16:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854579; cv=none; b=YXTAm53w5C2bsBCLZ4aT1uZrQGHEvLqF1tJAk7RyWpzKwSwXZCpiR0TxBm8lumgiSzcSjMo3V5xa8CNjYQ3M2HuCFnMubxrWUjVVjqZXNNFXsShzahoFQY6EdDuZNPC62Y/ZkTY8MlDytuDBX0y2OFu3Iz/+5Zfn5ktuL0d13qw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854579; c=relaxed/simple; bh=x/5fHTR183S/2RfEcYCstWfa0bGQ3QCOM8/PnsO9ubE=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=be9JDWWSnZflCjqxCiX9QnQv0pLyY7cmyrDiT53HjYLH6SJpyQANF5pIesHAXBAYpb4qawNYVc61b5GjAvx4lpLfqv/tNhrgEsBPRVMpDf6PaqTyyypGgKZ0OAECzvMRwRC545Q+akXMVogNO3h3HAjKn5ClPIT4JmpbuLHVzm0= 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=gtwdmomx; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6041dbb7a78so25540717b3.0 for ; Thu, 01 Feb 2024 22:16:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854576; x=1707459376; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=Rt20z4T5VPT3LRcytD9SJzsjA7tToX3uHX4SxOAPIZ4=; b=gtwdmomx2Cp+Mp32uFL94bep/cCR2gYlgs/3O7l6drunD0zB5E+ROXF0LAJg4mS7td V9c1sye0U63OOIwjoCg66JjJRdDIjyPXQhYVe4to8pYXthL4/fNelEVEUny1BOeaEBHz GkVvGREGlPESkavGdja3hKtySNT4g1Qk8bb1UlvO2r+nHOc5sCJd/8n8gVLULZMXBr3y inXC6NNB0s7nNUBUC6gBIV2aruABwj9vrdgmpOEH9ZZmeCsBiwd2PUyb8A7g9rE1nZ8m +xqFUYScUgWJpOCs2vZX9yctlGhVsb262klCmEGP59BtKoYS/tbl6kOM2t3lwCmlymnk 3RvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854576; x=1707459376; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Rt20z4T5VPT3LRcytD9SJzsjA7tToX3uHX4SxOAPIZ4=; b=KEcRDAanDMbrVtuXsDXqayJxb02PwsfrEIc+ABqBTil9XDaK9vHnC/Z8VJxYT+kPh0 2xPRRv8qFeQTD9SxrFcQoGXfq1RpgzLuuLL1118C3qEBTSTjs/seCl7KUpoR9wrJcdBu r2b7ey5hpy4jpDPZXrktXlCXKm/E/Mm1joL8PtdkWSF9xSIeYgqkd6dqEviIpS1N2lYg T9WoUVnPlQo99N7HgPJk+tLEaUgX7VBhK00Hoc3LFEob35itanImbnJN61TKdN0bocvT CM5dJgeWdCtdkYR2jvPN8+zWA2yEL87LpljfR6F4x9/04HenDjI/hJ2FV59W+CBriTdo TQiA== X-Gm-Message-State: AOJu0YyxUvd18hhmxSQji3/1/J9Ww3yNrSv591VfGVED4hJuZB3HKy+C u01Y7V1+t2hZ4pLy6JhmmdKG7UmSXq74wncsJYLk0iAaqVaeTe9qcF4JkvJm12hoHyYfyNxz/+Y D7i06hw== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a81:9b4d:0:b0:604:5ca:5ab2 with SMTP id s74-20020a819b4d000000b0060405ca5ab2mr1614230ywg.9.1706854576529; Thu, 01 Feb 2024 22:16:16 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:20 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-14-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 13/25] perf threads: Reduce table size from 256 to 8 From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766977290715858 X-GMAIL-MSGID: 1789766977290715858 The threads data structure is an array of hashmaps, previously rbtrees. The two levels allows for a fixed outer array where access is guarded by rw_semaphores. Commit 91e467bc568f ("perf machine: Use hashtable for machine threads") sized the outer table at 256 entries to avoid future scalability problems, however, this means the threads struct is sized at 30,720 bytes. As the hashmaps allow O(1) access for the common find/insert/remove operations, lower the number of entries to 8. This reduces the size overhead to 960 bytes. Signed-off-by: Ian Rogers --- tools/perf/util/threads.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/threads.h b/tools/perf/util/threads.h index d03bd91a7769..da68d2223f18 100644 --- a/tools/perf/util/threads.h +++ b/tools/perf/util/threads.h @@ -7,7 +7,7 @@ struct thread; -#define THREADS__TABLE_BITS 8 +#define THREADS__TABLE_BITS 3 #define THREADS__TABLE_SIZE (1 << THREADS__TABLE_BITS) struct threads_table_entry { From patchwork Fri Feb 2 06:15:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195595 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp238797dyc; Thu, 1 Feb 2024 22:19:48 -0800 (PST) X-Google-Smtp-Source: AGHT+IEz6bKkR2ubcykPFIi8MpjTsTBx/XRiymV1z19x8XzBqwc16nMI9eZFO4vEzPNq6e14be8W X-Received: by 2002:ac8:5bc1:0:b0:42a:85ee:a91 with SMTP id b1-20020ac85bc1000000b0042a85ee0a91mr4734909qtb.65.1706854788659; Thu, 01 Feb 2024 22:19:48 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854788; cv=pass; d=google.com; s=arc-20160816; b=sywxFS4cXU7v9TZP9BMJMqcQeJLfTVOMSEx1xhUmI/K1kTX/TecEo1EEtRWVe4gVMs VQ4rQ7ICJCzg50v/VwrwRuPeSuY+hB9aJTEN6+Zxl3B8tfyH3t3aPHlIKqs3cgZsJjl8 ymIDZ3SAXbpIqJUM7JLXC2zrCR6H9jAy9vIQ4hOac4bfTvol1HZQP9MHS0i4QPwaLXO3 56cuWwqdM3UfImhm/DmxQoOSDsmrCExGwu0peFA8iS3BSo828Q2AzCv1a332fl7sAXT8 6bRThVLEjZ5qWfPemujJxEZ34BSsFjBX+7G4UXnm2abDxht66ROvhdM5YS3c0zNrlQ1N mEkA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=mXogDo+6q/mPbZDdbW0fAeXsEyRZMpGXEP5SHwZqJ18=; fh=PNCmAy5BJMhTbkQn6DADhSAY4ncyMulWCqVN4JaelRs=; b=BUwnUmG5tCxHR/119PQ4P6gJMEtXAqHLwB4VvZOvjLXvhqQLGixYdDWLJGPDg1ntka yS7aVayicU3EjW4nyb2Nd9RLPWa4RXIXXCOoUA+94UNqtucMy34r87S9BbMB03cpjav3 SOLI+gtl82KeJ/E8a9tEuNKAmWBm3gu8DRlupvYuf5o9jJe/SyfwHDNIGv18ggZUKgE6 t5X7ppJDLO7etaRriuYkS6JLNEn/0Cq7rKppsbUGwYTAQL6SRvKUgV2Xi/VLe7WB5i7D YDZCYDtTK6KD46gyUB/LiD0B5RjdrQUzFznuHxwIx0igH/Be1IHP4ZKIAs+AE/3ylYJB 6OhA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=FMyNxbhY; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49253-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49253-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCXOH1DH4abG6Z2WzkVXqq87x3f2+VNdMsHWfOZfwsTZCfOrgdDLbT9EXgKn7gJ3Uac6WciBB0sjoAxpu5csCcVGDyqgyA== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id f14-20020ac87f0e000000b00429c9588f86si1261645qtk.753.2024.02.01.22.19.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:19:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49253-ouuuleilei=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; dkim=pass header.i=@google.com header.s=20230601 header.b=FMyNxbhY; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49253-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49253-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 662DF1C246FD for ; Fri, 2 Feb 2024 06:19:48 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7D69C3FE46; Fri, 2 Feb 2024 06:16:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="FMyNxbhY" Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 0E2DC199AD for ; Fri, 2 Feb 2024 06:16:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854581; cv=none; b=CA70JCFAfjXEkkxr7IdXffnkDqa/6sAZKrG9T9zhWTdsCDCov8BkFlv0vm3antPjGlMsDWSdgitEQf+pjRBynUpvaYhv3kR+qbrhaj7+SyHAj01vkhDtuEeu8L1OkfVrSKJdqj0rzl+Zd76bWKngwv7wMttHF4k09qP8Rx5vI2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854581; c=relaxed/simple; bh=j92hVn9YgCWJ2fm11qA6UVczuOUwP6B514JEUF/+mfg=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=tTob/0qJYOm5HFztLuiAZ51LnMXyErc+QcsC0zXqy2JpEwGemDY1QAZVv/1QT68ji8uJUVP/SGxoECstOBgflQu9D+SAYmyK+srMV64OaquSpGI+1P/I5q7fMUWS7ttpUV5nL05adNRqSHPMfDN94OnwnpsbjZGz2JK74L8hl90= 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=FMyNxbhY; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-60416f4cba4so33443597b3.2 for ; Thu, 01 Feb 2024 22:16:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854579; x=1707459379; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=mXogDo+6q/mPbZDdbW0fAeXsEyRZMpGXEP5SHwZqJ18=; b=FMyNxbhYBu/yB93ViMyKyecrw/utbWrA96Xqnw48W5N0GQF2JMN3Qcv29F7UTfZsPj bgRcP6ZVPIr4QRrhZBgxyaUJIv6IIWJquGeirlWtFuBgXebgYCFRDlxZcSTjv2WzLOC8 xNXhMaBxBcHKh9Ofo2Ot07t/tBM//sXnIIvsQjKz96+T1UlgrSquJJaREhSHleyldpJn q+pYu5oTCe7+BA4EKI3g1ndPvhODzAT4hrUR0jF8Ff922dqX7/rttwenxasfXNg2tZPe 4WnCcqeJ4iXWl8qLyP1synjB7g2fgtrI4WKcYuMY2///aqKpxXvTW4GV1uncPeJR4kbM py4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854579; x=1707459379; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mXogDo+6q/mPbZDdbW0fAeXsEyRZMpGXEP5SHwZqJ18=; b=iGor4hL0kxJPBRaJqBoyEa52hb88NyCoHduh4wu2PTkDHpF+q0lAlLrCpGqW3bFp9n 7if2PeHBhiZDyScvmV34Sf5e/v2tBL1aCxGU5i4Qh8seKLWit2mCfYPfGg761e4EUfcm CUEbJ0sqqrcwpSeFwg7f3WfdW294bxNYwHZTY7YXrpVDkGhwwmrAKB52KrNYuONqw3ND UUJwfyFNTvwpEz+YNMAVJV+9y8YYGjs4MT9QMcgJ9OgL+cpDhIDXqEfZbxi5FHS+BU26 L6cQf0kQ5GCBBdU7dcHBeCDiTMirM/3xf5+ZyFkA73Q5+cp6qvqpSqvNvmPOQCkgqCk3 GhKA== X-Gm-Message-State: AOJu0YxjiyuuJahoEXg28Wp9PWwD+DRMCLtjwoS/cHn4eYkhao5TkonA FHfBIG1m5PRaltRYujQVleaPrFWEJb53sAIF0o4BFPddiiGCxj5JYyLX+AJG5w4eX/Okfz/lVi/ 7HIzmdw== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a81:98d1:0:b0:604:225f:3b4b with SMTP id p200-20020a8198d1000000b00604225f3b4bmr341248ywg.5.1706854579150; Thu, 01 Feb 2024 22:16:19 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:21 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-15-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 14/25] perf dsos: Attempt to better abstract dsos internals From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789766967299611083 X-GMAIL-MSGID: 1789766967299611083 Move functions from machine and build-id to dsos. Pass dsos struct rather than internal state. Rename some functions to better represent which data structure they operate on. Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/util/build-id.c | 38 +--------------------------- tools/perf/util/build-id.h | 2 -- tools/perf/util/dso.h | 6 ----- tools/perf/util/dsos.c | 49 ++++++++++++++++++++++++++++++++++--- tools/perf/util/dsos.h | 19 +++++++++++--- tools/perf/util/machine.c | 40 ++++++------------------------ tools/perf/util/machine.h | 2 ++ tools/perf/util/session.c | 21 ++++++++++++++++ tools/perf/util/session.h | 2 ++ 11 files changed, 97 insertions(+), 86 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index eb3ef5c24b66..ef73317e6ae7 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -2122,7 +2122,7 @@ static int __cmd_inject(struct perf_inject *inject) */ if (perf_header__has_feat(&session->header, HEADER_BUILD_ID) && inject->have_auxtrace && !inject->itrace_synth_opts.set) - dsos__hit_all(session); + perf_session__dsos_hit_all(session); /* * The AUX areas have been removed and replaced with * synthesized hardware events, so clear the feature flag. diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0b6f29fa0064..b89460cfc96d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1787,7 +1787,7 @@ record__finish_output(struct record *rec) process_buildids(rec); if (rec->buildid_all) - dsos__hit_all(rec->session); + perf_session__dsos_hit_all(rec->session); } perf_session__write_header(rec->session, rec->evlist, fd, true); diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 03c64b85383b..a617b1917e6b 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -390,42 +390,6 @@ int perf_session__write_buildid_table(struct perf_session *session, return err; } -static int __dsos__hit_all(struct list_head *head) -{ - struct dso *pos; - - list_for_each_entry(pos, head, node) - pos->hit = true; - - return 0; -} - -static int machine__hit_all_dsos(struct machine *machine) -{ - return __dsos__hit_all(&machine->dsos.head); -} - -int dsos__hit_all(struct perf_session *session) -{ - struct rb_node *nd; - int err; - - err = machine__hit_all_dsos(&session->machines.host); - if (err) - return err; - - for (nd = rb_first_cached(&session->machines.guests); nd; - nd = rb_next(nd)) { - struct machine *pos = rb_entry(nd, struct machine, rb_node); - - err = machine__hit_all_dsos(pos); - if (err) - return err; - } - - return 0; -} - void disable_buildid_cache(void) { no_buildid_cache = true; @@ -992,7 +956,7 @@ int perf_session__cache_build_ids(struct perf_session *session) static bool machine__read_build_ids(struct machine *machine, bool with_hits) { - return __dsos__read_build_ids(&machine->dsos.head, with_hits); + return __dsos__read_build_ids(&machine->dsos, with_hits); } bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index 4e3a1169379b..3fa8bffb07ca 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -39,8 +39,6 @@ int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct evsel *evsel, struct machine *machine); -int dsos__hit_all(struct perf_session *session); - int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct evsel *evsel, struct machine *machine); diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 33a41bcea335..2b9cf9177085 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -232,12 +232,6 @@ struct dso { #define dso__for_each_symbol(dso, pos, n) \ symbols__for_each_entry(&(dso)->symbols, pos, n) -#define dsos__for_each_with_build_id(pos, head) \ - list_for_each_entry(pos, head, node) \ - if (!pos->has_build_id) \ - continue; \ - else - static inline void dso__set_loaded(struct dso *dso) { dso->loaded = true; diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index cf80aa42dd07..e65ef6762bed 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -12,6 +12,35 @@ #include // filename__read_build_id #include +void dsos__init(struct dsos *dsos) +{ + INIT_LIST_HEAD(&dsos->head); + dsos->root = RB_ROOT; + init_rwsem(&dsos->lock); +} + +static void dsos__purge(struct dsos *dsos) +{ + struct dso *pos, *n; + + down_write(&dsos->lock); + + list_for_each_entry_safe(pos, n, &dsos->head, node) { + RB_CLEAR_NODE(&pos->rb_node); + pos->root = NULL; + list_del_init(&pos->node); + dso__put(pos); + } + + up_write(&dsos->lock); +} + +void dsos__exit(struct dsos *dsos) +{ + dsos__purge(dsos); + exit_rwsem(&dsos->lock); +} + static int __dso_id__cmp(struct dso_id *a, struct dso_id *b) { if (a->maj > b->maj) return -1; @@ -73,8 +102,9 @@ int dso__cmp_id(struct dso *a, struct dso *b) return __dso_id__cmp(&a->id, &b->id); } -bool __dsos__read_build_ids(struct list_head *head, bool with_hits) +bool __dsos__read_build_ids(struct dsos *dsos, bool with_hits) { + struct list_head *head = &dsos->head; bool have_build_id = false; struct dso *pos; struct nscookie nsc; @@ -303,9 +333,10 @@ struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id return dso; } -size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, +size_t __dsos__fprintf_buildid(struct dsos *dsos, FILE *fp, bool (skip)(struct dso *dso, int parm), int parm) { + struct list_head *head = &dsos->head; struct dso *pos; size_t ret = 0; @@ -320,8 +351,9 @@ size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, return ret; } -size_t __dsos__fprintf(struct list_head *head, FILE *fp) +size_t __dsos__fprintf(struct dsos *dsos, FILE *fp) { + struct list_head *head = &dsos->head; struct dso *pos; size_t ret = 0; @@ -331,3 +363,14 @@ size_t __dsos__fprintf(struct list_head *head, FILE *fp) return ret; } + +int __dsos__hit_all(struct dsos *dsos) +{ + struct list_head *head = &dsos->head; + struct dso *pos; + + list_for_each_entry(pos, head, node) + pos->hit = true; + + return 0; +} diff --git a/tools/perf/util/dsos.h b/tools/perf/util/dsos.h index 5dbec2bc6966..1c81ddf07f8f 100644 --- a/tools/perf/util/dsos.h +++ b/tools/perf/util/dsos.h @@ -21,6 +21,15 @@ struct dsos { struct rw_semaphore lock; }; +#define dsos__for_each_with_build_id(pos, head) \ + list_for_each_entry(pos, head, node) \ + if (!pos->has_build_id) \ + continue; \ + else + +void dsos__init(struct dsos *dsos); +void dsos__exit(struct dsos *dsos); + void __dsos__add(struct dsos *dsos, struct dso *dso); void dsos__add(struct dsos *dsos, struct dso *dso); struct dso *__dsos__addnew(struct dsos *dsos, const char *name); @@ -28,13 +37,15 @@ struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short); struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id *id); +bool __dsos__read_build_ids(struct dsos *dsos, bool with_hits); + struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso *dso, const char *name, struct dso_id *id); -bool __dsos__read_build_ids(struct list_head *head, bool with_hits); - -size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, +size_t __dsos__fprintf_buildid(struct dsos *dsos, FILE *fp, bool (skip)(struct dso *dso, int parm), int parm); -size_t __dsos__fprintf(struct list_head *head, FILE *fp); +size_t __dsos__fprintf(struct dsos *dsos, FILE *fp); + +int __dsos__hit_all(struct dsos *dsos); #endif /* __PERF_DSOS */ diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index e668a97255f8..d235d65fb35b 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -48,13 +48,6 @@ static struct dso *machine__kernel_dso(struct machine *machine) return map__dso(machine->vmlinux_map); } -static void dsos__init(struct dsos *dsos) -{ - INIT_LIST_HEAD(&dsos->head); - dsos->root = RB_ROOT; - init_rwsem(&dsos->lock); -} - static int machine__set_mmap_name(struct machine *machine) { if (machine__is_host(machine)) @@ -165,28 +158,6 @@ struct machine *machine__new_kallsyms(void) return machine; } -static void dsos__purge(struct dsos *dsos) -{ - struct dso *pos, *n; - - down_write(&dsos->lock); - - list_for_each_entry_safe(pos, n, &dsos->head, node) { - RB_CLEAR_NODE(&pos->rb_node); - pos->root = NULL; - list_del_init(&pos->node); - dso__put(pos); - } - - up_write(&dsos->lock); -} - -static void dsos__exit(struct dsos *dsos) -{ - dsos__purge(dsos); - exit_rwsem(&dsos->lock); -} - void machine__delete_threads(struct machine *machine) { threads__remove_all_threads(&machine->threads); @@ -906,11 +877,11 @@ static struct map *machine__addnew_module_map(struct machine *machine, u64 start size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) { struct rb_node *nd; - size_t ret = __dsos__fprintf(&machines->host.dsos.head, fp); + size_t ret = __dsos__fprintf(&machines->host.dsos, fp); for (nd = rb_first_cached(&machines->guests); nd; nd = rb_next(nd)) { struct machine *pos = rb_entry(nd, struct machine, rb_node); - ret += __dsos__fprintf(&pos->dsos.head, fp); + ret += __dsos__fprintf(&pos->dsos, fp); } return ret; @@ -919,7 +890,7 @@ size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) size_t machine__fprintf_dsos_buildid(struct machine *m, FILE *fp, bool (skip)(struct dso *dso, int parm), int parm) { - return __dsos__fprintf_buildid(&m->dsos.head, fp, skip, parm); + return __dsos__fprintf_buildid(&m->dsos, fp, skip, parm); } size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp, @@ -3281,3 +3252,8 @@ bool machine__is_lock_function(struct machine *machine, u64 addr) return false; } + +int machine__hit_all_dsos(struct machine *machine) +{ + return __dsos__hit_all(&machine->dsos); +} diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index e28c787616fe..05927aa3e813 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -306,4 +306,6 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine, int machine__resolve(struct machine *machine, struct addr_location *al, struct perf_sample *sample); +int machine__hit_all_dsos(struct machine *machine); + #endif /* __PERF_MACHINE_H */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 199d3e8df315..e7b5d360a212 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -2906,3 +2906,24 @@ int perf_event__process_id_index(struct perf_session *session, } return 0; } + +int perf_session__dsos_hit_all(struct perf_session *session) +{ + struct rb_node *nd; + int err; + + err = machine__hit_all_dsos(&session->machines.host); + if (err) + return err; + + for (nd = rb_first_cached(&session->machines.guests); nd; + nd = rb_next(nd)) { + struct machine *pos = rb_entry(nd, struct machine, rb_node); + + err = machine__hit_all_dsos(pos); + if (err) + return err; + } + + return 0; +} diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index ee3715e8563b..25c0d6c9cac9 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -154,6 +154,8 @@ int perf_session__deliver_synth_event(struct perf_session *session, union perf_event *event, struct perf_sample *sample); +int perf_session__dsos_hit_all(struct perf_session *session); + int perf_event__process_id_index(struct perf_session *session, union perf_event *event); From patchwork Fri Feb 2 06:15:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195597 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239067dyc; Thu, 1 Feb 2024 22:20:34 -0800 (PST) X-Google-Smtp-Source: AGHT+IHDcoILf3nYj6JA9XiB/RfYL2N3a8gY6yIUTGt4HJRy2u8Z2Qq8tRtU3/vCVTjrZEYUJzbi X-Received: by 2002:a81:8392:0:b0:5ff:8409:edd7 with SMTP id t140-20020a818392000000b005ff8409edd7mr7191437ywf.9.1706854834329; Thu, 01 Feb 2024 22:20:34 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854834; cv=pass; d=google.com; s=arc-20160816; b=hdmvOsaKe1i9KVCgbC4h7Jbed8I/E+pZFkI+Kd7hq5wYsQSRlBZ/JH5oeI7QF4idVA o3XT0U8ha6Z+jc8RGsFzF3zbY3rNeR/221MJLjDohiLdUuBga+Ggcpd+d7tQxVUbwRuH isF4Wz3e8he6YVkgWb+qoTSVMs7+kFuw0+zn5w98YG265CX/T9WWe+ikULxVscoubQOY aijn4HafffUU0FqmCIb2gX75+XqXE0WYZSY6KvnQpJrTHQ4IoEHG3SLXc2of+tTLBlyl A8k772w2ECohXdLzwnTBd/FhkdrA5rsHeTZwuSrKeR8WlmtEDbdqB/DDKu4JqSi+kixU rNQQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=fHmnyEXJ+aSg4h9BKw1WGw91lR7H/mV+wfjuNobinPg=; fh=zgyhrM09UcJ4vBd0LlSELop4x/kUVsj/E+68lG/sLyM=; b=a761vXqUIIqJxi1Tq6qtYDYLqQWQ390Z0ld3bdNTHcvGBLc0FYQON6M6ejkd1Lf6cu RlEUEU1ei1ESgW/tiwART806GvZeMXVqVjtzE7uTAXISIemQrveasIi0f182oronFKFe W5g6DENYOaaOtmN9T0JcMAHk2YlczKlNMxgwS7rdIFzMumuw3+VBqhnDhvnUksrcOdzD MhEV1bjjcsB0r+RE7pvV3R20gKiot+8XAuhKtaEaOV6gVpMpsyKab50dMrfZxaPICFr5 rh7clLxg/nz+yja++rF3gnyfbHMs33IR5aWuwEL6ZuStBKx8IPe70KJgEh+NMiC0ZDTe On3A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=wPB7Jarw; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49254-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49254-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCW6ybhYgdG2x5EbAbjwtnddia1SnWoAFypftG9kdcdTXrkNyKy6+pZ0KzvQNI6mx7ZDFv9STYAF4eAUs03b31c4sXHMcA== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id m5-20020a170902768500b001d4beb54473si1132153pll.608.2024.02.01.22.20.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:20:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49254-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=wPB7Jarw; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49254-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49254-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 sv.mirrors.kernel.org (Postfix) with ESMTPS id A99132850D9 for ; Fri, 2 Feb 2024 06:20:06 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E5B8242077; Fri, 2 Feb 2024 06:16:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="wPB7Jarw" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.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 755CA38DD4 for ; Fri, 2 Feb 2024 06:16:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854584; cv=none; b=U9+Ko2NuR5M4ZFhQXPYbiB1FA7B86xPun5/5p3D2ecMmCM0NyJePJEehZfOUnEAXZpDgoJU5tY6cwPD608ymRQ2yJ4sKouIVxMXq02ctSLLLnisoZ3rq8XHE0KG4YORQRbiIoCGlbVTDskaZxQeawXd72207OaL9N9b30gxv8VU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854584; c=relaxed/simple; bh=I5t39Q4OYxgwWchaNh2tiLWYcttvWsIzR8MGfoxo6wY=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=a5FN0Ic4Se+SObC37UflF+HmKmB4WXZJ1b+pNoY/mFzczc009Ai8iyEGvCKziUihrpjZYhD3e0FiePyeM3sj90RCje1FbMnLjVg/VpitEgB8JqRKCjZkt5MFIZtxa6Nxj8j3HbJlq523huEC9S98TN45A7hcukjj9kEhuMgntsk= 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=wPB7Jarw; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc3645a6790so3198463276.0 for ; Thu, 01 Feb 2024 22:16:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854581; x=1707459381; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=fHmnyEXJ+aSg4h9BKw1WGw91lR7H/mV+wfjuNobinPg=; b=wPB7Jarwwz9pQDwgybEX/P6mCvZI6SsMmVqkoAGuL+t4zdfrinjXPowFc9ojgpgCN3 ObBxpfoCHpAGuNeipxEReZ4xBHjZ/qolMBWj6FNiuE1+oAIhWgoav99qYz8MKibycP/i 4yEBiS1zdqBdF/BTcq/1FqT7nI14X9GFvIrTETrg77VY5oD18X+TyzNwOiFcoyMNolCw r+glxu+c1Q5mAgke7jEXSn1l5QPKvkYKbvdoQ9Togt4PtiLcIs1sme8IY629whjKz0Bb 3tP2zASrdBfISHS3ZDnJprMWOhPp9aKyjBO2o9W1Pl8kJ/w0Lycuff77Osb8Gg64vjCW sPwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854581; x=1707459381; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fHmnyEXJ+aSg4h9BKw1WGw91lR7H/mV+wfjuNobinPg=; b=l7CJh8m3+A3toWZpB7AX1EMbHxLPI4qkkEl0HOqZzZQP3WmaNS6rBZBj4y2InI07mX vPnEmM12X6udwHJ9fVg/EqD7laF0lovb7DvgCZxvYaybA2j1q4B0fx42uHs6Q6bqLLvP 3xqJ7tyhnHmBWOyd/SKqyVFVBgglR/Z9GtcScUEXZ+Ufrlqz8kCYX+9dHZ4wQE/EMcm0 7Z55T5+TCOjq++KoPVUYd6cvLPAxASY7Hg1BbIqxkmqJGA6TVbmjxnoK5eSLltq9r0zZ B5HEJ9L3wI7lscrIlemT1uHyzOUPX6u20nc0rjhwbF5dnpo4lTLn5BYRtDbwkvTvns+F ktiw== X-Gm-Message-State: AOJu0Yx5/IT3vIVSQ/UZFhuG8pJuSym6UVdQVS+UyQDglnN472nLLMsn A73m7s3zCBFNyv6tWR11fQHTyv1egXlgsgpdWtm+I6ago9rY7I3TqCRBgLSKZgngWuHV2W81262 IIl9ifg== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:2387:b0:dc2:1c5d:eed5 with SMTP id dp7-20020a056902238700b00dc21c5deed5mr1847395ybb.12.1706854581490; Thu, 01 Feb 2024 22:16:21 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:22 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-16-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 15/25] perf dsos: Tidy reference counting and locking From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767014637823027 X-GMAIL-MSGID: 1789767014637823027 Move more functionality into dsos.c generally from machine, renaming functions to match their new usage. The find function is made to always "get" before returning a dso. Reduce the scope of locks in vdso to match the locking paradigm. Signed-off-by: Ian Rogers --- tools/perf/util/dsos.c | 73 +++++++++++++++++++++++++++++++++++---- tools/perf/util/dsos.h | 9 ++++- tools/perf/util/machine.c | 62 ++------------------------------- tools/perf/util/map.c | 4 +-- tools/perf/util/vdso.c | 48 +++++++++++-------------- 5 files changed, 97 insertions(+), 99 deletions(-) diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index e65ef6762bed..d269e09005a7 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -181,7 +181,7 @@ struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso * at the end of the list of duplicates. */ if (!dso || (dso == this)) - return this; /* Find matching dso */ + return dso__get(this); /* Find matching dso */ /* * The core kernel DSOs may have duplicated long name. * In this case, the short name should be different. @@ -253,15 +253,20 @@ static struct dso *__dsos__find_id(struct dsos *dsos, const char *name, struct d if (cmp_short) { list_for_each_entry(pos, &dsos->head, node) if (__dso__cmp_short_name(name, id, pos) == 0) - return pos; + return dso__get(pos); return NULL; } return __dsos__findnew_by_longname_id(&dsos->root, name, id); } -struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short) +struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short) { - return __dsos__find_id(dsos, name, NULL, cmp_short); + struct dso *res; + + down_read(&dsos->lock); + res = __dsos__find_id(dsos, name, NULL, cmp_short); + up_read(&dsos->lock); + return res; } static void dso__set_basename(struct dso *dso) @@ -303,8 +308,6 @@ static struct dso *__dsos__addnew_id(struct dsos *dsos, const char *name, struct if (dso != NULL) { __dsos__add(dsos, dso); dso__set_basename(dso); - /* Put dso here because __dsos_add already got it */ - dso__put(dso); } return dso; } @@ -328,7 +331,7 @@ struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id { struct dso *dso; down_write(&dsos->lock); - dso = dso__get(__dsos__findnew_id(dsos, name, id)); + dso = __dsos__findnew_id(dsos, name, id); up_write(&dsos->lock); return dso; } @@ -374,3 +377,59 @@ int __dsos__hit_all(struct dsos *dsos) return 0; } + +struct dso *dsos__findnew_module_dso(struct dsos *dsos, + struct machine *machine, + struct kmod_path *m, + const char *filename) +{ + struct dso *dso; + + down_write(&dsos->lock); + + dso = __dsos__find_id(dsos, m->name, NULL, /*cmp_short=*/true); + if (!dso) { + dso = __dsos__addnew(dsos, m->name); + if (dso == NULL) + goto out_unlock; + + dso__set_module_info(dso, m, machine); + dso__set_long_name(dso, strdup(filename), true); + dso->kernel = DSO_SPACE__KERNEL; + } + +out_unlock: + up_write(&dsos->lock); + return dso; +} + +struct dso *dsos__find_kernel_dso(struct dsos *dsos) +{ + struct dso *dso, *res = NULL; + + down_read(&dsos->lock); + list_for_each_entry(dso, &dsos->head, node) { + /* + * The cpumode passed to is_kernel_module is not the cpumode of + * *this* event. If we insist on passing correct cpumode to + * is_kernel_module, we should record the cpumode when we adding + * this dso to the linked list. + * + * However we don't really need passing correct cpumode. We + * know the correct cpumode must be kernel mode (if not, we + * should not link it onto kernel_dsos list). + * + * Therefore, we pass PERF_RECORD_MISC_CPUMODE_UNKNOWN. + * is_kernel_module() treats it as a kernel cpumode. + */ + if (!dso->kernel || + is_kernel_module(dso->long_name, + PERF_RECORD_MISC_CPUMODE_UNKNOWN)) + continue; + + res = dso__get(dso); + break; + } + up_read(&dsos->lock); + return res; +} diff --git a/tools/perf/util/dsos.h b/tools/perf/util/dsos.h index 1c81ddf07f8f..a7c7f723c5ff 100644 --- a/tools/perf/util/dsos.h +++ b/tools/perf/util/dsos.h @@ -10,6 +10,8 @@ struct dso; struct dso_id; +struct kmod_path; +struct machine; /* * DSOs are put into both a list for fast iteration and rbtree for fast @@ -33,7 +35,7 @@ void dsos__exit(struct dsos *dsos); void __dsos__add(struct dsos *dsos, struct dso *dso); void dsos__add(struct dsos *dsos, struct dso *dso); struct dso *__dsos__addnew(struct dsos *dsos, const char *name); -struct dso *__dsos__find(struct dsos *dsos, const char *name, bool cmp_short); +struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short); struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id *id); @@ -48,4 +50,9 @@ size_t __dsos__fprintf(struct dsos *dsos, FILE *fp); int __dsos__hit_all(struct dsos *dsos); +struct dso *dsos__findnew_module_dso(struct dsos *dsos, struct machine *machine, + struct kmod_path *m, const char *filename); + +struct dso *dsos__find_kernel_dso(struct dsos *dsos); + #endif /* __PERF_DSOS */ diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index d235d65fb35b..8d0ea17e432a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -645,31 +645,6 @@ int machine__process_lost_samples_event(struct machine *machine __maybe_unused, return 0; } -static struct dso *machine__findnew_module_dso(struct machine *machine, - struct kmod_path *m, - const char *filename) -{ - struct dso *dso; - - down_write(&machine->dsos.lock); - - dso = __dsos__find(&machine->dsos, m->name, true); - if (!dso) { - dso = __dsos__addnew(&machine->dsos, m->name); - if (dso == NULL) - goto out_unlock; - - dso__set_module_info(dso, m, machine); - dso__set_long_name(dso, strdup(filename), true); - dso->kernel = DSO_SPACE__KERNEL; - } - - dso__get(dso); -out_unlock: - up_write(&machine->dsos.lock); - return dso; -} - int machine__process_aux_event(struct machine *machine __maybe_unused, union perf_event *event) { @@ -853,7 +828,7 @@ static struct map *machine__addnew_module_map(struct machine *machine, u64 start if (kmod_path__parse_name(&m, filename)) return NULL; - dso = machine__findnew_module_dso(machine, &m, filename); + dso = dsos__findnew_module_dso(&machine->dsos, machine, &m, filename); if (dso == NULL) goto out; @@ -1662,40 +1637,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, * Should be there already, from the build-id table in * the header. */ - struct dso *kernel = NULL; - struct dso *dso; - - down_read(&machine->dsos.lock); - - list_for_each_entry(dso, &machine->dsos.head, node) { - - /* - * The cpumode passed to is_kernel_module is not the - * cpumode of *this* event. If we insist on passing - * correct cpumode to is_kernel_module, we should - * record the cpumode when we adding this dso to the - * linked list. - * - * However we don't really need passing correct - * cpumode. We know the correct cpumode must be kernel - * mode (if not, we should not link it onto kernel_dsos - * list). - * - * Therefore, we pass PERF_RECORD_MISC_CPUMODE_UNKNOWN. - * is_kernel_module() treats it as a kernel cpumode. - */ - - if (!dso->kernel || - is_kernel_module(dso->long_name, - PERF_RECORD_MISC_CPUMODE_UNKNOWN)) - continue; - - - kernel = dso__get(dso); - break; - } - - up_read(&machine->dsos.lock); + struct dso *kernel = dsos__find_kernel_dso(&machine->dsos); if (kernel == NULL) kernel = machine__findnew_dso(machine, machine->mmap_name); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index cf5a15db3a1f..7c1fff9e413d 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -196,9 +196,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, * reading the header will have the build ID set and all future mmaps will * have it missing. */ - down_read(&machine->dsos.lock); - header_bid_dso = __dsos__find(&machine->dsos, filename, false); - up_read(&machine->dsos.lock); + header_bid_dso = dsos__find(&machine->dsos, filename, false); if (header_bid_dso && header_bid_dso->header_build_id) { dso__set_build_id(dso, &header_bid_dso->bid); dso->header_build_id = 1; diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index df8963796187..35532dcbff74 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -133,8 +133,6 @@ static struct dso *__machine__addnew_vdso(struct machine *machine, const char *s if (dso != NULL) { __dsos__add(&machine->dsos, dso); dso__set_long_name(dso, long_name, false); - /* Put dso here because __dsos_add already got it */ - dso__put(dso); } return dso; @@ -252,17 +250,15 @@ static struct dso *__machine__findnew_compat(struct machine *machine, const char *file_name; struct dso *dso; - dso = __dsos__find(&machine->dsos, vdso_file->dso_name, true); + dso = dsos__find(&machine->dsos, vdso_file->dso_name, true); if (dso) - goto out; + return dso; file_name = vdso__get_compat_file(vdso_file); if (!file_name) - goto out; + return NULL; - dso = __machine__addnew_vdso(machine, vdso_file->dso_name, file_name); -out: - return dso; + return __machine__addnew_vdso(machine, vdso_file->dso_name, file_name); } static int __machine__findnew_vdso_compat(struct machine *machine, @@ -308,21 +304,21 @@ static struct dso *machine__find_vdso(struct machine *machine, dso_type = machine__thread_dso_type(machine, thread); switch (dso_type) { case DSO__TYPE_32BIT: - dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO32, true); + dso = dsos__find(&machine->dsos, DSO__NAME_VDSO32, true); if (!dso) { - dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO, - true); + dso = dsos__find(&machine->dsos, DSO__NAME_VDSO, + true); if (dso && dso_type != dso__type(dso, machine)) dso = NULL; } break; case DSO__TYPE_X32BIT: - dso = __dsos__find(&machine->dsos, DSO__NAME_VDSOX32, true); + dso = dsos__find(&machine->dsos, DSO__NAME_VDSOX32, true); break; case DSO__TYPE_64BIT: case DSO__TYPE_UNKNOWN: default: - dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO, true); + dso = dsos__find(&machine->dsos, DSO__NAME_VDSO, true); break; } @@ -334,37 +330,33 @@ struct dso *machine__findnew_vdso(struct machine *machine, { struct vdso_info *vdso_info; struct dso *dso = NULL; + char *file; - down_write(&machine->dsos.lock); if (!machine->vdso_info) machine->vdso_info = vdso_info__new(); vdso_info = machine->vdso_info; if (!vdso_info) - goto out_unlock; + return NULL; dso = machine__find_vdso(machine, thread); if (dso) - goto out_unlock; + return dso; #if BITS_PER_LONG == 64 if (__machine__findnew_vdso_compat(machine, thread, vdso_info, &dso)) - goto out_unlock; + return dso; #endif - dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO, true); - if (!dso) { - char *file; + dso = dsos__find(&machine->dsos, DSO__NAME_VDSO, true); + if (dso) + return dso; - file = get_file(&vdso_info->vdso); - if (file) - dso = __machine__addnew_vdso(machine, DSO__NAME_VDSO, file); - } + file = get_file(&vdso_info->vdso); + if (!file) + return NULL; -out_unlock: - dso__get(dso); - up_write(&machine->dsos.lock); - return dso; + return __machine__addnew_vdso(machine, DSO__NAME_VDSO, file); } bool dso__is_vdso(struct dso *dso) From patchwork Fri Feb 2 06:15:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195598 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239142dyc; Thu, 1 Feb 2024 22:20:47 -0800 (PST) X-Google-Smtp-Source: AGHT+IE1lC0ikWVArnGeAerHU0/vEbETeHlm4PuE0syI3jQZfMcgglbl3h4aH3MQV4+StDYnwM+H X-Received: by 2002:a05:6358:291f:b0:178:be64:c3d6 with SMTP id y31-20020a056358291f00b00178be64c3d6mr4994502rwb.18.1706854846872; Thu, 01 Feb 2024 22:20:46 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854846; cv=pass; d=google.com; s=arc-20160816; b=fiEyJafs9OxUW6MSWg93X74lWgoXI1fNvgscfJtoZX+IzUppQIci2y2LaRxcpGV0MW Tdt7JMNOZtd98SQvp6bQGm4TVSQ41EOrZWVZGwQJbX7++BqEIko9XOgHbMfpRc+knt5b E2c16u1CRiv/9Fi5NnZIszGpUBA6k6pC3gxeknNJXZSf7Aozu5Gl6/eGrN7/EreGk5+A bVsXkgb8KZ3wLn0Ru7QT6RisdZMoyqqn5iHTzUmeKS5pN/RfrGLJqLohTsO5fTvGLag+ rMX1ZbDPkUymI8ojA9a+T7BnlmtlSSH+di1kZ7a7B0E3Zb2FIdYD4YHotpuCs6PgPHle iIsg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=L9mbHm8cDPd1+y5BhdsOmJ6AdIbzp48vKITNdXoTURk=; fh=cU5V6vRK6ZVvt1qXyd/67Q5cRlZezObA0bX6rrv6zH4=; b=XUkX2eGEWXtCmgY3YjgWhPFPdWWAh93RXLGJPxCdpvDdgCYdL4ihRy1NG2vjRNeiLg umgh5lZ/yECgjcVbzWm+8nNiKjqQ29yseqP4wSLdLHRT0StT5PvZYOgAlmCCH2zQRWUY BBtgJnvul4WRAsT3lGzs6zr/6m6NhODkVu5yARJjA04zRTEvYpqx1htIJKAY0Y9xNlQ5 Q4Aj0q/tDRfVMtSgZUNgwEO0X0JUQfAZf4EWB/6o8P0afwk1voiLPOrOriQFc1z8UxbE g3hC+eZY80cjXgTty65ULMbeaLzXlkjglJRd8xNUHDc/UVw8wjbr+XN4Qo3Skbvf+/ib +UIg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=HBv5Y8X7; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49255-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49255-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCXhM3Jqaezr6gTvSITO6UjNO+YlvNLJBGb2AjbQ12fXPtsqZgieqtjPKSOdl8UusRKG0fN+AQ/7urRf09/qfEwz89aQZA== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id i16-20020a635410000000b005b91536981csi1118557pgb.11.2024.02.01.22.20.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:20:46 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49255-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=HBv5Y8X7; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49255-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49255-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 8367A282109 for ; Fri, 2 Feb 2024 06:20:21 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CD74F41770; Fri, 2 Feb 2024 06:16:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="HBv5Y8X7" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 AE8B13C6AB for ; Fri, 2 Feb 2024 06:16:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854587; cv=none; b=UvfmExpoXMOj84kXg2tAh4Dyx3nF7eY0X1hm8usgtXcXasfQVASk6PtcGdTsX3q7mEHRPDeoPnrbZ4/9YMlwoSlXDeL+w+hzcuL7L7Y9R6852MbVVEDeH0KL8/pdwh8P+mbW7y/tHWOGzDm8MYD76VCKuJmjjGUMa4vEVz4b8jY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854587; c=relaxed/simple; bh=5pE1qvK1fYTNOeSBYi4QQe4IkMxKf3KSLXZ7xDFk9OI=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=KfB0e5xI5sncKWuADkGKXpEDYCVMCk89Vv+pu1VaTUHfqEJ8aoTgMMZhmKNDLyNDq9mG9tYt+Eysrljm3sJZ3+PpuXN5At2iHLa9ErfWHFY3qUCE5tKMAackmOQ0dMcyHKWrjYYSOytzxmIxVirUBkyEhPXEisbtrAdTyNGK70U= 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=HBv5Y8X7; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60411f95c44so23830247b3.1 for ; Thu, 01 Feb 2024 22:16:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854584; x=1707459384; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=L9mbHm8cDPd1+y5BhdsOmJ6AdIbzp48vKITNdXoTURk=; b=HBv5Y8X7qkyqO2E2xUF1JYzCfLMBo7isiRnG8XNKC3P3jirWpos2Ma9nEfcSJ3NdIP oWUlCPBoUUMLNh9tlga5z1nlUP5OuCO4MRrMlU78T2bdRxPXi8NO6XbkuuS3llUF7WgE 5RdnmhEHUmlMEDFWOSs4MhLp1d5n1SSScm/0Q3RBr9xtbgcw63fR9Bgsx6miGL09DYRC swUhSITkxGdmjNCUGO3tClbTPYC9Tbwj40grsVJgn/uiKJ1SfEUldCi9onDh97d23GK3 w02SYCuOz9gS5r6LQ4x/yZSjmKLlKziGYbnBSqldoxSnDP9NCn4ljlCCiaDCVkJ9U80l VV2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854584; x=1707459384; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=L9mbHm8cDPd1+y5BhdsOmJ6AdIbzp48vKITNdXoTURk=; b=hzNIr/jGP/ZN+3tBMaYWjl47XwwYRri7sn9+dbE4D/fM539bB/spFvR2VLwfRAbWUL ntKWCF7YmivnWRNIK/C/fgQK/ckKgyk8Q1NRUI2WnKK3kdloWkvZrXKlnTdQU/I/cB3R Bi+IDdSRT00JtUHYnQO/PWlR6VWcwOEDKMo7szqiAyOuL1r/O4Axpovoee97r1XEhvMC PWxEG+XMAl4H13wMvcNXlWGnFOn9ByB/j/tAOA/fcajUqwt5B5lr1cxwhRrRbGY0TxZd uQ9wNcyVHtdgfa1UHZFcm5FpanhLJziT/fFI+CO+z9WueXFOv+Yr336ghGf13fnq+Ozt IAkg== X-Gm-Message-State: AOJu0YxiEJPY+9X231J3BOZ2lT2V1Lp9YUzqHlNLmqb0APpB0fEVDojv 3nG0wuLAguCNi4Pkd7x+w8Qstjp92QrRNesGD7ulQEhdorANXqpwAaSvWG7kOrARSZslr5wqq1m ftNOhMA== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:690c:f85:b0:5f9:abfe:243c with SMTP id df5-20020a05690c0f8500b005f9abfe243cmr1171029ywb.3.1706854583718; Thu, 01 Feb 2024 22:16:23 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:23 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-17-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 16/25] perf dsos: Add dsos__for_each_dso From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767027860741217 X-GMAIL-MSGID: 1789767027860741217 To better abstract the dsos internals, add dsos__for_each_dso that does a callback on each dso. This also means the read lock can be correctly held. Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 25 +++++++----- tools/perf/util/build-id.c | 76 ++++++++++++++++++++----------------- tools/perf/util/dsos.c | 16 ++++++++ tools/perf/util/dsos.h | 8 +--- tools/perf/util/machine.c | 40 +++++++++++-------- 5 files changed, 100 insertions(+), 65 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ef73317e6ae7..ce5e28eaad90 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -1187,23 +1187,28 @@ static int synthesize_build_id(struct perf_inject *inject, struct dso *dso, pid_ process_build_id, machine); } +static int guest_session__add_build_ids_cb(struct dso *dso, void *data) +{ + struct guest_session *gs = data; + struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session); + + if (!dso->has_build_id) + return 0; + + return synthesize_build_id(inject, dso, gs->machine_pid); + +} + static int guest_session__add_build_ids(struct guest_session *gs) { struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session); - struct machine *machine = &gs->session->machines.host; - struct dso *dso; - int ret; /* Build IDs will be put in the Build ID feature section */ perf_header__set_feat(&inject->session->header, HEADER_BUILD_ID); - dsos__for_each_with_build_id(dso, &machine->dsos.head) { - ret = synthesize_build_id(inject, dso, gs->machine_pid); - if (ret) - return ret; - } - - return 0; + return dsos__for_each_dso(&gs->session->machines.host.dsos, + guest_session__add_build_ids_cb, + gs); } static int guest_session__ksymbol_event(struct perf_tool *tool, diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index a617b1917e6b..a6d3c253f19f 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -327,48 +327,56 @@ static int write_buildid(const char *name, size_t name_len, struct build_id *bid return write_padded(fd, name, name_len + 1, len); } -static int machine__write_buildid_table(struct machine *machine, - struct feat_fd *fd) +struct machine__write_buildid_table_cb_args { + struct machine *machine; + struct feat_fd *fd; + u16 kmisc, umisc; +}; + +static int machine__write_buildid_table_cb(struct dso *dso, void *data) { - int err = 0; - struct dso *pos; - u16 kmisc = PERF_RECORD_MISC_KERNEL, - umisc = PERF_RECORD_MISC_USER; + struct machine__write_buildid_table_cb_args *args = data; + const char *name; + size_t name_len; + bool in_kernel = false; - if (!machine__is_host(machine)) { - kmisc = PERF_RECORD_MISC_GUEST_KERNEL; - umisc = PERF_RECORD_MISC_GUEST_USER; - } + if (!dso->has_build_id) + return 0; - dsos__for_each_with_build_id(pos, &machine->dsos.head) { - const char *name; - size_t name_len; - bool in_kernel = false; + if (!dso->hit && !dso__is_vdso(dso)) + return 0; - if (!pos->hit && !dso__is_vdso(pos)) - continue; + if (dso__is_vdso(dso)) { + name = dso->short_name; + name_len = dso->short_name_len; + } else if (dso__is_kcore(dso)) { + name = args->machine->mmap_name; + name_len = strlen(name); + } else { + name = dso->long_name; + name_len = dso->long_name_len; + } - if (dso__is_vdso(pos)) { - name = pos->short_name; - name_len = pos->short_name_len; - } else if (dso__is_kcore(pos)) { - name = machine->mmap_name; - name_len = strlen(name); - } else { - name = pos->long_name; - name_len = pos->long_name_len; - } + in_kernel = dso->kernel || is_kernel_module(name, PERF_RECORD_MISC_CPUMODE_UNKNOWN); + return write_buildid(name, name_len, &dso->bid, args->machine->pid, + in_kernel ? args->kmisc : args->umisc, args->fd); +} - in_kernel = pos->kernel || - is_kernel_module(name, - PERF_RECORD_MISC_CPUMODE_UNKNOWN); - err = write_buildid(name, name_len, &pos->bid, machine->pid, - in_kernel ? kmisc : umisc, fd); - if (err) - break; +static int machine__write_buildid_table(struct machine *machine, struct feat_fd *fd) +{ + struct machine__write_buildid_table_cb_args args = { + .machine = machine, + .fd = fd, + .kmisc = PERF_RECORD_MISC_KERNEL, + .umisc = PERF_RECORD_MISC_USER, + }; + + if (!machine__is_host(machine)) { + args.kmisc = PERF_RECORD_MISC_GUEST_KERNEL; + args.umisc = PERF_RECORD_MISC_GUEST_USER; } - return err; + return dsos__for_each_dso(&machine->dsos, machine__write_buildid_table_cb, &args); } int perf_session__write_buildid_table(struct perf_session *session, diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index d269e09005a7..d43f64939b12 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -433,3 +433,19 @@ struct dso *dsos__find_kernel_dso(struct dsos *dsos) up_read(&dsos->lock); return res; } + +int dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data) +{ + struct dso *dso; + + down_read(&dsos->lock); + list_for_each_entry(dso, &dsos->head, node) { + int err; + + err = cb(dso, data); + if (err) + return err; + } + up_read(&dsos->lock); + return 0; +} diff --git a/tools/perf/util/dsos.h b/tools/perf/util/dsos.h index a7c7f723c5ff..317a263f0e37 100644 --- a/tools/perf/util/dsos.h +++ b/tools/perf/util/dsos.h @@ -23,12 +23,6 @@ struct dsos { struct rw_semaphore lock; }; -#define dsos__for_each_with_build_id(pos, head) \ - list_for_each_entry(pos, head, node) \ - if (!pos->has_build_id) \ - continue; \ - else - void dsos__init(struct dsos *dsos); void dsos__exit(struct dsos *dsos); @@ -55,4 +49,6 @@ struct dso *dsos__findnew_module_dso(struct dsos *dsos, struct machine *machine, struct dso *dsos__find_kernel_dso(struct dsos *dsos); +int dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data); + #endif /* __PERF_DSOS */ diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 8d0ea17e432a..f1186a5bb73c 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1561,16 +1561,14 @@ int machine__create_kernel_maps(struct machine *machine) return ret; } -static bool machine__uses_kcore(struct machine *machine) +static int machine__uses_kcore_cb(struct dso *dso, void *data __maybe_unused) { - struct dso *dso; - - list_for_each_entry(dso, &machine->dsos.head, node) { - if (dso__is_kcore(dso)) - return true; - } + return dso__is_kcore(dso) ? 1 : 0; +} - return false; +static bool machine__uses_kcore(struct machine *machine) +{ + return dsos__for_each_dso(&machine->dsos, machine__uses_kcore_cb, NULL) != 0 ? true : false; } static bool perf_event__is_extra_kernel_mmap(struct machine *machine, @@ -3136,16 +3134,28 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch return sym->name; } +struct machine__for_each_dso_cb_args { + struct machine *machine; + machine__dso_t fn; + void *priv; +}; + +static int machine__for_each_dso_cb(struct dso *dso, void *data) +{ + struct machine__for_each_dso_cb_args *args = data; + + return args->fn(dso, args->machine, args->priv); +} + int machine__for_each_dso(struct machine *machine, machine__dso_t fn, void *priv) { - struct dso *pos; - int err = 0; + struct machine__for_each_dso_cb_args args = { + .machine = machine, + .fn = fn, + .priv = priv, + }; - list_for_each_entry(pos, &machine->dsos.head, node) { - if (fn(pos, machine, priv)) - err = -1; - } - return err; + return dsos__for_each_dso(&machine->dsos, machine__for_each_dso_cb, &args); } int machine__for_each_kernel_map(struct machine *machine, machine__map_t fn, void *priv) From patchwork Fri Feb 2 06:15:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195599 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239154dyc; Thu, 1 Feb 2024 22:20:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IFfrPWxwcNc/SCdiq49+hNLBGb/t/FjC8l0PjAaLr9e5IO7K1La7VbiuZPU01LYIRhEnDZu X-Received: by 2002:a05:6a20:93a7:b0:19c:881d:78e6 with SMTP id x39-20020a056a2093a700b0019c881d78e6mr1181893pzh.42.1706854850343; Thu, 01 Feb 2024 22:20:50 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854850; cv=pass; d=google.com; s=arc-20160816; b=gsmBhTU4FHMGCSrs+SGMQXi9zOzzcrqw2wk60yNDJr3qQcBmb1GNuA2OqPUDGANxmj PYDIKV2SoekKi8sxHSODZdg2op9ArOuhQPvwh6fft8B9Cl2l/zmYkHBfhETmGOJN4b3a HoIvKsIX3Z3KvzJiQv6kXg+I4/VhORVfLQ7uCB1rhT2itwosRDpRbCCiADyJQjXQgqR5 9QlRmgABm61P90e3XhoyLO+G3q+kFrXvDSJTtKijN7hZorZQpUNTGk53/nm4GKUNiSPE 1i3+tvQFlPR8pKMqcDktcyh7DMmitN7Kd40FDj9xhun+PLy7wxJ7M/nQgmaGvE7hhJEU zc8w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=mottUhS25FsEFHcj0V/KGhVDM/ufFOH0iq7vn6sYGZo=; fh=sqJDmMf/xtVzTXwxC4nj8YzjdIJrVzjjLgBm6YTYKN4=; b=wPnZT2q8NoG0mWaYmeSdWsveNDV79sgg1d6kUxx+mceMRkNKH0omshg72FPAbGaarb n/6Lrf7+cYH8ZL1MySZBRH3a1sOgqL9lhI1Am74kqjyIxXKlaVK/RyS6HtdIsEqUObv/ V7f/CQ7B43ONpTqp+IUhEC/LL8lE/I4aaqt6BorSFlKuy/ULFQLmQZV+dmCk9bMbg5GB W6/fZ5czlguRt21WHAj/ylPmcEAqeApPkBA0zwenoc68vT8np1qT8+nnHu8oaMG+IBvM iNomCbchScGO4jxxiX3I2sKHxqDN2uwI5cT/S9IR4T8Z//a7eeXxlxGPU60XWLcIrbm4 xW/g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=nyNKy1MV; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49256-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49256-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCVNGzHrcK85BYrAKAc9dTgnXaTY48JK65/ePbc7GESfva99x7K5LCAjBMRZgIhbMPaA9CVojBcY1zlhZo/QP9UfnETuyg== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id mh1-20020a17090b4ac100b002961cebf1cesi2462988pjb.166.2024.02.01.22.20.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:20:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49256-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=nyNKy1MV; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49256-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49256-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 9C5542810A3 for ; Fri, 2 Feb 2024 06:20:25 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6917447F55; Fri, 2 Feb 2024 06:16:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="nyNKy1MV" Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 B79293FB37 for ; Fri, 2 Feb 2024 06:16:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854588; cv=none; b=NOJ7wt7ztIycpOYlfJWKN+ohf3sn45/sWNLKmiWHS9/FyfKx0gCpRhQObyyGbwfeYgCIeNJYrTehZAqqhbgJWaS4PD20nbegodd9SpUZzrfKSyMUTBCMwwQ0SkxHPieCYQJabSFEGQjoPkeKz01cxpdyjzZ10+A277tVtNL22i4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854588; c=relaxed/simple; bh=6VWn0G9osA8gozSelQTcU7d5xrzfIxfJu3Uomo4VPvE=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=rkyprOUTpwkDnzgtxW33Rwby/BlLcKQVaGZlndSueZXAl07KqwrQh4EfWUHpDqVpi+65n2MSufqOhHs4nL3Jvm9S5cWI0c/2O2jgbK2up7rm1I14fFDFAorCmWGL2wTu8PHUGcD0gwG6yVLHG1MHgIvay7teeTOU3vrmAWWbKQ8= 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=nyNKy1MV; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-5ee22efe5eeso30800897b3.3 for ; Thu, 01 Feb 2024 22:16:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854586; x=1707459386; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=mottUhS25FsEFHcj0V/KGhVDM/ufFOH0iq7vn6sYGZo=; b=nyNKy1MVCa74G88wL78AybqbkKBeVGrFmHs3qnuRFw77/A4myTrpMTdXIwSi5UUtDf OlhOiHOJCQKMzwp2Txv1xilT35y1lLG2Y2bFV2+TSYNhcMPK8Cm6EAqynMlsSWgVMWHr ZC6LEXngcE47N7QhPuf0P6/j23yg3oUw+IPyMWXfCmGvwfosj6AQxupQ2ptSslRSiIhz C97tta0qxjQfjEfnlwvF9eNjmNZt7DrypM0gtnM0ZkmB2rzhLf0Kh91rTl2PMa6BpySq lB7H2S4ujCAUq6JLMUiFZhuLMP5qtfHWvZFGISsozj8xj0aHM8IODnGZKvLTy/8hPb+6 SiRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854586; x=1707459386; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mottUhS25FsEFHcj0V/KGhVDM/ufFOH0iq7vn6sYGZo=; b=iTVjeoiRA4uqrj/htienNJF9NpCXU941BHFy+mLq5rWk0ervxc3p5acVBkOpi1wXPv i/e6ZJ/25CmvM9Tci8aMT+U77t2ff6CMZRUesVeoiu+ElvROZDnkmrs2IEPDYCaaCvUF XBukupCdNWImt79ZVDdukrTCNeuUHGpxam6dPXlZLdybnBZYTlHJCeszk8B9vUhEnc6t DNCJMgUJcX1V8TLpIepIJt1c2FOR5KyVzVqy5efnn+BeOCiCKwB7IPrL+2Ow7hurh412 VAYNTDRn2Xc1tt197+C3uT5RzXIoF7MIVeRAdwCN5fAMEZbSTPvES6WUNZnVB0RRVSvb ng/Q== X-Gm-Message-State: AOJu0Yzhi5MzDhGXO3ta506tHL1VcCgweyBLqEKpUOXA+/rG59pLBo2O C/EJXDaONhNt94IzVsBPOMy+whSHlhW+d3rnyTD5yGhl1gCbppJR9SpBdIQqnLkuTogLGb7vPCL KcJT5jg== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:690c:19:b0:600:2492:f962 with SMTP id bc25-20020a05690c001900b006002492f962mr751446ywb.8.1706854585762; Thu, 01 Feb 2024 22:16:25 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:24 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-18-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 17/25] perf dso: Move dso functions out of dsos From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767031278241810 X-GMAIL-MSGID: 1789767031278241810 Move dso and dso_id functions to dso.c to match the struct declarations. Signed-off-by: Ian Rogers --- tools/perf/util/dso.c | 61 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/dso.h | 4 +++ tools/perf/util/dsos.c | 61 ------------------------------------------ 3 files changed, 65 insertions(+), 61 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 22fd5fa806ed..69b9aa256776 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1269,6 +1269,67 @@ static void dso__set_long_name_id(struct dso *dso, const char *name, struct dso_ __dsos__findnew_link_by_longname_id(root, dso, NULL, id); } +static int __dso_id__cmp(struct dso_id *a, struct dso_id *b) +{ + if (a->maj > b->maj) return -1; + if (a->maj < b->maj) return 1; + + if (a->min > b->min) return -1; + if (a->min < b->min) return 1; + + if (a->ino > b->ino) return -1; + if (a->ino < b->ino) return 1; + + /* + * Synthesized MMAP events have zero ino_generation, avoid comparing + * them with MMAP events with actual ino_generation. + * + * I found it harmful because the mismatch resulted in a new + * dso that did not have a build ID whereas the original dso did have a + * build ID. The build ID was essential because the object was not found + * otherwise. - Adrian + */ + if (a->ino_generation && b->ino_generation) { + if (a->ino_generation > b->ino_generation) return -1; + if (a->ino_generation < b->ino_generation) return 1; + } + + return 0; +} + +bool dso_id__empty(struct dso_id *id) +{ + if (!id) + return true; + + return !id->maj && !id->min && !id->ino && !id->ino_generation; +} + +void dso__inject_id(struct dso *dso, struct dso_id *id) +{ + dso->id.maj = id->maj; + dso->id.min = id->min; + dso->id.ino = id->ino; + dso->id.ino_generation = id->ino_generation; +} + +int dso_id__cmp(struct dso_id *a, struct dso_id *b) +{ + /* + * The second is always dso->id, so zeroes if not set, assume passing + * NULL for a means a zeroed id + */ + if (dso_id__empty(a) || dso_id__empty(b)) + return 0; + + return __dso_id__cmp(a, b); +} + +int dso__cmp_id(struct dso *a, struct dso *b) +{ + return __dso_id__cmp(&a->id, &b->id); +} + void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated) { dso__set_long_name_id(dso, name, NULL, name_allocated); diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 2b9cf9177085..7447d7a1942a 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -237,6 +237,9 @@ static inline void dso__set_loaded(struct dso *dso) dso->loaded = true; } +int dso_id__cmp(struct dso_id *a, struct dso_id *b); +bool dso_id__empty(struct dso_id *id); + struct dso *dso__new_id(const char *name, struct dso_id *id); struct dso *dso__new(const char *name); void dso__delete(struct dso *dso); @@ -244,6 +247,7 @@ void dso__delete(struct dso *dso); int dso__cmp_id(struct dso *a, struct dso *b); void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated); void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated); +void dso__inject_id(struct dso *dso, struct dso_id *id); int dso__name_len(const struct dso *dso); diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index d43f64939b12..f816927a21ff 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -41,67 +41,6 @@ void dsos__exit(struct dsos *dsos) exit_rwsem(&dsos->lock); } -static int __dso_id__cmp(struct dso_id *a, struct dso_id *b) -{ - if (a->maj > b->maj) return -1; - if (a->maj < b->maj) return 1; - - if (a->min > b->min) return -1; - if (a->min < b->min) return 1; - - if (a->ino > b->ino) return -1; - if (a->ino < b->ino) return 1; - - /* - * Synthesized MMAP events have zero ino_generation, avoid comparing - * them with MMAP events with actual ino_generation. - * - * I found it harmful because the mismatch resulted in a new - * dso that did not have a build ID whereas the original dso did have a - * build ID. The build ID was essential because the object was not found - * otherwise. - Adrian - */ - if (a->ino_generation && b->ino_generation) { - if (a->ino_generation > b->ino_generation) return -1; - if (a->ino_generation < b->ino_generation) return 1; - } - - return 0; -} - -static bool dso_id__empty(struct dso_id *id) -{ - if (!id) - return true; - - return !id->maj && !id->min && !id->ino && !id->ino_generation; -} - -static void dso__inject_id(struct dso *dso, struct dso_id *id) -{ - dso->id.maj = id->maj; - dso->id.min = id->min; - dso->id.ino = id->ino; - dso->id.ino_generation = id->ino_generation; -} - -static int dso_id__cmp(struct dso_id *a, struct dso_id *b) -{ - /* - * The second is always dso->id, so zeroes if not set, assume passing - * NULL for a means a zeroed id - */ - if (dso_id__empty(a) || dso_id__empty(b)) - return 0; - - return __dso_id__cmp(a, b); -} - -int dso__cmp_id(struct dso *a, struct dso *b) -{ - return __dso_id__cmp(&a->id, &b->id); -} - bool __dsos__read_build_ids(struct dsos *dsos, bool with_hits) { struct list_head *head = &dsos->head; From patchwork Fri Feb 2 06:15:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195600 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239152dyc; Thu, 1 Feb 2024 22:20:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IH0jBx+PkDjAM4avuLxAHUKcCHv4u0wd5tYQN40t5dP6oimfdHUChD6uc+BVZejODpS7lMW X-Received: by 2002:a2e:910c:0:b0:2cf:4b6d:3629 with SMTP id m12-20020a2e910c000000b002cf4b6d3629mr583622ljg.9.1706854849781; Thu, 01 Feb 2024 22:20:49 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854849; cv=pass; d=google.com; s=arc-20160816; b=zPP0WHC8AhoBA4LESgELnA0XFIepOcRDXV30f7yzaXixmYtCjWlDzQ58bPoJAV4Zp9 gvB03vO01XIFsCKd8yXXIVNkPzR4ZPWG4HOMraM+IyYvwqlEcq+wqhXu60//8X9lNTHo WJRo5deAhAMbTlOkcKQ1S+8MjHYS0rcwWRCzbrCam4efLomWPcZlV1WkJ7+FYleivwik Zd5DSPsOZDldF9O8Lc2ykdVq5BTe3u+Y1lJfJlyFAL+1rvJ6HD257cs/7RguTQ2WW/Q/ QwyvuiaeEbgtP7ZhZjXxL+fdwAZe9slDYCRA6amBGWlA5c88I0dvuCuxkwsYHAkzpeTs YBdg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=IEt/HhvaikjrXk417TIKKA0b0VlDk+cefIrmM8vaVdc=; fh=6p7/8pVbpj8xcXZfAvLuRTSmzm/RAxLMyOfp72mcqk0=; b=udafH608fbAsSW826vteLfJLVN/h8Hk3vzi1DUiuvfwNFsk5GlChayhJJTzIno0zKe x0gEcgArp5AxUnAfj6OQUEKv1m5WLjQXffvli1VynlmHg3BjG6P68DgGzCu08QP5c6SJ LBjGU7hMoJRropnPqoQBFFTKU+AZKhZxmgFGomDYysRL32dHWoqEPkCEV7uhJK3LChvT JTiq19IVXkSt7DuY9ffxtmef1JrAs23TTawLnqL7PNpQHB9D6QAWkb8rO5tUz8TcXJ4z /0+2/vqdeFzTV0lH4qRVQEPtZQ3yoTeDt36pWxdQxm+F3VIwlBKXpXPvL0ALUAJoHVqY LVHw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=EcTbpZv9; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49257-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49257-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCXXfW8te+3CFnp6LmMmYnS3jprrlPUF4RZ/ET3GjZ91VrXk2+jX2+3oDnfu8jZS4Y4Hxr9OODAr6WtfhUfY/q4QMRhWRA== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id cy2-20020a0564021c8200b0055f4bb53829si510265edb.518.2024.02.01.22.20.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:20:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49257-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=EcTbpZv9; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49257-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49257-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 am.mirrors.kernel.org (Postfix) with ESMTPS id 383511F23A2D for ; Fri, 2 Feb 2024 06:20:49 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B8C2347F65; Fri, 2 Feb 2024 06:16:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="EcTbpZv9" Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 5893C41776 for ; Fri, 2 Feb 2024 06:16:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854591; cv=none; b=ZPBKygWcbhf+6Dx31iQKLVQ9OATI7F6Jp7tTz243AgWRVWy+rbHaepH8hp0XHqTiY1Mea5BPPLabPU/Er9CPL6Fokp+3Ynka2XPPi6+oRKFUNJI4DdgcrAkdhPjGRq6XpiQdebe7Z8AyWvPfeL11yWJK1TojwTVjNvS7KIsXVik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854591; c=relaxed/simple; bh=ZW9bWMhQgdSxxoE8Iz1YXTTH0Zd8kJ+n/WM54hp3/gQ=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=X4huGzQ+C6CNU/gVYl/jAw09kcmi9giTGDHIu/ig7Ve+2Xv2iv5clYkTKT1JVAfNaf0W6xWCwDSFhXPzRS7TJW6cqpuMRvvxh6az2h2pJ7uMzBs2CKb0U1vyoPTy0F5OyTvZ+3DS0YfcaLFW7RuwEmXbJIHMtRk2HtMRk2LlRtQ= 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=EcTbpZv9; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-603f93acd7cso34013727b3.0 for ; Thu, 01 Feb 2024 22:16:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854588; x=1707459388; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=IEt/HhvaikjrXk417TIKKA0b0VlDk+cefIrmM8vaVdc=; b=EcTbpZv9RBNUQ0o6qYwNzjrAiA8s14e6CQCGATWaZWWfi8TgeQ7oLOXh+ISlqlr0i8 uGxmqki0EkgUZiggQiTRvZcCACHwADazUBtJOozBoADTN39O7ttYYzDym3lc9W9cZp3x YI0J+nHUPhBNaJ3EqQB6WYC513kDcEiI9S767IaEk+4vgNEIW4xkw6qGdvyKMhXltTPa XVJ5jnfmw3ELQ9HQ4rCAF6BlBhC7bJnBJeqEwJ9dqbQhU04DwZIvJht5yr845JbkaiZ2 Xdmfvg+V4UJ9+vtFoJlNUNCazypnziiL+P6L5+J60ULpwfjoqdESHdNs/EWmNgsFNhXN kM/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854588; x=1707459388; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=IEt/HhvaikjrXk417TIKKA0b0VlDk+cefIrmM8vaVdc=; b=LMXugzNBm1pmK87FSFwbGAmfNmiU7YdrXc5iFDKAVJE8KrZ/LeDUdyXg5AORCqUcR4 PU9jr5UkvwLKa2Ry0JvHA9x/l3eigs3tzSElgXE5C6NCt/bxWhrfoGmvwEM/3sQGsCxO k9bVod1wWMyAtb7dcgRB1OKjh8GeGFTPLWtYG7adPj0hUflI9ohwQ0Ngu5iCcqfpZ8bR zZ+ySeMfhqTJP6ygEavM/KmNc1V80ADjfM4Zlb5wFe9Lp0piQZ7oBflKgwe4uKWTvz9K qZJLCj8NKrWHLMdJKg9J+Y7mEGqjT/BnqCUZtP+C0+lar5vqQIvUzMK9FAlrQ1ixZixR Uwzg== X-Gm-Message-State: AOJu0YxFt8haqxbU1vmpUsOP5lH8MI5a2F6yLd2adLfZslVrZmw1Wpmb Mx1npT9KspiMB5MFkK9QSJ+FP9olNbgBEhF3tsNq7tPNyGl1+Owmr9CZXuWzswf5UM/1gNupaWm yVLIZQQ== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:690c:17:b0:5f9:990d:78c0 with SMTP id bc23-20020a05690c001700b005f9990d78c0mr343132ywb.4.1706854588307; Thu, 01 Feb 2024 22:16:28 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:25 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-19-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 18/25] perf dsos: Switch more loops to dsos__for_each_dso From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767030787807284 X-GMAIL-MSGID: 1789767030787807284 Switch loops within dsos.c, add a version that isn't locked. Switch some unlocked loops to hold the read lock. Signed-off-by: Ian Rogers --- tools/perf/util/build-id.c | 2 +- tools/perf/util/dsos.c | 258 ++++++++++++++++++++++++------------- tools/perf/util/dsos.h | 8 +- tools/perf/util/machine.c | 8 +- 4 files changed, 174 insertions(+), 102 deletions(-) diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index a6d3c253f19f..864bc26b6b46 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -964,7 +964,7 @@ int perf_session__cache_build_ids(struct perf_session *session) static bool machine__read_build_ids(struct machine *machine, bool with_hits) { - return __dsos__read_build_ids(&machine->dsos, with_hits); + return dsos__read_build_ids(&machine->dsos, with_hits); } bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index f816927a21ff..b7fbfb877ae3 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -41,38 +41,65 @@ void dsos__exit(struct dsos *dsos) exit_rwsem(&dsos->lock); } -bool __dsos__read_build_ids(struct dsos *dsos, bool with_hits) + +static int __dsos__for_each_dso(struct dsos *dsos, + int (*cb)(struct dso *dso, void *data), + void *data) +{ + struct dso *dso; + + list_for_each_entry(dso, &dsos->head, node) { + int err; + + err = cb(dso, data); + if (err) + return err; + } + return 0; +} + +struct dsos__read_build_ids_cb_args { + bool with_hits; + bool have_build_id; +}; + +static int dsos__read_build_ids_cb(struct dso *dso, void *data) { - struct list_head *head = &dsos->head; - bool have_build_id = false; - struct dso *pos; + struct dsos__read_build_ids_cb_args *args = data; struct nscookie nsc; - list_for_each_entry(pos, head, node) { - if (with_hits && !pos->hit && !dso__is_vdso(pos)) - continue; - if (pos->has_build_id) { - have_build_id = true; - continue; - } - nsinfo__mountns_enter(pos->nsinfo, &nsc); - if (filename__read_build_id(pos->long_name, &pos->bid) > 0) { - have_build_id = true; - pos->has_build_id = true; - } else if (errno == ENOENT && pos->nsinfo) { - char *new_name = dso__filename_with_chroot(pos, pos->long_name); - - if (new_name && filename__read_build_id(new_name, - &pos->bid) > 0) { - have_build_id = true; - pos->has_build_id = true; - } - free(new_name); + if (args->with_hits && !dso->hit && !dso__is_vdso(dso)) + return 0; + if (dso->has_build_id) { + args->have_build_id = true; + return 0; + } + nsinfo__mountns_enter(dso->nsinfo, &nsc); + if (filename__read_build_id(dso->long_name, &dso->bid) > 0) { + args->have_build_id = true; + dso->has_build_id = true; + } else if (errno == ENOENT && dso->nsinfo) { + char *new_name = dso__filename_with_chroot(dso, dso->long_name); + + if (new_name && filename__read_build_id(new_name, &dso->bid) > 0) { + args->have_build_id = true; + dso->has_build_id = true; } - nsinfo__mountns_exit(&nsc); + free(new_name); } + nsinfo__mountns_exit(&nsc); + return 0; +} - return have_build_id; +bool dsos__read_build_ids(struct dsos *dsos, bool with_hits) +{ + struct dsos__read_build_ids_cb_args args = { + .with_hits = with_hits, + .have_build_id = false, + }; + + dsos__for_each_dso(dsos, dsos__read_build_ids_cb, &args); + return args.have_build_id; } static int __dso__cmp_long_name(const char *long_name, struct dso_id *id, struct dso *b) @@ -105,6 +132,7 @@ struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso if (!name) name = dso->long_name; + /* * Find node with the matching name */ @@ -185,17 +213,40 @@ static struct dso *__dsos__findnew_by_longname_id(struct rb_root *root, const ch return __dsos__findnew_link_by_longname_id(root, NULL, name, id); } +struct dsos__find_id_cb_args { + const char *name; + struct dso_id *id; + struct dso *res; +}; + +static int dsos__find_id_cb(struct dso *dso, void *data) +{ + struct dsos__find_id_cb_args *args = data; + + if (__dso__cmp_short_name(args->name, args->id, dso) == 0) { + args->res = dso__get(dso); + return 1; + } + return 0; + +} + static struct dso *__dsos__find_id(struct dsos *dsos, const char *name, struct dso_id *id, bool cmp_short) { - struct dso *pos; + struct dso *res; if (cmp_short) { - list_for_each_entry(pos, &dsos->head, node) - if (__dso__cmp_short_name(name, id, pos) == 0) - return dso__get(pos); - return NULL; + struct dsos__find_id_cb_args args = { + .name = name, + .id = id, + .res = NULL, + }; + + __dsos__for_each_dso(dsos, dsos__find_id_cb, &args); + return args.res; } - return __dsos__findnew_by_longname_id(&dsos->root, name, id); + res = __dsos__findnew_by_longname_id(&dsos->root, name, id); + return res; } struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short) @@ -275,48 +326,74 @@ struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id return dso; } -size_t __dsos__fprintf_buildid(struct dsos *dsos, FILE *fp, - bool (skip)(struct dso *dso, int parm), int parm) -{ - struct list_head *head = &dsos->head; - struct dso *pos; - size_t ret = 0; +struct dsos__fprintf_buildid_cb_args { + FILE *fp; + bool (*skip)(struct dso *dso, int parm); + int parm; + size_t ret; +}; - list_for_each_entry(pos, head, node) { - char sbuild_id[SBUILD_ID_SIZE]; +static int dsos__fprintf_buildid_cb(struct dso *dso, void *data) +{ + struct dsos__fprintf_buildid_cb_args *args = data; + char sbuild_id[SBUILD_ID_SIZE]; - if (skip && skip(pos, parm)) - continue; - build_id__sprintf(&pos->bid, sbuild_id); - ret += fprintf(fp, "%-40s %s\n", sbuild_id, pos->long_name); - } - return ret; + if (args->skip && args->skip(dso, args->parm)) + return 0; + build_id__sprintf(&dso->bid, sbuild_id); + args->ret += fprintf(args->fp, "%-40s %s\n", sbuild_id, dso->long_name); + return 0; } -size_t __dsos__fprintf(struct dsos *dsos, FILE *fp) +size_t dsos__fprintf_buildid(struct dsos *dsos, FILE *fp, + bool (*skip)(struct dso *dso, int parm), int parm) { - struct list_head *head = &dsos->head; - struct dso *pos; - size_t ret = 0; + struct dsos__fprintf_buildid_cb_args args = { + .fp = fp, + .skip = skip, + .parm = parm, + .ret = 0, + }; + + dsos__for_each_dso(dsos, dsos__fprintf_buildid_cb, &args); + return args.ret; +} - list_for_each_entry(pos, head, node) { - ret += dso__fprintf(pos, fp); - } +struct dsos__fprintf_cb_args { + FILE *fp; + size_t ret; +}; - return ret; +static int dsos__fprintf_cb(struct dso *dso, void *data) +{ + struct dsos__fprintf_cb_args *args = data; + + args->ret += dso__fprintf(dso, args->fp); + return 0; } -int __dsos__hit_all(struct dsos *dsos) +size_t dsos__fprintf(struct dsos *dsos, FILE *fp) { - struct list_head *head = &dsos->head; - struct dso *pos; + struct dsos__fprintf_cb_args args = { + .fp = fp, + .ret = 0, + }; - list_for_each_entry(pos, head, node) - pos->hit = true; + dsos__for_each_dso(dsos, dsos__fprintf_cb, &args); + return args.ret; +} +static int dsos__hit_all_cb(struct dso *dso, void *data __maybe_unused) +{ + dso->hit = true; return 0; } +int dsos__hit_all(struct dsos *dsos) +{ + return dsos__for_each_dso(dsos, dsos__hit_all_cb, NULL); +} + struct dso *dsos__findnew_module_dso(struct dsos *dsos, struct machine *machine, struct kmod_path *m, @@ -342,49 +419,44 @@ struct dso *dsos__findnew_module_dso(struct dsos *dsos, return dso; } -struct dso *dsos__find_kernel_dso(struct dsos *dsos) +static int dsos__find_kernel_dso_cb(struct dso *dso, void *data) { - struct dso *dso, *res = NULL; + struct dso **res = data; + /* + * The cpumode passed to is_kernel_module is not the cpumode of *this* + * event. If we insist on passing correct cpumode to is_kernel_module, + * we should record the cpumode when we adding this dso to the linked + * list. + * + * However we don't really need passing correct cpumode. We know the + * correct cpumode must be kernel mode (if not, we should not link it + * onto kernel_dsos list). + * + * Therefore, we pass PERF_RECORD_MISC_CPUMODE_UNKNOWN. + * is_kernel_module() treats it as a kernel cpumode. + */ + if (!dso->kernel || + is_kernel_module(dso->long_name, PERF_RECORD_MISC_CPUMODE_UNKNOWN)) + return 0; - down_read(&dsos->lock); - list_for_each_entry(dso, &dsos->head, node) { - /* - * The cpumode passed to is_kernel_module is not the cpumode of - * *this* event. If we insist on passing correct cpumode to - * is_kernel_module, we should record the cpumode when we adding - * this dso to the linked list. - * - * However we don't really need passing correct cpumode. We - * know the correct cpumode must be kernel mode (if not, we - * should not link it onto kernel_dsos list). - * - * Therefore, we pass PERF_RECORD_MISC_CPUMODE_UNKNOWN. - * is_kernel_module() treats it as a kernel cpumode. - */ - if (!dso->kernel || - is_kernel_module(dso->long_name, - PERF_RECORD_MISC_CPUMODE_UNKNOWN)) - continue; + *res = dso__get(dso); + return 1; +} - res = dso__get(dso); - break; - } - up_read(&dsos->lock); +struct dso *dsos__find_kernel_dso(struct dsos *dsos) +{ + struct dso *res = NULL; + + dsos__for_each_dso(dsos, dsos__find_kernel_dso_cb, &res); return res; } int dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data) { - struct dso *dso; + int err; down_read(&dsos->lock); - list_for_each_entry(dso, &dsos->head, node) { - int err; - - err = cb(dso, data); - if (err) - return err; - } + err = __dsos__for_each_dso(dsos, cb, data); up_read(&dsos->lock); - return 0; + return err; } diff --git a/tools/perf/util/dsos.h b/tools/perf/util/dsos.h index 317a263f0e37..50bd51523475 100644 --- a/tools/perf/util/dsos.h +++ b/tools/perf/util/dsos.h @@ -33,16 +33,16 @@ struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short); struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id *id); -bool __dsos__read_build_ids(struct dsos *dsos, bool with_hits); +bool dsos__read_build_ids(struct dsos *dsos, bool with_hits); struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso *dso, const char *name, struct dso_id *id); -size_t __dsos__fprintf_buildid(struct dsos *dsos, FILE *fp, +size_t dsos__fprintf_buildid(struct dsos *dsos, FILE *fp, bool (skip)(struct dso *dso, int parm), int parm); -size_t __dsos__fprintf(struct dsos *dsos, FILE *fp); +size_t dsos__fprintf(struct dsos *dsos, FILE *fp); -int __dsos__hit_all(struct dsos *dsos); +int dsos__hit_all(struct dsos *dsos); struct dso *dsos__findnew_module_dso(struct dsos *dsos, struct machine *machine, struct kmod_path *m, const char *filename); diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index f1186a5bb73c..0210c10e616b 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -852,11 +852,11 @@ static struct map *machine__addnew_module_map(struct machine *machine, u64 start size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) { struct rb_node *nd; - size_t ret = __dsos__fprintf(&machines->host.dsos, fp); + size_t ret = dsos__fprintf(&machines->host.dsos, fp); for (nd = rb_first_cached(&machines->guests); nd; nd = rb_next(nd)) { struct machine *pos = rb_entry(nd, struct machine, rb_node); - ret += __dsos__fprintf(&pos->dsos, fp); + ret += dsos__fprintf(&pos->dsos, fp); } return ret; @@ -865,7 +865,7 @@ size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) size_t machine__fprintf_dsos_buildid(struct machine *m, FILE *fp, bool (skip)(struct dso *dso, int parm), int parm) { - return __dsos__fprintf_buildid(&m->dsos, fp, skip, parm); + return dsos__fprintf_buildid(&m->dsos, fp, skip, parm); } size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp, @@ -3207,5 +3207,5 @@ bool machine__is_lock_function(struct machine *machine, u64 addr) int machine__hit_all_dsos(struct machine *machine) { - return __dsos__hit_all(&machine->dsos); + return dsos__hit_all(&machine->dsos); } From patchwork Fri Feb 2 06:15:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195602 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239370dyc; Thu, 1 Feb 2024 22:21:35 -0800 (PST) X-Google-Smtp-Source: AGHT+IGofZqBWj42hB1iON4RRaAVtS3zD4owyEV7q9O73QvyuvV+5gtBqx6qfWWL6Tx86dDOVieA X-Received: by 2002:a05:6a20:b287:b0:19c:6f2b:ad0a with SMTP id ei7-20020a056a20b28700b0019c6f2bad0amr6041860pzb.51.1706854894776; Thu, 01 Feb 2024 22:21:34 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854894; cv=pass; d=google.com; s=arc-20160816; b=y0TcVETeIUAleSM+ndvZJg9chyunyWy2h5v2HDeaL3DGMp0/ypZl4P9bclswmg40kt E1AHjlhbXx1pet08d68Tas7tEWuwOTYaL0wFZv5mqkN993x/2aV7HNYYE3TYJDkXljUs vYFKJdiR4pbk/PEHvrTDoPEATV73NEpMr59301P1pL0kkAJW1D73Bn4Qg9ivIDe8xyej 1KugufgLbqCdcdRcvA5kt/OMQgtDV8sn/GjU7ypuht3XmjIk0/f3gS/0IZ4dT8irKg5d eFp/k1X5YY56/GsNNx+SFnHJMBn3Vxf01J0NtQ68icyyi8znyxn8UmFio08+2nMHjZgo +QMg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=AnF8aiyu6Fn8VVDc78sSvgkUo/iZ+iabrZX10GOtvkQ=; fh=G2sB6FTbbnrqodVIND00WksVvaOKWCyCMM4vu8gwYfQ=; b=EYdr6dfrmosvUFmMLZYotcIuhgm6+BwuKekPAlBS0FBqXv5hh8INtv34n6Qfl4H6MM znP7KeU+H6sVwD9RnYRTo6+hgGUBdzu6BizvD/Kz0hXIxSqRCqJUu7+aXlRtKOKe/BEQ n3xuPV9ZiR0G7aJrYgONP2YCNyrSxSVW4O5AxdKgX+pihq/t8ww0Jh+8jwPQ2GJ68Mul 29mALsVKWKsfnhtemn2CiAXdSjFl/8LXlv9RmxPwtc49GAe4NAd/B/bSUZnjetOLMQ5r ECXjmJelQGkrMGCIDeldyKq9vYjaI/YXfQtZ6waDhj+Ur5twdglXTEbLx41lfIxQ0px/ 2T6Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=blNF90yQ; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49258-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49258-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCWIUJKl3NVCCaMFeIgQSh/Gp7DE+7Qgt/Gnduxbn/x2SVZwv4YWjLAUAkugNFym+3OOQeSdfvUy85So7Df89d1I0W3/xw== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id d6-20020a170903230600b001d70fef0d09si1257368plh.52.2024.02.01.22.21.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:21:34 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49258-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=blNF90yQ; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49258-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49258-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 948B92848D6 for ; Fri, 2 Feb 2024 06:21:19 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B30B2482F4; Fri, 2 Feb 2024 06:16:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="blNF90yQ" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 7937238DD4 for ; Fri, 2 Feb 2024 06:16:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854593; cv=none; b=DkCi2KxQ4IO3MKpHXpx/pjeh92T7pPIP0QU/+6SwunrLAcYxNiPL+IW+CkIuuSP2ymk0HI/JFarK7Ynhcc9RS5ORVtSqk0E/jhwnKekGu1LpB1F+FCcJFpTvAXwLEtlqn5MfCX+KScqvnmsgDuXLmgsj73OXKrg9tGeGKs12068= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854593; c=relaxed/simple; bh=sB+RJMuB50u+qTZ+GviEmhYLnUySSFrrwB7yOy2hy8Y=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=PyIPAQTq8maFTM/Z4f77lF7H8WWwG1psDNRhRmZJqWPJsCk92r/tjAeyJY9G972LbUBV2/hFPv93mDxnx14mr19uc/OLyO7kf9DR2IffXlflp/o64T3QZtyj08YzZRsWdMtliXfsS7fgap+Orsvl6EqFCfANVRBst6zIouBTeAg= 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=blNF90yQ; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6041c45ce1cso25620577b3.1 for ; Thu, 01 Feb 2024 22:16:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854590; x=1707459390; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=AnF8aiyu6Fn8VVDc78sSvgkUo/iZ+iabrZX10GOtvkQ=; b=blNF90yQFn3kjp+Qb2WVxGCtj77EQb1hKOqBCrfMDOrqHf+t4kCNEirgocQ3vk0lSA CGNqCwktl7ZIl08D+XHZDv4ecW+V2qEXAlXH0kNLFD615cvW2rniKbu4+gf65rtv+Nu2 RpLbPkUmRk8R/Ifl3JndiANZLGOmdDdwiruSrFX0c+1AayP7/SE7kfZL5koU/CyER/S0 PMJVrPupcgk2YDp56NXMizFfEFZxXXj7hFQ5Dc2/k3kwnAoSu4Bmi2IdAp8jkBqoCPQM pR4UAWlSnXod/Qh60xquS0ReUvWD0+5wSOfCiWJxdyic7rPUZHcgsZoumZpvHjNNxvqI ce5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854590; x=1707459390; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=AnF8aiyu6Fn8VVDc78sSvgkUo/iZ+iabrZX10GOtvkQ=; b=KBGOicBD27pdbtR0XxsjS9r8hkFX28+NrpTkzdwufzMDjjMia+T8bPgW2t5CWHzOZD RUKkzBNoh89Owo6X/MnCoDlMhkC9gQQrwjneCiKsk9wCb/LB9lc4D2cu+Jsq3nm8oSR6 iah/DzLdJ9zXmW7A4dVk7i/0EDILxdRTM4lv0LodpMUV+Af6s3SD1npNSon1xe+GQfSx fBcfk0MPtbtTNqvGe0F0gmpCJvTI1lk728bJyneB7jzNHaXUTysNoIt8BUhY1+YpOq7V pCpEDR2X7fWcF6x/ZXAYkwAUb0x2eBXl+zcjbt36ruSW9g1cNq61bqscJkAM30CRZWRg gO9A== X-Gm-Message-State: AOJu0YzbkH8Kh1kJ77DuhybmdgELvv9nueO0/WDP6BXeDEQkZvY2tEgL ayro5EACu30EGQzuNxgKLjRTvm7Qydrakvv1rcDbdj/1CvmbVlAOEsVrQZPSWY026KLtPbUdXEE 3bOeQ9Q== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a81:57d3:0:b0:602:cd33:5392 with SMTP id l202-20020a8157d3000000b00602cd335392mr748847ywb.3.1706854590477; Thu, 01 Feb 2024 22:16:30 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:26 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-20-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 19/25] perf dsos: Switch backing storage to array from rbtree/list From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767078318814217 X-GMAIL-MSGID: 1789767078318814217 DSOs were held on a list for fast iteration and in an rbtree for fast finds. Switch to using a lazily sorted array where iteration is just iterating through the array and binary searches are the same complexity as searching the rbtree. The find may need to sort the array first which does increase the complexity, but add operations have lower complexity and overall the complexity should remain about the same. The set name operations on the dso just records that the array is no longer sorted, avoiding complexity in rebalancing the rbtree. Tighter locking discipline is enforced to avoid the array being resorted while long and short names or ids are changed. The array is smaller in size, replacing 6 pointers with 2, and so even with extra allocated space in the array, the array may be 50% unoccupied, the memory saving should be at least 2x. Signed-off-by: Ian Rogers --- tools/perf/util/dso.c | 67 +++++++++------ tools/perf/util/dso.h | 10 +-- tools/perf/util/dsos.c | 188 ++++++++++++++++++++++++++--------------- tools/perf/util/dsos.h | 21 +++-- 4 files changed, 177 insertions(+), 109 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 69b9aa256776..e96369fb490b 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1241,35 +1241,35 @@ struct dso *machine__findnew_kernel(struct machine *machine, const char *name, return dso; } -static void dso__set_long_name_id(struct dso *dso, const char *name, struct dso_id *id, bool name_allocated) +static void dso__set_long_name_id(struct dso *dso, const char *name, bool name_allocated) { - struct rb_root *root = dso->root; + struct dsos *dsos = dso->dsos; if (name == NULL) return; - if (dso->long_name_allocated) - free((char *)dso->long_name); - - if (root) { - rb_erase(&dso->rb_node, root); + if (dsos) { /* - * __dsos__findnew_link_by_longname_id() isn't guaranteed to - * add it back, so a clean removal is required here. + * Need to avoid re-sorting the dsos breaking by non-atomically + * renaming the dso. */ - RB_CLEAR_NODE(&dso->rb_node); - dso->root = NULL; + down_write(&dsos->lock); } + if (dso->long_name_allocated) + free((char *)dso->long_name); + dso->long_name = name; dso->long_name_len = strlen(name); dso->long_name_allocated = name_allocated; - if (root) - __dsos__findnew_link_by_longname_id(root, dso, NULL, id); + if (dsos) { + dsos->sorted = false; + up_write(&dsos->lock); + } } -static int __dso_id__cmp(struct dso_id *a, struct dso_id *b) +static int __dso_id__cmp(const struct dso_id *a, const struct dso_id *b) { if (a->maj > b->maj) return -1; if (a->maj < b->maj) return 1; @@ -1297,7 +1297,7 @@ static int __dso_id__cmp(struct dso_id *a, struct dso_id *b) return 0; } -bool dso_id__empty(struct dso_id *id) +bool dso_id__empty(const struct dso_id *id) { if (!id) return true; @@ -1305,15 +1305,22 @@ bool dso_id__empty(struct dso_id *id) return !id->maj && !id->min && !id->ino && !id->ino_generation; } -void dso__inject_id(struct dso *dso, struct dso_id *id) +void __dso__inject_id(struct dso *dso, struct dso_id *id) { + struct dsos *dsos = dso->dsos; + + /* dsos write lock held by caller. */ + dso->id.maj = id->maj; dso->id.min = id->min; dso->id.ino = id->ino; dso->id.ino_generation = id->ino_generation; + + if (dsos) + dsos->sorted = false; } -int dso_id__cmp(struct dso_id *a, struct dso_id *b) +int dso_id__cmp(const struct dso_id *a, const struct dso_id *b) { /* * The second is always dso->id, so zeroes if not set, assume passing @@ -1332,20 +1339,34 @@ int dso__cmp_id(struct dso *a, struct dso *b) void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated) { - dso__set_long_name_id(dso, name, NULL, name_allocated); + dso__set_long_name_id(dso, name, name_allocated); } void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated) { + struct dsos *dsos = dso->dsos; + if (name == NULL) return; + if (dsos) { + /* + * Need to avoid re-sorting the dsos breaking by non-atomically + * renaming the dso. + */ + down_write(&dsos->lock); + } if (dso->short_name_allocated) free((char *)dso->short_name); dso->short_name = name; dso->short_name_len = strlen(name); dso->short_name_allocated = name_allocated; + + if (dsos) { + dsos->sorted = false; + up_write(&dsos->lock); + } } int dso__name_len(const struct dso *dso) @@ -1381,7 +1402,7 @@ struct dso *dso__new_id(const char *name, struct dso_id *id) strcpy(dso->name, name); if (id) dso->id = *id; - dso__set_long_name_id(dso, dso->name, id, false); + dso__set_long_name_id(dso, dso->name, false); dso__set_short_name(dso, dso->name, false); dso->symbols = RB_ROOT_CACHED; dso->symbol_names = NULL; @@ -1405,9 +1426,6 @@ struct dso *dso__new_id(const char *name, struct dso_id *id) dso->is_kmod = 0; dso->needs_swap = DSO_SWAP__UNSET; dso->comp = COMP_ID__NONE; - RB_CLEAR_NODE(&dso->rb_node); - dso->root = NULL; - INIT_LIST_HEAD(&dso->node); INIT_LIST_HEAD(&dso->data.open_entry); mutex_init(&dso->lock); refcount_set(&dso->refcnt, 1); @@ -1423,9 +1441,8 @@ struct dso *dso__new(const char *name) void dso__delete(struct dso *dso) { - if (!RB_EMPTY_NODE(&dso->rb_node)) - pr_err("DSO %s is still in rbtree when being deleted!\n", - dso->long_name); + if (dso->dsos) + pr_err("DSO %s is still in rbtree when being deleted!\n", dso->long_name); /* free inlines first, as they reference symbols */ inlines__tree_delete(&dso->inlined_nodes); diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 7447d7a1942a..2e227822f10c 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -146,9 +146,7 @@ struct auxtrace_cache; struct dso { struct mutex lock; - struct list_head node; - struct rb_node rb_node; /* rbtree node sorted by long name */ - struct rb_root *root; /* root of rbtree that rb_node is in */ + struct dsos *dsos; struct rb_root_cached symbols; struct symbol **symbol_names; size_t symbol_names_len; @@ -237,8 +235,8 @@ static inline void dso__set_loaded(struct dso *dso) dso->loaded = true; } -int dso_id__cmp(struct dso_id *a, struct dso_id *b); -bool dso_id__empty(struct dso_id *id); +int dso_id__cmp(const struct dso_id *a, const struct dso_id *b); +bool dso_id__empty(const struct dso_id *id); struct dso *dso__new_id(const char *name, struct dso_id *id); struct dso *dso__new(const char *name); @@ -247,7 +245,7 @@ void dso__delete(struct dso *dso); int dso__cmp_id(struct dso *a, struct dso *b); void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated); void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated); -void dso__inject_id(struct dso *dso, struct dso_id *id); +void __dso__inject_id(struct dso *dso, struct dso_id *id); int dso__name_len(const struct dso *dso); diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index b7fbfb877ae3..cfc10e1a6802 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -14,24 +14,30 @@ void dsos__init(struct dsos *dsos) { - INIT_LIST_HEAD(&dsos->head); - dsos->root = RB_ROOT; init_rwsem(&dsos->lock); + + dsos->cnt = 0; + dsos->allocated = 0; + dsos->dsos = NULL; + dsos->sorted = true; } static void dsos__purge(struct dsos *dsos) { - struct dso *pos, *n; - down_write(&dsos->lock); - list_for_each_entry_safe(pos, n, &dsos->head, node) { - RB_CLEAR_NODE(&pos->rb_node); - pos->root = NULL; - list_del_init(&pos->node); - dso__put(pos); + for (unsigned int i = 0; i < dsos->cnt; i++) { + struct dso *dso = dsos->dsos[i]; + + dso__put(dso); + dso->dsos = NULL; } + zfree(&dsos->dsos); + dsos->cnt = 0; + dsos->allocated = 0; + dsos->sorted = true; + up_write(&dsos->lock); } @@ -46,9 +52,8 @@ static int __dsos__for_each_dso(struct dsos *dsos, int (*cb)(struct dso *dso, void *data), void *data) { - struct dso *dso; - - list_for_each_entry(dso, &dsos->head, node) { + for (unsigned int i = 0; i < dsos->cnt; i++) { + struct dso *dso = dsos->dsos[i]; int err; err = cb(dso, data); @@ -119,16 +124,47 @@ static int dso__cmp_short_name(struct dso *a, struct dso *b) return __dso__cmp_short_name(a->short_name, &a->id, b); } +static int dsos__cmp_long_name_id_short_name(const void *va, const void *vb) +{ + const struct dso *a = *((const struct dso **)va); + const struct dso *b = *((const struct dso **)vb); + int rc = strcmp(a->long_name, b->long_name); + + if (!rc) { + rc = dso_id__cmp(&a->id, &b->id); + if (!rc) + rc = strcmp(a->short_name, b->short_name); + } + return rc; +} + /* * Find a matching entry and/or link current entry to RB tree. * Either one of the dso or name parameter must be non-NULL or the * function will not work. */ -struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso *dso, - const char *name, struct dso_id *id) +struct dso *__dsos__findnew_link_by_longname_id(struct dsos *dsos, + struct dso *dso, + const char *name, + struct dso_id *id, + bool write_locked) { - struct rb_node **p = &root->rb_node; - struct rb_node *parent = NULL; + int low = 0, high = dsos->cnt - 1; + + if (!dsos->sorted) { + if (!write_locked) { + up_read(&dsos->lock); + down_write(&dsos->lock); + dso = __dsos__findnew_link_by_longname_id(dsos, dso, name, id, + /*write_locked=*/true); + up_write(&dsos->lock); + down_read(&dsos->lock); + return dso; + } + qsort(dsos->dsos, dsos->cnt, sizeof(struct dso *), + dsos__cmp_long_name_id_short_name); + dsos->sorted = true; + } if (!name) name = dso->long_name; @@ -136,11 +172,11 @@ struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso /* * Find node with the matching name */ - while (*p) { - struct dso *this = rb_entry(*p, struct dso, rb_node); + while (low <= high) { + int mid = (low + high) / 2; + struct dso *this = dsos->dsos[mid]; int rc = __dso__cmp_long_name(name, id, this); - parent = *p; if (rc == 0) { /* * In case the new DSO is a duplicate of an existing @@ -161,56 +197,53 @@ struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso } } if (rc < 0) - p = &parent->rb_left; + high = mid - 1; else - p = &parent->rb_right; - } - if (dso) { - /* Add new node and rebalance tree */ - rb_link_node(&dso->rb_node, parent, p); - rb_insert_color(&dso->rb_node, root); - dso->root = root; + low = mid + 1; } + if (dso) + __dsos__add(dsos, dso); return NULL; } -void __dsos__add(struct dsos *dsos, struct dso *dso) +int __dsos__add(struct dsos *dsos, struct dso *dso) { - list_add_tail(&dso->node, &dsos->head); - __dsos__findnew_link_by_longname_id(&dsos->root, dso, NULL, &dso->id); - /* - * It is now in the linked list, grab a reference, then garbage collect - * this when needing memory, by looking at LRU dso instances in the - * list with atomic_read(&dso->refcnt) == 1, i.e. no references - * anywhere besides the one for the list, do, under a lock for the - * list: remove it from the list, then a dso__put(), that probably will - * be the last and will then call dso__delete(), end of life. - * - * That, or at the end of the 'struct machine' lifetime, when all - * 'struct dso' instances will be removed from the list, in - * dsos__exit(), if they have no other reference from some other data - * structure. - * - * E.g.: after processing a 'perf.data' file and storing references - * to objects instantiated while processing events, we will have - * references to the 'thread', 'map', 'dso' structs all from 'struct - * hist_entry' instances, but we may not need anything not referenced, - * so we might as well call machines__exit()/machines__delete() and - * garbage collect it. - */ - dso__get(dso); + if (dsos->cnt == dsos->allocated) { + unsigned int to_allocate = 2; + struct dso **temp; + + if (dsos->allocated > 0) + to_allocate = dsos->allocated * 2; + temp = realloc(dsos->dsos, sizeof(struct dso *) * to_allocate); + if (!temp) + return -ENOMEM; + dsos->dsos = temp; + dsos->allocated = to_allocate; + } + dsos->dsos[dsos->cnt++] = dso__get(dso); + if (dsos->cnt >= 2 && dsos->sorted) { + dsos->sorted = dsos__cmp_long_name_id_short_name(&dsos->dsos[dsos->cnt - 2], + &dsos->dsos[dsos->cnt - 1]) + <= 0; + } + dso->dsos = dsos; + return 0; } -void dsos__add(struct dsos *dsos, struct dso *dso) +int dsos__add(struct dsos *dsos, struct dso *dso) { + int ret; + down_write(&dsos->lock); - __dsos__add(dsos, dso); + ret = __dsos__add(dsos, dso); up_write(&dsos->lock); + return ret; } -static struct dso *__dsos__findnew_by_longname_id(struct rb_root *root, const char *name, struct dso_id *id) +static struct dso *__dsos__findnew_by_longname_id(struct dsos *dsos, const char *name, + struct dso_id *id, bool write_locked) { - return __dsos__findnew_link_by_longname_id(root, NULL, name, id); + return __dsos__findnew_link_by_longname_id(dsos, NULL, name, id, write_locked); } struct dsos__find_id_cb_args { @@ -231,7 +264,8 @@ static int dsos__find_id_cb(struct dso *dso, void *data) } -static struct dso *__dsos__find_id(struct dsos *dsos, const char *name, struct dso_id *id, bool cmp_short) +static struct dso *__dsos__find_id(struct dsos *dsos, const char *name, struct dso_id *id, + bool cmp_short, bool write_locked) { struct dso *res; @@ -245,7 +279,7 @@ static struct dso *__dsos__find_id(struct dsos *dsos, const char *name, struct d __dsos__for_each_dso(dsos, dsos__find_id_cb, &args); return args.res; } - res = __dsos__findnew_by_longname_id(&dsos->root, name, id); + res = __dsos__findnew_by_longname_id(dsos, name, id, write_locked); return res; } @@ -254,7 +288,7 @@ struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short) struct dso *res; down_read(&dsos->lock); - res = __dsos__find_id(dsos, name, NULL, cmp_short); + res = __dsos__find_id(dsos, name, NULL, cmp_short, /*write_locked=*/false); up_read(&dsos->lock); return res; } @@ -296,8 +330,13 @@ static struct dso *__dsos__addnew_id(struct dsos *dsos, const char *name, struct struct dso *dso = dso__new_id(name, id); if (dso != NULL) { - __dsos__add(dsos, dso); + /* + * The dsos lock is held on entry, so rename the dso before + * adding it to avoid needing to take the dsos lock again to say + * the array isn't sorted. + */ dso__set_basename(dso); + __dsos__add(dsos, dso); } return dso; } @@ -309,10 +348,10 @@ struct dso *__dsos__addnew(struct dsos *dsos, const char *name) static struct dso *__dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id *id) { - struct dso *dso = __dsos__find_id(dsos, name, id, false); + struct dso *dso = __dsos__find_id(dsos, name, id, false, /*write_locked=*/true); if (dso && dso_id__empty(&dso->id) && !dso_id__empty(id)) - dso__inject_id(dso, id); + __dso__inject_id(dso, id); return dso ? dso : __dsos__addnew_id(dsos, name, id); } @@ -403,18 +442,27 @@ struct dso *dsos__findnew_module_dso(struct dsos *dsos, down_write(&dsos->lock); - dso = __dsos__find_id(dsos, m->name, NULL, /*cmp_short=*/true); + dso = __dsos__find_id(dsos, m->name, NULL, /*cmp_short=*/true, /*write_locked=*/true); + if (dso) { + up_write(&dsos->lock); + return dso; + } + /* + * Failed to find the dso so create it. Change the name before adding it + * to the array, to avoid unnecessary sorts and potential locking + * issues. + */ + dso = dso__new_id(m->name, /*id=*/NULL); if (!dso) { - dso = __dsos__addnew(dsos, m->name); - if (dso == NULL) - goto out_unlock; - - dso__set_module_info(dso, m, machine); - dso__set_long_name(dso, strdup(filename), true); - dso->kernel = DSO_SPACE__KERNEL; + up_write(&dsos->lock); + return NULL; } + dso__set_basename(dso); + dso__set_module_info(dso, m, machine); + dso__set_long_name(dso, strdup(filename), true); + dso->kernel = DSO_SPACE__KERNEL; + __dsos__add(dsos, dso); -out_unlock: up_write(&dsos->lock); return dso; } diff --git a/tools/perf/util/dsos.h b/tools/perf/util/dsos.h index 50bd51523475..c1b3979ad4bd 100644 --- a/tools/perf/util/dsos.h +++ b/tools/perf/util/dsos.h @@ -14,20 +14,22 @@ struct kmod_path; struct machine; /* - * DSOs are put into both a list for fast iteration and rbtree for fast - * long name lookup. + * Collection of DSOs as an array for iteration speed, but sorted for O(n) + * lookup. */ struct dsos { - struct list_head head; - struct rb_root root; /* rbtree root sorted by long name */ struct rw_semaphore lock; + struct dso **dsos; + unsigned int cnt; + unsigned int allocated; + bool sorted; }; void dsos__init(struct dsos *dsos); void dsos__exit(struct dsos *dsos); -void __dsos__add(struct dsos *dsos, struct dso *dso); -void dsos__add(struct dsos *dsos, struct dso *dso); +int __dsos__add(struct dsos *dsos, struct dso *dso); +int dsos__add(struct dsos *dsos, struct dso *dso); struct dso *__dsos__addnew(struct dsos *dsos, const char *name); struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short); @@ -35,8 +37,11 @@ struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id bool dsos__read_build_ids(struct dsos *dsos, bool with_hits); -struct dso *__dsos__findnew_link_by_longname_id(struct rb_root *root, struct dso *dso, - const char *name, struct dso_id *id); +struct dso *__dsos__findnew_link_by_longname_id(struct dsos *dsos, + struct dso *dso, + const char *name, + struct dso_id *id, + bool write_locked); size_t dsos__fprintf_buildid(struct dsos *dsos, FILE *fp, bool (skip)(struct dso *dso, int parm), int parm); From patchwork Fri Feb 2 06:15:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195601 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239249dyc; Thu, 1 Feb 2024 22:21:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IEkYSC3KopbacFkDOcImalpf3VX2P1WNFO5PxJF7nXM4dUwziTwqWd2xPoYiZhlPY6XUcE1 X-Received: by 2002:a05:6a20:c78d:b0:19e:3af0:af33 with SMTP id hk13-20020a056a20c78d00b0019e3af0af33mr6164239pzb.60.1706854869372; Thu, 01 Feb 2024 22:21:09 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854869; cv=pass; d=google.com; s=arc-20160816; b=XQghBguHASc3tIZHMevy2DGuwAsbkqLqxCFeTquCEA6ALLKaqPIQk3w7ojE+YPjbPz 8hiPKzQbsASch/tYQrwUG0h7zXF8yzEXuP+7lZiaGtY6W1JnU3rnbo9AmBqSZApadAdU XNLxCZPNB3/QaTGH/YOlZpGjoLA258QsTL/6cDz+yz8+f5nUApsmW7S9rGk20BNAO+gq fQ/ItjUQrJIkB1PCswobxcWhtzyl1m3EvXNBOjqAtLGlDH0o8j4QO4RJ0X3pSuirSgKD U622Z93Fxp9raV9iqVleImOsE/DeA88EJbpWr+kirnHopxaxlP/WdrfFU/Dr7/mbS1+M 6dyQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=9ypNKo2tr4KsqSZVI47f8lu+x9dprlYfSiowX/NLn3s=; fh=1KsuWU0Mb4Pz2xqRamHphzG0JY/h+NVkPwdjOXNql3w=; b=al8ad2uGLavdKNNw9NR7RVaMJ7J52UwjMAJ2bFF9gASPUojGNJwQqrI4/w9ooB4308 GDsOpClUa80LuU34RTRAa0Y78aTy7TjkONmSWmKEyEP5ID3JAAQDc5L2wSqKBsApI7Fh A4PgXgyRQYB6C0YxxsOKcyI8eZCFf1qfH6mIY3ZFFFIFsTVywd7rED6GNQxbwK1e/C9l MjruKv0PTj1OG/ggLQd31Jg3FuGuMFS9S3iV28Pp6XHXgiCocWbdQWdMCnaA+aTIyvSv /Ncc0gUCWfuOoMv7nAhk+/ovMIVSUBMtEBEJNHpyP5GaFEUVefBkmI3tvbnZypPTpqOu BxwA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=Vb22f27d; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49259-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49259-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCWsEq2QEDEW3HXkD2nJ3SP/jHkWjaE9LeLetv3zLJCrsAYUIo4YlaOklHINRSw16uG3+XPY31UndVa2aVDB94D2//DFtA== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id y15-20020a17090a16cf00b00290358165d9si1201204pje.13.2024.02.01.22.21.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:21:09 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49259-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=Vb22f27d; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49259-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49259-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 sy.mirrors.kernel.org (Postfix) with ESMTPS id 59993B20E58 for ; Fri, 2 Feb 2024 06:21:08 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1D714482CC; Fri, 2 Feb 2024 06:16:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Vb22f27d" Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 9DDE03FB37 for ; Fri, 2 Feb 2024 06:16:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854595; cv=none; b=rDwnFSObHkfOAw8GrRlRbU3hQw6xqgXW4FtBMY8HrX1Fvb+DolhON9bOQLbUd6eZAAICxKe2wPouvkbxQHOIrdKm8GoD5CXuv6EoorUsWQ1x2TWZDFP1vz4s5RKypnFtpKqgnYUXIGoT+SR1nq9EUhyC2q2D5RgICmGsfInIZ4A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854595; c=relaxed/simple; bh=WyIYFrIhagbqEpEtSnjdCLJyMzbzoqJYvfr5Sd4U2xw=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=uezguFm+SX3x6zaoZaMajBq9JTE8JyiF2S246T1V+79QcOlghzH54QcEWQi0PliNGOZG6vddVfxktzDZP95ToKLLOSdk2TT+cyCG9OmxTV8QFR6oK8WMQC2xJP0myvOMg5oLd3ibF3Xoxyh5v3+Soiw6k7UbQEttTo1vcqExlJo= 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=Vb22f27d; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-60406626b50so38939417b3.0 for ; Thu, 01 Feb 2024 22:16:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854593; x=1707459393; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=9ypNKo2tr4KsqSZVI47f8lu+x9dprlYfSiowX/NLn3s=; b=Vb22f27dMpxIkeXh0L5WJ4HCOXp8tebLiiFazOzgAIuAzCgp1FwUyln3t/tXFvexWg BFif2qdUFnp1pFfLJd1qq6nvbpGn+4K9aEI4G06OJ62lb+y5GYcjBpXvcNTEHqY4xfWA 4rOa+7Y15HmQ3hSZOqXbOqteCZDzOSONtv8ZUTe9D1SPbCdwmv0SBGo3Hii7F5e0gooD Px4HEM0yrUJlaTw51YYLigJ4ZUHU70fYgmi1UCMlFCmylLTbbfb5R2uAcooS7rTvFC0s kYDEwC6sySJYoeuWabfjkjDHUEtjWMUOZjd12OKS0X8Ix0wDcO1pYy4d7M99QMP7166t s9cw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854593; x=1707459393; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9ypNKo2tr4KsqSZVI47f8lu+x9dprlYfSiowX/NLn3s=; b=Bes0M9zcJVzbLUooDSDVnMKE0xG20D2xIZwkGZ7lZR2du8qLNBmg2TbG1jzWQG/1OG 0fhboehnndIsnWLcLKBBdcfTD7GrpIp6xnq7T8MoCILKJ90cL1PTOjCI5O2AQEjhQOvq 8ICs/slAVXTX+rXo5XS0+VlQGcZLkOITSXoVh4jtCDZYlLj7XIdVmvpV1MmOQMH/nQCY u7ctFhu/ah2YOCcytJLFRmMK6zb06VGXaBNduFP04TLLv/j/ClB2HeNeS5gWsg2iO6J7 g+8QVCixm0vXYGmwqjVjRd1LB+PZf1JX+rDETOVHy973lyKyMQoBYzVpi/DprNg6gvHf Z3tQ== X-Gm-Message-State: AOJu0YyN4O6EX2NMgZkf9hNJjJbeo0d5UrF9mK1jEVfIPgE3gS4Er4Rx W2YKEFjfURkq83FIaLFgp763joKFl0AF+n0ypng22qJ7PEIdxT3sBmJO8r5lzmxrwf+r8px7K8U +QZvo8Q== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:690c:84:b0:604:2252:7827 with SMTP id be4-20020a05690c008400b0060422527827mr331617ywb.10.1706854592816; Thu, 01 Feb 2024 22:16:32 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:27 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-21-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 20/25] perf dsos: Remove __dsos__addnew From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767051484008330 X-GMAIL-MSGID: 1789767051484008330 Function no longer used so remove. Signed-off-by: Ian Rogers --- tools/perf/util/dsos.c | 5 ----- tools/perf/util/dsos.h | 1 - 2 files changed, 6 deletions(-) diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index cfc10e1a6802..1495ab1cd7a0 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -341,11 +341,6 @@ static struct dso *__dsos__addnew_id(struct dsos *dsos, const char *name, struct return dso; } -struct dso *__dsos__addnew(struct dsos *dsos, const char *name) -{ - return __dsos__addnew_id(dsos, name, NULL); -} - static struct dso *__dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id *id) { struct dso *dso = __dsos__find_id(dsos, name, id, false, /*write_locked=*/true); diff --git a/tools/perf/util/dsos.h b/tools/perf/util/dsos.h index c1b3979ad4bd..d1497b11d64c 100644 --- a/tools/perf/util/dsos.h +++ b/tools/perf/util/dsos.h @@ -30,7 +30,6 @@ void dsos__exit(struct dsos *dsos); int __dsos__add(struct dsos *dsos, struct dso *dso); int dsos__add(struct dsos *dsos, struct dso *dso); -struct dso *__dsos__addnew(struct dsos *dsos, const char *name); struct dso *dsos__find(struct dsos *dsos, const char *name, bool cmp_short); struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id *id); From patchwork Fri Feb 2 06:15:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195603 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239380dyc; Thu, 1 Feb 2024 22:21:36 -0800 (PST) X-Google-Smtp-Source: AGHT+IFPkfW1Jq6LZ8Eeod2nx//s9l9HZeZnAl7Ec2nBcOq9A/AZyVH75UHm4m6YF9z84TYTgfmq X-Received: by 2002:a05:6512:239c:b0:511:3261:d112 with SMTP id c28-20020a056512239c00b005113261d112mr2069871lfv.9.1706854896423; Thu, 01 Feb 2024 22:21:36 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854896; cv=pass; d=google.com; s=arc-20160816; b=RjBgRCXYhdyMKxgu4LLemRtXb9nrVbf2p3P/mhT28EcKAM9MdmtefcyNkT4IPR9NGy UfnKjbBQ00riCc8+mGDCzgDWQ6JGh/UPDG4xlSbJv93u31KV8aCP5oqAoHV43h5nmFOi 05fpUs6ilX0jcn5115dUsdVxZQ8iuzzHGaKZQa3CECpx/Ibgx7IY+7fruBbexca8Hpe1 juHJabFUC3GwRo9fEmJ8vEBSFz7yZFB5al2vCxy/HJNjITomoEaGv0SGECk4RjVOh2lJ yuHeZhQe1WQ/Jk/qnFN8tfNYnyrY3LsH4jasJ+bU//OtyrYglasryXBt7lQKPyan49r6 Rm3Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=XOKWqBGia5OyCougv9iLJxqXDjaf1HrWKaNIyp4iI8U=; fh=51KEsH+bXw20aIUSISAowRWR0xm6qOAf1/0MR5X1u04=; b=d5wNmIVt+5Sa5FCfoM7gp5cCV/C9/6c2M4yhMf0ujL6JNBCwsuKaVsW3QLkVOOWbzQ HjlSqnGr/+i6ja6QZVrRA2WpyQ2KRYFZ9orr4OTEWCGv3Lv4/Hdf8FbaPh2tLUenoWkY G0a9R5394TVTWbLuwfmjoe4rnSUtKzt3ed2hV5rLFfRDf2Kupx4oNBa9gUlMc39xVeJk Juv8iWLpAXX82Yp/sJ1m1awiFvBwfp2EE7jqWl7gRj1x7GR/QlcY1gXkzP75HoIKzKfp phewMF8iBzjlFDbwnPy9ls1I7e57MarHs+22GOX1JV5hwaFR2jMiiwjNXZ3lIVX76TPM djSQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=fK43sBvg; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49260-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49260-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCWvg1EWgj0AjthiTtaGE6DD8kvTGOdzqqSJc/S+iL4VllEoCyDzmWO4SU92IpipV0kIrjPRKHNF/07KiFzD6BJWowHr5g== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id l14-20020a1709061c4e00b00a36134c3e03si514428ejg.770.2024.02.01.22.21.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:21:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49260-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=fK43sBvg; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49260-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49260-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 am.mirrors.kernel.org (Postfix) with ESMTPS id C34C21F267AB for ; Fri, 2 Feb 2024 06:21:24 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5D066482FE; Fri, 2 Feb 2024 06:16:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="fK43sBvg" Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 E9F3B481A2 for ; Fri, 2 Feb 2024 06:16:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854597; cv=none; b=dvrGVMhk3ZDOa1qsqpHQUWg9oRYlIGqVwjrFCQz3w3ruYjQf61wCXVve945jknLguvTTSc56zYUHfl0dXcg/6aZrENtPiIvp+p/sqFiuKD4kP3JjZbxWq1oeYKwTSB4qeAHl1AzlSUfCQwtdAahPDCcg09vKOAZobWNC6P+do9o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854597; c=relaxed/simple; bh=E66uxfEVT8gu+OCIYrlFGYMg89yCZ/I5pQEusMkrRVM=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=jcexoceoGk52mnl6a56VUJy/eIBbPQ0oUajKyutU/FYTa+kzuk1chQAPdQEzWbIwRNYxrVYgMLLUom1DH3bUXxYIkazOQHYuYLOJOhh9urdLK3vTCmcts0e35YFXg6MTjNCJDJFRNW1w7qPHGge9vW6qoNW34DR3hziYlBgAx0s= 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=fK43sBvg; arc=none smtp.client-ip=209.85.128.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 Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-6040607c642so33582057b3.3 for ; Thu, 01 Feb 2024 22:16:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854595; x=1707459395; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=XOKWqBGia5OyCougv9iLJxqXDjaf1HrWKaNIyp4iI8U=; b=fK43sBvgF/eoBTya87fmyKJdj+hhrn0Ce5hujqNBRbCimjddCzYyimyYQ3c5e0vgVs uXdpIuNNieh4Dbwi78J/Xq2IKQRwveqEXV9NRTyj1ayH0IAH+Afg9fkiM3kLRWDKgvYE WZ4CwQt+IhzaC1NroLgOIRUFFKhFJV5s7U+lL9XJ68yn0IiafebC+QT25HJQa1GShrkj W6uZccZq/sHH1z6/u5QkZwTS4plHmGNM+6YYJ7XN2lZdlsNp5SYRg6N/WjK+0RUb0Pq0 V6w9GMCsaG8dcnah0YeQCxaAaXxvI0U4MAvfgk9smt/FOsrp7xq7oEzYSnbVKwvBuqys O3aA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854595; x=1707459395; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=XOKWqBGia5OyCougv9iLJxqXDjaf1HrWKaNIyp4iI8U=; b=EDwHzgtVnPorKdfGIhqtIjxY9ZPurhnzxaz56ev3/+7cOeoqfWXzL/2m1SiUa5Db2E 2TV4iUE5Q8sIEMuMumWRiYy7KagWtgG8WLzMhl/p7gU473s6N6jGc2v+3J3f/0/QIAst 3TGAZX6KemgOhNTU6oG8muhpsGLJYpAcm6tRVim3KcfKCRxcO5eZPfhZR8J0ai5IF9bT RalVbf/uyh7Oz2CCVg1pFrP1Y09DFsGTx2qMlyL8/7FKetshBUSRMbu7y+kTJ4VDswmA EnYaGfQsqHBW2v2QIhmmEHOVS8m8YPEV4hNDe1g9GD5I/noLvyIkguyaf7bnI8ynCJpR KybQ== X-Gm-Message-State: AOJu0Yy5+qysZ7uM1IIFl2spqIA1CUg6zeoO2CDsJYCzlsc6vikCmipc PukxbXg4qFhvZz6mVNG99O+R9+D+eZt728gSj/Ots5KA+HmVXQUpfGgs+g3Nf299QRWSi4mOHMv oOdF1Qg== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:2004:b0:dc6:af9a:8cfa with SMTP id dh4-20020a056902200400b00dc6af9a8cfamr375539ybb.6.1706854595155; Thu, 01 Feb 2024 22:16:35 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:28 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-22-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 21/25] perf dsos: Remove __dsos__findnew_link_by_longname_id From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767080063493431 X-GMAIL-MSGID: 1789767080063493431 Function was only called in dsos.c with the dso parameter as NULL. Remove the function and specialize for the dso being NULL case removing other unused functions along the way. Signed-off-by: Ian Rogers --- tools/perf/util/dsos.c | 51 +++++++++--------------------------------- tools/perf/util/dsos.h | 6 ----- 2 files changed, 10 insertions(+), 47 deletions(-) diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index 1495ab1cd7a0..e4110438841b 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -119,11 +119,6 @@ static int __dso__cmp_short_name(const char *short_name, struct dso_id *id, stru return rc ?: dso_id__cmp(id, &b->id); } -static int dso__cmp_short_name(struct dso *a, struct dso *b) -{ - return __dso__cmp_short_name(a->short_name, &a->id, b); -} - static int dsos__cmp_long_name_id_short_name(const void *va, const void *vb) { const struct dso *a = *((const struct dso **)va); @@ -143,20 +138,21 @@ static int dsos__cmp_long_name_id_short_name(const void *va, const void *vb) * Either one of the dso or name parameter must be non-NULL or the * function will not work. */ -struct dso *__dsos__findnew_link_by_longname_id(struct dsos *dsos, - struct dso *dso, - const char *name, - struct dso_id *id, - bool write_locked) +static struct dso *__dsos__find_by_longname_id(struct dsos *dsos, + const char *name, + struct dso_id *id, + bool write_locked) { int low = 0, high = dsos->cnt - 1; if (!dsos->sorted) { if (!write_locked) { + struct dso *dso; + up_read(&dsos->lock); down_write(&dsos->lock); - dso = __dsos__findnew_link_by_longname_id(dsos, dso, name, id, - /*write_locked=*/true); + dso = __dsos__find_by_longname_id(dsos, name, id, + /*write_locked=*/true); up_write(&dsos->lock); down_read(&dsos->lock); return dso; @@ -166,9 +162,6 @@ struct dso *__dsos__findnew_link_by_longname_id(struct dsos *dsos, dsos->sorted = true; } - if (!name) - name = dso->long_name; - /* * Find node with the matching name */ @@ -178,31 +171,13 @@ struct dso *__dsos__findnew_link_by_longname_id(struct dsos *dsos, int rc = __dso__cmp_long_name(name, id, this); if (rc == 0) { - /* - * In case the new DSO is a duplicate of an existing - * one, print a one-time warning & put the new entry - * at the end of the list of duplicates. - */ - if (!dso || (dso == this)) - return dso__get(this); /* Find matching dso */ - /* - * The core kernel DSOs may have duplicated long name. - * In this case, the short name should be different. - * Comparing the short names to differentiate the DSOs. - */ - rc = dso__cmp_short_name(dso, this); - if (rc == 0) { - pr_err("Duplicated dso name: %s\n", name); - return NULL; - } + return dso__get(this); /* Find matching dso */ } if (rc < 0) high = mid - 1; else low = mid + 1; } - if (dso) - __dsos__add(dsos, dso); return NULL; } @@ -240,12 +215,6 @@ int dsos__add(struct dsos *dsos, struct dso *dso) return ret; } -static struct dso *__dsos__findnew_by_longname_id(struct dsos *dsos, const char *name, - struct dso_id *id, bool write_locked) -{ - return __dsos__findnew_link_by_longname_id(dsos, NULL, name, id, write_locked); -} - struct dsos__find_id_cb_args { const char *name; struct dso_id *id; @@ -279,7 +248,7 @@ static struct dso *__dsos__find_id(struct dsos *dsos, const char *name, struct d __dsos__for_each_dso(dsos, dsos__find_id_cb, &args); return args.res; } - res = __dsos__findnew_by_longname_id(dsos, name, id, write_locked); + res = __dsos__find_by_longname_id(dsos, name, id, write_locked); return res; } diff --git a/tools/perf/util/dsos.h b/tools/perf/util/dsos.h index d1497b11d64c..6c13b65648bc 100644 --- a/tools/perf/util/dsos.h +++ b/tools/perf/util/dsos.h @@ -36,12 +36,6 @@ struct dso *dsos__findnew_id(struct dsos *dsos, const char *name, struct dso_id bool dsos__read_build_ids(struct dsos *dsos, bool with_hits); -struct dso *__dsos__findnew_link_by_longname_id(struct dsos *dsos, - struct dso *dso, - const char *name, - struct dso_id *id, - bool write_locked); - size_t dsos__fprintf_buildid(struct dsos *dsos, FILE *fp, bool (skip)(struct dso *dso, int parm), int parm); size_t dsos__fprintf(struct dsos *dsos, FILE *fp); From patchwork Fri Feb 2 06:15:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195604 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239422dyc; Thu, 1 Feb 2024 22:21:42 -0800 (PST) X-Google-Smtp-Source: AGHT+IE5uukHGqIHMvCLI6EPqfBWrQ3DX66zTYIz+57p3jLJFKZemReA/yOKIibXcX1KtluJ0NUx X-Received: by 2002:a17:906:c289:b0:a36:ce4c:ebe0 with SMTP id r9-20020a170906c28900b00a36ce4cebe0mr2599771ejz.19.1706854901844; Thu, 01 Feb 2024 22:21:41 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854901; cv=pass; d=google.com; s=arc-20160816; b=1BEBVb9YUUJZrmEMjEqzAi4GIq+k2AEmFdy3lzeu6ed7bXu5SRM+jQVkAWGHEARpcG RLq/R2OSDGV6VXPTiwPbVRtGAWtQ4kb56Rho2nN0c/5cXtI7jIoGW7zTM/6QN9JLBtG9 zbm+D+n49+GZNBYmePaC+fExbC6XZSMedH2XKuOUurUOQaoYhq5TAiHQzueFaXb6of0i O8Bv52zEWqIamNRuslCrJ6evCK8m3VzuRvLb5C9HSJbiF/8nnX+1dfr622Y2dD5PjP1E 7LEdLHjGc+3+nKvYUbeZ10Iebcw/UMdlGL7xIH3lfMLTc6vwhbyFtDVsNBQZR3ZhZVH5 tNQQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=C/Pk6SJ35jEAj4GFAF5mDm6iqfrtol9Y+OYWK8WFxKo=; fh=zfxyGlyyNkKYdlV1RitpS++AjrvTaDJ7nbwj5rTY9Sw=; b=BeBnHGKb77YP+QAQRMG7lNcRNa67ZxhVOe9Nda5Ljj8vptSmjtHmI2jXIPEDXiR+ae WXNe9FMfcDwjsC/gP5LTeHarSchogIbo6lMeRLSQifKVOCDfwetaxzF5KGhkdF+MteDe 5T8eqYvVQxL+zBmipdp+Vv5EL9Mz6BqAXWiX67wQpZLPojD2JbTvbjcXnNT6IffEnS8L twSOalnWwDXxT4LF7OlcI7e9yMcJm2GXurbWh6+d9nIqloB/pvV6XI8gQmzEXR0CXf00 htAzUaEKnPsZb8UgHkZ5CRQvsybvJVWxVro+NJ7LjZkBBnwGriPRzn7SEt8csQCIJU9u SoMg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=aliQj6aw; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49261-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49261-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCVPKwUkJD6c1bMToXFx7rSq6KleUElgyRBBHKDnB17VhjS2I5b1pV9QpzPJQ80fyqOzPSK3ocRsBMVjLM4QFBycduf/2A== Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id j13-20020a170906830d00b00a36481d25desi472781ejx.308.2024.02.01.22.21.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:21:41 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49261-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=aliQj6aw; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49261-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49261-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 am.mirrors.kernel.org (Postfix) with ESMTPS id 8BF361F26253 for ; Fri, 2 Feb 2024 06:21:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C8A8848785; Fri, 2 Feb 2024 06:16:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="aliQj6aw" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.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 B1C9E482C6 for ; Fri, 2 Feb 2024 06:16:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854600; cv=none; b=NWAUAauCUheWHqBoKE7UqhuWzFK8hcQ/akYxUfxBztWef54HxZIRq1CHaWTRu+Wno1kHK80R/rvkFdm3clwBeBqT+Qq4n2QdIeusfgf9GLe2c1WAfEgtO0uZglAohQConG7y6VriFbfk9uz9CG1q2i6AE5myjIEDNz2kt6iZZZI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854600; c=relaxed/simple; bh=xDTTHE1+3Q/N7SIwR8+1310MYI2J+UCB79HiHPCwufc=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=OtdaEVuK80KK9i/CpHiR/5Eu6phuqLtLHaJF04Bix/CiXsLLnj/Hk4ToOx60HGbWA+y97p1aIhRv1l0AMGuLvkwZ7h7j09CvvEDK9Kx5lYdebO6HaCxABotlFN5shAIp9u59ON5fjFeNtdwgugavgNgHQnbVtEB7FJApvDqnlqY= 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=aliQj6aw; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc6ba69e803so3078965276.2 for ; Thu, 01 Feb 2024 22:16:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854597; x=1707459397; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=C/Pk6SJ35jEAj4GFAF5mDm6iqfrtol9Y+OYWK8WFxKo=; b=aliQj6awUeLxTBXLmiOAd7NSRgnNGgx8OxnFFbCVTNXsrXSVml3mWixNzSXbVqj1RP l/jnFfDGl6qTADw6swZnjmbYa1VxvdOGzPncw7+aI7+4RKZo5gMenFzMDPXcj06kPNvD V266u5BC3NrrYQfxVkLjULhgqijgxrcGJLOqW+paNYd0p7MUAeHL99dgQ/NZ5TgCs3b0 pEx67VJYlIFvDz43dOdPUzQfxLqW0a4WTTOiwqe2QziFDCmdIZVhNLkAN/WQUuxD0m7P +1eRN5KQhbsoDOpX9CjA1bmqjk3aH1AUfgv+4fOm8m3KElaZCcsqX+xApQ1gnkT2S7vc XwVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854597; x=1707459397; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=C/Pk6SJ35jEAj4GFAF5mDm6iqfrtol9Y+OYWK8WFxKo=; b=NNNqjLP6h1q77t9Ge2UkVEdFnuqnAbLOGpinjvkqdVOMEHXz14SHWr1PStoRLDw12l JGwXtQ5YlD0HJudbmAruKentSqF1y8nmP8knByvEtE5l2OwPsmRi7KuuuAbgzVGrHN+5 dXRCy7yCpjbY8aHP+SyKDDJb0R2sRUDrKdaq33xWEl5o8oT0QkJAISJrfi5wDKDDPT+5 BkbFpmuaIkCbOGFkAPYAWB594xA0UPBy0PN1fqX8zOLQiiEffXW7yQEK/5/VmSYDSfk+ YQN+oy6IIMizcnMMm8lr1r26ylK8CymYD+zOXICCcrBmUyWDYSGrh+Jl0JIEbpVoBeM2 VRiQ== X-Gm-Message-State: AOJu0YzBO9k26CQ/pAm+/VCwX3Mc8ZMA/nXA8QTznnJrc9P0rJ4NhcTb xm3V86sl/tSZ6+6R6/jbD/QSynlfqMBKXmFjNpqB0qdfcE5Hq4Nlhkm+GcV0QKtRpK+Fo9aXqUE 5kCq9ew== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:2212:b0:dc6:c7ed:e72d with SMTP id dm18-20020a056902221200b00dc6c7ede72dmr356062ybb.4.1706854597627; Thu, 01 Feb 2024 22:16:37 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:29 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-23-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 22/25] perf dsos: Switch hand code to bsearch From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767085909793376 X-GMAIL-MSGID: 1789767085909793376 Switch to using the bsearch library function rather than having a hand written binary search. Const-ify some static functions to avoid compiler warnings. Signed-off-by: Ian Rogers --- tools/perf/util/dsos.c | 46 +++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index e4110438841b..23c3fe4f2abb 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -107,13 +107,15 @@ bool dsos__read_build_ids(struct dsos *dsos, bool with_hits) return args.have_build_id; } -static int __dso__cmp_long_name(const char *long_name, struct dso_id *id, struct dso *b) +static int __dso__cmp_long_name(const char *long_name, const struct dso_id *id, + const struct dso *b) { int rc = strcmp(long_name, b->long_name); return rc ?: dso_id__cmp(id, &b->id); } -static int __dso__cmp_short_name(const char *short_name, struct dso_id *id, struct dso *b) +static int __dso__cmp_short_name(const char *short_name, const struct dso_id *id, + const struct dso *b) { int rc = strcmp(short_name, b->short_name); return rc ?: dso_id__cmp(id, &b->id); @@ -133,6 +135,19 @@ static int dsos__cmp_long_name_id_short_name(const void *va, const void *vb) return rc; } +struct dsos__key { + const char *long_name; + const struct dso_id *id; +}; + +static int dsos__cmp_key_long_name_id(const void *vkey, const void *vdso) +{ + const struct dsos__key *key = vkey; + const struct dso *dso = *((const struct dso **)vdso); + + return __dso__cmp_long_name(key->long_name, key->id, dso); +} + /* * Find a matching entry and/or link current entry to RB tree. * Either one of the dso or name parameter must be non-NULL or the @@ -143,7 +158,11 @@ static struct dso *__dsos__find_by_longname_id(struct dsos *dsos, struct dso_id *id, bool write_locked) { - int low = 0, high = dsos->cnt - 1; + struct dsos__key key = { + .long_name = name, + .id = id, + }; + struct dso **res; if (!dsos->sorted) { if (!write_locked) { @@ -162,23 +181,12 @@ static struct dso *__dsos__find_by_longname_id(struct dsos *dsos, dsos->sorted = true; } - /* - * Find node with the matching name - */ - while (low <= high) { - int mid = (low + high) / 2; - struct dso *this = dsos->dsos[mid]; - int rc = __dso__cmp_long_name(name, id, this); + res = bsearch(&key, dsos->dsos, dsos->cnt, sizeof(struct dso *), + dsos__cmp_key_long_name_id); + if (!res) + return NULL; - if (rc == 0) { - return dso__get(this); /* Find matching dso */ - } - if (rc < 0) - high = mid - 1; - else - low = mid + 1; - } - return NULL; + return dso__get(*res); } int __dsos__add(struct dsos *dsos, struct dso *dso) From patchwork Fri Feb 2 06:15:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195607 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239684dyc; Thu, 1 Feb 2024 22:22:26 -0800 (PST) X-Google-Smtp-Source: AGHT+IGJNUqXkg3T1aZH4MpaejAoolsUlTtcS6YPg5B1UIP2mZm44l6avhZtz6AayWos4O4pevfz X-Received: by 2002:a05:622a:15d5:b0:42a:b257:2019 with SMTP id d21-20020a05622a15d500b0042ab2572019mr7558542qty.39.1706854945972; Thu, 01 Feb 2024 22:22:25 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854945; cv=pass; d=google.com; s=arc-20160816; b=ddug6QZH7dZw2HYjj2BbfJxEJhSFJGSls3xrwTnz2koMXojBAy0Kj7QpJyuImz/rx4 oIhJ2wZ3cvDG7jDdVFx2XfwMz0oYktoGKB0cRfCgeV91+Yx0wOE9F04ay4zyuRhNeF+d 5EILU53O+GiTdG9LMm+47VGpOXlU0f1eGvPxNV+DaGTteNoDn/AnOLjkD40+JP7qeh1x OJtxpUN+4WYbOrgaj1Br5K8yJWFx8JgUKeCmNicHWHh1WR1YhvylmkcC7tDELnf0vul3 ZXgDSVEuaEABiD/oxOFukGNHn+LoGIu3tACPcRmFLnFvVQsrcp08bCm5kpuwcEH2Qc19 YeDA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=tIealv889NAxEr2xYCNET8sEiiz1VeDDnePfK9F0VE4=; fh=oZ+Ut+cyDH18X20Nn57mTBYZphbc5GP1BJ6MKy95Cbs=; b=tlycZwFAvs4Ua/wUDz+ABEUyqQ8Gq+1u7awbmtqs/QHnsGn9rjMUGHfyqBdKosPndG frAdkfMfAtSmVS2cJcLRh8TO1m1TWt0RWD9s/Bt1jITVKGfB5E64cYi8uRWgq7XlN+IV WNfaYEJ4YIuXEhCi6hGB0+40CWEGNRzyEjy5FqWz3ymE7AXh9ylI7BM/R2vGm3730LH8 Zhjg9D3trpjLaLCc6/BYk5DJpNncX+zvpZ5DwvexOycuyguXU8/pldE1BcnifnWdvHLm CPHewtoEttb150E3nWTmOrF4EabtO1vJKPGmOMMPBZ9zluNIFDlsS43N6/fVxhoQizXS WrWA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=EFhAhJvb; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49264-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49264-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCU3BAKM5efLtF9TSKu6UGK1lfGsr+Wk94KHaVmGHtWVCBzy83K/QLfw+HO/gIxJcZ4HbFTmEz112wEoIiHtw3zqt0GV6Q== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id g15-20020ac87f4f000000b0042a7e2a02adsi1384520qtk.126.2024.02.01.22.22.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:22:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49264-ouuuleilei=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; dkim=pass header.i=@google.com header.s=20230601 header.b=EFhAhJvb; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49264-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49264-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 8EE301C23D6A for ; Fri, 2 Feb 2024 06:22:25 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2914C4BA8E; Fri, 2 Feb 2024 06:17:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="EFhAhJvb" Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.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 4D8A0482FB for ; Fri, 2 Feb 2024 06:16:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854609; cv=none; b=nTdS38u5Me1WyysVVZ11t+TJOP/V7uZoI9bYzjLnJCYCTyimDJHz+oM0upgU6zVRoAtrxcZi9JDh3Cnp3ZiUBc7B7UihMDlGtFqc4PzhA5qgLTyvOZGP3NotEqnZAhqw5ICDnyU5gnDnUgn9knvn2qRGrIfUwZZONq/FGnjJ77Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854609; c=relaxed/simple; bh=HOI+PCvurIoV95iofH/JcCQBNH1Kc01Nopt36MsxP50=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=pg7DOVOAh/w9WsmDG85xRaRHa8ArauNX1YRnSW9mgtuwZNXhhXQ0sEZl+OX1DqdDn4mZ1tBEYt/UJZhElM/G4t8QTF7gcYETSv109F/NkbtC+cRFkrfqq3qNWL2hNw0a0IfjrLQZx360S3/LHhFVk+wsppixjLHUkAwX2spnm7k= 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=EFhAhJvb; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dc657e9bdc4so2429688276.0 for ; Thu, 01 Feb 2024 22:16:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854600; x=1707459400; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=tIealv889NAxEr2xYCNET8sEiiz1VeDDnePfK9F0VE4=; b=EFhAhJvbrTtVpMYpIn7yzqyl5gdnrNmF/4MMP26Ays3tnsnP/FXtsFYnOtGmeKVDjk zUoKN4QVYjniwYadjCsvSDBOXGNLe+OM1Grd7YHI6uj9dyZbXhTGhKd70H9N6InLL8Kl gpQIjLDDWqfgylNhrcurRsBrJ1hSKudmbvm5XAJNSiSWqn/Md79RYjmXQvcZJYZW+67k 7wB29MhxrSgq1Lkl8q5mMgOLNQ18JKYSDYzKrWUzIaC9uWV5zOnge102iFaoU/YqzDPj wvSrQ76451de3llwrBYywqqtwdAc4ouYpG5PI+LmQGEI7nd76+1Rd0ZJuCND1W/jmbH8 v77A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854600; x=1707459400; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tIealv889NAxEr2xYCNET8sEiiz1VeDDnePfK9F0VE4=; b=tU3r9rvEMjtyTMudh1fc7huo5LRlTtqu8rfS4ilRjZJBQHkuO2rRCjFADLTeLl/DoC +0P4m1JfIBcbT7cb7eaX5DusVb80K0QdCdPNXbrWwvaorNZ0GldQqn9JlVsek9a2I3Is XX7fTENBnrqHWUZPqndX6KExRrR0pYlVqD8uDAL44glR5C9M0SJCOVTy9ccwcJjD0Hdz V8gwuujODvi7/K9mT2kEV9TZfXEtXYVGxRI8GiHRDYep9DOu7h/QYilfYDX0+cjsKFFx aRdNzCzJDYFd0ItPKgkvOA7K6pSXvbIKcdI6jynH0v2fGIwA7YrK3W8qIL72tjJYOdIo 03xg== X-Gm-Message-State: AOJu0YzEyRMaAIGCNiff0E7m7ZVOLWW1LDhVRR8ne5O6fXcpUGhoo0Et 7dkAdzArCjOW7s0SL1cViXQXpOq6DabLijT/iPCp6I31VGYCFOCkRWhTcg9LgtHWvkwr9K6Lo1a aT8DbqA== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:2187:b0:dc6:e20f:80cb with SMTP id dl7-20020a056902218700b00dc6e20f80cbmr68377ybb.3.1706854600245; Thu, 01 Feb 2024 22:16:40 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:30 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-24-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 23/25] perf dso: Add reference count checking and accessor functions From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767131924124196 X-GMAIL-MSGID: 1789767131924124196 Add reference count checking to struct dso, this can help with implementing correct reference counting discipline. To avoid RC_CHK_ACCESS everywhere, add accessor functions for the variables in struct dso. The majority of the change is mechanical in nature and not easy to split up. Signed-off-by: Ian Rogers --- tools/perf/builtin-annotate.c | 8 +- tools/perf/builtin-buildid-cache.c | 2 +- tools/perf/builtin-buildid-list.c | 18 +- tools/perf/builtin-inject.c | 71 ++- tools/perf/builtin-kallsyms.c | 2 +- tools/perf/builtin-mem.c | 4 +- tools/perf/builtin-report.c | 6 +- tools/perf/builtin-script.c | 8 +- tools/perf/builtin-top.c | 4 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/code-reading.c | 8 +- tools/perf/tests/dso-data.c | 11 +- tools/perf/tests/hists_common.c | 6 +- tools/perf/tests/hists_cumulate.c | 4 +- tools/perf/tests/hists_output.c | 2 +- tools/perf/tests/maps.c | 4 +- tools/perf/tests/symbols.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 6 +- tools/perf/ui/browsers/annotate.c | 6 +- tools/perf/ui/browsers/hists.c | 8 +- tools/perf/ui/browsers/map.c | 4 +- tools/perf/util/annotate-data.c | 6 +- tools/perf/util/annotate.c | 45 +- tools/perf/util/auxtrace.c | 2 +- tools/perf/util/block-info.c | 2 +- tools/perf/util/bpf-event.c | 8 +- tools/perf/util/build-id.c | 38 +- tools/perf/util/callchain.c | 2 +- tools/perf/util/data-convert-json.c | 2 +- tools/perf/util/db-export.c | 6 +- tools/perf/util/dlfilter.c | 12 +- tools/perf/util/dso.c | 365 +++++++------ tools/perf/util/dso.h | 483 ++++++++++++++++-- tools/perf/util/dsos.c | 54 +- tools/perf/util/event.c | 8 +- tools/perf/util/header.c | 8 +- tools/perf/util/hist.c | 4 +- tools/perf/util/intel-pt.c | 22 +- tools/perf/util/machine.c | 46 +- tools/perf/util/map.c | 69 ++- tools/perf/util/maps.c | 14 +- tools/perf/util/probe-event.c | 25 +- .../util/scripting-engines/trace-event-perl.c | 6 +- .../scripting-engines/trace-event-python.c | 21 +- tools/perf/util/sort.c | 19 +- tools/perf/util/srcline.c | 65 +-- tools/perf/util/symbol-elf.c | 92 ++-- tools/perf/util/symbol.c | 186 +++---- tools/perf/util/symbol_fprintf.c | 4 +- tools/perf/util/synthetic-events.c | 24 +- tools/perf/util/thread.c | 4 +- tools/perf/util/unwind-libunwind-local.c | 18 +- tools/perf/util/unwind-libunwind.c | 2 +- tools/perf/util/vdso.c | 8 +- 54 files changed, 1140 insertions(+), 716 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 6c1cc797692d..52260a14e38f 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -217,7 +217,7 @@ static int process_branch_callback(struct evsel *evsel, } if (a.map != NULL) - map__dso(a.map)->hit = 1; + dso__set_hit(map__dso(a.map)); hist__account_cycles(sample->branch_stack, al, sample, false, NULL); @@ -252,7 +252,7 @@ static int evsel__add_sample(struct evsel *evsel, struct perf_sample *sample, if (al->sym != NULL) { struct dso *dso = map__dso(al->map); - rb_erase_cached(&al->sym->rb_node, &dso->symbols); + rb_erase_cached(&al->sym->rb_node, dso__symbols(dso)); symbol__delete(al->sym); dso__reset_find_symbol_cache(dso); } @@ -341,7 +341,7 @@ static void print_annotated_data_header(struct hist_entry *he, struct evsel *evs } printf("Annotate type: '%s' in %s (%d samples):\n", - he->mem_type->self.type_name, dso->name, nr_samples); + he->mem_type->self.type_name, dso__name(dso), nr_samples); if (evsel__is_group_event(evsel)) { struct evsel *pos; @@ -487,7 +487,7 @@ static void hists__find_annotations(struct hists *hists, struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); struct annotation *notes; - if (he->ms.sym == NULL || map__dso(he->ms.map)->annotate_warned) + if (he->ms.sym == NULL || dso__annotate_warned(map__dso(he->ms.map))) goto find_next; if (ann->sym_hist_filter && diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index e2a40f1d9225..b0511d16aeb6 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -286,7 +286,7 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused) pr_warning("Problems with %s file, consider removing it from the cache\n", filename); - } else if (memcmp(dso->bid.data, bid.data, bid.size)) { + } else if (memcmp(dso__bid(dso)->data, bid.data, bid.size)) { pr_warning("Problems with %s file, consider removing it from the cache\n", filename); } diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index c9037477865a..383d5de36ce4 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -26,16 +26,18 @@ static int buildid__map_cb(struct map *map, void *arg __maybe_unused) { const struct dso *dso = map__dso(map); char bid_buf[SBUILD_ID_SIZE]; + const char *dso_long_name = dso__long_name(dso); + const char *dso_short_name = dso__short_name(dso); memset(bid_buf, 0, sizeof(bid_buf)); - if (dso->has_build_id) - build_id__sprintf(&dso->bid, bid_buf); + if (dso__has_build_id(dso)) + build_id__sprintf(dso__bid_const(dso), bid_buf); printf("%s %16" PRIx64 " %16" PRIx64, bid_buf, map__start(map), map__end(map)); - if (dso->long_name != NULL) { - printf(" %s", dso->long_name); - } else if (dso->short_name != NULL) { - printf(" %s", dso->short_name); - } + if (dso_long_name != NULL) + printf(" %s", dso_long_name); + else if (dso_short_name != NULL) + printf(" %s", dso_short_name); + printf("\n"); return 0; @@ -76,7 +78,7 @@ static int filename__fprintf_build_id(const char *name, FILE *fp) static bool dso__skip_buildid(struct dso *dso, int with_hits) { - return with_hits && !dso->hit; + return with_hits && !dso__hit(dso); } static int perf_session__list_build_ids(bool force, bool with_hits) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ce5e28eaad90..a212678d47be 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -445,10 +445,9 @@ static struct dso *findnew_dso(int pid, int tid, const char *filename, } if (dso) { - mutex_lock(&dso->lock); - nsinfo__put(dso->nsinfo); - dso->nsinfo = nsi; - mutex_unlock(&dso->lock); + mutex_lock(dso__lock(dso)); + dso__set_nsinfo(dso, nsi); + mutex_unlock(dso__lock(dso)); } else nsinfo__put(nsi); @@ -466,8 +465,8 @@ static int perf_event__repipe_buildid_mmap(struct perf_tool *tool, dso = findnew_dso(event->mmap.pid, event->mmap.tid, event->mmap.filename, NULL, machine); - if (dso && !dso->hit) { - dso->hit = 1; + if (dso && !dso__hit(dso)) { + dso__set_hit(dso); dso__inject_build_id(dso, tool, machine, sample->cpumode, 0); } dso__put(dso); @@ -492,7 +491,7 @@ static int perf_event__repipe_mmap2(struct perf_tool *tool, event->mmap2.filename, NULL, machine); if (dso) { /* mark it not to inject build-id */ - dso->hit = 1; + dso__set_hit(dso); } dso__put(dso); } @@ -544,7 +543,7 @@ static int perf_event__repipe_buildid_mmap2(struct perf_tool *tool, event->mmap2.filename, NULL, machine); if (dso) { /* mark it not to inject build-id */ - dso->hit = 1; + dso__set_hit(dso); } dso__put(dso); perf_event__repipe(tool, event, sample, machine); @@ -554,8 +553,8 @@ static int perf_event__repipe_buildid_mmap2(struct perf_tool *tool, dso = findnew_dso(event->mmap2.pid, event->mmap2.tid, event->mmap2.filename, &dso_id, machine); - if (dso && !dso->hit) { - dso->hit = 1; + if (dso && !dso__hit(dso)) { + dso__set_hit(dso); dso__inject_build_id(dso, tool, machine, sample->cpumode, event->mmap2.flags); } @@ -631,24 +630,24 @@ static int dso__read_build_id(struct dso *dso) { struct nscookie nsc; - if (dso->has_build_id) + if (dso__has_build_id(dso)) return 0; - mutex_lock(&dso->lock); - nsinfo__mountns_enter(dso->nsinfo, &nsc); - if (filename__read_build_id(dso->long_name, &dso->bid) > 0) - dso->has_build_id = true; - else if (dso->nsinfo) { - char *new_name = dso__filename_with_chroot(dso, dso->long_name); + mutex_lock(dso__lock(dso)); + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); + if (filename__read_build_id(dso__long_name(dso), dso__bid(dso)) > 0) + dso__set_has_build_id(dso); + else if (dso__nsinfo(dso)) { + char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso)); - if (new_name && filename__read_build_id(new_name, &dso->bid) > 0) - dso->has_build_id = true; + if (new_name && filename__read_build_id(new_name, dso__bid(dso)) > 0) + dso__set_has_build_id(dso); free(new_name); } nsinfo__mountns_exit(&nsc); - mutex_unlock(&dso->lock); + mutex_unlock(dso__lock(dso)); - return dso->has_build_id ? 0 : -1; + return dso__has_build_id(dso) ? 0 : -1; } static struct strlist *perf_inject__parse_known_build_ids( @@ -700,14 +699,14 @@ static bool perf_inject__lookup_known_build_id(struct perf_inject *inject, dso_name = strchr(build_id, ' '); bid_len = dso_name - pos->s; dso_name = skip_spaces(dso_name); - if (strcmp(dso->long_name, dso_name)) + if (strcmp(dso__long_name(dso), dso_name)) continue; for (int ix = 0; 2 * ix + 1 < bid_len; ++ix) { - dso->bid.data[ix] = (hex(build_id[2 * ix]) << 4 | - hex(build_id[2 * ix + 1])); + dso__bid(dso)->data[ix] = (hex(build_id[2 * ix]) << 4 | + hex(build_id[2 * ix + 1])); } - dso->bid.size = bid_len / 2; - dso->has_build_id = 1; + dso__bid(dso)->size = bid_len / 2; + dso__set_has_build_id(dso); return true; } return false; @@ -720,9 +719,9 @@ static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool, tool); int err; - if (is_anon_memory(dso->long_name) || flags & MAP_HUGETLB) + if (is_anon_memory(dso__long_name(dso)) || flags & MAP_HUGETLB) return 0; - if (is_no_dso_memory(dso->long_name)) + if (is_no_dso_memory(dso__long_name(dso))) return 0; if (inject->known_build_ids != NULL && @@ -730,14 +729,14 @@ static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool, return 1; if (dso__read_build_id(dso) < 0) { - pr_debug("no build_id found for %s\n", dso->long_name); + pr_debug("no build_id found for %s\n", dso__long_name(dso)); return -1; } err = perf_event__synthesize_build_id(tool, dso, cpumode, perf_event__repipe, machine); if (err) { - pr_err("Can't synthesize build_id event for %s\n", dso->long_name); + pr_err("Can't synthesize build_id event for %s\n", dso__long_name(dso)); return -1; } @@ -763,8 +762,8 @@ int perf_event__inject_buildid(struct perf_tool *tool, union perf_event *event, if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) { struct dso *dso = map__dso(al.map); - if (!dso->hit) { - dso->hit = 1; + if (!dso__hit(dso)) { + dso__set_hit(dso); dso__inject_build_id(dso, tool, machine, sample->cpumode, map__flags(al.map)); } @@ -1146,8 +1145,8 @@ static bool dso__is_in_kernel_space(struct dso *dso) return false; return dso__is_kcore(dso) || - dso->kernel || - is_kernel_module(dso->long_name, PERF_RECORD_MISC_CPUMODE_UNKNOWN); + dso__kernel(dso) || + is_kernel_module(dso__long_name(dso), PERF_RECORD_MISC_CPUMODE_UNKNOWN); } static u64 evlist__first_id(struct evlist *evlist) @@ -1181,7 +1180,7 @@ static int synthesize_build_id(struct perf_inject *inject, struct dso *dso, pid_ if (!machine) return -ENOMEM; - dso->hit = 1; + dso__set_hit(dso); return perf_event__synthesize_build_id(&inject->tool, dso, cpumode, process_build_id, machine); @@ -1192,7 +1191,7 @@ static int guest_session__add_build_ids_cb(struct dso *dso, void *data) struct guest_session *gs = data; struct perf_inject *inject = container_of(gs, struct perf_inject, guest_session); - if (!dso->has_build_id) + if (!dso__has_build_id(dso)) return 0; return synthesize_build_id(inject, dso, gs->machine_pid); diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c index 7f75c5b73f26..a3c2ffdc1af8 100644 --- a/tools/perf/builtin-kallsyms.c +++ b/tools/perf/builtin-kallsyms.c @@ -38,7 +38,7 @@ static int __cmd_kallsyms(int argc, const char **argv) dso = map__dso(map); printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n", - symbol->name, dso->short_name, dso->long_name, + symbol->name, dso__short_name(dso), dso__long_name(dso), map__unmap_ip(map, symbol->start), map__unmap_ip(map, symbol->end), symbol->start, symbol->end); } diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 5b851e64e4a1..863fcd735dae 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -213,7 +213,7 @@ dump_raw_samples(struct perf_tool *tool, if (al.map != NULL) { dso = map__dso(al.map); if (dso) - dso->hit = 1; + dso__set_hit(dso); } field_sep = symbol_conf.field_sep; @@ -255,7 +255,7 @@ dump_raw_samples(struct perf_tool *tool, symbol_conf.field_sep, sample->data_src, symbol_conf.field_sep, - dso ? dso->long_name : "???", + dso ? dso__long_name(dso) : "???", al.sym ? al.sym->name : "???"); out_put: addr_location__exit(&al); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 590dff09899c..dbe2d5a25eea 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -322,7 +322,7 @@ static int process_sample_event(struct perf_tool *tool, } if (al.map != NULL) - map__dso(al.map)->hit = 1; + dso__set_hit(map__dso(al.map)); if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) { hist__account_cycles(sample->branch_stack, &al, sample, @@ -609,7 +609,7 @@ static void report__warn_kptr_restrict(const struct report *rep) return; if (kernel_map == NULL || - (map__dso(kernel_map)->hit && + (dso__hit(map__dso(kernel_map)) && (kernel_kmap->ref_reloc_sym == NULL || kernel_kmap->ref_reloc_sym->addr == 0))) { const char *desc = @@ -850,7 +850,7 @@ static int maps__fprintf_task_cb(struct map *map, void *data) prot & PROT_EXEC ? 'x' : '-', map__flags(map) ? 's' : 'p', map__pgoff(map), - dso->id.ino, dso->name); + dso__id_const(dso)->ino, dso__name(dso)); if (ret < 0) return ret; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index b1f57401ff23..e31333c5ebd2 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1011,11 +1011,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample, to = entries[i].to; if (thread__find_map_fb(thread, sample->cpumode, from, &alf) && - !map__dso(alf.map)->adjust_symbols) + !dso__adjust_symbols(map__dso(alf.map))) from = map__dso_map_ip(alf.map, from); if (thread__find_map_fb(thread, sample->cpumode, to, &alt) && - !map__dso(alt.map)->adjust_symbols) + !dso__adjust_symbols(map__dso(alt.map))) to = map__dso_map_ip(alt.map, to); printed += fprintf(fp, " 0x%"PRIx64, from); @@ -1076,7 +1076,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); goto out; } - if (dso->data.status == DSO_DATA_STATUS_ERROR) { + if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR) { pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); goto out; } @@ -1088,7 +1088,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer, end - start + MAXINSN); - *is64bit = dso->is_64_bit; + *is64bit = dso__is_64_bit(dso); if (len <= 0) pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n", start, end); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 03cf45088fd8..ba2fddc30c7c 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -129,7 +129,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) /* * We can't annotate with just /proc/kallsyms */ - if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) { + if (dso__symtab_type(dso) == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) { pr_err("Can't annotate %s: No vmlinux file was found in the " "path\n", sym->name); sleep(1); @@ -182,7 +182,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) "Tools: %s\n\n" "Not all samples will be on the annotation output.\n\n" "Please report to linux-kernel@vger.kernel.org\n", - ip, dso->long_name, dso__symtab_origin(dso), + ip, dso__long_name(dso), dso__symtab_origin(dso), map__start(map), map__end(map), sym->start, sym->end, sym->binding == STB_GLOBAL ? 'g' : sym->binding == STB_LOCAL ? 'l' : 'w', sym->name, diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 90eaff8c0f6e..81300965d60d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2903,7 +2903,7 @@ static void print_location(FILE *f, struct perf_sample *sample, { if ((verbose > 0 || print_dso) && al->map) - fprintf(f, "%s@", map__dso(al->map)->long_name); + fprintf(f, "%s@", dso__long_name(map__dso(al->map))); if ((verbose > 0 || print_sym) && al->sym) fprintf(f, "%s+0x%" PRIx64, al->sym->name, diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 7a3a7bbbec71..6208f58622d1 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -253,9 +253,9 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, goto out; } dso = map__dso(al.map); - pr_debug("File is: %s\n", dso->long_name); + pr_debug("File is: %s\n", dso__long_name(dso)); - if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) { + if (dso__symtab_type(dso) == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) { pr_debug("Unexpected kernel address - skipping\n"); goto out; } @@ -274,7 +274,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, * modules to manage long jumps. Check if the ip offset falls in stubs * sections for kernel modules. And skip module address after text end */ - if (dso->is_kmod && al.addr > dso->text_end) { + if (dso__is_kmod(dso) && al.addr > dso__text_end(dso)) { pr_debug("skipping the module address %#"PRIx64" after text end\n", al.addr); goto out; } @@ -315,7 +315,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, state->done[state->done_cnt++] = map__start(al.map); } - objdump_name = dso->long_name; + objdump_name = dso__long_name(dso); if (dso__needs_decompress(dso)) { if (dso__decompress_kmodule_path(dso, objdump_name, decomp_name, diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 2d67422c1222..fde4eca84b6f 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -228,7 +228,8 @@ static void dsos__delete(int cnt) for (i = 0; i < cnt; i++) { struct dso *dso = dsos[i]; - unlink(dso->name); + dso__data_close(dso); + unlink(dso__name(dso)); dso__put(dso); } @@ -289,14 +290,14 @@ static int test__dso_data_cache(struct test_suite *test __maybe_unused, int subt } /* verify the first one is already open */ - TEST_ASSERT_VAL("dsos[0] is not open", dsos[0]->data.fd != -1); + TEST_ASSERT_VAL("dsos[0] is not open", dso__data(dsos[0])->fd != -1); /* open +1 dso to reach the allowed limit */ fd = dso__data_fd(dsos[i], &machine); TEST_ASSERT_VAL("failed to get fd", fd > 0); /* should force the first one to be closed */ - TEST_ASSERT_VAL("failed to close dsos[0]", dsos[0]->data.fd == -1); + TEST_ASSERT_VAL("failed to close dsos[0]", dso__data(dsos[0])->fd == -1); /* cleanup everything */ dsos__delete(dso_cnt); @@ -371,7 +372,7 @@ static int test__dso_data_reopen(struct test_suite *test __maybe_unused, int sub * dso_0 should get closed, because we reached * the file descriptor limit */ - TEST_ASSERT_VAL("failed to close dso_0", dso_0->data.fd == -1); + TEST_ASSERT_VAL("failed to close dso_0", dso__data(dso_0)->fd == -1); /* open dso_0 */ fd = dso__data_fd(dso_0, &machine); @@ -381,7 +382,7 @@ static int test__dso_data_reopen(struct test_suite *test __maybe_unused, int sub * dso_1 should get closed, because we reached * the file descriptor limit */ - TEST_ASSERT_VAL("failed to close dso_1", dso_1->data.fd == -1); + TEST_ASSERT_VAL("failed to close dso_1", dso__data(dso_1)->fd == -1); /* cleanup everything */ close(fd_extra); diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index d08add0f4da6..187f12f5bc21 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -146,7 +146,7 @@ struct machine *setup_fake_machine(struct machines *machines) goto out; } - symbols__insert(&dso->symbols, sym); + symbols__insert(dso__symbols(dso), sym); } dso__put(dso); @@ -183,7 +183,7 @@ void print_hists_in(struct hists *hists) pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n", i, thread__comm_str(he->thread), - dso->short_name, + dso__short_name(dso), he->ms.sym->name, he->stat.period); } @@ -212,7 +212,7 @@ void print_hists_out(struct hists *hists) pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period = %"PRIu64"/%"PRIu64"\n", i, thread__comm_str(he->thread), thread__tid(he->thread), - dso->short_name, + dso__short_name(dso), he->ms.sym->name, he->stat.period, he->stat_acc ? he->stat_acc->period : 0); } diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 71dacb0fec4d..1e0f5a310fd5 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -164,11 +164,11 @@ static void put_fake_samples(void) typedef int (*test_fn_t)(struct evsel *, struct machine *); #define COMM(he) (thread__comm_str(he->thread)) -#define DSO(he) (map__dso(he->ms.map)->short_name) +#define DSO(he) (dso__short_name(map__dso(he->ms.map))) #define SYM(he) (he->ms.sym->name) #define CPU(he) (he->cpu) #define DEPTH(he) (he->callchain->max_depth) -#define CDSO(cl) (map__dso(cl->ms.map)->short_name) +#define CDSO(cl) (dso__short_name(map__dso(cl->ms.map))) #define CSYM(cl) (cl->ms.sym->name) struct result { diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index ba1cccf57049..33b5cc8352a7 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -129,7 +129,7 @@ static void put_fake_samples(void) typedef int (*test_fn_t)(struct evsel *, struct machine *); #define COMM(he) (thread__comm_str(he->thread)) -#define DSO(he) (map__dso(he->ms.map)->short_name) +#define DSO(he) (dso__short_name(map__dso(he->ms.map))) #define SYM(he) (he->ms.sym->name) #define CPU(he) (he->cpu) #define PID(he) (thread__tid(he->thread)) diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index b15417a0d617..4f1f9385ea9c 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -26,7 +26,7 @@ static int check_maps_cb(struct map *map, void *data) if (map__start(map) != merged->start || map__end(map) != merged->end || - strcmp(map__dso(map)->name, merged->name) || + strcmp(dso__name(map__dso(map)), merged->name) || refcount_read(map__refcnt(map)) != 1) { return 1; } @@ -39,7 +39,7 @@ static int failed_cb(struct map *map, void *data __maybe_unused) pr_debug("\tstart: %" PRIu64 " end: %" PRIu64 " name: '%s' refcnt: %d\n", map__start(map), map__end(map), - map__dso(map)->name, + dso__name(map__dso(map)), refcount_read(map__refcnt(map))); return 0; diff --git a/tools/perf/tests/symbols.c b/tools/perf/tests/symbols.c index 16e1c5502b09..4bcb277b0cac 100644 --- a/tools/perf/tests/symbols.c +++ b/tools/perf/tests/symbols.c @@ -72,7 +72,7 @@ static int test_dso(struct dso *dso) if (verbose > 1) dso__fprintf(dso, stderr); - for (nd = rb_first_cached(&dso->symbols); nd; nd = rb_next(nd)) { + for (nd = rb_first_cached(dso__symbols(dso)); nd; nd = rb_next(nd)) { struct symbol *sym = rb_entry(nd, struct symbol, rb_node); if (sym->type != STT_FUNC && sym->type != STT_GNU_IFUNC) diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index fecbf851bb2e..e30fd55f8e51 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -129,7 +129,7 @@ static int test__vmlinux_matches_kallsyms_cb1(struct map *map, void *data) * cases. */ struct map *pair = maps__find_by_name(args->kallsyms.kmaps, - (dso->kernel ? dso->short_name : dso->name)); + (dso__kernel(dso) ? dso__short_name(dso) : dso__name(dso))); if (pair) { map__set_priv(pair, 1); @@ -162,11 +162,11 @@ static int test__vmlinux_matches_kallsyms_cb2(struct map *map, void *data) } pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", - map__start(map), map__end(map), map__pgoff(map), dso->name); + map__start(map), map__end(map), map__pgoff(map), dso__name(dso)); if (mem_end != map__end(pair)) pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, map__start(pair), map__end(pair), map__pgoff(pair)); - pr_info(" %s\n", dso->name); + pr_info(" %s\n", dso__name(dso)); map__set_priv(pair, 1); } map__put(pair); diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index ec5e21932876..c0fb4888f092 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -438,7 +438,7 @@ static int sym_title(struct symbol *sym, struct map *map, char *title, size_t sz, int percent_type) { return snprintf(title, sz, "%s %s [Percent: %s]", sym->name, - map__dso(map)->long_name, + dso__long_name(map__dso(map)), percent_type_str(percent_type)); } @@ -967,14 +967,14 @@ int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel, return -1; dso = map__dso(ms->map); - if (dso->annotate_warned) + if (dso__annotate_warned(dso)) return -1; if (not_annotated) { err = symbol__annotate2(ms, evsel, &browser.arch); if (err) { char msg[BUFSIZ]; - dso->annotate_warned = true; + dso__set_annotate_warned(dso); symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s:\n%s", sym->name, msg); goto out_free_offsets; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 0c02b3a8e121..2b32c5da47c9 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2488,7 +2488,7 @@ add_annotate_opt(struct hist_browser *browser __maybe_unused, { struct dso *dso; - if (!ms->map || (dso = map__dso(ms->map)) == NULL || dso->annotate_warned) + if (!ms->map || (dso = map__dso(ms->map)) == NULL || dso__annotate_warned(dso)) return 0; if (!ms->sym) @@ -2581,7 +2581,7 @@ static int hists_browser__zoom_map(struct hist_browser *browser, struct map *map } else { struct dso *dso = map__dso(map); ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DSO\"", - __map__is_kernel(map) ? "the Kernel" : dso->short_name); + __map__is_kernel(map) ? "the Kernel" : dso__short_name(dso)); browser->hists->dso_filter = dso; perf_hpp__set_elide(HISTC_DSO, true); pstack__push(browser->pstack, &browser->hists->dso_filter); @@ -2607,7 +2607,7 @@ add_dso_opt(struct hist_browser *browser, struct popup_action *act, if (asprintf(optstr, "Zoom %s %s DSO (use the 'k' hotkey to zoom directly into the kernel)", browser->hists->dso_filter ? "out of" : "into", - __map__is_kernel(map) ? "the Kernel" : map__dso(map)->short_name) < 0) + __map__is_kernel(map) ? "the Kernel" : dso__short_name(map__dso(map))) < 0) return 0; act->ms.map = map; @@ -3083,7 +3083,7 @@ static int evsel__hists_browse(struct evsel *evsel, int nr_events, const char *h if (!browser->selection || !browser->selection->map || !map__dso(browser->selection->map) || - map__dso(browser->selection->map)->annotate_warned) { + dso__annotate_warned(map__dso(browser->selection->map))) { continue; } diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 3d1b958d8832..fba55175a935 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -76,7 +76,7 @@ static int map_browser__run(struct map_browser *browser) { int key; - if (ui_browser__show(&browser->b, map__dso(browser->map)->long_name, + if (ui_browser__show(&browser->b, dso__long_name(map__dso(browser->map)), "Press ESC to exit, %s / to search", verbose > 0 ? "" : "restart with -v to use") < 0) return -1; @@ -106,7 +106,7 @@ int map__browse(struct map *map) { struct map_browser mb = { .b = { - .entries = &map__dso(map)->symbols, + .entries = dso__symbols(map__dso(map)), .refresh = ui_browser__rb_tree_refresh, .seek = ui_browser__rb_tree_seek, .write = map_browser__write, diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index 30c4d19fcf11..371c99849f4b 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -143,7 +143,7 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso, /* Check existing nodes in dso->data_types tree */ key.self.type_name = type_name; key.self.size = size; - node = rb_find(&key, &dso->data_types, data_type_cmp); + node = rb_find(&key, dso__data_types(dso), data_type_cmp); if (node) { result = rb_entry(node, struct annotated_data_type, node); free(type_name); @@ -164,7 +164,7 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso, if (symbol_conf.annotate_data_member) add_member_types(result, type_die); - rb_add(&result->node, &dso->data_types, data_type_less); + rb_add(&result->node, dso__data_types(dso), data_type_less); return result; } @@ -369,7 +369,7 @@ struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, Dwarf_Die type_die; u64 pc; - di = debuginfo__new(dso->long_name); + di = debuginfo__new(dso__long_name(dso)); if (di == NULL) { pr_debug("cannot get the debug info\n"); return NULL; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 107b264fa41e..aa8d12195d3a 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1794,8 +1794,8 @@ int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *buf, s char bf[SBUILD_ID_SIZE + 15] = " with build id "; char *build_id_msg = NULL; - if (dso->has_build_id) { - build_id__sprintf(&dso->bid, bf + 15); + if (dso__has_build_id(dso)) { + build_id__sprintf(dso__bid(dso), bf + 15); build_id_msg = bf; } scnprintf(buf, buflen, @@ -1817,11 +1817,11 @@ int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *buf, s scnprintf(buf, buflen, "Problems while parsing the CPUID in the arch specific initialization."); break; case SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE: - scnprintf(buf, buflen, "Invalid BPF file: %s.", dso->long_name); + scnprintf(buf, buflen, "Invalid BPF file: %s.", dso__long_name(dso)); break; case SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF: scnprintf(buf, buflen, "The %s BPF file has no BTF section, compile with -g or use pahole -J.", - dso->long_name); + dso__long_name(dso)); break; default: scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum); @@ -1839,7 +1839,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil char *pos; int len; - if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && + if (dso__symtab_type(dso) == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; @@ -1848,7 +1848,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil __symbol__join_symfs(filename, filename_size, build_id_filename); free(build_id_filename); } else { - if (dso->has_build_id) + if (dso__has_build_id(dso)) return ENOMEM; goto fallback; } @@ -1882,20 +1882,20 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil * cache, or is just a kallsyms file, well, lets hope that this * DSO is the same as when 'perf record' ran. */ - if (dso->kernel && dso->long_name[0] == '/') - snprintf(filename, filename_size, "%s", dso->long_name); + if (dso__kernel(dso) && dso__long_name(dso)[0] == '/') + snprintf(filename, filename_size, "%s", dso__long_name(dso)); else - __symbol__join_symfs(filename, filename_size, dso->long_name); + __symbol__join_symfs(filename, filename_size, dso__long_name(dso)); - mutex_lock(&dso->lock); - if (access(filename, R_OK) && errno == ENOENT && dso->nsinfo) { + mutex_lock(dso__lock(dso)); + if (access(filename, R_OK) && errno == ENOENT && dso__nsinfo(dso)) { char *new_name = dso__filename_with_chroot(dso, filename); if (new_name) { strlcpy(filename, new_name, filename_size); free(new_name); } } - mutex_unlock(&dso->lock); + mutex_unlock(dso__lock(dso)); } free(build_id_path); @@ -2181,11 +2181,11 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) map__unmap_ip(map, sym->end)); pr_debug("annotating [%p] %30s : [%p] %30s\n", - dso, dso->long_name, sym, sym->name); + dso, dso__long_name(dso), sym, sym->name); - if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) { + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) { return symbol__disassemble_bpf(sym, args); - } else if (dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE) { + } else if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) { return symbol__disassemble_bpf_image(sym, args); } else if (dso__is_kcore(dso)) { kce.kcore_filename = symfs_filename; @@ -2626,7 +2626,7 @@ int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel) int graph_dotted_len; char buf[512]; - filename = strdup(dso->long_name); + filename = strdup(dso__long_name(dso)); if (!filename) return -ENOMEM; @@ -2791,7 +2791,7 @@ int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel) } fprintf(fp, "%s() %s\nEvent: %s\n\n", - ms->sym->name, map__dso(ms->map)->long_name, ev_name); + ms->sym->name, dso__long_name(map__dso(ms->map)), ev_name); symbol__annotate_fprintf2(ms->sym, fp); fclose(fp); @@ -3045,7 +3045,7 @@ int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel) if (err) { char msg[BUFSIZ]; - dso->annotate_warned = true; + dso__set_annotate_warned(dso); symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s:\n%s", sym->name, msg); return -1; @@ -3054,13 +3054,12 @@ int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel) if (annotate_opts.print_lines) { srcline_full_filename = annotate_opts.full_path; symbol__calc_lines(ms, &source_line); - print_summary(&source_line, dso->long_name); + print_summary(&source_line, dso__long_name(dso)); } hists__scnprintf_title(hists, buf, sizeof(buf)); fprintf(stdout, "%s, [percent: %s]\n%s() %s\n", - buf, percent_type_str(annotate_opts.percent_type), sym->name, - dso->long_name); + buf, percent_type_str(annotate_opts.percent_type), sym->name, dso__long_name(dso)); symbol__annotate_fprintf2(sym, stdout); annotated_source__purge(symbol__annotation(sym)->src); @@ -3079,7 +3078,7 @@ int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel) if (err) { char msg[BUFSIZ]; - dso->annotate_warned = true; + dso__set_annotate_warned(dso); symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s:\n%s", sym->name, msg); return -1; @@ -3090,7 +3089,7 @@ int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel) if (annotate_opts.print_lines) { srcline_full_filename = annotate_opts.full_path; symbol__calc_lines(ms, &source_line); - print_summary(&source_line, dso->long_name); + print_summary(&source_line, dso__long_name(dso)); } symbol__annotate_printf(ms, evsel); diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 3684e6009b63..9b6151ec90e2 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -2652,7 +2652,7 @@ static int addr_filter__entire_dso(struct addr_filter *filt, struct dso *dso) } filt->addr = 0; - filt->size = dso->data.file_size; + filt->size = dso__data(dso)->file_size; return 0; } diff --git a/tools/perf/util/block-info.c b/tools/perf/util/block-info.c index dec910989701..895ee8adf3b3 100644 --- a/tools/perf/util/block-info.c +++ b/tools/perf/util/block-info.c @@ -319,7 +319,7 @@ static int block_dso_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, if (map && map__dso(map)) { return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, - map__dso(map)->short_name); + dso__short_name(map__dso(map))); } return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 83709146a48a..827695cd0408 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -59,10 +59,10 @@ static int machine__process_bpf_event_load(struct machine *machine, if (map) { struct dso *dso = map__dso(map); - dso->binary_type = DSO_BINARY_TYPE__BPF_PROG_INFO; - dso->bpf_prog.id = id; - dso->bpf_prog.sub_id = i; - dso->bpf_prog.env = env; + dso__set_binary_type(dso, DSO_BINARY_TYPE__BPF_PROG_INFO); + dso__bpf_prog(dso)->id = id; + dso__bpf_prog(dso)->sub_id = i; + dso__bpf_prog(dso)->env = env; map__put(map); } } diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 864bc26b6b46..83a1581e8cf1 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -60,7 +60,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, addr_location__init(&al); if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) - map__dso(al.map)->hit = 1; + dso__set_hit(map__dso(al.map)); addr_location__exit(&al); thread__put(thread); @@ -272,10 +272,10 @@ char *__dso__build_id_filename(const struct dso *dso, char *bf, size_t size, bool alloc = (bf == NULL); int ret; - if (!dso->has_build_id) + if (!dso__has_build_id(dso)) return NULL; - build_id__sprintf(&dso->bid, sbuild_id); + build_id__sprintf(dso__bid_const(dso), sbuild_id); linkname = build_id_cache__linkname(sbuild_id, NULL, 0); if (!linkname) return NULL; @@ -340,25 +340,25 @@ static int machine__write_buildid_table_cb(struct dso *dso, void *data) size_t name_len; bool in_kernel = false; - if (!dso->has_build_id) + if (!dso__has_build_id(dso)) return 0; - if (!dso->hit && !dso__is_vdso(dso)) + if (!dso__hit(dso) && !dso__is_vdso(dso)) return 0; if (dso__is_vdso(dso)) { - name = dso->short_name; - name_len = dso->short_name_len; + name = dso__short_name(dso); + name_len = dso__short_name_len(dso); } else if (dso__is_kcore(dso)) { name = args->machine->mmap_name; name_len = strlen(name); } else { - name = dso->long_name; - name_len = dso->long_name_len; + name = dso__long_name(dso); + name_len = dso__long_name_len(dso); } - in_kernel = dso->kernel || is_kernel_module(name, PERF_RECORD_MISC_CPUMODE_UNKNOWN); - return write_buildid(name, name_len, &dso->bid, args->machine->pid, + in_kernel = dso__kernel(dso) || is_kernel_module(name, PERF_RECORD_MISC_CPUMODE_UNKNOWN); + return write_buildid(name, name_len, dso__bid(dso), args->machine->pid, in_kernel ? args->kmisc : args->umisc, args->fd); } @@ -876,11 +876,11 @@ static bool dso__build_id_mismatch(struct dso *dso, const char *name) struct build_id bid; bool ret = false; - mutex_lock(&dso->lock); - if (filename__read_build_id_ns(name, &bid, dso->nsinfo) >= 0) + mutex_lock(dso__lock(dso)); + if (filename__read_build_id_ns(name, &bid, dso__nsinfo(dso)) >= 0) ret = !dso__build_id_equal(dso, &bid); - mutex_unlock(&dso->lock); + mutex_unlock(dso__lock(dso)); return ret; } @@ -890,13 +890,13 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine, { bool is_kallsyms = dso__is_kallsyms(dso); bool is_vdso = dso__is_vdso(dso); - const char *name = dso->long_name; + const char *name = dso__long_name(dso); const char *proper_name = NULL; const char *root_dir = NULL; char *allocated_name = NULL; int ret = 0; - if (!dso->has_build_id) + if (!dso__has_build_id(dso)) return 0; if (dso__is_kcore(dso)) { @@ -921,10 +921,10 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine, if (!is_kallsyms && dso__build_id_mismatch(dso, name)) goto out_free; - mutex_lock(&dso->lock); - ret = build_id_cache__add_b(&dso->bid, name, dso->nsinfo, + mutex_lock(dso__lock(dso)); + ret = build_id_cache__add_b(dso__bid(dso), name, dso__nsinfo(dso), is_kallsyms, is_vdso, proper_name, root_dir); - mutex_unlock(&dso->lock); + mutex_unlock(dso__lock(dso)); out_free: free(allocated_name); return ret; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 7517d16c02ec..68feed871809 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1205,7 +1205,7 @@ char *callchain_list__sym_name(struct callchain_list *cl, if (show_dso) scnprintf(bf + printed, bfsize - printed, " %s", cl->ms.map ? - map__dso(cl->ms.map)->short_name : + dso__short_name(map__dso(cl->ms.map)) : "unknown"); return bf; diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-convert-json.c index 5bb3c2ba95ca..86ef936e2e04 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -134,7 +134,7 @@ static void output_sample_callchain_entry(struct perf_tool *tool, output_json_key_string(out, false, 5, "symbol", al->sym->name); if (dso) { - const char *dso_name = dso->short_name; + const char *dso_name = dso__short_name(dso); if (dso_name && strlen(dso_name) > 0) { fputc(',', out); diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index 106429155c2e..50f916374d87 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -146,10 +146,10 @@ int db_export__comm_thread(struct db_export *dbe, struct comm *comm, int db_export__dso(struct db_export *dbe, struct dso *dso, struct machine *machine) { - if (dso->db_id) + if (dso__db_id(dso)) return 0; - dso->db_id = ++dbe->dso_last_db_id; + dso__set_db_id(dso, ++dbe->dso_last_db_id); if (dbe->export_dso) return dbe->export_dso(dbe, dso, machine); @@ -184,7 +184,7 @@ static int db_ids_from_al(struct db_export *dbe, struct addr_location *al, err = db_export__dso(dbe, dso, maps__machine(al->maps)); if (err) return err; - *dso_db_id = dso->db_id; + *dso_db_id = dso__db_id(dso); if (!al->sym) { al->sym = symbol__new(al->addr, 0, 0, 0, "unknown"); diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index 908e16813722..7d180bdaedbc 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -33,13 +33,13 @@ static void al_to_d_al(struct addr_location *al, struct perf_dlfilter_al *d_al) if (al->map) { struct dso *dso = map__dso(al->map); - if (symbol_conf.show_kernel_path && dso->long_name) - d_al->dso = dso->long_name; + if (symbol_conf.show_kernel_path && dso__long_name(dso)) + d_al->dso = dso__long_name(dso); else - d_al->dso = dso->name; - d_al->is_64_bit = dso->is_64_bit; - d_al->buildid_size = dso->bid.size; - d_al->buildid = dso->bid.data; + d_al->dso = dso__name(dso); + d_al->is_64_bit = dso__is_64_bit(dso); + d_al->buildid_size = dso__bid(dso)->size; + d_al->buildid = dso__bid(dso)->data; } else { d_al->dso = NULL; d_al->is_64_bit = 0; diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index e96369fb490b..ddf58f594df0 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -40,6 +40,12 @@ static const char * const debuglink_paths[] = { "/usr/lib/debug%s/%s" }; +void dso__set_nsinfo(struct dso *dso, struct nsinfo *nsi) +{ + nsinfo__put(RC_CHK_ACCESS(dso)->nsinfo); + RC_CHK_ACCESS(dso)->nsinfo = nsi; +} + char dso__symtab_origin(const struct dso *dso) { static const char origin[] = { @@ -63,14 +69,14 @@ char dso__symtab_origin(const struct dso *dso) [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V', }; - if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND) + if (dso == NULL || dso__symtab_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) return '!'; - return origin[dso->symtab_type]; + return origin[dso__symtab_type(dso)]; } bool dso__is_object_file(const struct dso *dso) { - switch (dso->binary_type) { + switch (dso__binary_type(dso)) { case DSO_BINARY_TYPE__KALLSYMS: case DSO_BINARY_TYPE__GUEST_KALLSYMS: case DSO_BINARY_TYPE__JAVA_JIT: @@ -117,7 +123,7 @@ int dso__read_binary_type_filename(const struct dso *dso, char symfile[PATH_MAX]; unsigned int i; - len = __symbol__join_symfs(filename, size, dso->long_name); + len = __symbol__join_symfs(filename, size, dso__long_name(dso)); last_slash = filename + len; while (last_slash != filename && *last_slash != '/') last_slash--; @@ -159,12 +165,12 @@ int dso__read_binary_type_filename(const struct dso *dso, case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); - snprintf(filename + len, size - len, "%s.debug", dso->long_name); + snprintf(filename + len, size - len, "%s.debug", dso__long_name(dso)); break; case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); - snprintf(filename + len, size - len, "%s", dso->long_name); + snprintf(filename + len, size - len, "%s", dso__long_name(dso)); break; case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO: @@ -173,13 +179,13 @@ int dso__read_binary_type_filename(const struct dso *dso, * /usr/lib/debug/lib when it is expected to be in * /usr/lib/debug/usr/lib */ - if (strlen(dso->long_name) < 9 || - strncmp(dso->long_name, "/usr/lib/", 9)) { + if (strlen(dso__long_name(dso)) < 9 || + strncmp(dso__long_name(dso), "/usr/lib/", 9)) { ret = -1; break; } len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); - snprintf(filename + len, size - len, "%s", dso->long_name + 4); + snprintf(filename + len, size - len, "%s", dso__long_name(dso) + 4); break; case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: @@ -187,29 +193,29 @@ int dso__read_binary_type_filename(const struct dso *dso, const char *last_slash; size_t dir_size; - last_slash = dso->long_name + dso->long_name_len; - while (last_slash != dso->long_name && *last_slash != '/') + last_slash = dso__long_name(dso) + dso__long_name_len(dso); + while (last_slash != dso__long_name(dso) && *last_slash != '/') last_slash--; len = __symbol__join_symfs(filename, size, ""); - dir_size = last_slash - dso->long_name + 2; + dir_size = last_slash - dso__long_name(dso) + 2; if (dir_size > (size - len)) { ret = -1; break; } - len += scnprintf(filename + len, dir_size, "%s", dso->long_name); + len += scnprintf(filename + len, dir_size, "%s", dso__long_name(dso)); len += scnprintf(filename + len , size - len, ".debug%s", last_slash); break; } case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: - if (!dso->has_build_id) { + if (!dso__has_build_id(dso)) { ret = -1; break; } - build_id__sprintf(&dso->bid, build_id_hex); + build_id__sprintf(dso__bid_const(dso), build_id_hex); len = __symbol__join_symfs(filename, size, "/usr/lib/debug/.build-id/"); snprintf(filename + len, size - len, "%.2s/%s.debug", build_id_hex, build_id_hex + 2); @@ -218,23 +224,23 @@ int dso__read_binary_type_filename(const struct dso *dso, case DSO_BINARY_TYPE__VMLINUX: case DSO_BINARY_TYPE__GUEST_VMLINUX: case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: - __symbol__join_symfs(filename, size, dso->long_name); + __symbol__join_symfs(filename, size, dso__long_name(dso)); break; case DSO_BINARY_TYPE__GUEST_KMODULE: case DSO_BINARY_TYPE__GUEST_KMODULE_COMP: path__join3(filename, size, symbol_conf.symfs, - root_dir, dso->long_name); + root_dir, dso__long_name(dso)); break; case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP: - __symbol__join_symfs(filename, size, dso->long_name); + __symbol__join_symfs(filename, size, dso__long_name(dso)); break; case DSO_BINARY_TYPE__KCORE: case DSO_BINARY_TYPE__GUEST_KCORE: - snprintf(filename, size, "%s", dso->long_name); + snprintf(filename, size, "%s", dso__long_name(dso)); break; default: @@ -310,8 +316,8 @@ bool is_kernel_module(const char *pathname, int cpumode) bool dso__needs_decompress(struct dso *dso) { - return dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP || - dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; + return dso__symtab_type(dso) == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP || + dso__symtab_type(dso) == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; } int filename__decompress(const char *name, char *pathname, @@ -363,11 +369,10 @@ static int decompress_kmodule(struct dso *dso, const char *name, if (!dso__needs_decompress(dso)) return -1; - if (dso->comp == COMP_ID__NONE) + if (dso__comp(dso) == COMP_ID__NONE) return -1; - return filename__decompress(name, pathname, len, dso->comp, - &dso->load_errno); + return filename__decompress(name, pathname, len, dso__comp(dso), dso__load_errno(dso)); } int dso__decompress_kmodule_fd(struct dso *dso, const char *name) @@ -468,17 +473,17 @@ void dso__set_module_info(struct dso *dso, struct kmod_path *m, struct machine *machine) { if (machine__is_host(machine)) - dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE; + dso__set_symtab_type(dso, DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE); else - dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE; + dso__set_symtab_type(dso, DSO_BINARY_TYPE__GUEST_KMODULE); /* _KMODULE_COMP should be next to _KMODULE */ if (m->kmod && m->comp) { - dso->symtab_type++; - dso->comp = m->comp; + dso__set_symtab_type(dso, dso__symtab_type(dso) + 1); + dso__set_comp(dso, m->comp); } - dso->is_kmod = 1; + dso__set_is_kmod(dso); dso__set_short_name(dso, strdup(m->name), true); } @@ -491,13 +496,15 @@ static pthread_mutex_t dso__data_open_lock = PTHREAD_MUTEX_INITIALIZER; static void dso__list_add(struct dso *dso) { - list_add_tail(&dso->data.open_entry, &dso__data_open); + list_add_tail(&dso__data(dso)->open_entry, &dso__data_open); + dso__data(dso)->dso = dso__get(dso); dso__data_open_cnt++; } static void dso__list_del(struct dso *dso) { - list_del_init(&dso->data.open_entry); + list_del_init(&dso__data(dso)->open_entry); + dso__put(dso__data(dso)->dso); WARN_ONCE(dso__data_open_cnt <= 0, "DSO data fd counter out of bounds."); dso__data_open_cnt--; @@ -528,7 +535,7 @@ static int do_open(char *name) char *dso__filename_with_chroot(const struct dso *dso, const char *filename) { - return filename_with_chroot(nsinfo__pid(dso->nsinfo), filename); + return filename_with_chroot(nsinfo__pid(dso__nsinfo_const(dso)), filename); } static int __open_dso(struct dso *dso, struct machine *machine) @@ -541,18 +548,18 @@ static int __open_dso(struct dso *dso, struct machine *machine) if (!name) return -ENOMEM; - mutex_lock(&dso->lock); + mutex_lock(dso__lock(dso)); if (machine) root_dir = machine->root_dir; - if (dso__read_binary_type_filename(dso, dso->binary_type, + if (dso__read_binary_type_filename(dso, dso__binary_type(dso), root_dir, name, PATH_MAX)) goto out; if (!is_regular_file(name)) { char *new_name; - if (errno != ENOENT || dso->nsinfo == NULL) + if (errno != ENOENT || dso__nsinfo(dso) == NULL) goto out; new_name = dso__filename_with_chroot(dso, name); @@ -568,7 +575,7 @@ static int __open_dso(struct dso *dso, struct machine *machine) size_t len = sizeof(newpath); if (dso__decompress_kmodule_path(dso, name, newpath, len) < 0) { - fd = -dso->load_errno; + fd = -(*dso__load_errno(dso)); goto out; } @@ -582,7 +589,7 @@ static int __open_dso(struct dso *dso, struct machine *machine) unlink(name); out: - mutex_unlock(&dso->lock); + mutex_unlock(dso__lock(dso)); free(name); return fd; } @@ -601,13 +608,13 @@ static int open_dso(struct dso *dso, struct machine *machine) int fd; struct nscookie nsc; - if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) { - mutex_lock(&dso->lock); - nsinfo__mountns_enter(dso->nsinfo, &nsc); - mutex_unlock(&dso->lock); + if (dso__binary_type(dso) != DSO_BINARY_TYPE__BUILD_ID_CACHE) { + mutex_lock(dso__lock(dso)); + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); + mutex_unlock(dso__lock(dso)); } fd = __open_dso(dso, machine); - if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) + if (dso__binary_type(dso) != DSO_BINARY_TYPE__BUILD_ID_CACHE) nsinfo__mountns_exit(&nsc); if (fd >= 0) { @@ -624,10 +631,10 @@ static int open_dso(struct dso *dso, struct machine *machine) static void close_data_fd(struct dso *dso) { - if (dso->data.fd >= 0) { - close(dso->data.fd); - dso->data.fd = -1; - dso->data.file_size = 0; + if (dso__data(dso)->fd >= 0) { + close(dso__data(dso)->fd); + dso__data(dso)->fd = -1; + dso__data(dso)->file_size = 0; dso__list_del(dso); } } @@ -646,10 +653,10 @@ static void close_dso(struct dso *dso) static void close_first_dso(void) { - struct dso *dso; + struct dso_data *dso_data; - dso = list_first_entry(&dso__data_open, struct dso, data.open_entry); - close_dso(dso); + dso_data = list_first_entry(&dso__data_open, struct dso_data, open_entry); + close_dso(dso_data->dso); } static rlim_t get_fd_limit(void) @@ -728,28 +735,29 @@ static void try_to_open_dso(struct dso *dso, struct machine *machine) DSO_BINARY_TYPE__NOT_FOUND, }; int i = 0; + struct dso_data *dso_data = dso__data(dso); - if (dso->data.fd >= 0) + if (dso_data->fd >= 0) return; - if (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND) { - dso->data.fd = open_dso(dso, machine); + if (dso__binary_type(dso) != DSO_BINARY_TYPE__NOT_FOUND) { + dso_data->fd = open_dso(dso, machine); goto out; } do { - dso->binary_type = binary_type_data[i++]; + dso__set_binary_type(dso, binary_type_data[i++]); - dso->data.fd = open_dso(dso, machine); - if (dso->data.fd >= 0) + dso_data->fd = open_dso(dso, machine); + if (dso_data->fd >= 0) goto out; - } while (dso->binary_type != DSO_BINARY_TYPE__NOT_FOUND); + } while (dso__binary_type(dso) != DSO_BINARY_TYPE__NOT_FOUND); out: - if (dso->data.fd >= 0) - dso->data.status = DSO_DATA_STATUS_OK; + if (dso_data->fd >= 0) + dso_data->status = DSO_DATA_STATUS_OK; else - dso->data.status = DSO_DATA_STATUS_ERROR; + dso_data->status = DSO_DATA_STATUS_ERROR; } /** @@ -763,7 +771,7 @@ static void try_to_open_dso(struct dso *dso, struct machine *machine) */ int dso__data_get_fd(struct dso *dso, struct machine *machine) { - if (dso->data.status == DSO_DATA_STATUS_ERROR) + if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR) return -1; if (pthread_mutex_lock(&dso__data_open_lock) < 0) @@ -771,10 +779,10 @@ int dso__data_get_fd(struct dso *dso, struct machine *machine) try_to_open_dso(dso, machine); - if (dso->data.fd < 0) + if (dso__data(dso)->fd < 0) pthread_mutex_unlock(&dso__data_open_lock); - return dso->data.fd; + return dso__data(dso)->fd; } void dso__data_put_fd(struct dso *dso __maybe_unused) @@ -786,10 +794,10 @@ bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by) { u32 flag = 1 << by; - if (dso->data.status_seen & flag) + if (dso__data(dso)->status_seen & flag) return true; - dso->data.status_seen |= flag; + dso__data(dso)->status_seen |= flag; return false; } @@ -799,12 +807,13 @@ static ssize_t bpf_read(struct dso *dso, u64 offset, char *data) { struct bpf_prog_info_node *node; ssize_t size = DSO__DATA_CACHE_SIZE; + struct dso_bpf_prog *dso_bpf_prog = dso__bpf_prog(dso); u64 len; u8 *buf; - node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id); + node = perf_env__find_bpf_prog_info(dso_bpf_prog->env, dso_bpf_prog->id); if (!node || !node->info_linear) { - dso->data.status = DSO_DATA_STATUS_ERROR; + dso__data(dso)->status = DSO_DATA_STATUS_ERROR; return -1; } @@ -822,14 +831,15 @@ static ssize_t bpf_read(struct dso *dso, u64 offset, char *data) static int bpf_size(struct dso *dso) { struct bpf_prog_info_node *node; + struct dso_bpf_prog *dso_bpf_prog = dso__bpf_prog(dso); - node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id); + node = perf_env__find_bpf_prog_info(dso_bpf_prog->env, dso_bpf_prog->id); if (!node || !node->info_linear) { - dso->data.status = DSO_DATA_STATUS_ERROR; + dso__data(dso)->status = DSO_DATA_STATUS_ERROR; return -1; } - dso->data.file_size = node->info_linear->info.jited_prog_len; + dso__data(dso)->file_size = node->info_linear->info.jited_prog_len; return 0; } #endif // HAVE_LIBBPF_SUPPORT @@ -837,10 +847,10 @@ static int bpf_size(struct dso *dso) static void dso_cache__free(struct dso *dso) { - struct rb_root *root = &dso->data.cache; + struct rb_root *root = &dso__data(dso)->cache; struct rb_node *next = rb_first(root); - mutex_lock(&dso->lock); + mutex_lock(dso__lock(dso)); while (next) { struct dso_cache *cache; @@ -849,12 +859,12 @@ dso_cache__free(struct dso *dso) rb_erase(&cache->rb_node, root); free(cache); } - mutex_unlock(&dso->lock); + mutex_unlock(dso__lock(dso)); } static struct dso_cache *__dso_cache__find(struct dso *dso, u64 offset) { - const struct rb_root *root = &dso->data.cache; + const struct rb_root *root = &dso__data(dso)->cache; struct rb_node * const *p = &root->rb_node; const struct rb_node *parent = NULL; struct dso_cache *cache; @@ -880,13 +890,13 @@ static struct dso_cache *__dso_cache__find(struct dso *dso, u64 offset) static struct dso_cache * dso_cache__insert(struct dso *dso, struct dso_cache *new) { - struct rb_root *root = &dso->data.cache; + struct rb_root *root = &dso__data(dso)->cache; struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct dso_cache *cache; u64 offset = new->offset; - mutex_lock(&dso->lock); + mutex_lock(dso__lock(dso)); while (*p != NULL) { u64 end; @@ -907,7 +917,7 @@ dso_cache__insert(struct dso *dso, struct dso_cache *new) cache = NULL; out: - mutex_unlock(&dso->lock); + mutex_unlock(dso__lock(dso)); return cache; } @@ -932,18 +942,18 @@ static ssize_t file_read(struct dso *dso, struct machine *machine, pthread_mutex_lock(&dso__data_open_lock); /* - * dso->data.fd might be closed if other thread opened another + * dso__data(dso)->fd might be closed if other thread opened another * file (dso) due to open file limit (RLIMIT_NOFILE). */ try_to_open_dso(dso, machine); - if (dso->data.fd < 0) { - dso->data.status = DSO_DATA_STATUS_ERROR; + if (dso__data(dso)->fd < 0) { + dso__data(dso)->status = DSO_DATA_STATUS_ERROR; ret = -errno; goto out; } - ret = pread(dso->data.fd, data, DSO__DATA_CACHE_SIZE, offset); + ret = pread(dso__data(dso)->fd, data, DSO__DATA_CACHE_SIZE, offset); out: pthread_mutex_unlock(&dso__data_open_lock); return ret; @@ -963,11 +973,11 @@ static struct dso_cache *dso_cache__populate(struct dso *dso, return NULL; } #ifdef HAVE_LIBBPF_SUPPORT - if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) *ret = bpf_read(dso, cache_offset, cache->data); else #endif - if (dso->binary_type == DSO_BINARY_TYPE__OOL) + if (dso__binary_type(dso) == DSO_BINARY_TYPE__OOL) *ret = DSO__DATA_CACHE_SIZE; else *ret = file_read(dso, machine, cache_offset, cache->data); @@ -1056,25 +1066,25 @@ static int file_size(struct dso *dso, struct machine *machine) pthread_mutex_lock(&dso__data_open_lock); /* - * dso->data.fd might be closed if other thread opened another + * dso__data(dso)->fd might be closed if other thread opened another * file (dso) due to open file limit (RLIMIT_NOFILE). */ try_to_open_dso(dso, machine); - if (dso->data.fd < 0) { + if (dso__data(dso)->fd < 0) { ret = -errno; - dso->data.status = DSO_DATA_STATUS_ERROR; + dso__data(dso)->status = DSO_DATA_STATUS_ERROR; goto out; } - if (fstat(dso->data.fd, &st) < 0) { + if (fstat(dso__data(dso)->fd, &st) < 0) { ret = -errno; pr_err("dso cache fstat failed: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); - dso->data.status = DSO_DATA_STATUS_ERROR; + dso__data(dso)->status = DSO_DATA_STATUS_ERROR; goto out; } - dso->data.file_size = st.st_size; + dso__data(dso)->file_size = st.st_size; out: pthread_mutex_unlock(&dso__data_open_lock); @@ -1083,13 +1093,13 @@ static int file_size(struct dso *dso, struct machine *machine) int dso__data_file_size(struct dso *dso, struct machine *machine) { - if (dso->data.file_size) + if (dso__data(dso)->file_size) return 0; - if (dso->data.status == DSO_DATA_STATUS_ERROR) + if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR) return -1; #ifdef HAVE_LIBBPF_SUPPORT - if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) return bpf_size(dso); #endif return file_size(dso, machine); @@ -1108,7 +1118,7 @@ off_t dso__data_size(struct dso *dso, struct machine *machine) return -1; /* For now just estimate dso data size is close to file size */ - return dso->data.file_size; + return dso__data(dso)->file_size; } static ssize_t data_read_write_offset(struct dso *dso, struct machine *machine, @@ -1119,7 +1129,7 @@ static ssize_t data_read_write_offset(struct dso *dso, struct machine *machine, return -1; /* Check the offset sanity. */ - if (offset > dso->data.file_size) + if (offset > dso__data(dso)->file_size) return -1; if (offset + size < offset) @@ -1142,7 +1152,7 @@ static ssize_t data_read_write_offset(struct dso *dso, struct machine *machine, ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, u64 offset, u8 *data, ssize_t size) { - if (dso->data.status == DSO_DATA_STATUS_ERROR) + if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR) return -1; return data_read_write_offset(dso, machine, offset, data, size, true); @@ -1182,7 +1192,7 @@ ssize_t dso__data_write_cache_offs(struct dso *dso, struct machine *machine, { u8 *data = (u8 *)data_in; /* cast away const to use same fns for r/w */ - if (dso->data.status == DSO_DATA_STATUS_ERROR) + if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR) return -1; return data_read_write_offset(dso, machine, offset, data, size, false); @@ -1235,7 +1245,7 @@ struct dso *machine__findnew_kernel(struct machine *machine, const char *name, */ if (dso != NULL) { dso__set_short_name(dso, short_name, false); - dso->kernel = dso_type; + dso__set_kernel(dso, dso_type); } return dso; @@ -1243,7 +1253,7 @@ struct dso *machine__findnew_kernel(struct machine *machine, const char *name, static void dso__set_long_name_id(struct dso *dso, const char *name, bool name_allocated) { - struct dsos *dsos = dso->dsos; + struct dsos *dsos = dso__dsos(dso); if (name == NULL) return; @@ -1256,12 +1266,12 @@ static void dso__set_long_name_id(struct dso *dso, const char *name, bool name_a down_write(&dsos->lock); } - if (dso->long_name_allocated) - free((char *)dso->long_name); + if (dso__long_name_allocated(dso)) + free((char *)dso__long_name(dso)); - dso->long_name = name; - dso->long_name_len = strlen(name); - dso->long_name_allocated = name_allocated; + RC_CHK_ACCESS(dso)->long_name = name; + RC_CHK_ACCESS(dso)->long_name_len = strlen(name); + dso__set_long_name_allocated(dso, name_allocated); if (dsos) { dsos->sorted = false; @@ -1307,14 +1317,15 @@ bool dso_id__empty(const struct dso_id *id) void __dso__inject_id(struct dso *dso, struct dso_id *id) { - struct dsos *dsos = dso->dsos; + struct dsos *dsos = dso__dsos(dso); + struct dso_id *dso_id = dso__id(dso); /* dsos write lock held by caller. */ - dso->id.maj = id->maj; - dso->id.min = id->min; - dso->id.ino = id->ino; - dso->id.ino_generation = id->ino_generation; + dso_id->maj = id->maj; + dso_id->min = id->min; + dso_id->ino = id->ino; + dso_id->ino_generation = id->ino_generation; if (dsos) dsos->sorted = false; @@ -1334,7 +1345,7 @@ int dso_id__cmp(const struct dso_id *a, const struct dso_id *b) int dso__cmp_id(struct dso *a, struct dso *b) { - return __dso_id__cmp(&a->id, &b->id); + return __dso_id__cmp(dso__id(a), dso__id(b)); } void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated) @@ -1344,7 +1355,7 @@ void dso__set_long_name(struct dso *dso, const char *name, bool name_allocated) void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated) { - struct dsos *dsos = dso->dsos; + struct dsos *dsos = dso__dsos(dso); if (name == NULL) return; @@ -1356,12 +1367,12 @@ void dso__set_short_name(struct dso *dso, const char *name, bool name_allocated) */ down_write(&dsos->lock); } - if (dso->short_name_allocated) - free((char *)dso->short_name); + if (dso__short_name_allocated(dso)) + free((char *)dso__short_name(dso)); - dso->short_name = name; - dso->short_name_len = strlen(name); - dso->short_name_allocated = name_allocated; + RC_CHK_ACCESS(dso)->short_name = name; + RC_CHK_ACCESS(dso)->short_name_len = strlen(name); + dso__set_short_name_allocated(dso, name_allocated); if (dsos) { dsos->sorted = false; @@ -1374,40 +1385,44 @@ int dso__name_len(const struct dso *dso) if (!dso) return strlen("[unknown]"); if (verbose > 0) - return dso->long_name_len; + return dso__long_name_len(dso); - return dso->short_name_len; + return dso__short_name_len(dso); } bool dso__loaded(const struct dso *dso) { - return dso->loaded; + return RC_CHK_ACCESS(dso)->loaded; } bool dso__sorted_by_name(const struct dso *dso) { - return dso->sorted_by_name; + return RC_CHK_ACCESS(dso)->sorted_by_name; } void dso__set_sorted_by_name(struct dso *dso) { - dso->sorted_by_name = true; + RC_CHK_ACCESS(dso)->sorted_by_name = true; } struct dso *dso__new_id(const char *name, struct dso_id *id) { - struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1); + RC_STRUCT(dso) *dso = zalloc(sizeof(*dso) + strlen(name) + 1); + struct dso *res; + struct dso_data *data; - if (dso != NULL) { + if (!dso) + return NULL; + + if (ADD_RC_CHK(res, dso)) { strcpy(dso->name, name); if (id) dso->id = *id; - dso__set_long_name_id(dso, dso->name, false); - dso__set_short_name(dso, dso->name, false); + dso__set_long_name_id(res, dso->name, false); + dso__set_short_name(res, dso->name, false); dso->symbols = RB_ROOT_CACHED; dso->symbol_names = NULL; dso->symbol_names_len = 0; - dso->data.cache = RB_ROOT; dso->inlined_nodes = RB_ROOT_CACHED; dso->srclines = RB_ROOT_CACHED; dso->data_types = RB_ROOT; @@ -1426,12 +1441,16 @@ struct dso *dso__new_id(const char *name, struct dso_id *id) dso->is_kmod = 0; dso->needs_swap = DSO_SWAP__UNSET; dso->comp = COMP_ID__NONE; - INIT_LIST_HEAD(&dso->data.open_entry); mutex_init(&dso->lock); refcount_set(&dso->refcnt, 1); + data = &dso->data; + data->cache = RB_ROOT; + data->fd = -1; + data->status = DSO_DATA_STATUS_UNKNOWN; + INIT_LIST_HEAD(&data->open_entry); + data->dso = NULL; /* Set when on the open_entry list. */ } - - return dso; + return res; } struct dso *dso__new(const char *name) @@ -1441,70 +1460,76 @@ struct dso *dso__new(const char *name) void dso__delete(struct dso *dso) { - if (dso->dsos) - pr_err("DSO %s is still in rbtree when being deleted!\n", dso->long_name); + if (dso__dsos(dso)) + pr_err("DSO %s is still in rbtree when being deleted!\n", dso__long_name(dso)); /* free inlines first, as they reference symbols */ - inlines__tree_delete(&dso->inlined_nodes); - srcline__tree_delete(&dso->srclines); - symbols__delete(&dso->symbols); - dso->symbol_names_len = 0; - zfree(&dso->symbol_names); - annotated_data_type__tree_delete(&dso->data_types); - - if (dso->short_name_allocated) { - zfree((char **)&dso->short_name); - dso->short_name_allocated = false; + inlines__tree_delete(&RC_CHK_ACCESS(dso)->inlined_nodes); + srcline__tree_delete(&RC_CHK_ACCESS(dso)->srclines); + symbols__delete(&RC_CHK_ACCESS(dso)->symbols); + RC_CHK_ACCESS(dso)->symbol_names_len = 0; + zfree(&RC_CHK_ACCESS(dso)->symbol_names); + annotated_data_type__tree_delete(dso__data_types(dso)); + if (RC_CHK_ACCESS(dso)->short_name_allocated) { + zfree((char **)&RC_CHK_ACCESS(dso)->short_name); + RC_CHK_ACCESS(dso)->short_name_allocated = false; } - if (dso->long_name_allocated) { - zfree((char **)&dso->long_name); - dso->long_name_allocated = false; + if (RC_CHK_ACCESS(dso)->long_name_allocated) { + zfree((char **)&RC_CHK_ACCESS(dso)->long_name); + RC_CHK_ACCESS(dso)->long_name_allocated = false; } dso__data_close(dso); - auxtrace_cache__free(dso->auxtrace_cache); + auxtrace_cache__free(RC_CHK_ACCESS(dso)->auxtrace_cache); dso_cache__free(dso); dso__free_a2l(dso); - zfree(&dso->symsrc_filename); - nsinfo__zput(dso->nsinfo); - mutex_destroy(&dso->lock); - free(dso); + zfree(&RC_CHK_ACCESS(dso)->symsrc_filename); + nsinfo__zput(RC_CHK_ACCESS(dso)->nsinfo); + mutex_destroy(dso__lock(dso)); + RC_CHK_FREE(dso); } struct dso *dso__get(struct dso *dso) { - if (dso) - refcount_inc(&dso->refcnt); - return dso; + struct dso *result; + + if (RC_CHK_GET(result, dso)) + refcount_inc(&RC_CHK_ACCESS(dso)->refcnt); + + return result; } void dso__put(struct dso *dso) { - if (dso && refcount_dec_and_test(&dso->refcnt)) + if (dso && refcount_dec_and_test(&RC_CHK_ACCESS(dso)->refcnt)) dso__delete(dso); + else + RC_CHK_PUT(dso); } void dso__set_build_id(struct dso *dso, struct build_id *bid) { - dso->bid = *bid; - dso->has_build_id = 1; + RC_CHK_ACCESS(dso)->bid = *bid; + RC_CHK_ACCESS(dso)->has_build_id = 1; } bool dso__build_id_equal(const struct dso *dso, struct build_id *bid) { - if (dso->bid.size > bid->size && dso->bid.size == BUILD_ID_SIZE) { + const struct build_id *dso_bid = dso__bid_const(dso); + + if (dso_bid->size > bid->size && dso_bid->size == BUILD_ID_SIZE) { /* * For the backward compatibility, it allows a build-id has * trailing zeros. */ - return !memcmp(dso->bid.data, bid->data, bid->size) && - !memchr_inv(&dso->bid.data[bid->size], 0, - dso->bid.size - bid->size); + return !memcmp(dso_bid->data, bid->data, bid->size) && + !memchr_inv(&dso_bid->data[bid->size], 0, + dso_bid->size - bid->size); } - return dso->bid.size == bid->size && - memcmp(dso->bid.data, bid->data, dso->bid.size) == 0; + return dso_bid->size == bid->size && + memcmp(dso_bid->data, bid->data, dso_bid->size) == 0; } void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine) @@ -1514,8 +1539,8 @@ void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine) if (machine__is_default_guest(machine)) return; sprintf(path, "%s/sys/kernel/notes", machine->root_dir); - if (sysfs__read_build_id(path, &dso->bid) == 0) - dso->has_build_id = true; + if (sysfs__read_build_id(path, dso__bid(dso)) == 0) + dso__set_has_build_id(dso); } int dso__kernel_module_get_build_id(struct dso *dso, @@ -1526,14 +1551,14 @@ int dso__kernel_module_get_build_id(struct dso *dso, * kernel module short names are of the form "[module]" and * we need just "module" here. */ - const char *name = dso->short_name + 1; + const char *name = dso__short_name(dso) + 1; snprintf(filename, sizeof(filename), "%s/sys/module/%.*s/notes/.note.gnu.build-id", root_dir, (int)strlen(name) - 1, name); - if (sysfs__read_build_id(filename, &dso->bid) == 0) - dso->has_build_id = true; + if (sysfs__read_build_id(filename, dso__bid(dso)) == 0) + dso__set_has_build_id(dso); return 0; } @@ -1542,21 +1567,21 @@ static size_t dso__fprintf_buildid(struct dso *dso, FILE *fp) { char sbuild_id[SBUILD_ID_SIZE]; - build_id__sprintf(&dso->bid, sbuild_id); + build_id__sprintf(dso__bid(dso), sbuild_id); return fprintf(fp, "%s", sbuild_id); } size_t dso__fprintf(struct dso *dso, FILE *fp) { struct rb_node *nd; - size_t ret = fprintf(fp, "dso: %s (", dso->short_name); + size_t ret = fprintf(fp, "dso: %s (", dso__short_name(dso)); - if (dso->short_name != dso->long_name) - ret += fprintf(fp, "%s, ", dso->long_name); + if (dso__short_name(dso) != dso__long_name(dso)) + ret += fprintf(fp, "%s, ", dso__long_name(dso)); ret += fprintf(fp, "%sloaded, ", dso__loaded(dso) ? "" : "NOT "); ret += dso__fprintf_buildid(dso, fp); ret += fprintf(fp, ")\n"); - for (nd = rb_first_cached(&dso->symbols); nd; nd = rb_next(nd)) { + for (nd = rb_first_cached(dso__symbols(dso)); nd; nd = rb_next(nd)) { struct symbol *pos = rb_entry(nd, struct symbol, rb_node); ret += symbol__fprintf(pos, fp); } @@ -1580,7 +1605,7 @@ enum dso_type dso__type(struct dso *dso, struct machine *machine) int dso__strerror_load(struct dso *dso, char *buf, size_t buflen) { - int idx, errnum = dso->load_errno; + int idx, errnum = *dso__load_errno(dso); /* * This must have a same ordering as the enum dso_load_errno. */ diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 2e227822f10c..3e27f93898f2 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -11,6 +11,7 @@ #include #include "build-id.h" #include "mutex.h" +#include struct machine; struct map; @@ -100,26 +101,27 @@ enum dso_load_errno { __DSO_LOAD_ERRNO__END, }; -#define DSO__SWAP(dso, type, val) \ -({ \ - type ____r = val; \ - BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \ - if (dso->needs_swap == DSO_SWAP__YES) { \ - switch (sizeof(____r)) { \ - case 2: \ - ____r = bswap_16(val); \ - break; \ - case 4: \ - ____r = bswap_32(val); \ - break; \ - case 8: \ - ____r = bswap_64(val); \ - break; \ - default: \ - BUG_ON(1); \ - } \ - } \ - ____r; \ +#define DSO__SWAP(dso, type, val) \ +({ \ + type ____r = val; \ + enum dso_swap_type ___dst = dso__needs_swap(dso); \ + BUG_ON(___dst == DSO_SWAP__UNSET); \ + if (___dst == DSO_SWAP__YES) { \ + switch (sizeof(____r)) { \ + case 2: \ + ____r = bswap_16(val); \ + break; \ + case 4: \ + ____r = bswap_32(val); \ + break; \ + case 8: \ + ____r = bswap_64(val); \ + break; \ + default: \ + BUG_ON(1); \ + } \ + } \ + ____r; \ }) #define DSO__DATA_CACHE_SIZE 4096 @@ -142,9 +144,29 @@ struct dso_cache { char data[]; }; +struct dso_data { + struct rb_root cache; + struct list_head open_entry; + struct dso *dso; + int fd; + int status; + u32 status_seen; + u64 file_size; + u64 elf_base_addr; + u64 debug_frame_offset; + u64 eh_frame_hdr_addr; + u64 eh_frame_hdr_offset; +}; + +struct dso_bpf_prog { + u32 id; + u32 sub_id; + struct perf_env *env; +}; + struct auxtrace_cache; -struct dso { +DECLARE_RC_STRUCT(dso) { struct mutex lock; struct dsos *dsos; struct rb_root_cached symbols; @@ -175,24 +197,9 @@ struct dso { u64 db_id; }; /* bpf prog information */ - struct { - struct perf_env *env; - u32 id; - u32 sub_id; - } bpf_prog; + struct dso_bpf_prog bpf_prog; /* dso data file */ - struct { - struct rb_root cache; - struct list_head open_entry; - u64 file_size; - u64 elf_base_addr; - u64 debug_frame_offset; - u64 eh_frame_hdr_addr; - u64 eh_frame_hdr_offset; - int fd; - int status; - u32 status_seen; - } data; + struct dso_data data; struct dso_id id; unsigned int a2l_fails; int comp; @@ -228,11 +235,383 @@ struct dso { * @n: the 'struct rb_node *' to use as a temporary storage */ #define dso__for_each_symbol(dso, pos, n) \ - symbols__for_each_entry(&(dso)->symbols, pos, n) + symbols__for_each_entry(dso__symbols(dso), pos, n) + +static inline void *dso__a2l(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->a2l; +} + +static inline void dso__set_a2l(struct dso *dso, void *val) +{ + RC_CHK_ACCESS(dso)->a2l = val; +} + +static inline unsigned int dso__a2l_fails(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->a2l_fails; +} + +static inline void dso__set_a2l_fails(struct dso *dso, unsigned int val) +{ + RC_CHK_ACCESS(dso)->a2l_fails = val; +} + +static inline bool dso__adjust_symbols(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->adjust_symbols; +} + +static inline void dso__set_adjust_symbols(struct dso *dso, bool val) +{ + RC_CHK_ACCESS(dso)->adjust_symbols = val; +} + +static inline bool dso__annotate_warned(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->annotate_warned; +} + +static inline void dso__set_annotate_warned(struct dso *dso) +{ + RC_CHK_ACCESS(dso)->annotate_warned = 1; +} + +static inline struct auxtrace_cache *dso__auxtrace_cache(struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->auxtrace_cache; +} + +static inline void dso__set_auxtrace_cache(struct dso *dso, struct auxtrace_cache *cache) +{ + RC_CHK_ACCESS(dso)->auxtrace_cache = cache; +} + +static inline struct build_id *dso__bid(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->bid; +} + +static inline const struct build_id *dso__bid_const(const struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->bid; +} + +static inline struct dso_bpf_prog *dso__bpf_prog(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->bpf_prog; +} + +static inline bool dso__has_build_id(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->has_build_id; +} + +static inline void dso__set_has_build_id(struct dso *dso) +{ + RC_CHK_ACCESS(dso)->has_build_id = true; +} + +static inline bool dso__has_srcline(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->has_srcline; +} + +static inline void dso__set_has_srcline(struct dso *dso, bool val) +{ + RC_CHK_ACCESS(dso)->has_srcline = val; +} + +static inline int dso__comp(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->comp; +} + +static inline void dso__set_comp(struct dso *dso, int comp) +{ + RC_CHK_ACCESS(dso)->comp = comp; +} + +static inline struct dso_data *dso__data(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->data; +} + +static inline u64 dso__db_id(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->db_id; +} + +static inline void dso__set_db_id(struct dso *dso, u64 db_id) +{ + RC_CHK_ACCESS(dso)->db_id = db_id; +} + +static inline struct dsos *dso__dsos(struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->dsos; +} + +static inline void dso__set_dsos(struct dso *dso, struct dsos *dsos) +{ + RC_CHK_ACCESS(dso)->dsos = dsos; +} + +static inline bool dso__header_build_id(struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->header_build_id; +} + +static inline void dso__set_header_build_id(struct dso *dso, bool val) +{ + RC_CHK_ACCESS(dso)->header_build_id = val; +} + +static inline bool dso__hit(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->hit; +} + +static inline void dso__set_hit(struct dso *dso) +{ + RC_CHK_ACCESS(dso)->hit = 1; +} + +static inline struct dso_id *dso__id(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->id; +} + +static inline const struct dso_id *dso__id_const(const struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->id; +} + +static inline struct rb_root_cached *dso__inlined_nodes(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->inlined_nodes; +} + +static inline bool dso__is_64_bit(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->is_64_bit; +} + +static inline void dso__set_is_64_bit(struct dso *dso, bool is) +{ + RC_CHK_ACCESS(dso)->is_64_bit = is; +} + +static inline bool dso__is_kmod(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->is_kmod; +} + +static inline void dso__set_is_kmod(struct dso *dso) +{ + RC_CHK_ACCESS(dso)->is_kmod = 1; +} + +static inline enum dso_space_type dso__kernel(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->kernel; +} + +static inline void dso__set_kernel(struct dso *dso, enum dso_space_type kernel) +{ + RC_CHK_ACCESS(dso)->kernel = kernel; +} + +static inline u64 dso__last_find_result_addr(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->last_find_result.addr; +} + +static inline void dso__set_last_find_result_addr(struct dso *dso, u64 addr) +{ + RC_CHK_ACCESS(dso)->last_find_result.addr = addr; +} + +static inline struct symbol *dso__last_find_result_symbol(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->last_find_result.symbol; +} + +static inline void dso__set_last_find_result_symbol(struct dso *dso, struct symbol *symbol) +{ + RC_CHK_ACCESS(dso)->last_find_result.symbol = symbol; +} + +static inline enum dso_load_errno *dso__load_errno(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->load_errno; +} static inline void dso__set_loaded(struct dso *dso) { - dso->loaded = true; + RC_CHK_ACCESS(dso)->loaded = true; +} + +static inline struct mutex *dso__lock(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->lock; +} + +static inline const char *dso__long_name(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->long_name; +} + +static inline bool dso__long_name_allocated(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->long_name_allocated; +} + +static inline void dso__set_long_name_allocated(struct dso *dso, bool allocated) +{ + RC_CHK_ACCESS(dso)->long_name_allocated = allocated; +} + +static inline u16 dso__long_name_len(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->long_name_len; +} + +static inline const char *dso__name(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->name; +} + +static inline enum dso_swap_type dso__needs_swap(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->needs_swap; +} + +static inline void dso__set_needs_swap(struct dso *dso, enum dso_swap_type type) +{ + RC_CHK_ACCESS(dso)->needs_swap = type; +} + +static inline struct nsinfo *dso__nsinfo(struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->nsinfo; +} + +static inline const struct nsinfo *dso__nsinfo_const(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->nsinfo; +} + +static inline struct nsinfo **dso__nsinfo_ptr(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->nsinfo; +} + +void dso__set_nsinfo(struct dso *dso, struct nsinfo *nsi); + +static inline u8 dso__rel(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->rel; +} + +static inline void dso__set_rel(struct dso *dso, u8 rel) +{ + RC_CHK_ACCESS(dso)->rel = rel; +} + +static inline const char *dso__short_name(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->short_name; +} + +static inline bool dso__short_name_allocated(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->short_name_allocated; +} + +static inline void dso__set_short_name_allocated(struct dso *dso, bool allocated) +{ + RC_CHK_ACCESS(dso)->short_name_allocated = allocated; +} + +static inline u16 dso__short_name_len(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->short_name_len; +} + +static inline struct rb_root_cached *dso__srclines(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->srclines; +} + +static inline struct rb_root *dso__data_types(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->data_types; +} + +static inline struct rb_root_cached *dso__symbols(struct dso *dso) +{ + return &RC_CHK_ACCESS(dso)->symbols; +} + +static inline struct symbol **dso__symbol_names(struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->symbol_names; +} + +static inline void dso__set_symbol_names(struct dso *dso, struct symbol **names) +{ + RC_CHK_ACCESS(dso)->symbol_names = names; +} + +static inline size_t dso__symbol_names_len(struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->symbol_names_len; +} + +static inline void dso__set_symbol_names_len(struct dso *dso, size_t len) +{ + RC_CHK_ACCESS(dso)->symbol_names_len = len; +} + +static inline const char *dso__symsrc_filename(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->symsrc_filename; +} + +static inline void dso__set_symsrc_filename(struct dso *dso, char *val) +{ + RC_CHK_ACCESS(dso)->symsrc_filename = val; +} + +static inline enum dso_binary_type dso__symtab_type(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->symtab_type; +} + +static inline void dso__set_symtab_type(struct dso *dso, enum dso_binary_type bt) +{ + RC_CHK_ACCESS(dso)->symtab_type = bt; +} + +static inline u64 dso__text_end(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->text_end; +} + +static inline void dso__set_text_end(struct dso *dso, u64 val) +{ + RC_CHK_ACCESS(dso)->text_end = val; +} + +static inline u64 dso__text_offset(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->text_offset; +} + +static inline void dso__set_text_offset(struct dso *dso, u64 val) +{ + RC_CHK_ACCESS(dso)->text_offset = val; } int dso_id__cmp(const struct dso_id *a, const struct dso_id *b); @@ -264,7 +643,7 @@ bool dso__loaded(const struct dso *dso); static inline bool dso__has_symbols(const struct dso *dso) { - return !RB_EMPTY_ROOT(&dso->symbols.rb_root); + return !RB_EMPTY_ROOT(&RC_CHK_ACCESS(dso)->symbols.rb_root); } char *dso__filename_with_chroot(const struct dso *dso, const char *filename); @@ -380,21 +759,33 @@ 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); +static inline enum dso_binary_type dso__binary_type(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->binary_type; +} + +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__is_vmlinux(const struct dso *dso) { - return dso->binary_type == DSO_BINARY_TYPE__VMLINUX || - dso->binary_type == DSO_BINARY_TYPE__GUEST_VMLINUX; + enum dso_binary_type bt = dso__binary_type(dso); + + return bt == DSO_BINARY_TYPE__VMLINUX || bt == DSO_BINARY_TYPE__GUEST_VMLINUX; } static inline bool dso__is_kcore(const struct dso *dso) { - return dso->binary_type == DSO_BINARY_TYPE__KCORE || - dso->binary_type == DSO_BINARY_TYPE__GUEST_KCORE; + enum dso_binary_type bt = dso__binary_type(dso); + + return bt == DSO_BINARY_TYPE__KCORE || bt == DSO_BINARY_TYPE__GUEST_KCORE; } static inline bool dso__is_kallsyms(const struct dso *dso) { - return dso->kernel && dso->long_name[0] != '/'; + return RC_CHK_ACCESS(dso)->kernel && RC_CHK_ACCESS(dso)->long_name[0] != '/'; } bool dso__is_object_file(const struct dso *dso); diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index 23c3fe4f2abb..ab3d0c01dd63 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -29,8 +29,8 @@ static void dsos__purge(struct dsos *dsos) for (unsigned int i = 0; i < dsos->cnt; i++) { struct dso *dso = dsos->dsos[i]; + dso__set_dsos(dso, NULL); dso__put(dso); - dso->dsos = NULL; } zfree(&dsos->dsos); @@ -73,22 +73,22 @@ static int dsos__read_build_ids_cb(struct dso *dso, void *data) struct dsos__read_build_ids_cb_args *args = data; struct nscookie nsc; - if (args->with_hits && !dso->hit && !dso__is_vdso(dso)) + if (args->with_hits && !dso__hit(dso) && !dso__is_vdso(dso)) return 0; - if (dso->has_build_id) { + if (dso__has_build_id(dso)) { args->have_build_id = true; return 0; } - nsinfo__mountns_enter(dso->nsinfo, &nsc); - if (filename__read_build_id(dso->long_name, &dso->bid) > 0) { + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); + if (filename__read_build_id(dso__long_name(dso), dso__bid(dso)) > 0) { args->have_build_id = true; - dso->has_build_id = true; - } else if (errno == ENOENT && dso->nsinfo) { - char *new_name = dso__filename_with_chroot(dso, dso->long_name); + dso__set_has_build_id(dso); + } else if (errno == ENOENT && dso__nsinfo(dso)) { + char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso)); - if (new_name && filename__read_build_id(new_name, &dso->bid) > 0) { + if (new_name && filename__read_build_id(new_name, dso__bid(dso)) > 0) { args->have_build_id = true; - dso->has_build_id = true; + dso__set_has_build_id(dso); } free(new_name); } @@ -110,27 +110,27 @@ bool dsos__read_build_ids(struct dsos *dsos, bool with_hits) static int __dso__cmp_long_name(const char *long_name, const struct dso_id *id, const struct dso *b) { - int rc = strcmp(long_name, b->long_name); - return rc ?: dso_id__cmp(id, &b->id); + int rc = strcmp(long_name, dso__long_name(b)); + return rc ?: dso_id__cmp(id, dso__id_const(b)); } static int __dso__cmp_short_name(const char *short_name, const struct dso_id *id, const struct dso *b) { - int rc = strcmp(short_name, b->short_name); - return rc ?: dso_id__cmp(id, &b->id); + int rc = strcmp(short_name, dso__short_name(b)); + return rc ?: dso_id__cmp(id, dso__id_const(b)); } static int dsos__cmp_long_name_id_short_name(const void *va, const void *vb) { const struct dso *a = *((const struct dso **)va); const struct dso *b = *((const struct dso **)vb); - int rc = strcmp(a->long_name, b->long_name); + int rc = strcmp(dso__long_name(a), dso__long_name(b)); if (!rc) { - rc = dso_id__cmp(&a->id, &b->id); + rc = dso_id__cmp(dso__id_const(a), dso__id_const(b)); if (!rc) - rc = strcmp(a->short_name, b->short_name); + rc = strcmp(dso__short_name(a), dso__short_name(b)); } return rc; } @@ -209,7 +209,7 @@ int __dsos__add(struct dsos *dsos, struct dso *dso) &dsos->dsos[dsos->cnt - 1]) <= 0; } - dso->dsos = dsos; + dso__set_dsos(dso, dsos); return 0; } @@ -275,7 +275,7 @@ static void dso__set_basename(struct dso *dso) char *base, *lname; int tid; - if (sscanf(dso->long_name, "/tmp/perf-%d.map", &tid) == 1) { + if (sscanf(dso__long_name(dso), "/tmp/perf-%d.map", &tid) == 1) { if (asprintf(&base, "[JIT] tid %d", tid) < 0) return; } else { @@ -283,7 +283,7 @@ static void dso__set_basename(struct dso *dso) * basename() may modify path buffer, so we must pass * a copy. */ - lname = strdup(dso->long_name); + lname = strdup(dso__long_name(dso)); if (!lname) return; @@ -322,7 +322,7 @@ static struct dso *__dsos__findnew_id(struct dsos *dsos, const char *name, struc { struct dso *dso = __dsos__find_id(dsos, name, id, false, /*write_locked=*/true); - if (dso && dso_id__empty(&dso->id) && !dso_id__empty(id)) + if (dso && dso_id__empty(dso__id(dso)) && !dso_id__empty(id)) __dso__inject_id(dso, id); return dso ? dso : __dsos__addnew_id(dsos, name, id); @@ -351,8 +351,8 @@ static int dsos__fprintf_buildid_cb(struct dso *dso, void *data) if (args->skip && args->skip(dso, args->parm)) return 0; - build_id__sprintf(&dso->bid, sbuild_id); - args->ret += fprintf(args->fp, "%-40s %s\n", sbuild_id, dso->long_name); + build_id__sprintf(dso__bid(dso), sbuild_id); + args->ret += fprintf(args->fp, "%-40s %s\n", sbuild_id, dso__long_name(dso)); return 0; } @@ -396,7 +396,7 @@ size_t dsos__fprintf(struct dsos *dsos, FILE *fp) static int dsos__hit_all_cb(struct dso *dso, void *data __maybe_unused) { - dso->hit = true; + dso__set_hit(dso); return 0; } @@ -432,7 +432,7 @@ struct dso *dsos__findnew_module_dso(struct dsos *dsos, dso__set_basename(dso); dso__set_module_info(dso, m, machine); dso__set_long_name(dso, strdup(filename), true); - dso->kernel = DSO_SPACE__KERNEL; + dso__set_kernel(dso, DSO_SPACE__KERNEL); __dsos__add(dsos, dso); up_write(&dsos->lock); @@ -455,8 +455,8 @@ static int dsos__find_kernel_dso_cb(struct dso *dso, void *data) * Therefore, we pass PERF_RECORD_MISC_CPUMODE_UNKNOWN. * is_kernel_module() treats it as a kernel cpumode. */ - if (!dso->kernel || - is_kernel_module(dso->long_name, PERF_RECORD_MISC_CPUMODE_UNKNOWN)) + if (!dso__kernel(dso) || + is_kernel_module(dso__long_name(dso), PERF_RECORD_MISC_CPUMODE_UNKNOWN)) return 0; *res = dso__get(dso); diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 198903157f9e..f32f9abf6344 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -726,7 +726,7 @@ int machine__resolve(struct machine *machine, struct addr_location *al, dso = al->map ? map__dso(al->map) : NULL; dump_printf(" ...... dso: %s\n", dso - ? dso->long_name + ? dso__long_name(dso) : (al->level == 'H' ? "[hypervisor]" : "")); if (thread__is_filtered(thread)) @@ -750,10 +750,10 @@ int machine__resolve(struct machine *machine, struct addr_location *al, if (al->map) { if (symbol_conf.dso_list && (!dso || !(strlist__has_entry(symbol_conf.dso_list, - dso->short_name) || - (dso->short_name != dso->long_name && + dso__short_name(dso)) || + (dso__short_name(dso) != dso__long_name(dso) && strlist__has_entry(symbol_conf.dso_list, - dso->long_name))))) { + dso__long_name(dso)))))) { al->filtered |= (1 << HIST_FILTER__DSO); } diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3fe28edc3d01..55e9553861d0 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -2308,7 +2308,7 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev, build_id__init(&bid, bev->data, size); dso__set_build_id(dso, &bid); - dso->header_build_id = 1; + dso__set_header_build_id(dso, true); if (dso_space != DSO_SPACE__USER) { struct kmod_path m = { .name = NULL, }; @@ -2316,13 +2316,13 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev, if (!kmod_path__parse_name(&m, filename) && m.kmod) dso__set_module_info(dso, &m, machine); - dso->kernel = dso_space; + dso__set_kernel(dso, dso_space); free(m.name); } - build_id__sprintf(&dso->bid, sbuild_id); + build_id__sprintf(dso__bid(dso), sbuild_id); pr_debug("build id event received for %s: %s [%zu]\n", - dso->long_name, sbuild_id, size); + dso__long_name(dso), sbuild_id, size); dso__put(dso); } diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0888b7163b7c..a9eef8b5aff0 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2128,7 +2128,7 @@ static bool hists__filter_entry_by_dso(struct hists *hists, struct hist_entry *he) { if (hists->dso_filter != NULL && - (he->ms.map == NULL || map__dso(he->ms.map) != hists->dso_filter)) { + (he->ms.map == NULL || !RC_CHK_EQUAL(map__dso(he->ms.map), hists->dso_filter))) { he->filtered |= (1 << HIST_FILTER__DSO); return true; } @@ -2808,7 +2808,7 @@ int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool sh } if (dso) printed += scnprintf(bf + printed, size - printed, - ", DSO: %s", dso->short_name); + ", DSO: %s", dso__short_name(dso)); if (socket_id > -1) printed += scnprintf(bf + printed, size - printed, ", Processor Socket: %d", socket_id); diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index f38893e0b036..04a291562b14 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -598,15 +598,15 @@ static struct auxtrace_cache *intel_pt_cache(struct dso *dso, struct auxtrace_cache *c; unsigned int bits; - if (dso->auxtrace_cache) - return dso->auxtrace_cache; + if (dso__auxtrace_cache(dso)) + return dso__auxtrace_cache(dso); bits = intel_pt_cache_size(dso, machine); /* Ignoring cache creation failure */ c = auxtrace_cache__new(bits, sizeof(struct intel_pt_cache_entry), 200); - dso->auxtrace_cache = c; + dso__set_auxtrace_cache(dso, c); return c; } @@ -650,7 +650,7 @@ intel_pt_cache_lookup(struct dso *dso, struct machine *machine, u64 offset) if (!c) return NULL; - return auxtrace_cache__lookup(dso->auxtrace_cache, offset); + return auxtrace_cache__lookup(dso__auxtrace_cache(dso), offset); } static void intel_pt_cache_invalidate(struct dso *dso, struct machine *machine, @@ -661,7 +661,7 @@ static void intel_pt_cache_invalidate(struct dso *dso, struct machine *machine, if (!c) return; - auxtrace_cache__remove(dso->auxtrace_cache, offset); + auxtrace_cache__remove(dso__auxtrace_cache(dso), offset); } static inline bool intel_pt_guest_kernel_ip(uint64_t ip) @@ -820,8 +820,8 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, } dso = map__dso(al.map); - if (dso->data.status == DSO_DATA_STATUS_ERROR && - dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE)) { + if (dso__data(dso)->status == DSO_DATA_STATUS_ERROR && + dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE)) { ret = -ENOENT; goto out_ret; } @@ -854,7 +854,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, /* Load maps to ensure dso->is_64_bit has been updated */ map__load(al.map); - x86_64 = dso->is_64_bit; + x86_64 = dso__is_64_bit(dso); while (1) { len = dso__data_read_offset(dso, machine, @@ -1008,7 +1008,7 @@ static int __intel_pt_pgd_ip(uint64_t ip, void *data) offset = map__map_ip(al.map, ip); - res = intel_pt_match_pgd_ip(ptq->pt, ip, offset, map__dso(al.map)->long_name); + res = intel_pt_match_pgd_ip(ptq->pt, ip, offset, dso__long_name(map__dso(al.map))); addr_location__exit(&al); return res; } @@ -3416,7 +3416,7 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event) } dso = map__dso(al.map); - if (!dso || !dso->auxtrace_cache) + if (!dso || !dso__auxtrace_cache(dso)) continue; offset = map__map_ip(al.map, addr); @@ -3436,7 +3436,7 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event) } else { intel_pt_cache_invalidate(dso, machine, offset); intel_pt_log("Invalidated instruction cache for %s at %#"PRIx64"\n", - dso->long_name, addr); + dso__long_name(dso), addr); } } out: diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 0210c10e616b..49b8ccd5affe 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -693,7 +693,7 @@ static int machine__process_ksymbol_register(struct machine *machine, err = -ENOMEM; goto out; } - dso->kernel = DSO_SPACE__KERNEL; + dso__set_kernel(dso, DSO_SPACE__KERNEL); map = map__new2(0, dso); dso__put(dso); if (!map) { @@ -701,8 +701,8 @@ static int machine__process_ksymbol_register(struct machine *machine, goto out; } if (event->ksymbol.ksym_type == PERF_RECORD_KSYMBOL_TYPE_OOL) { - dso->binary_type = DSO_BINARY_TYPE__OOL; - dso->data.file_size = event->ksymbol.len; + dso__set_binary_type(dso, DSO_BINARY_TYPE__OOL); + dso__data(dso)->file_size = event->ksymbol.len; dso__set_loaded(dso); } @@ -717,7 +717,7 @@ static int machine__process_ksymbol_register(struct machine *machine, dso__set_loaded(dso); if (is_bpf_image(event->ksymbol.name)) { - dso->binary_type = DSO_BINARY_TYPE__BPF_IMAGE; + dso__set_binary_type(dso, DSO_BINARY_TYPE__BPF_IMAGE); dso__set_long_name(dso, "", false); } } else { @@ -887,17 +887,17 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp) size_t printed = 0; struct dso *kdso = machine__kernel_dso(machine); - if (kdso->has_build_id) { + if (dso__has_build_id(kdso)) { char filename[PATH_MAX]; - if (dso__build_id_filename(kdso, filename, sizeof(filename), - false)) + + if (dso__build_id_filename(kdso, filename, sizeof(filename), false)) printed += fprintf(fp, "[0] %s\n", filename); } - for (i = 0; i < vmlinux_path__nr_entries; ++i) - printed += fprintf(fp, "[%d] %s\n", - i + kdso->has_build_id, vmlinux_path[i]); - + for (i = 0; i < vmlinux_path__nr_entries; ++i) { + printed += fprintf(fp, "[%d] %s\n", i + dso__has_build_id(kdso), + vmlinux_path[i]); + } return printed; } @@ -947,7 +947,7 @@ static struct dso *machine__get_kernel(struct machine *machine) DSO_SPACE__KERNEL_GUEST); } - if (kernel != NULL && (!kernel->has_build_id)) + if (kernel != NULL && (!dso__has_build_id(kernel))) dso__read_running_kernel_build_id(kernel, machine); return kernel; @@ -1312,8 +1312,8 @@ static char *get_kernel_version(const char *root_dir) static bool is_kmod_dso(struct dso *dso) { - return dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE || - dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE; + return dso__symtab_type(dso) == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE || + dso__symtab_type(dso) == DSO_BINARY_TYPE__GUEST_KMODULE; } static int maps__set_module_path(struct maps *maps, const char *path, struct kmod_path *m) @@ -1340,8 +1340,8 @@ static int maps__set_module_path(struct maps *maps, const char *path, struct kmo * we need to update the symtab_type if needed. */ if (m->comp && is_kmod_dso(dso)) { - dso->symtab_type++; - dso->comp = m->comp; + dso__set_symtab_type(dso, dso__symtab_type(dso)); + dso__set_comp(dso, m->comp); } map__put(map); return 0; @@ -1642,13 +1642,13 @@ static int machine__process_kernel_mmap_event(struct machine *machine, if (kernel == NULL) goto out_problem; - kernel->kernel = dso_space; + dso__set_kernel(kernel, dso_space); if (__machine__create_kernel_maps(machine, kernel) < 0) { dso__put(kernel); goto out_problem; } - if (strstr(kernel->long_name, "vmlinux")) + if (strstr(dso__long_name(kernel), "vmlinux")) dso__set_short_name(kernel, "[kernel.vmlinux]", false); if (machine__update_kernel_mmap(machine, xm->start, xm->end) < 0) { @@ -2030,14 +2030,14 @@ static char *callchain_srcline(struct map_symbol *ms, u64 ip) return srcline; dso = map__dso(map); - srcline = srcline__tree_find(&dso->srclines, ip); + srcline = srcline__tree_find(dso__srclines(dso), ip); if (!srcline) { bool show_sym = false; bool show_addr = callchain_param.key == CCKEY_ADDRESS; srcline = get_srcline(dso, map__rip_2objdump(map, ip), ms->sym, show_sym, show_addr, ip); - srcline__tree_insert(&dso->srclines, ip, srcline); + srcline__tree_insert(dso__srclines(dso), ip, srcline); } return srcline; @@ -2835,12 +2835,12 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms addr = map__rip_2objdump(map, addr); dso = map__dso(map); - inline_node = inlines__tree_find(&dso->inlined_nodes, addr); + inline_node = inlines__tree_find(dso__inlined_nodes(dso), addr); if (!inline_node) { inline_node = dso__parse_addr_inlines(dso, addr, sym); if (!inline_node) return ret; - inlines__tree_insert(&dso->inlined_nodes, inline_node); + inlines__tree_insert(dso__inlined_nodes(dso), inline_node); } ilist_ms = (struct map_symbol) { @@ -3129,7 +3129,7 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch if (sym == NULL) return NULL; - *modp = __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NULL; + *modp = __map__is_kmodule(map) ? (char *)dso__short_name(map__dso(map)) : NULL; *addrp = map__unmap_ip(map, sym->start); return sym->name; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 7c1fff9e413d..14fb8cf65b13 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -168,7 +168,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, if (dso == NULL) goto out_delete; - assert(!dso->kernel); + assert(!dso__kernel(dso)); map__init(result, start, start + len, pgoff, dso); if (anon || no_dso) { @@ -182,10 +182,9 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, if (!(prot & PROT_EXEC)) dso__set_loaded(dso); } - mutex_lock(&dso->lock); - nsinfo__put(dso->nsinfo); - dso->nsinfo = nsi; - mutex_unlock(&dso->lock); + mutex_lock(dso__lock(dso)); + dso__set_nsinfo(dso, nsi); + mutex_unlock(dso__lock(dso)); if (build_id__is_defined(bid)) { dso__set_build_id(dso, bid); @@ -197,9 +196,9 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, * have it missing. */ header_bid_dso = dsos__find(&machine->dsos, filename, false); - if (header_bid_dso && header_bid_dso->header_build_id) { - dso__set_build_id(dso, &header_bid_dso->bid); - dso->header_build_id = 1; + if (header_bid_dso && dso__header_build_id(header_bid_dso)) { + dso__set_build_id(dso, dso__bid(header_bid_dso)); + dso__set_header_build_id(dso, 1); } } dso__put(dso); @@ -221,7 +220,7 @@ struct map *map__new2(u64 start, struct dso *dso) struct map *result; RC_STRUCT(map) *map; - map = calloc(1, sizeof(*map) + (dso->kernel ? sizeof(struct kmap) : 0)); + map = calloc(1, sizeof(*map) + (dso__kernel(dso) ? sizeof(struct kmap) : 0)); if (ADD_RC_CHK(result, map)) { /* * ->end will be filled after we load all the symbols @@ -234,7 +233,7 @@ struct map *map__new2(u64 start, struct dso *dso) bool __map__is_kernel(const struct map *map) { - if (!map__dso(map)->kernel) + if (!dso__kernel(map__dso(map))) return false; return machine__kernel_map(maps__machine(map__kmaps((struct map *)map))) == map; } @@ -251,7 +250,7 @@ bool __map__is_bpf_prog(const struct map *map) const char *name; struct dso *dso = map__dso(map); - if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) return true; /* @@ -259,7 +258,7 @@ bool __map__is_bpf_prog(const struct map *map) * type of DSO_BINARY_TYPE__BPF_PROG_INFO. In such cases, we can * guess the type based on name. */ - name = dso->short_name; + name = dso__short_name(dso); return name && (strstr(name, "bpf_prog_") == name); } @@ -268,7 +267,7 @@ bool __map__is_bpf_image(const struct map *map) const char *name; struct dso *dso = map__dso(map); - if (dso->binary_type == DSO_BINARY_TYPE__BPF_IMAGE) + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) return true; /* @@ -276,7 +275,7 @@ bool __map__is_bpf_image(const struct map *map) * type of DSO_BINARY_TYPE__BPF_IMAGE. In such cases, we can * guess the type based on name. */ - name = dso->short_name; + name = dso__short_name(dso); return name && is_bpf_image(name); } @@ -284,7 +283,7 @@ bool __map__is_ool(const struct map *map) { const struct dso *dso = map__dso(map); - return dso && dso->binary_type == DSO_BINARY_TYPE__OOL; + return dso && dso__binary_type(dso) == DSO_BINARY_TYPE__OOL; } bool map__has_symbols(const struct map *map) @@ -315,7 +314,7 @@ void map__put(struct map *map) void map__fixup_start(struct map *map) { struct dso *dso = map__dso(map); - struct rb_root_cached *symbols = &dso->symbols; + struct rb_root_cached *symbols = dso__symbols(dso); struct rb_node *nd = rb_first_cached(symbols); if (nd != NULL) { @@ -328,7 +327,7 @@ void map__fixup_start(struct map *map) void map__fixup_end(struct map *map) { struct dso *dso = map__dso(map); - struct rb_root_cached *symbols = &dso->symbols; + struct rb_root_cached *symbols = dso__symbols(dso); struct rb_node *nd = rb_last(&symbols->rb_root); if (nd != NULL) { @@ -342,7 +341,7 @@ void map__fixup_end(struct map *map) int map__load(struct map *map) { struct dso *dso = map__dso(map); - const char *name = dso->long_name; + const char *name = dso__long_name(dso); int nr; if (dso__loaded(dso)) @@ -350,10 +349,10 @@ int map__load(struct map *map) nr = dso__load(dso, map); if (nr < 0) { - if (dso->has_build_id) { + if (dso__has_build_id(dso)) { char sbuild_id[SBUILD_ID_SIZE]; - build_id__sprintf(&dso->bid, sbuild_id); + build_id__sprintf(dso__bid(dso), sbuild_id); pr_debug("%s with build id %s not found", name, sbuild_id); } else pr_debug("Failed to open %s", name); @@ -415,7 +414,7 @@ struct map *map__clone(struct map *from) size_t size = sizeof(RC_STRUCT(map)); struct dso *dso = map__dso(from); - if (dso && dso->kernel) + if (dso && dso__kernel(dso)) size += sizeof(struct kmap); map = memdup(RC_CHK_ACCESS(from), size); @@ -432,14 +431,14 @@ size_t map__fprintf(struct map *map, FILE *fp) const struct dso *dso = map__dso(map); return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", - map__start(map), map__end(map), map__pgoff(map), dso->name); + map__start(map), map__end(map), map__pgoff(map), dso__name(dso)); } static bool prefer_dso_long_name(const struct dso *dso, bool print_off) { - return dso->long_name && + return dso__long_name(dso) && (symbol_conf.show_kernel_path || - (print_off && (dso->name[0] == '[' || dso__is_kcore(dso)))); + (print_off && (dso__name(dso)[0] == '[' || dso__is_kcore(dso)))); } static size_t __map__fprintf_dsoname(struct map *map, bool print_off, FILE *fp) @@ -450,9 +449,9 @@ static size_t __map__fprintf_dsoname(struct map *map, bool print_off, FILE *fp) if (dso) { if (prefer_dso_long_name(dso, print_off)) - dsoname = dso->long_name; + dsoname = dso__long_name(dso); else - dsoname = dso->name; + dsoname = dso__name(dso); } if (symbol_conf.pad_output_len_dso) { @@ -545,18 +544,18 @@ u64 map__rip_2objdump(struct map *map, u64 rip) } } - if (!dso->adjust_symbols) + if (!dso__adjust_symbols(dso)) return rip; - if (dso->rel) + if (dso__rel(dso)) return rip - map__pgoff(map); /* * kernel modules also have DSO_TYPE_USER in dso->kernel, * but all kernel modules are ET_REL, so won't get here. */ - if (dso->kernel == DSO_SPACE__USER) - return rip + dso->text_offset; + if (dso__kernel(dso) == DSO_SPACE__USER) + return rip + dso__text_offset(dso); return map__unmap_ip(map, rip) - map__reloc(map); } @@ -577,18 +576,18 @@ u64 map__objdump_2mem(struct map *map, u64 ip) { const struct dso *dso = map__dso(map); - if (!dso->adjust_symbols) + if (!dso__adjust_symbols(dso)) return map__unmap_ip(map, ip); - if (dso->rel) + if (dso__rel(dso)) return map__unmap_ip(map, ip + map__pgoff(map)); /* * kernel modules also have DSO_TYPE_USER in dso->kernel, * but all kernel modules are ET_REL, so won't get here. */ - if (dso->kernel == DSO_SPACE__USER) - return map__unmap_ip(map, ip - dso->text_offset); + if (dso__kernel(dso) == DSO_SPACE__USER) + return map__unmap_ip(map, ip - dso__text_offset(dso)); return ip + map__reloc(map); } @@ -604,7 +603,7 @@ struct kmap *__map__kmap(struct map *map) { const struct dso *dso = map__dso(map); - if (!dso || !dso->kernel) + if (!dso || !dso__kernel(dso)) return NULL; return (struct kmap *)(&RC_CHK_ACCESS(map)[1]); } diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index d5db1f284dad..a00d41da572d 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -76,7 +76,7 @@ static void check_invariants(const struct maps *maps __maybe_unused) /* Expect at least 1 reference count. */ assert(refcount_read(map__refcnt(map)) > 0); - if (map__dso(map) && map__dso(map)->kernel) + if (map__dso(map) && dso__kernel(map__dso(map))) assert(RC_CHK_EQUAL(map__kmap(map)->kmaps, maps)); if (i > 0) { @@ -346,7 +346,7 @@ static int map__strcmp(const void *a, const void *b) const struct map *map_b = *(const struct map * const *)b; const struct dso *dso_a = map__dso(map_a); const struct dso *dso_b = map__dso(map_b); - int ret = strcmp(dso_a->short_name, dso_b->short_name); + int ret = strcmp(dso__short_name(dso_a), dso__short_name(dso_b)); if (ret == 0 && RC_CHK_ACCESS(map_a) != RC_CHK_ACCESS(map_b)) { /* Ensure distinct but name equal maps have an order. */ @@ -485,7 +485,7 @@ static int __maps__insert(struct maps *maps, struct map *new) } if (map__end(new) < map__start(new)) RC_CHK_ACCESS(maps)->ends_broken = true; - if (dso && dso->kernel) { + if (dso && dso__kernel(dso)) { struct kmap *kmap = map__kmap(new); if (kmap) @@ -760,7 +760,7 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new) if (use_browser) { pr_debug("overlapping maps in %s (disable tui for more info)\n", - map__dso(new)->name); + dso__name(map__dso(new))); } else if (verbose >= 2) { pr_debug("overlapping maps:\n"); map__fprintf(new, fp); @@ -981,7 +981,7 @@ static int map__strcmp_name(const void *name, const void *b) { const struct dso *dso = map__dso(*(const struct map **)b); - return strcmp(name, dso->short_name); + return strcmp(name, dso__short_name(dso)); } struct map *maps__find_by_name(struct maps *maps, const char *name) @@ -1000,7 +1000,7 @@ struct map *maps__find_by_name(struct maps *maps, const char *name) if (i < maps__nr_maps(maps) && maps__maps_by_name(maps)) { struct dso *dso = map__dso(maps__maps_by_name(maps)[i]); - if (dso && strcmp(dso->short_name, name) == 0) { + if (dso && strcmp(dso__short_name(dso), name) == 0) { result = map__get(maps__maps_by_name(maps)[i]); done = true; } @@ -1037,7 +1037,7 @@ struct map *maps__find_by_name(struct maps *maps, const char *name) struct map *pos = maps_by_address[i]; struct dso *dso = map__dso(pos); - if (dso && strcmp(dso->short_name, name) == 0) { + if (dso && strcmp(dso__short_name(dso), name) == 0) { result = map__get(pos); break; } diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index be71abe8b9b0..26c084b4a4a6 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -158,8 +158,8 @@ static int kernel_get_module_map_cb(struct map *map, void *data) { struct kernel_get_module_map_cb_args *args = data; struct dso *dso = map__dso(map); - const char *short_name = dso->short_name; /* short_name is "[module]" */ - u16 short_name_len = dso->short_name_len; + const char *short_name = dso__short_name(dso); + u16 short_name_len = dso__short_name_len(dso); if (strncmp(short_name + 1, args->module, short_name_len - 2) == 0 && args->module[short_name_len - 2] == '\0') { @@ -201,10 +201,9 @@ struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user) map = dso__new_map(target); dso = map ? map__dso(map) : NULL; if (dso) { - mutex_lock(&dso->lock); - nsinfo__put(dso->nsinfo); - dso->nsinfo = nsinfo__get(nsi); - mutex_unlock(&dso->lock); + mutex_lock(dso__lock(dso)); + dso__set_nsinfo(dso, nsinfo__get(nsi)); + mutex_unlock(dso__lock(dso)); } return map; } else { @@ -367,11 +366,11 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) map = machine__kernel_map(host_machine); dso = map__dso(map); - if (!dso->has_build_id) + if (!dso__has_build_id(dso)) dso__read_running_kernel_build_id(dso, host_machine); vmlinux_name = symbol_conf.vmlinux_name; - dso->load_errno = 0; + *dso__load_errno(dso) = 0; if (vmlinux_name) ret = dso__load_vmlinux(dso, map, vmlinux_name, false); else @@ -498,7 +497,7 @@ static struct debuginfo *open_from_debuginfod(struct dso *dso, struct nsinfo *ns if (!c) return NULL; - build_id__sprintf(&dso->bid, sbuild_id); + build_id__sprintf(dso__bid(dso), sbuild_id); fd = debuginfod_find_debuginfo(c, (const unsigned char *)sbuild_id, 0, &path); if (fd >= 0) @@ -541,7 +540,7 @@ static struct debuginfo *open_debuginfo(const char *module, struct nsinfo *nsi, if (!module || !strchr(module, '/')) { err = kernel_get_module_dso(module, &dso); if (err < 0) { - if (!dso || dso->load_errno == 0) { + if (!dso || *dso__load_errno(dso) == 0) { if (!str_error_r(-err, reason, STRERR_BUFSIZE)) strcpy(reason, "(unknown)"); } else @@ -558,7 +557,7 @@ static struct debuginfo *open_debuginfo(const char *module, struct nsinfo *nsi, } return NULL; } - path = dso->long_name; + path = dso__long_name(dso); } nsinfo__mountns_enter(nsi, &nsc); ret = debuginfo__new(path); @@ -3796,8 +3795,8 @@ int show_available_funcs(const char *target, struct nsinfo *nsi, /* Show all (filtered) symbols */ setup_pager(); - for (size_t i = 0; i < dso->symbol_names_len; i++) { - struct symbol *pos = dso->symbol_names[i]; + for (size_t i = 0; i < dso__symbol_names_len(dso); i++) { + struct symbol *pos = dso__symbol_names(dso)[i]; if (strfilter__compare(_filter, pos->name)) printf("%s\n", pos->name); diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index b072ac5d3bc2..e16257d5ab2c 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -320,10 +320,10 @@ static SV *perl_process_callchain(struct perf_sample *sample, const char *dsoname = "[unknown]"; if (dso) { - if (symbol_conf.show_kernel_path && dso->long_name) - dsoname = dso->long_name; + if (symbol_conf.show_kernel_path && dso__long_name(dso)) + dsoname = dso__long_name(dso); else - dsoname = dso->name; + dsoname = dso__name(dso); } if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) { hv_undef(elem); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 860e1837ba96..9cc2372c93c3 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -393,10 +393,10 @@ static const char *get_dsoname(struct map *map) struct dso *dso = map ? map__dso(map) : NULL; if (dso) { - if (symbol_conf.show_kernel_path && dso->long_name) - dsoname = dso->long_name; + if (symbol_conf.show_kernel_path && dso__long_name(dso)) + dsoname = dso__long_name(dso); else - dsoname = dso->name; + dsoname = dso__name(dso); } return dsoname; @@ -799,8 +799,9 @@ static void set_sym_in_dict(PyObject *dict, struct addr_location *al, if (al->map) { struct dso *dso = map__dso(al->map); - pydict_set_item_string_decref(dict, dso_field, _PyUnicode_FromString(dso->name)); - build_id__sprintf(&dso->bid, sbuild_id); + pydict_set_item_string_decref(dict, dso_field, + _PyUnicode_FromString(dso__name(dso))); + build_id__sprintf(dso__bid(dso), sbuild_id); pydict_set_item_string_decref(dict, dso_bid_field, _PyUnicode_FromString(sbuild_id)); pydict_set_item_string_decref(dict, dso_map_start, @@ -1242,14 +1243,14 @@ static int python_export_dso(struct db_export *dbe, struct dso *dso, char sbuild_id[SBUILD_ID_SIZE]; PyObject *t; - build_id__sprintf(&dso->bid, sbuild_id); + build_id__sprintf(dso__bid(dso), sbuild_id); t = tuple_new(5); - tuple_set_d64(t, 0, dso->db_id); + tuple_set_d64(t, 0, dso__db_id(dso)); tuple_set_d64(t, 1, machine->db_id); - tuple_set_string(t, 2, dso->short_name); - tuple_set_string(t, 3, dso->long_name); + tuple_set_string(t, 2, dso__short_name(dso)); + tuple_set_string(t, 3, dso__long_name(dso)); tuple_set_string(t, 4, sbuild_id); call_object(tables->dso_handler, t, "dso_table"); @@ -1269,7 +1270,7 @@ static int python_export_symbol(struct db_export *dbe, struct symbol *sym, t = tuple_new(6); tuple_set_d64(t, 0, *sym_db_id); - tuple_set_d64(t, 1, dso->db_id); + tuple_set_d64(t, 1, dso__db_id(dso)); tuple_set_d64(t, 2, sym->start); tuple_set_d64(t, 3, sym->end); tuple_set_s32(t, 4, sym->binding); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 30254eb63709..87c2ed6051ee 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -239,11 +239,11 @@ static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r) return cmp_null(dso_r, dso_l); if (verbose > 0) { - dso_name_l = dso_l->long_name; - dso_name_r = dso_r->long_name; + dso_name_l = dso__long_name(dso_l); + dso_name_r = dso__long_name(dso_r); } else { - dso_name_l = dso_l->short_name; - dso_name_r = dso_r->short_name; + dso_name_l = dso__short_name(dso_l); + dso_name_r = dso__short_name(dso_r); } return strcmp(dso_name_l, dso_name_r); @@ -262,7 +262,7 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf, const char *dso_name = "[unknown]"; if (dso) - dso_name = verbose > 0 ? dso->long_name : dso->short_name; + dso_name = verbose > 0 ? dso__long_name(dso) : dso__short_name(dso); return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); } @@ -364,7 +364,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms, char o = dso ? dso__symtab_origin(dso) : '!'; u64 rip = ip; - if (dso && dso->kernel && dso->adjust_symbols) + if (dso && dso__kernel(dso) && dso__adjust_symbols(dso)) rip = map__unmap_ip(map, ip); ret += repsep_snprintf(bf, size, "%-#*llx %c ", @@ -1586,8 +1586,8 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right) */ if ((left->cpumode != PERF_RECORD_MISC_KERNEL) && - (!(map__flags(l_map) & MAP_SHARED)) && !l_dso->id.maj && !l_dso->id.min && - !l_dso->id.ino && !l_dso->id.ino_generation) { + (!(map__flags(l_map) & MAP_SHARED)) && !dso__id(l_dso)->maj && !dso__id(l_dso)->min && + !dso__id(l_dso)->ino && !dso__id(l_dso)->ino_generation) { /* userspace anonymous */ if (thread__pid(left->thread) > thread__pid(right->thread)) @@ -1626,7 +1626,8 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf, if ((he->cpumode != PERF_RECORD_MISC_KERNEL) && map && !(map__prot(map) & PROT_EXEC) && (map__flags(map) & MAP_SHARED) && - (dso->id.maj || dso->id.min || dso->id.ino || dso->id.ino_generation)) + (dso__id(dso)->maj || dso__id(dso)->min || dso__id(dso)->ino || + dso__id(dso)->ino_generation)) level = 's'; else if (!map) level = 'X'; diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 034b496df297..7a56b8b0792a 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -27,14 +27,14 @@ bool srcline_full_filename; char *srcline__unknown = (char *)"??:0"; -static const char *dso__name(struct dso *dso) +static const char *srcline_dso_name(struct dso *dso) { const char *dso_name; - if (dso->symsrc_filename) - dso_name = dso->symsrc_filename; + if (dso__symsrc_filename(dso)) + dso_name = dso__symsrc_filename(dso); else - dso_name = dso->long_name; + dso_name = dso__long_name(dso); if (dso_name[0] == '[') return NULL; @@ -636,7 +636,7 @@ static int addr2line(const char *dso_name, u64 addr, struct inline_node *node, struct symbol *sym __maybe_unused) { - struct child_process *a2l = dso->a2l; + struct child_process *a2l = dso__a2l(dso); char *record_function = NULL; char *record_filename = NULL; unsigned int record_line_nr = 0; @@ -653,8 +653,9 @@ static int addr2line(const char *dso_name, u64 addr, if (!filename__has_section(dso_name, ".debug_line")) goto out; - dso->a2l = addr2line_subprocess_init(symbol_conf.addr2line_path, dso_name); - a2l = dso->a2l; + dso__set_a2l(dso, + addr2line_subprocess_init(symbol_conf.addr2line_path, dso_name)); + a2l = dso__a2l(dso); } if (a2l == NULL) { @@ -768,7 +769,7 @@ static int addr2line(const char *dso_name, u64 addr, free(record_function); free(record_filename); if (io.eof) { - dso->a2l = NULL; + dso__set_a2l(dso, NULL); addr2line_subprocess_cleanup(a2l); } return ret; @@ -776,14 +777,14 @@ static int addr2line(const char *dso_name, u64 addr, void dso__free_a2l(struct dso *dso) { - struct child_process *a2l = dso->a2l; + struct child_process *a2l = dso__a2l(dso); if (!a2l) return; addr2line_subprocess_cleanup(a2l); - dso->a2l = NULL; + dso__set_a2l(dso, NULL); } #endif /* HAVE_LIBBFD_SUPPORT */ @@ -821,33 +822,34 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, char *srcline; const char *dso_name; - if (!dso->has_srcline) + if (!dso__has_srcline(dso)) goto out; - dso_name = dso__name(dso); + dso_name = srcline_dso_name(dso); if (dso_name == NULL) - goto out; + goto out_err; if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines, NULL, sym)) - goto out; + goto out_err; srcline = srcline_from_fileline(file, line); free(file); if (!srcline) - goto out; + goto out_err; - dso->a2l_fails = 0; + dso__set_a2l_fails(dso, 0); return srcline; -out: - if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { - dso->has_srcline = 0; +out_err: + dso__set_a2l_fails(dso, dso__a2l_fails(dso) + 1); + if (dso__a2l_fails(dso) > A2L_FAIL_LIMIT) { + dso__set_has_srcline(dso, false); dso__free_a2l(dso); } - +out: if (!show_addr) return (show_sym && sym) ? strndup(sym->name, sym->namelen) : SRCLINE_UNKNOWN; @@ -856,7 +858,7 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", ip - sym->start) < 0) return SRCLINE_UNKNOWN; - } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0) + } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso__short_name(dso), addr) < 0) return SRCLINE_UNKNOWN; return srcline; } @@ -867,22 +869,23 @@ char *get_srcline_split(struct dso *dso, u64 addr, unsigned *line) char *file = NULL; const char *dso_name; - if (!dso->has_srcline) - goto out; + if (!dso__has_srcline(dso)) + return NULL; - dso_name = dso__name(dso); + dso_name = srcline_dso_name(dso); if (dso_name == NULL) - goto out; + goto out_err; if (!addr2line(dso_name, addr, &file, line, dso, true, NULL, NULL)) - goto out; + goto out_err; - dso->a2l_fails = 0; + dso__set_a2l_fails(dso, 0); return file; -out: - if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { - dso->has_srcline = 0; +out_err: + dso__set_a2l_fails(dso, dso__a2l_fails(dso) + 1); + if (dso__a2l_fails(dso) > A2L_FAIL_LIMIT) { + dso__set_has_srcline(dso, false); dso__free_a2l(dso); } @@ -980,7 +983,7 @@ struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr, { const char *dso_name; - dso_name = dso__name(dso); + dso_name = srcline_dso_name(dso); if (dso_name == NULL) return NULL; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 5990e3fabdb5..de73f9fb3fe4 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -311,8 +311,8 @@ static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name) * DWARF DW_compile_unit has this, but we don't always have access * to it... */ - if (!want_demangle(dso->kernel || kmodule)) - return demangled; + if (!want_demangle(dso__kernel(dso) || kmodule)) + return demangled; demangled = cxx_demangle_sym(elf_name, verbose > 0, verbose > 0); if (demangled == NULL) { @@ -469,7 +469,7 @@ static bool get_plt_sizes(struct dso *dso, GElf_Ehdr *ehdr, GElf_Shdr *shdr_plt, } if (*plt_entry_size) return true; - pr_debug("Missing PLT entry size for %s\n", dso->long_name); + pr_debug("Missing PLT entry size for %s\n", dso__long_name(dso)); return false; } @@ -653,7 +653,7 @@ static int dso__synthesize_plt_got_symbols(struct dso *dso, Elf *elf, sym = symbol__new(shdr.sh_offset + i, shdr.sh_entsize, STB_GLOBAL, STT_FUNC, buf); if (!sym) goto out; - symbols__insert(&dso->symbols, sym); + symbols__insert(dso__symbols(dso), sym); } err = 0; out: @@ -707,7 +707,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss) plt_sym = symbol__new(shdr_plt.sh_offset, plt_header_size, STB_GLOBAL, STT_FUNC, ".plt"); if (!plt_sym) goto out_elf_end; - symbols__insert(&dso->symbols, plt_sym); + symbols__insert(dso__symbols(dso), plt_sym); /* Only x86 has .plt.got */ if (machine_is_x86(ehdr.e_machine) && @@ -829,7 +829,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss) goto out_elf_end; plt_offset += plt_entry_size; - symbols__insert(&dso->symbols, f); + symbols__insert(dso__symbols(dso), f); ++nr; } @@ -839,7 +839,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss) if (err == 0) return nr; pr_debug("%s: problems reading %s PLT info.\n", - __func__, dso->long_name); + __func__, dso__long_name(dso)); return 0; } @@ -1174,19 +1174,19 @@ static int dso__swap_init(struct dso *dso, unsigned char eidata) { static unsigned int const endian = 1; - dso->needs_swap = DSO_SWAP__NO; + dso__set_needs_swap(dso, DSO_SWAP__NO); switch (eidata) { case ELFDATA2LSB: /* We are big endian, DSO is little endian. */ if (*(unsigned char const *)&endian != 1) - dso->needs_swap = DSO_SWAP__YES; + dso__set_needs_swap(dso, DSO_SWAP__YES); break; case ELFDATA2MSB: /* We are little endian, DSO is big endian. */ if (*(unsigned char const *)&endian != 0) - dso->needs_swap = DSO_SWAP__YES; + dso__set_needs_swap(dso, DSO_SWAP__YES); break; default: @@ -1237,11 +1237,11 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, if (fd < 0) return -1; - type = dso->symtab_type; + type = dso__symtab_type(dso); } else { fd = open(name, O_RDONLY); if (fd < 0) { - dso->load_errno = errno; + *dso__load_errno(dso) = errno; return -1; } } @@ -1249,37 +1249,37 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); if (elf == NULL) { pr_debug("%s: cannot read %s ELF file.\n", __func__, name); - dso->load_errno = DSO_LOAD_ERRNO__INVALID_ELF; + *dso__load_errno(dso) = DSO_LOAD_ERRNO__INVALID_ELF; goto out_close; } if (gelf_getehdr(elf, &ehdr) == NULL) { - dso->load_errno = DSO_LOAD_ERRNO__INVALID_ELF; + *dso__load_errno(dso) = DSO_LOAD_ERRNO__INVALID_ELF; pr_debug("%s: cannot get elf header.\n", __func__); goto out_elf_end; } if (dso__swap_init(dso, ehdr.e_ident[EI_DATA])) { - dso->load_errno = DSO_LOAD_ERRNO__INTERNAL_ERROR; + *dso__load_errno(dso) = DSO_LOAD_ERRNO__INTERNAL_ERROR; goto out_elf_end; } /* Always reject images with a mismatched build-id: */ - if (dso->has_build_id && !symbol_conf.ignore_vmlinux_buildid) { + if (dso__has_build_id(dso) && !symbol_conf.ignore_vmlinux_buildid) { u8 build_id[BUILD_ID_SIZE]; struct build_id bid; int size; size = elf_read_build_id(elf, build_id, BUILD_ID_SIZE); if (size <= 0) { - dso->load_errno = DSO_LOAD_ERRNO__CANNOT_READ_BUILDID; + *dso__load_errno(dso) = DSO_LOAD_ERRNO__CANNOT_READ_BUILDID; goto out_elf_end; } build_id__init(&bid, build_id, size); if (!dso__build_id_equal(dso, &bid)) { pr_debug("%s: build id mismatch for %s.\n", __func__, name); - dso->load_errno = DSO_LOAD_ERRNO__MISMATCHING_BUILDID; + *dso__load_errno(dso) = DSO_LOAD_ERRNO__MISMATCHING_BUILDID; goto out_elf_end; } } @@ -1304,14 +1304,14 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, if (ss->opdshdr.sh_type != SHT_PROGBITS) ss->opdsec = NULL; - if (dso->kernel == DSO_SPACE__USER) + if (dso__kernel(dso) == DSO_SPACE__USER) ss->adjust_symbols = true; else ss->adjust_symbols = elf__needs_adjust_symbols(ehdr); ss->name = strdup(name); if (!ss->name) { - dso->load_errno = errno; + *dso__load_errno(dso) = errno; goto out_elf_end; } @@ -1378,7 +1378,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, if (adjust_kernel_syms) sym->st_value -= shdr->sh_addr - shdr->sh_offset; - if (strcmp(section_name, (curr_dso->short_name + dso->short_name_len)) == 0) + if (strcmp(section_name, (dso__short_name(curr_dso) + dso__short_name_len(dso))) == 0) return 0; if (strcmp(section_name, ".text") == 0) { @@ -1387,7 +1387,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, * kallsyms and identity maps. Overwrite it to * map to the kernel dso. */ - if (*remap_kernel && dso->kernel && !kmodule) { + if (*remap_kernel && dso__kernel(dso) && !kmodule) { *remap_kernel = false; map__set_start(map, shdr->sh_addr + ref_reloc(kmap)); map__set_end(map, map__start(map) + shdr->sh_size); @@ -1424,7 +1424,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, if (!kmap) return 0; - snprintf(dso_name, sizeof(dso_name), "%s%s", dso->short_name, section_name); + snprintf(dso_name, sizeof(dso_name), "%s%s", dso__short_name(dso), section_name); curr_map = maps__find_by_name(kmaps, dso_name); if (curr_map == NULL) { @@ -1436,17 +1436,17 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, curr_dso = dso__new(dso_name); if (curr_dso == NULL) return -1; - curr_dso->kernel = dso->kernel; - curr_dso->long_name = dso->long_name; - curr_dso->long_name_len = dso->long_name_len; - curr_dso->binary_type = dso->binary_type; - curr_dso->adjust_symbols = dso->adjust_symbols; + dso__set_kernel(curr_dso, dso__kernel(dso)); + RC_CHK_ACCESS(curr_dso)->long_name = dso__long_name(dso); + RC_CHK_ACCESS(curr_dso)->long_name_len = dso__long_name_len(dso); + dso__set_binary_type(curr_dso, dso__binary_type(dso)); + dso__set_adjust_symbols(curr_dso, dso__adjust_symbols(dso)); curr_map = map__new2(start, curr_dso); dso__put(curr_dso); if (curr_map == NULL) return -1; - if (curr_dso->kernel) + if (dso__kernel(curr_dso)) map__kmap(curr_map)->kmaps = kmaps; if (adjust_kernel_syms) { @@ -1456,7 +1456,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, } else { map__set_mapping_type(curr_map, MAPPING_TYPE__IDENTITY); } - curr_dso->symtab_type = dso->symtab_type; + dso__set_symtab_type(curr_dso, dso__symtab_type(dso)); if (maps__insert(kmaps, curr_map)) return -1; /* @@ -1482,7 +1482,7 @@ static int dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, struct symsrc *runtime_ss, int kmodule, int dynsym) { - struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL; + struct kmap *kmap = dso__kernel(dso) ? map__kmap(map) : NULL; struct maps *kmaps = kmap ? map__kmaps(map) : NULL; struct map *curr_map = map; struct dso *curr_dso = dso; @@ -1515,8 +1515,8 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, if (elf_section_by_name(runtime_ss->elf, &runtime_ss->ehdr, &tshdr, ".text", NULL)) { - dso->text_offset = tshdr.sh_addr - tshdr.sh_offset; - dso->text_end = tshdr.sh_offset + tshdr.sh_size; + dso__set_text_offset(dso, tshdr.sh_addr - tshdr.sh_offset); + dso__set_text_end(dso, tshdr.sh_offset + tshdr.sh_size); } if (runtime_ss->opdsec) @@ -1575,16 +1575,16 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, * attempted to prelink vdso to its virtual address. */ if (dso__is_vdso(dso)) - map__set_reloc(map, map__start(map) - dso->text_offset); + map__set_reloc(map, map__start(map) - dso__text_offset(dso)); - dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap); + dso__set_adjust_symbols(dso, runtime_ss->adjust_symbols || ref_reloc(kmap)); /* * Initial kernel and module mappings do not map to the dso. * Flag the fixups. */ - if (dso->kernel) { + if (dso__kernel(dso)) { remap_kernel = true; - adjust_kernel_syms = dso->adjust_symbols; + adjust_kernel_syms = dso__adjust_symbols(dso); } elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { struct symbol *f; @@ -1673,7 +1673,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, (sym.st_value & 1)) --sym.st_value; - if (dso->kernel) { + if (dso__kernel(dso)) { if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map, section_name, adjust_kernel_syms, kmodule, &remap_kernel)) goto out_elf_end; @@ -1721,7 +1721,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, arch__sym_update(f, &sym); - __symbols__insert(&curr_dso->symbols, f, dso->kernel); + __symbols__insert(dso__symbols(curr_dso), f, dso__kernel(dso)); nr++; } @@ -1729,8 +1729,8 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, * For misannotated, zeroed, ASM function sizes. */ if (nr > 0) { - symbols__fixup_end(&dso->symbols, false); - symbols__fixup_duplicate(&dso->symbols); + symbols__fixup_end(dso__symbols(dso), false); + symbols__fixup_duplicate(dso__symbols(dso)); if (kmap) { /* * We need to fixup this here too because we create new @@ -1750,16 +1750,16 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, int nr = 0; int err = -1; - dso->symtab_type = syms_ss->type; - dso->is_64_bit = syms_ss->is_64_bit; - dso->rel = syms_ss->ehdr.e_type == ET_REL; + dso__set_symtab_type(dso, syms_ss->type); + dso__set_is_64_bit(dso, syms_ss->is_64_bit); + dso__set_rel(dso, syms_ss->ehdr.e_type == ET_REL); /* * Modules may already have symbols from kallsyms, but those symbols * have the wrong values for the dso maps, so remove them. */ if (kmodule && syms_ss->symtab) - symbols__delete(&dso->symbols); + symbols__delete(dso__symbols(dso)); if (!syms_ss->symtab) { /* @@ -1767,7 +1767,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, * to using kallsyms. The vmlinux runtime symbols aren't * of much use. */ - if (dso->kernel) + if (dso__kernel(dso)) return err; } else { err = dso__load_sym_internal(dso, map, syms_ss, runtime_ss, diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 35975189999b..7a065a075a32 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -515,52 +515,52 @@ static struct symbol *symbols__find_by_name(struct symbol *symbols[], void dso__reset_find_symbol_cache(struct dso *dso) { - dso->last_find_result.addr = 0; - dso->last_find_result.symbol = NULL; + dso__set_last_find_result_addr(dso, 0); + dso__set_last_find_result_symbol(dso, NULL); } void dso__insert_symbol(struct dso *dso, struct symbol *sym) { - __symbols__insert(&dso->symbols, sym, dso->kernel); + __symbols__insert(dso__symbols(dso), sym, dso__kernel(dso)); /* update the symbol cache if necessary */ - if (dso->last_find_result.addr >= sym->start && - (dso->last_find_result.addr < sym->end || + if (dso__last_find_result_addr(dso) >= sym->start && + (dso__last_find_result_addr(dso) < sym->end || sym->start == sym->end)) { - dso->last_find_result.symbol = sym; + dso__set_last_find_result_symbol(dso, sym); } } void dso__delete_symbol(struct dso *dso, struct symbol *sym) { - rb_erase_cached(&sym->rb_node, &dso->symbols); + rb_erase_cached(&sym->rb_node, dso__symbols(dso)); symbol__delete(sym); dso__reset_find_symbol_cache(dso); } struct symbol *dso__find_symbol(struct dso *dso, u64 addr) { - if (dso->last_find_result.addr != addr || dso->last_find_result.symbol == NULL) { - dso->last_find_result.addr = addr; - dso->last_find_result.symbol = symbols__find(&dso->symbols, addr); + if (dso__last_find_result_addr(dso) != addr || dso__last_find_result_symbol(dso) == NULL) { + dso__set_last_find_result_addr(dso, addr); + dso__set_last_find_result_symbol(dso, symbols__find(dso__symbols(dso), addr)); } - return dso->last_find_result.symbol; + return dso__last_find_result_symbol(dso); } struct symbol *dso__find_symbol_nocache(struct dso *dso, u64 addr) { - return symbols__find(&dso->symbols, addr); + return symbols__find(dso__symbols(dso), addr); } struct symbol *dso__first_symbol(struct dso *dso) { - return symbols__first(&dso->symbols); + return symbols__first(dso__symbols(dso)); } struct symbol *dso__last_symbol(struct dso *dso) { - return symbols__last(&dso->symbols); + return symbols__last(dso__symbols(dso)); } struct symbol *dso__next_symbol(struct symbol *sym) @@ -570,11 +570,11 @@ struct symbol *dso__next_symbol(struct symbol *sym) struct symbol *dso__next_symbol_by_name(struct dso *dso, size_t *idx) { - if (*idx + 1 >= dso->symbol_names_len) + if (*idx + 1 >= dso__symbol_names_len(dso)) return NULL; ++*idx; - return dso->symbol_names[*idx]; + return dso__symbol_names(dso)[*idx]; } /* @@ -582,27 +582,29 @@ struct symbol *dso__next_symbol_by_name(struct dso *dso, size_t *idx) */ struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name, size_t *idx) { - struct symbol *s = symbols__find_by_name(dso->symbol_names, dso->symbol_names_len, - name, SYMBOL_TAG_INCLUDE__NONE, idx); - if (!s) - s = symbols__find_by_name(dso->symbol_names, dso->symbol_names_len, - name, SYMBOL_TAG_INCLUDE__DEFAULT_ONLY, idx); + struct symbol *s = symbols__find_by_name(dso__symbol_names(dso), + dso__symbol_names_len(dso), + name, SYMBOL_TAG_INCLUDE__NONE, idx); + if (!s) { + s = symbols__find_by_name(dso__symbol_names(dso), dso__symbol_names_len(dso), + name, SYMBOL_TAG_INCLUDE__DEFAULT_ONLY, idx); + } return s; } void dso__sort_by_name(struct dso *dso) { - mutex_lock(&dso->lock); + mutex_lock(dso__lock(dso)); if (!dso__sorted_by_name(dso)) { size_t len; - dso->symbol_names = symbols__sort_by_name(&dso->symbols, &len); - if (dso->symbol_names) { - dso->symbol_names_len = len; + dso__set_symbol_names(dso, symbols__sort_by_name(dso__symbols(dso), &len)); + if (dso__symbol_names(dso)) { + dso__set_symbol_names_len(dso, len); dso__set_sorted_by_name(dso); } } - mutex_unlock(&dso->lock); + mutex_unlock(dso__lock(dso)); } /* @@ -729,7 +731,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name, { struct symbol *sym; struct dso *dso = arg; - struct rb_root_cached *root = &dso->symbols; + struct rb_root_cached *root = dso__symbols(dso); if (!symbol_type__filter(type)) return 0; @@ -769,8 +771,8 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) { struct symbol *pos; int count = 0; - struct rb_root_cached old_root = dso->symbols; - struct rb_root_cached *root = &dso->symbols; + struct rb_root_cached *root = dso__symbols(dso); + struct rb_root_cached old_root = *root; struct rb_node *next = rb_first_cached(root); if (!kmaps) @@ -804,13 +806,13 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) pos->end = map__end(curr_map); if (pos->end) pos->end -= map__start(curr_map) - map__pgoff(curr_map); - symbols__insert(&curr_map_dso->symbols, pos); + symbols__insert(dso__symbols(curr_map_dso), pos); ++count; map__put(curr_map); } /* Symbols have been adjusted */ - dso->adjust_symbols = 1; + dso__set_adjust_symbols(dso, true); return count; } @@ -827,7 +829,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, struct map *curr_map = map__get(initial_map); struct symbol *pos; int count = 0, moved = 0; - struct rb_root_cached *root = &dso->symbols; + struct rb_root_cached *root = dso__symbols(dso); struct rb_node *next = rb_first_cached(root); int kernel_range = 0; bool x86_64; @@ -854,9 +856,9 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, *module++ = '\0'; curr_map_dso = map__dso(curr_map); - if (strcmp(curr_map_dso->short_name, module)) { + if (strcmp(dso__short_name(curr_map_dso), module)) { if (!RC_CHK_EQUAL(curr_map, initial_map) && - dso->kernel == DSO_SPACE__KERNEL_GUEST && + dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(machine)) { /* * We assume all symbols of a module are @@ -879,7 +881,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, goto discard_symbol; } curr_map_dso = map__dso(curr_map); - if (curr_map_dso->loaded && + if (dso__loaded(curr_map_dso) && !machine__is_default_guest(machine)) goto discard_symbol; } @@ -915,7 +917,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, goto add_symbol; } - if (dso->kernel == DSO_SPACE__KERNEL_GUEST) + if (dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST) snprintf(dso_name, sizeof(dso_name), "[guest.kernel].%d", kernel_range++); @@ -929,7 +931,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, if (ndso == NULL) return -1; - ndso->kernel = dso->kernel; + dso__set_kernel(ndso, dso__kernel(dso)); curr_map = map__new2(pos->start, ndso); if (curr_map == NULL) { @@ -954,7 +956,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, struct dso *curr_map_dso = map__dso(curr_map); rb_erase_cached(&pos->rb_node, root); - symbols__insert(&curr_map_dso->symbols, pos); + symbols__insert(dso__symbols(curr_map_dso), pos); ++moved; } else ++count; @@ -966,7 +968,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, } if (!RC_CHK_EQUAL(curr_map, initial_map) && - dso->kernel == DSO_SPACE__KERNEL_GUEST && + dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(maps__machine(kmaps))) { dso__set_loaded(map__dso(curr_map)); } @@ -1140,7 +1142,7 @@ static int do_validate_kcore_modules_cb(struct map *old_map, void *data) dso = map__dso(old_map); /* Module must be in memory at the same address */ - mi = find_module(dso->short_name, modules); + mi = find_module(dso__short_name(dso), modules); if (!mi || mi->start != map__start(old_map)) return -EINVAL; @@ -1309,7 +1311,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map, &is_64_bit); if (err) goto out_err; - dso->is_64_bit = is_64_bit; + dso__set_is_64_bit(dso, is_64_bit); if (list_empty(&md.maps)) { err = -EINVAL; @@ -1401,10 +1403,10 @@ static int dso__load_kcore(struct dso *dso, struct map *map, * Set the data type and long name so that kcore can be read via * dso__data_read_addr(). */ - if (dso->kernel == DSO_SPACE__KERNEL_GUEST) - dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE; + if (dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST) + dso__set_binary_type(dso, DSO_BINARY_TYPE__GUEST_KCORE); else - dso->binary_type = DSO_BINARY_TYPE__KCORE; + dso__set_binary_type(dso, DSO_BINARY_TYPE__KCORE); dso__set_long_name(dso, strdup(kcore_filename), true); close(fd); @@ -1465,13 +1467,13 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename, if (kallsyms__delta(kmap, filename, &delta)) return -1; - symbols__fixup_end(&dso->symbols, true); - symbols__fixup_duplicate(&dso->symbols); + symbols__fixup_end(dso__symbols(dso), true); + symbols__fixup_duplicate(dso__symbols(dso)); - if (dso->kernel == DSO_SPACE__KERNEL_GUEST) - dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; + if (dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST) + dso__set_symtab_type(dso, DSO_BINARY_TYPE__GUEST_KALLSYMS); else - dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS; + dso__set_symtab_type(dso, DSO_BINARY_TYPE__KALLSYMS); if (!no_kcore && !dso__load_kcore(dso, map, filename)) return maps__split_kallsyms_for_kcore(kmap->kmaps, dso); @@ -1527,7 +1529,7 @@ static int dso__load_perf_map(const char *map_path, struct dso *dso) if (sym == NULL) goto out_delete_line; - symbols__insert(&dso->symbols, sym); + symbols__insert(dso__symbols(dso), sym); nr_syms++; } @@ -1653,15 +1655,15 @@ int dso__load_bfd_symbols(struct dso *dso, const char *debugfile) if (!symbol) goto out_free; - symbols__insert(&dso->symbols, symbol); + symbols__insert(dso__symbols(dso), symbol); } #ifdef bfd_get_section #undef bfd_asymbol_section #endif - symbols__fixup_end(&dso->symbols, false); - symbols__fixup_duplicate(&dso->symbols); - dso->adjust_symbols = 1; + symbols__fixup_end(dso__symbols(dso), false); + symbols__fixup_duplicate(dso__symbols(dso)); + dso__set_adjust_symbols(dso); err = 0; out_free: @@ -1684,17 +1686,17 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO: case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: - return !kmod && dso->kernel == DSO_SPACE__USER; + return !kmod && dso__kernel(dso) == DSO_SPACE__USER; case DSO_BINARY_TYPE__KALLSYMS: case DSO_BINARY_TYPE__VMLINUX: case DSO_BINARY_TYPE__KCORE: - return dso->kernel == DSO_SPACE__KERNEL; + return dso__kernel(dso) == DSO_SPACE__KERNEL; case DSO_BINARY_TYPE__GUEST_KALLSYMS: case DSO_BINARY_TYPE__GUEST_VMLINUX: case DSO_BINARY_TYPE__GUEST_KCORE: - return dso->kernel == DSO_SPACE__KERNEL_GUEST; + return dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST; case DSO_BINARY_TYPE__GUEST_KMODULE: case DSO_BINARY_TYPE__GUEST_KMODULE_COMP: @@ -1704,7 +1706,7 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, * kernel modules know their symtab type - it's set when * creating a module dso in machine__addnew_module_map(). */ - return kmod && dso->symtab_type == type; + return kmod && dso__symtab_type(dso) == type; case DSO_BINARY_TYPE__BUILD_ID_CACHE: case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO: @@ -1772,18 +1774,19 @@ int dso__load(struct dso *dso, struct map *map) struct build_id bid; struct nscookie nsc; char newmapname[PATH_MAX]; - const char *map_path = dso->long_name; + const char *map_path = dso__long_name(dso); - mutex_lock(&dso->lock); - perfmap = strncmp(dso->name, "/tmp/perf-", 10) == 0; + mutex_lock(dso__lock(dso)); + perfmap = strncmp(dso__name(dso), "/tmp/perf-", 10) == 0; if (perfmap) { - if (dso->nsinfo && (dso__find_perf_map(newmapname, - sizeof(newmapname), &dso->nsinfo) == 0)) { + if (dso__nsinfo(dso) && + (dso__find_perf_map(newmapname, sizeof(newmapname), + dso__nsinfo_ptr(dso)) == 0)) { map_path = newmapname; } } - nsinfo__mountns_enter(dso->nsinfo, &nsc); + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); /* check again under the dso->lock */ if (dso__loaded(dso)) { @@ -1791,15 +1794,15 @@ int dso__load(struct dso *dso, struct map *map) goto out; } - kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE || - dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP || - dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE || - dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; + kmod = dso__symtab_type(dso) == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE || + dso__symtab_type(dso) == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP || + dso__symtab_type(dso) == DSO_BINARY_TYPE__GUEST_KMODULE || + dso__symtab_type(dso) == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; - if (dso->kernel && !kmod) { - if (dso->kernel == DSO_SPACE__KERNEL) + if (dso__kernel(dso) && !kmod) { + if (dso__kernel(dso) == DSO_SPACE__KERNEL) ret = dso__load_kernel_sym(dso, map); - else if (dso->kernel == DSO_SPACE__KERNEL_GUEST) + else if (dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST) ret = dso__load_guest_kernel_sym(dso, map); machine = maps__machine(map__kmaps(map)); @@ -1808,12 +1811,13 @@ int dso__load(struct dso *dso, struct map *map) goto out; } - dso->adjust_symbols = 0; + dso__set_adjust_symbols(dso, false); if (perfmap) { ret = dso__load_perf_map(map_path, dso); - dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT : - DSO_BINARY_TYPE__NOT_FOUND; + dso__set_symtab_type(dso, ret > 0 + ? DSO_BINARY_TYPE__JAVA_JIT + : DSO_BINARY_TYPE__NOT_FOUND); goto out; } @@ -1828,9 +1832,9 @@ int dso__load(struct dso *dso, struct map *map) * Read the build id if possible. This is required for * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work */ - if (!dso->has_build_id && - is_regular_file(dso->long_name)) { - __symbol__join_symfs(name, PATH_MAX, dso->long_name); + if (!dso__has_build_id(dso) && + is_regular_file(dso__long_name(dso))) { + __symbol__join_symfs(name, PATH_MAX, dso__long_name(dso)); if (filename__read_build_id(name, &bid) > 0) dso__set_build_id(dso, &bid); } @@ -1864,7 +1868,7 @@ int dso__load(struct dso *dso, struct map *map) nsinfo__mountns_exit(&nsc); is_reg = is_regular_file(name); - if (!is_reg && errno == ENOENT && dso->nsinfo) { + if (!is_reg && errno == ENOENT && dso__nsinfo(dso)) { char *new_name = dso__filename_with_chroot(dso, name); if (new_name) { is_reg = is_regular_file(new_name); @@ -1881,7 +1885,7 @@ int dso__load(struct dso *dso, struct map *map) sirc = symsrc__init(ss, dso, name, symtab_type); if (nsexit) - nsinfo__mountns_enter(dso->nsinfo, &nsc); + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); if (bfdrc == 0) { ret = 0; @@ -1894,8 +1898,8 @@ int dso__load(struct dso *dso, struct map *map) if (!syms_ss && symsrc__has_symtab(ss)) { syms_ss = ss; next_slot = true; - if (!dso->symsrc_filename) - dso->symsrc_filename = strdup(name); + if (!dso__symsrc_filename(dso)) + dso__set_symsrc_filename(dso, strdup(name)); } if (!runtime_ss && symsrc__possibly_runtime(ss)) { @@ -1942,11 +1946,11 @@ int dso__load(struct dso *dso, struct map *map) symsrc__destroy(&ss_[ss_pos - 1]); out_free: free(name); - if (ret < 0 && strstr(dso->name, " (deleted)") != NULL) + if (ret < 0 && strstr(dso__name(dso), " (deleted)") != NULL) ret = 0; out: dso__set_loaded(dso); - mutex_unlock(&dso->lock); + mutex_unlock(dso__lock(dso)); nsinfo__mountns_exit(&nsc); return ret; @@ -1965,7 +1969,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map, else symbol__join_symfs(symfs_vmlinux, vmlinux); - if (dso->kernel == DSO_SPACE__KERNEL_GUEST) + if (dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST) symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX; else symtab_type = DSO_BINARY_TYPE__VMLINUX; @@ -1978,10 +1982,10 @@ int dso__load_vmlinux(struct dso *dso, struct map *map, * an incorrect long name unless we set it here first. */ dso__set_long_name(dso, vmlinux, vmlinux_allocated); - if (dso->kernel == DSO_SPACE__KERNEL_GUEST) - dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX; + if (dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST) + dso__set_binary_type(dso, DSO_BINARY_TYPE__GUEST_VMLINUX); else - dso->binary_type = DSO_BINARY_TYPE__VMLINUX; + dso__set_binary_type(dso, DSO_BINARY_TYPE__VMLINUX); err = dso__load_sym(dso, map, &ss, &ss, 0); symsrc__destroy(&ss); @@ -2074,7 +2078,7 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map) bool is_host = false; char path[PATH_MAX]; - if (!dso->has_build_id) { + if (!dso__has_build_id(dso)) { /* * Last resort, if we don't have a build-id and couldn't find * any vmlinux file, try the running kernel kallsyms table. @@ -2099,7 +2103,7 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map) goto proc_kallsyms; } - build_id__sprintf(&dso->bid, sbuild_id); + build_id__sprintf(dso__bid(dso), sbuild_id); /* Find kallsyms in build-id cache with kcore */ scnprintf(path, sizeof(path), "%s/%s/%s", @@ -2192,7 +2196,7 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map) free(kallsyms_allocated_filename); if (err > 0 && !dso__is_kcore(dso)) { - dso->binary_type = DSO_BINARY_TYPE__KALLSYMS; + dso__set_binary_type(dso, DSO_BINARY_TYPE__KALLSYMS); dso__set_long_name(dso, DSO__NAME_KALLSYMS, false); map__fixup_start(map); map__fixup_end(map); @@ -2235,7 +2239,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map) if (err > 0) pr_debug("Using %s for symbols\n", kallsyms_filename); if (err > 0 && !dso__is_kcore(dso)) { - dso->binary_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; + dso__set_binary_type(dso, DSO_BINARY_TYPE__GUEST_KALLSYMS); dso__set_long_name(dso, machine->mmap_name, false); map__fixup_start(map); map__fixup_end(map); diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fprintf.c index 088f4abf230f..53e1af4ed9ac 100644 --- a/tools/perf/util/symbol_fprintf.c +++ b/tools/perf/util/symbol_fprintf.c @@ -64,8 +64,8 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso, { size_t ret = 0; - for (size_t i = 0; i < dso->symbol_names_len; i++) { - struct symbol *pos = dso->symbol_names[i]; + for (size_t i = 0; i < dso__symbol_names_len(dso); i++) { + struct symbol *pos = dso__symbol_names(dso)[i]; ret += fprintf(fp, "%s\n", pos->name); } diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 3712186353fb..10753303034a 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -385,8 +385,8 @@ static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event, id.ino_generation = event->ino_generation; dso = dsos__findnew_id(&machine->dsos, event->filename, &id); - if (dso && dso->has_build_id) { - bid = dso->bid; + if (dso && dso__has_build_id(dso)) { + bid = *dso__bid(dso); rc = 0; goto out; } @@ -407,7 +407,7 @@ static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event, event->__reserved_1 = 0; event->__reserved_2 = 0; - if (dso && !dso->has_build_id) + if (dso && !dso__has_build_id(dso)) dso__set_build_id(dso, &bid); } else { if (event->filename[0] == '/') { @@ -684,7 +684,7 @@ static int perf_event__synthesize_modules_maps_cb(struct map *map, void *data) dso = map__dso(map); if (symbol_conf.buildid_mmap2) { - size = PERF_ALIGN(dso->long_name_len + 1, sizeof(u64)); + size = PERF_ALIGN(dso__long_name_len(dso) + 1, sizeof(u64)); event->mmap2.header.type = PERF_RECORD_MMAP2; event->mmap2.header.size = (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size)); @@ -694,11 +694,11 @@ static int perf_event__synthesize_modules_maps_cb(struct map *map, void *data) event->mmap2.len = map__size(map); event->mmap2.pid = args->machine->pid; - memcpy(event->mmap2.filename, dso->long_name, dso->long_name_len + 1); + memcpy(event->mmap2.filename, dso__long_name(dso), dso__long_name_len(dso) + 1); perf_record_mmap2__read_build_id(&event->mmap2, args->machine, false); } else { - size = PERF_ALIGN(dso->long_name_len + 1, sizeof(u64)); + size = PERF_ALIGN(dso__long_name_len(dso) + 1, sizeof(u64)); event->mmap.header.type = PERF_RECORD_MMAP; event->mmap.header.size = (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size)); @@ -708,7 +708,7 @@ static int perf_event__synthesize_modules_maps_cb(struct map *map, void *data) event->mmap.len = map__size(map); event->mmap.pid = args->machine->pid; - memcpy(event->mmap.filename, dso->long_name, dso->long_name_len + 1); + memcpy(event->mmap.filename, dso__long_name(dso), dso__long_name_len(dso) + 1); } if (perf_tool__process_synth_event(args->tool, event, args->machine, args->process) != 0) @@ -2231,20 +2231,20 @@ int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *pos, u16 union perf_event ev; size_t len; - if (!pos->hit) + if (!dso__hit(pos)) return 0; memset(&ev, 0, sizeof(ev)); - len = pos->long_name_len + 1; + len = dso__long_name_len(pos) + 1; len = PERF_ALIGN(len, NAME_ALIGN); - ev.build_id.size = min(pos->bid.size, sizeof(pos->bid.data)); - memcpy(&ev.build_id.build_id, pos->bid.data, ev.build_id.size); + ev.build_id.size = min(dso__bid(pos)->size, sizeof(dso__bid(pos)->data)); + memcpy(&ev.build_id.build_id, dso__bid(pos)->data, ev.build_id.size); ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; ev.build_id.header.misc = misc | PERF_RECORD_MISC_BUILD_ID_SIZE; ev.build_id.pid = machine->pid; ev.build_id.header.size = sizeof(ev.build_id) + len; - memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); + memcpy(&ev.build_id.filename, dso__long_name(pos), dso__long_name_len(pos)); return process(tool, &ev, NULL, machine); } diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 1aa8962dcf52..0a473112f881 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -457,14 +457,14 @@ int thread__memcpy(struct thread *thread, struct machine *machine, dso = map__dso(al.map); - if (!dso || dso->data.status == DSO_DATA_STATUS_ERROR || map__load(al.map) < 0) { + if (!dso || dso__data(dso)->status == DSO_DATA_STATUS_ERROR || map__load(al.map) < 0) { addr_location__exit(&al); return -1; } offset = map__map_ip(al.map, ip); if (is64bit) - *is64bit = dso->is_64_bit; + *is64bit = dso__is_64_bit(dso); addr_location__exit(&al); diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 6a5ac0faa6f4..cde267ea3e99 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -329,27 +329,27 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct unwind_info *ui, }; int ret, fd; - if (dso->data.eh_frame_hdr_offset == 0) { + if (dso__data(dso)->eh_frame_hdr_offset == 0) { fd = dso__data_get_fd(dso, ui->machine); if (fd < 0) return -EINVAL; /* Check the .eh_frame section for unwinding info */ ret = elf_section_address_and_offset(fd, ".eh_frame_hdr", - &dso->data.eh_frame_hdr_addr, - &dso->data.eh_frame_hdr_offset); - dso->data.elf_base_addr = elf_base_address(fd); + &dso__data(dso)->eh_frame_hdr_addr, + &dso__data(dso)->eh_frame_hdr_offset); + dso__data(dso)->elf_base_addr = elf_base_address(fd); dso__data_put_fd(dso); - if (ret || dso->data.eh_frame_hdr_offset == 0) + if (ret || dso__data(dso)->eh_frame_hdr_offset == 0) return -EINVAL; } maps__for_each_map(thread__maps(ui->thread), read_unwind_spec_eh_frame_maps_cb, &args); - args.base_addr -= dso->data.elf_base_addr; + args.base_addr -= dso__data(dso)->elf_base_addr; /* Address of .eh_frame_hdr */ - *segbase = args.base_addr + dso->data.eh_frame_hdr_addr; - ret = unwind_spec_ehframe(dso, ui->machine, dso->data.eh_frame_hdr_offset, + *segbase = args.base_addr + dso__data(dso)->eh_frame_hdr_addr; + ret = unwind_spec_ehframe(dso, ui->machine, dso__data(dso)->eh_frame_hdr_offset, table_data, fde_count); if (ret) return ret; @@ -460,7 +460,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, return -EINVAL; } - pr_debug("unwind: find_proc_info dso %s\n", dso->name); + pr_debug("unwind: find_proc_info dso %s\n", dso__name(dso)); /* Check the .eh_frame section for unwinding info */ if (!read_unwind_spec_eh_frame(dso, ui, &table_data, &segbase, &fde_count)) { diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 2728eb4f13ea..cb8be6acfb6f 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -25,7 +25,7 @@ int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized return 0; if (maps__addr_space(maps)) { - pr_debug("unwind: thread map already set, dso=%s\n", dso->name); + pr_debug("unwind: thread map already set, dso=%s\n", dso__name(dso)); if (initialized) *initialized = true; return 0; diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 35532dcbff74..1b6f8f6db7aa 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -148,7 +148,7 @@ static int machine__thread_dso_type_maps_cb(struct map *map, void *data) struct machine__thread_dso_type_maps_cb_args *args = data; struct dso *dso = map__dso(map); - if (!dso || dso->long_name[0] != '/') + if (!dso || dso__long_name(dso)[0] != '/') return 0; args->dso_type = dso__type(dso, args->machine); @@ -361,7 +361,7 @@ struct dso *machine__findnew_vdso(struct machine *machine, bool dso__is_vdso(struct dso *dso) { - return !strcmp(dso->short_name, DSO__NAME_VDSO) || - !strcmp(dso->short_name, DSO__NAME_VDSO32) || - !strcmp(dso->short_name, DSO__NAME_VDSOX32); + return !strcmp(dso__short_name(dso), DSO__NAME_VDSO) || + !strcmp(dso__short_name(dso), DSO__NAME_VDSO32) || + !strcmp(dso__short_name(dso), DSO__NAME_VDSOX32); } From patchwork Fri Feb 2 06:15:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195605 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239518dyc; Thu, 1 Feb 2024 22:21:57 -0800 (PST) X-Google-Smtp-Source: AGHT+IGjTUbV5KoAqQKd5wgtGWTfGQzkhUmqrQIKW/ePA4oDdvVTGZl9zUZ1SoS1Eo6jrFC4fXgD X-Received: by 2002:a05:622a:1007:b0:42a:339f:516c with SMTP id d7-20020a05622a100700b0042a339f516cmr7311081qte.68.1706854917334; Thu, 01 Feb 2024 22:21:57 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854917; cv=pass; d=google.com; s=arc-20160816; b=NRJgp6qfgbcPBrO/sFDljZDsw3M6P+KDiGHvfJJf/kkFvMvItdireJPdDxi0JWRMO9 0b6mhVPMeDJCrDUz8Fd7YHTDIWVdNCj55G1pInBDC3Z6K1M2r4roC68BUAMEghbddAEO k3ccREyWSZqxmPygBFGjSm3orjUUwcom7+QRZeBnB0HMJU3/YPWBIdIUtaw5BpZ2GBkA igG6dhVzzslTNPIwQhhVWdsVlhwcYR1ynG85AC0P9sC/mKeT4ZOibBKwe3wUwWcBJJpu 7/9/IqaMA3v9iXpP94pAfvajf20bZNy8Z6db3o58Gb1+jV0FD6mNTq9TZU4dvpZyl1E7 FYtg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=n5YvFgFYxmEyXAB6dNy5nJiKJQA6ckdB9Gak22tlTgE=; fh=PTRHhjrTWr/ESokv+sRc/CXZeI+LI4CFGyM0+u40K7s=; b=TTGX2hr0PTgihVZ+rx7SdUHXlJAa3vtNl9k7CoLNwwB5e0YwRSPlXvmobnVJarP8QX 9uKm2qWE5kGHH+2ocEem9jDgFA7dKhlsHX9Bh550ilhYjfhNr0z9K3PADLNRKIYPAwPP AgsUS9YNKOookDtQI9ErsUsKjHuJcV1b0e+SqeRlgg5vYVl36eiFAEV3cSfmBsMtJjRX 8bS0DYZ2HoWBrnle5q50zd9Jd0PNVtasMX7ZGf8L4I4bMeR3S+dZk342wKpGp9jonHt5 8XwS1CzyWRMD9tF2fU0PKKJgH9O8fSNi/AGl3V3RVZzdVgDPpHXXMV+NCpUXnJ8qsf/g 8UVA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=eWgChzYT; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49262-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49262-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCXe4rpWXO0G4oZsmk7XBXboIYqNUpPmz6yDNJXvskO1WK0TRjBQpigVqYog5XsgD040PERY3c1ywKXbEKYerDowKsMB9A== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id t22-20020a05622a01d600b0042bffb5a617si1245668qtw.273.2024.02.01.22.21.57 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:21:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49262-ouuuleilei=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; dkim=pass header.i=@google.com header.s=20230601 header.b=eWgChzYT; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49262-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49262-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 148DB1C23B86 for ; Fri, 2 Feb 2024 06:21:57 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3DB5B17BD9; Fri, 2 Feb 2024 06:16:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="eWgChzYT" Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.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 A9F87487A2 for ; Fri, 2 Feb 2024 06:16:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854605; cv=none; b=FuYiwds8BZxgA0rdbJT9w4c9YDtOz2/N3odjPMRxa/55xN/XlsfN7f+V7Hifz/l/qNnkEubsWSwvBDZhegYWtgj7HCQlgTQiqu/SCmeFCFLkudw8iqx3/6qZWeo3f4rVfO7F6K/PLbNx7TtH3pIEQZEw56NU0WzFi3iYCd8yKuc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854605; c=relaxed/simple; bh=HTmMDuQzLKDWBOK/Fg5hhps0giyc5BqyAMhZAoiZKiY=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=qBTJgmKtXlkOTbtRcoJB1YatGL6fq6/oUjxGryyF1XCkhMEC2HEJzEsNjdW8Ee6w+RY6aCqth4qQ1+Hrd7l38Pn2M6QguqiZgleJkheKx3d6rx/LWD0ioFuBM+8aMcKSaCoEem6HPO8hjgiTT6iqNnMmWqvO+/6vKngYBbNMgho= 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=eWgChzYT; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dc6b2681571so2728574276.2 for ; Thu, 01 Feb 2024 22:16:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854602; x=1707459402; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=n5YvFgFYxmEyXAB6dNy5nJiKJQA6ckdB9Gak22tlTgE=; b=eWgChzYTYpjx/3ijzvouZXIZFaSP6xov+U/cMp5k+LtJ/r7vGdB5g4G5XZAzu7DK3T QoiK4Xkb9YmmLDa0SgiWAya+7UAYAuhNHm7QCvJn5v0GYx3zKoDEX+LBOTZmufyMekKT AEPFcr/QEdtl/of3otCDKXEX6u4/ONSeneyCQzAqmzApifhsdWLFpt4pxdqWtDISI3dm LqWOtYChweAahOcF8ko1HEjMZ9uOkaYqBnGlWCVDy35g5S9ISuwpDCl2Rh3podUg6/z1 /SAJFDz1kJc4l9Oj4mah9cgblyqwxJlYbsIXX4ELQ381iVwil9PQaYxAotcHUSpfbTzL xTCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854602; x=1707459402; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=n5YvFgFYxmEyXAB6dNy5nJiKJQA6ckdB9Gak22tlTgE=; b=fzSSu9MgFc6mipyslJxAGjhEwm55oIqAND2QW2xVStW0AgExsSYLvWpqpdtP40IhQB 8FMPNW6xNOELPZOQeUVXuvi3WobdjbqSJW8+X+NyJlIJ0Osjl5yljMLZARrOx4b7TFVv KQJ2seaPFfUEw8jyVNf4eh1tBhstFKhTH+K7XB4UFDyRGuw1Nr2n4XBPe+OKjDuSRN9/ JU9DmNPSuGpnb+Iq7hDWMwK483S5mtxHMeC4nRqDyCN0zHE6NuHaFZPPVzoyGTKXvW42 Ly5m3K+bcnu/StNRmu0EeAuBOXALJqhPaBTokH/GMHm7sCvqJOvkPrMwdvyCDMfTdZcm fQDw== X-Gm-Message-State: AOJu0YxjTFe49Astmk5r+39Ozd+fhExg/hsTtSblF44ZxktTZ7cIRBjq c6Cui8iYrGRYDBQnrYWsZx5aPjeS+IyTK4KKLPkE5lseFn9n0ocCIe8ZI1EErgSf1A9t24tAvfe 1U/OFFw== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:cc9:b0:dc2:57c9:b44d with SMTP id cq9-20020a0569020cc900b00dc257c9b44dmr179235ybb.8.1706854602622; Thu, 01 Feb 2024 22:16:42 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:31 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-25-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 24/25] perf dso: Reference counting related fixes From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767101908994955 X-GMAIL-MSGID: 1789767101908994955 Ensure gets and puts are better aligned fixing reference couting checking problems. Signed-off-by: Ian Rogers --- tools/perf/util/machine.c | 4 ++-- tools/perf/util/map.c | 1 + tools/perf/util/symbol-elf.c | 38 +++++++++++++++++------------------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 49b8ccd5affe..2dbb7b06b117 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -682,7 +682,7 @@ static int machine__process_ksymbol_register(struct machine *machine, struct perf_sample *sample __maybe_unused) { struct symbol *sym; - struct dso *dso; + struct dso *dso = NULL; struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr); int err = 0; @@ -695,7 +695,6 @@ static int machine__process_ksymbol_register(struct machine *machine, } dso__set_kernel(dso, DSO_SPACE__KERNEL); map = map__new2(0, dso); - dso__put(dso); if (!map) { err = -ENOMEM; goto out; @@ -734,6 +733,7 @@ static int machine__process_ksymbol_register(struct machine *machine, dso__insert_symbol(dso, sym); out: map__put(map); + dso__put(dso); return err; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 14fb8cf65b13..4480134ef4ea 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -200,6 +200,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, dso__set_build_id(dso, dso__bid(header_bid_dso)); dso__set_header_build_id(dso, 1); } + dso__put(header_bid_dso); } dso__put(dso); } diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index de73f9fb3fe4..4c00463abb7e 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1366,7 +1366,7 @@ void __weak arch__sym_update(struct symbol *s __maybe_unused, static int dso__process_kernel_symbol(struct dso *dso, struct map *map, GElf_Sym *sym, GElf_Shdr *shdr, struct maps *kmaps, struct kmap *kmap, - struct dso **curr_dsop, struct map **curr_mapp, + struct dso **curr_dsop, const char *section_name, bool adjust_kernel_syms, bool kmodule, bool *remap_kernel) { @@ -1416,8 +1416,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, map__set_pgoff(map, shdr->sh_offset); } - *curr_mapp = map; - *curr_dsop = dso; + dso__put(*curr_dsop); + *curr_dsop = dso__get(dso); return 0; } @@ -1442,10 +1442,10 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, dso__set_binary_type(curr_dso, dso__binary_type(dso)); dso__set_adjust_symbols(curr_dso, dso__adjust_symbols(dso)); curr_map = map__new2(start, curr_dso); - dso__put(curr_dso); - if (curr_map == NULL) + if (curr_map == NULL) { + dso__put(curr_dso); return -1; - + } if (dso__kernel(curr_dso)) map__kmap(curr_map)->kmaps = kmaps; @@ -1459,21 +1459,15 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map, dso__set_symtab_type(curr_dso, dso__symtab_type(dso)); if (maps__insert(kmaps, curr_map)) return -1; - /* - * Add it before we drop the reference to curr_map, i.e. while - * we still are sure to have a reference to this DSO via - * *curr_map->dso. - */ dsos__add(&maps__machine(kmaps)->dsos, curr_dso); - /* kmaps already got it */ - map__put(curr_map); dso__set_loaded(curr_dso); - *curr_mapp = curr_map; + dso__put(*curr_dsop); *curr_dsop = curr_dso; } else { - *curr_dsop = map__dso(curr_map); - map__put(curr_map); + dso__put(*curr_dsop); + *curr_dsop = dso__get(map__dso(curr_map)); } + map__put(curr_map); return 0; } @@ -1484,8 +1478,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, { struct kmap *kmap = dso__kernel(dso) ? map__kmap(map) : NULL; struct maps *kmaps = kmap ? map__kmaps(map) : NULL; - struct map *curr_map = map; - struct dso *curr_dso = dso; + struct dso *curr_dso; Elf_Data *symstrs, *secstrs, *secstrs_run, *secstrs_sym; uint32_t nr_syms; int err = -1; @@ -1586,6 +1579,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, remap_kernel = true; adjust_kernel_syms = dso__adjust_symbols(dso); } + curr_dso = dso__get(dso); elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { struct symbol *f; const char *elf_name = elf_sym__name(&sym, symstrs); @@ -1674,8 +1668,11 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, --sym.st_value; if (dso__kernel(dso)) { - if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map, - section_name, adjust_kernel_syms, kmodule, &remap_kernel)) + if (dso__process_kernel_symbol(dso, map, &sym, &shdr, + kmaps, kmap, &curr_dso, + section_name, + adjust_kernel_syms, + kmodule, &remap_kernel)) goto out_elf_end; } else if ((used_opd && runtime_ss->adjust_symbols) || (!used_opd && syms_ss->adjust_symbols)) { @@ -1724,6 +1721,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss, __symbols__insert(dso__symbols(curr_dso), f, dso__kernel(dso)); nr++; } + dso__put(curr_dso); /* * For misannotated, zeroed, ASM function sizes. From patchwork Fri Feb 2 06:15:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 195606 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:9bc1:b0:106:209c:c626 with SMTP id op1csp239578dyc; Thu, 1 Feb 2024 22:22:07 -0800 (PST) X-Google-Smtp-Source: AGHT+IGBJfJPNj4g+NqdkKaZRQdYB2QlB03RPvnhf3WYr1dRhzv5/uGFKXj8VUTbU+3dUng+ovGb X-Received: by 2002:a05:620a:4094:b0:785:546b:7dc3 with SMTP id f20-20020a05620a409400b00785546b7dc3mr1251503qko.9.1706854927806; Thu, 01 Feb 2024 22:22:07 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706854927; cv=pass; d=google.com; s=arc-20160816; b=wzFlP7pcSDkrk2idWC4CeUL40rrxTqVnIgvPlrUlB5rMGsUBKIqYU3T+lzQIX4wkxP 2KwNkMuNQzymqqH/SDIaQohKYiwwF6gePm7urJLAdO6wZHzynJ1b3cSXUdU3avkspLXk ATok7/h/FHNfoj1s4slz8IJ/Che4/ANUjvjJacIu2pHmfICn+5huHnPIi+gNuyR+AY9n W7vLqbaGpdH15EuXBy6XhqiNjryR8BvZNhtQqMKEw/hMbiXH2FqvNmUf78Ma/rEgD/6M F3Y7ntsfQ9ID4+bEwrq/gYs3bSuPzDkplXrxSltZKIXmsNnXcfGlxUeUdM8KTjKtFmUH 9ztg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:from:subject:references:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:in-reply-to:date :dkim-signature; bh=O7s4uPo6a6IUX6P+LNwsbu+H+dBYWvGrbbrG302CchI=; fh=SvPPW/vyDAo4/CD/0DyoCri17fIjahFLHzmwgaYn+bc=; b=ufa5Y/kLSaJRCGZa72XHfGijcD0W5Yarnb0/Q79nCWmGKCqY2XUMtPK2h8dED3Bkec hd4KVjmyuR8xKlbYSuAwCJVW3k9gajFGwKBUT8Zk16bBplqldg2hkR3mrMglu365Ov9C 9x6FSiJO/8NFdONiG6PdskmvBv1RlNOs3YYQgFzd9tbt00/QHI2xGJAb7u/xEUFfxeVk E9MPlMQQSPGpaaOFSRcRrlwdy+IJkw8h6YDJ0+T46svSYnRq9f4Tqa5STv7BD3ZBg4Rz xm25voPtwlSkzKcvYKmf+r1Pv8rgdwX+axMkhqLTGgH7KGq5ZRa3r1bJYHe+CF3fPcB2 hmwg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=B+NNC7IR; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49263-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49263-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCUHzq2dbXMWhcKCljJxWm8tbMdBBdsZsX5BfYzDRGm8F3iLfN3p/vkqc+S4hCbBmamg7pijnkYIW3x8dCcVrN47a8He1w== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id b21-20020a05620a127500b00783ab5f86adsi1327537qkl.265.2024.02.01.22.22.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Feb 2024 22:22:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-49263-ouuuleilei=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; dkim=pass header.i=@google.com header.s=20230601 header.b=B+NNC7IR; arc=pass (i=1 spf=pass spfdomain=flex--irogers.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-49263-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-49263-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.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 88BCC1C241E1 for ; Fri, 2 Feb 2024 06:22:07 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3101748CFF; Fri, 2 Feb 2024 06:16:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="B+NNC7IR" Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.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 D933E17BC4 for ; Fri, 2 Feb 2024 06:16:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854607; cv=none; b=PbA2p7NFq5IF8QODzfhI6bzhsJxBsu2B42B9dhXniDBv72BCGr28cwPmcyQTvj6DolPA6bUDtVaMh71aq8DyLGjdTUe1q/3FZPwQMxwy4tn+pjK16/VDeUcLBdQndsAgQ6toYdnV3wc1mPqc+rooIC5ED0tJ9ZiP5V8GQtlfGIE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706854607; c=relaxed/simple; bh=xA5Ts8mXmjH0ByX7hN5Pia0888YuBQgn/eJu9XRxSZo=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=sA9g5ngg1yIbLdz4Fhh7tFksJfNI71P1qRXb1LBDG4Tpla0lQUto9xqYsDt5mdxDcJ4f7GTKu+8bMrLumvMU2ekZxdL74i+bfPNcrPMKn7FKeC98RXNqxlMgx4PtQiEYpWjvVN4aNtU1WC8X+48FjlSS1OP1hePO4BkKfOBo4e8= 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=B+NNC7IR; arc=none smtp.client-ip=209.85.219.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 Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dc6c24a4ce1so2745778276.2 for ; Thu, 01 Feb 2024 22:16:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706854605; x=1707459405; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=O7s4uPo6a6IUX6P+LNwsbu+H+dBYWvGrbbrG302CchI=; b=B+NNC7IRggfOAoQQn6QX+RtqILSsG3TRD9+yeuh6C+nF7PgUm066kctM9Y6cveXI6Z D5yX/Iur8MGVQxBzYR/RNm9joUZiiLi2kMJe+a78k8hR9u4xLVBPw+x5gjS6nf99iPct y9dsq8GFVrc8y9YxiC2+7v9vf13zz6nKt8T1oD8dIWACkQVqGNpA4GpmLE+Ef3nLsTcK flCCoIqj0ROisNakwM2T1YcQ7ZTm10BtzccOJ1rhGNUAKE2PBn/FbDRU0paPPnEUHBB4 6z1HctWLDW7M9flrkBdeiWUb/DwNYwq2Az0mhNJPmlVM20pk+kltn3MVSMgjrCtas2lG ShgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706854605; x=1707459405; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=O7s4uPo6a6IUX6P+LNwsbu+H+dBYWvGrbbrG302CchI=; b=BsvMJG7Fp9PTg6h4UJgP2poDQZUm9r+mRFI2B+F/s9mfgpGN+mMUpYmcPyFT93KkgB GBgp+h7/e7OG4bRrLNFK0F8UMSCYQZIXJROYl3EZSDHS17KWDU+IqJvMmvnMQS6mVAQy m/+mWRmimMhsCrQrwwIEfDGP5/289XB6pWKLa76+ZEzXzK5BfSw7Wu+gZ5zWuZ2zOyHT 2SEEADhJIFzr7oI2FiVht3bWpmFMAu2vU42GvHsK98UvLmkRDEFI0PZQUBpvaCmPDuGl pszByKePn5a3H8STqXWDOsIj6f0MHgws/egeFNS3991d3JaBB8ore9MZMR7QeKSqxIi8 6HNA== X-Gm-Message-State: AOJu0Yzf5Fbfbq5AcMhWgoorXux/L65H+9J9Oll32f78If0S0OrM/IT1 n6hy5qQqtsJSCtb+GVYC/Bq0ut966qe9LtBth2lBaJ8trPX+U/Fdszm8qqr7JyBeya7W1h3Wycc wsZ7rzA== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:a85f:db1d:a66b:7f53]) (user=irogers job=sendgmr) by 2002:a05:6902:240c:b0:dc2:4009:b35e with SMTP id dr12-20020a056902240c00b00dc24009b35emr1783465ybb.9.1706854604950; Thu, 01 Feb 2024 22:16:44 -0800 (PST) Date: Thu, 1 Feb 2024 22:15:32 -0800 In-Reply-To: <20240202061532.1939474-1-irogers@google.com> Message-Id: <20240202061532.1939474-26-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240202061532.1939474-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.594.gd9cf4e227d-goog Subject: [PATCH v8 25/25] perf dso: Use container_of to avoid a pointer in dso_data From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789767112542063957 X-GMAIL-MSGID: 1789767112542063957 The dso pointer in dso_data is necessary for reference count checking to account for the dso_data forming a global list of open dso's with references to the dso. The dso pointer also allows for the indirection that reference count checking needs. Outside of reference count checking the indirection isn't needed and container_of is more efficient and saves space. The reference count won't be increased by placing items onto the global list, matching how things were before the reference count checking change, but we assert the dso is in dsos holding it live (and that the set of open dsos is a subset of all dsos for the machine). Update the DSO data tests so that they use a dsos struct to make the invariant true. Signed-off-by: Ian Rogers --- tools/perf/tests/dso-data.c | 60 ++++++++++++++++++------------------- tools/perf/util/dso.c | 16 +++++++++- tools/perf/util/dso.h | 2 ++ 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index fde4eca84b6f..5286ae8bd2d7 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -10,6 +10,7 @@ #include #include #include "dso.h" +#include "dsos.h" #include "machine.h" #include "symbol.h" #include "tests.h" @@ -123,9 +124,10 @@ static int test__dso_data(struct test_suite *test __maybe_unused, int subtest __ TEST_ASSERT_VAL("No test file", file); memset(&machine, 0, sizeof(machine)); + dsos__init(&machine.dsos); - dso = dso__new((const char *)file); - + dso = dso__new(file); + TEST_ASSERT_VAL("Failed to add dso", !dsos__add(&machine.dsos, dso)); TEST_ASSERT_VAL("Failed to access to dso", dso__data_fd(dso, &machine) >= 0); @@ -170,6 +172,7 @@ static int test__dso_data(struct test_suite *test __maybe_unused, int subtest __ } dso__put(dso); + dsos__exit(&machine.dsos); unlink(file); return 0; } @@ -199,41 +202,35 @@ static long open_files_cnt(void) return nr - 1; } -static struct dso **dsos; - -static int dsos__create(int cnt, int size) +static int dsos__create(int cnt, int size, struct dsos *dsos) { int i; - dsos = malloc(sizeof(*dsos) * cnt); - TEST_ASSERT_VAL("failed to alloc dsos array", dsos); + dsos__init(dsos); for (i = 0; i < cnt; i++) { - char *file; + struct dso *dso; + char *file = test_file(size); - file = test_file(size); TEST_ASSERT_VAL("failed to get dso file", file); - - dsos[i] = dso__new(file); - TEST_ASSERT_VAL("failed to get dso", dsos[i]); + dso = dso__new(file); + TEST_ASSERT_VAL("failed to get dso", dso); + TEST_ASSERT_VAL("failed to add dso", !dsos__add(dsos, dso)); + dso__put(dso); } return 0; } -static void dsos__delete(int cnt) +static void dsos__delete(struct dsos *dsos) { - int i; - - for (i = 0; i < cnt; i++) { - struct dso *dso = dsos[i]; + for (unsigned int i = 0; i < dsos->cnt; i++) { + struct dso *dso = dsos->dsos[i]; dso__data_close(dso); unlink(dso__name(dso)); - dso__put(dso); } - - free(dsos); + dsos__exit(dsos); } static int set_fd_limit(int n) @@ -267,10 +264,10 @@ static int test__dso_data_cache(struct test_suite *test __maybe_unused, int subt /* and this is now our dso open FDs limit */ dso_cnt = limit / 2; TEST_ASSERT_VAL("failed to create dsos\n", - !dsos__create(dso_cnt, TEST_FILE_SIZE)); + !dsos__create(dso_cnt, TEST_FILE_SIZE, &machine.dsos)); for (i = 0; i < (dso_cnt - 1); i++) { - struct dso *dso = dsos[i]; + struct dso *dso = machine.dsos.dsos[i]; /* * Open dsos via dso__data_fd(), it opens the data @@ -290,17 +287,17 @@ static int test__dso_data_cache(struct test_suite *test __maybe_unused, int subt } /* verify the first one is already open */ - TEST_ASSERT_VAL("dsos[0] is not open", dso__data(dsos[0])->fd != -1); + TEST_ASSERT_VAL("dsos[0] is not open", dso__data(machine.dsos.dsos[0])->fd != -1); /* open +1 dso to reach the allowed limit */ - fd = dso__data_fd(dsos[i], &machine); + fd = dso__data_fd(machine.dsos.dsos[i], &machine); TEST_ASSERT_VAL("failed to get fd", fd > 0); /* should force the first one to be closed */ - TEST_ASSERT_VAL("failed to close dsos[0]", dso__data(dsos[0])->fd == -1); + TEST_ASSERT_VAL("failed to close dsos[0]", dso__data(machine.dsos.dsos[0])->fd == -1); /* cleanup everything */ - dsos__delete(dso_cnt); + dsos__delete(&machine.dsos); /* Make sure we did not leak any file descriptor. */ nr_end = open_files_cnt(); @@ -325,9 +322,9 @@ static int test__dso_data_reopen(struct test_suite *test __maybe_unused, int sub long nr_end, nr = open_files_cnt(), lim = new_limit(3); int fd, fd_extra; -#define dso_0 (dsos[0]) -#define dso_1 (dsos[1]) -#define dso_2 (dsos[2]) +#define dso_0 (machine.dsos.dsos[0]) +#define dso_1 (machine.dsos.dsos[1]) +#define dso_2 (machine.dsos.dsos[2]) /* Rest the internal dso open counter limit. */ reset_fd_limit(); @@ -347,7 +344,8 @@ static int test__dso_data_reopen(struct test_suite *test __maybe_unused, int sub TEST_ASSERT_VAL("failed to set file limit", !set_fd_limit((lim))); - TEST_ASSERT_VAL("failed to create dsos\n", !dsos__create(3, TEST_FILE_SIZE)); + TEST_ASSERT_VAL("failed to create dsos\n", + !dsos__create(3, TEST_FILE_SIZE, &machine.dsos)); /* open dso_0 */ fd = dso__data_fd(dso_0, &machine); @@ -386,7 +384,7 @@ static int test__dso_data_reopen(struct test_suite *test __maybe_unused, int sub /* cleanup everything */ close(fd_extra); - dsos__delete(3); + dsos__delete(&machine.dsos); /* Make sure we did not leak any file descriptor. */ nr_end = open_files_cnt(); diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index ddf58f594df0..83de99e52141 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -497,14 +497,20 @@ static pthread_mutex_t dso__data_open_lock = PTHREAD_MUTEX_INITIALIZER; static void dso__list_add(struct dso *dso) { list_add_tail(&dso__data(dso)->open_entry, &dso__data_open); +#ifdef REFCNT_CHECKING dso__data(dso)->dso = dso__get(dso); +#endif + /* Assume the dso is part of dsos, hence the optional reference count above. */ + assert(dso__dsos(dso)); dso__data_open_cnt++; } static void dso__list_del(struct dso *dso) { list_del_init(&dso__data(dso)->open_entry); +#ifdef REFCNT_CHECKING dso__put(dso__data(dso)->dso); +#endif WARN_ONCE(dso__data_open_cnt <= 0, "DSO data fd counter out of bounds."); dso__data_open_cnt--; @@ -654,9 +660,15 @@ static void close_dso(struct dso *dso) static void close_first_dso(void) { struct dso_data *dso_data; + struct dso *dso; dso_data = list_first_entry(&dso__data_open, struct dso_data, open_entry); - close_dso(dso_data->dso); +#ifdef REFCNT_CHECKING + dso = dso_data->dso; +#else + dso = container_of(dso_data, struct dso, data); +#endif + close_dso(dso); } static rlim_t get_fd_limit(void) @@ -1448,7 +1460,9 @@ struct dso *dso__new_id(const char *name, struct dso_id *id) data->fd = -1; data->status = DSO_DATA_STATUS_UNKNOWN; INIT_LIST_HEAD(&data->open_entry); +#ifdef REFCNT_CHECKING data->dso = NULL; /* Set when on the open_entry list. */ +#endif } return res; } diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 3e27f93898f2..3311c1740840 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -147,7 +147,9 @@ struct dso_cache { struct dso_data { struct rb_root cache; struct list_head open_entry; +#ifdef REFCNT_CHECKING struct dso *dso; +#endif int fd; int status; u32 status_seen;