Received: by 2002:a05:7412:b795:b0:e2:908c:2ebd with SMTP id iv21csp563882rdb; Thu, 2 Nov 2023 11:14:08 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEmbN+vIDVnl3q9I8RsG/yjAESiOYxBzo7vQ0TKLXJ1zg6sJ8dtbBD9C7HUmeW86GQQi2yv X-Received: by 2002:a05:6a20:9150:b0:15e:f2a1:dae with SMTP id x16-20020a056a20915000b0015ef2a10daemr257982pzc.27.1698948848178; Thu, 02 Nov 2023 11:14:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698948848; cv=none; d=google.com; s=arc-20160816; b=aWaguxv6sEhQ/4wfOGvdhV4O/poMdvPKpf2mm5jAkX5EngZCmelJRHqU3jMH+C1WHS 7q249XrCGvWqRZj1m3C9YVMrrpv9uwzOYuWpoUqBpec22ma8fGkMoYw84kuCrG9DY7iZ IY4Jo7e9gV8VEJSEk03hP0nDdkvWSPyuA5DD3Fus8Vr9/b7FgWKv7EKHRbH3F3usIMyG +QPdEMsO81RqpXsjY/QHWVO/ukisFn3i/CMpWtOngd8l9JQURzX/1viMUVwegYV/7IzJ 6CxrBeU8rOghKBPpjRsOLoSpIw+Q84M0L+bnKAttmHxUHQ7hfPaFlPfPRQtqIscVJbat LkJw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=K/Jhn6xCbnHiyHqsQ6OV87Jm0NhFFz3VxLu59mRjmOo=; fh=z1KcSqUpYQ9oC4uLSeIkhAYTnJ2bvP0QbNW2xqV5NqA=; b=gMMwGH5qJAG44EdWOJBrv1z/7TGVK3aqDEC1Wl++4fZib0ZXhUOwzRzQLKbmlW9xEv azfSourxXYcgMZTJX05ByJYLoXPqcCl+DMVriDM1BPGJbTP5oLmxkiO1aJg5UFH6YlnB YGoIz+6wzAiVjKzPC/iLfvnmy0HH36lMa9pb7+AA734X1QJwtyStQuANJ63UquH7HNUR A6IoQcHGYM03/Wi+p+f8fmGtVMcytW743Eqk3WRO8phIKtfhUuUk/ZruXixpRowBdrh+ IB9CnzhxwCzayN2fhGlmvjhTEj9N64lk1trjt5JAY6PFwV8Ku6SqGpx0zofV60kIyf0c iUuA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=iBoZZbpU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from groat.vger.email (groat.vger.email. [23.128.96.35]) by mx.google.com with ESMTPS id o6-20020a656a46000000b005b928e39429si77324pgu.259.2023.11.02.11.14.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Nov 2023 11:14:08 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) client-ip=23.128.96.35; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=iBoZZbpU; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id A83688060354; Thu, 2 Nov 2023 11:14:04 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235728AbjKBSNU (ORCPT + 99 others); Thu, 2 Nov 2023 14:13:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377181AbjKBSNG (ORCPT ); Thu, 2 Nov 2023 14:13:06 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 468612D4D for ; Thu, 2 Nov 2023 10:59:56 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-d9ab79816a9so1487455276.3 for ; Thu, 02 Nov 2023 10:59:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1698947995; x=1699552795; 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=K/Jhn6xCbnHiyHqsQ6OV87Jm0NhFFz3VxLu59mRjmOo=; b=iBoZZbpUfZViBY4M/SMvUo/a9r30tvua28VrPB0fe9xsUT0/8q72tAzfR7GqnwtFzo S+1WLDNL097p3shvOAsKmMfA+g+Az5BvcvHPrDWYxyEspgT//sp/phXJQHmQgJBCeLfg hRFQ7gVtWBkqkg271qKALDOMUVl/sMPpTWz7CVeOz60TWIVp8z9V5yvCpQla/WF3tClH V7uCL8bDi6lp8a+iRF070FDru8j7JsdMZJ9I7UlpPHUz5U2tzb58mBj7zznSJRDLjppA 46gSQ9eOWm9c8obUfZ95oMFcOraFaw0CfD5kE0hU1y3SOfdGWVxw6twAETlAKUg8bQ5A 31qA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698947995; x=1699552795; 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=K/Jhn6xCbnHiyHqsQ6OV87Jm0NhFFz3VxLu59mRjmOo=; b=ZkTypkRvsimr+DGZ9Kv6KWtal5RuvXHqOQ1tSqe18/aKEPDVynjBdBKmYno8Me4l23 GoU86TjWdb/zEVvhXe7LnedXmUTlR89HvAbjNwA1pFHqxAnfDbMBPZEL9RyAWVe+gYJq L5csZGlUcCWjzm5BeFHAP4D6FS5uIWCCGeACYVfL8p1FbezcFK5BgwjN5R5KuCkpaFgR O4O6tFppXlHfATi/KnHp4draCiMl1bd7hubv/8jIz613CJQDccJW+F7er4+g/bki7Bzi oUKSq7tRH6BZr2XmgJ+SuSlVW+nMx66BYdJ2fMIGAKsEeSeiYuyWTdndZJyHMguKZY68 5RVQ== X-Gm-Message-State: AOJu0Yxky0+Qavki9kTbubTZgRvDDkSgiIKXJB6qRYAR4OpY3WRMSHFi EEWzO68k4oyjm3IhybkWSt3pVZBjzrLG X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:bb34:df9c:836c:afca]) (user=irogers job=sendgmr) by 2002:a25:5046:0:b0:da0:433e:871d with SMTP id e67-20020a255046000000b00da0433e871dmr325587ybb.7.1698947995138; Thu, 02 Nov 2023 10:59:55 -0700 (PDT) Date: Thu, 2 Nov 2023 10:57:34 -0700 In-Reply-To: <20231102175735.2272696-1-irogers@google.com> Message-Id: <20231102175735.2272696-53-irogers@google.com> Mime-Version: 1.0 References: <20231102175735.2272696-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.869.gea05f2083d-goog Subject: [PATCH v4 52/53] 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 , Vincent Whitchurch , "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 , liuwenyu , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-8.4 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Thu, 02 Nov 2023 11:14:05 -0700 (PDT) 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 | 56 +++++++++++++++++-------------------- tools/perf/util/dso.c | 16 ++++++++++- tools/perf/util/dso.h | 2 ++ 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 625dbb2ffe8a..e5018d390763 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,31 @@ 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; + 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]); + TEST_ASSERT_VAL("failed to get dso", !dsos__add(dsos, dso__new(file))); } 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 +260,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 +283,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 +318,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 +340,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 +380,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 0fef597725c7..4f20dac89b77 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -496,14 +496,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--; @@ -653,9 +659,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) @@ -1444,7 +1456,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 fa311ffd2538..e02a4718f1f8 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; -- 2.42.0.869.gea05f2083d-goog