Received: by 2002:a05:7412:b995:b0:f9:9502:5bb8 with SMTP id it21csp6936905rdb; Tue, 2 Jan 2024 21:14:17 -0800 (PST) X-Google-Smtp-Source: AGHT+IEHfIuVP8MwLhUEr4CqizEO+6d9tHsZ1/dnYLJ+A78S0B2n81kY2agmTLKmTrE7tMR57/Nm X-Received: by 2002:a05:6214:400a:b0:680:c80b:7acf with SMTP id kd10-20020a056214400a00b00680c80b7acfmr1649064qvb.86.1704258857756; Tue, 02 Jan 2024 21:14:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704258857; cv=none; d=google.com; s=arc-20160816; b=pIHJJIxmP8TY0B1/mwTM8PGYRYvngyE/XxMMigc1rvpmpS3PrRQR321D0z8d0Z/HLx ssYvlW/dTQ57QuKRD9nM2R1u+XaSSF5GcoUFUkMbtc7UHRU2ce9hlW1lemdyG2jtPYl6 HoUOXakHUGKJr/kUGiUzTL0/PRPlnw4YwWm0qapfsRopFKXrtgtRIDS7ecN2eLBtuo1a 3K85UgyCmwU9mLoIEU6ZJIoOKGd1bAO9Ut34KWL4wQMNlcYGQEapDbgn6d13V+4/wEBO LcI5/5dvtTCIb+FiWxZIx5AILVNQZCss5nuyJyFts21uvfbbuGR6jz8dLcV4PjvzoDyx EedQ== ARC-Message-Signature: i=1; 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=C38NvwcCeyU/k+g8J+mMKwfDhTmgD8SAkc8c8ZmGOFs=; fh=Io7x3OacpefNRRNKoYAzVE0aWTDwD7FRzyCdD1e3AN4=; b=igQ6OvHTz8QyTGKsnj9zuLlUmUfIsaWMNuX2s8nA290nXibCkrCC4FUYnykfxQXPLo QKSerFH4C+8VT9hCV3h1gLWeMIfdvtKsAlfx21n358Z7+Tel2/oK4i6zoVvRZi7hbsHD 05gqpnBT9FrB5Br9/OQk3+iUbapbqn79jMHdz/mPbZF7wCrjbPIyJr2c0Zl/hl9Msn3J YqabN3IX2RyivM8h7izlW+r/rXn3bBi2bJC9hQjNcTUpPTUV7hjyv4L70UfqnEoCMbWs bb9aeZ7f9b/TfQSsSx3zAEpIoE/6XfasuZartCW3S220pnBYDpDheICuk4/8aNzhLuZd /ytg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b="37UavV/Y"; spf=pass (google.com: domain of linux-kernel+bounces-15183-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-15183-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id s4-20020a0ce304000000b0068087e996c1si11507940qvl.455.2024.01.02.21.14.17 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jan 2024 21:14:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-15183-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b="37UavV/Y"; spf=pass (google.com: domain of linux-kernel+bounces-15183-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-15183-linux.lists.archive=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 76BEF1C22ED8 for ; Wed, 3 Jan 2024 05:14:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 51B6F1BDDD; Wed, 3 Jan 2024 05:07:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="37UavV/Y" X-Original-To: linux-kernel@vger.kernel.org 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 0D0D618043 for ; Wed, 3 Jan 2024 05:07:44 +0000 (UTC) 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-dbe02d0c945so3692150276.3 for ; Tue, 02 Jan 2024 21:07:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1704258464; x=1704863264; 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=C38NvwcCeyU/k+g8J+mMKwfDhTmgD8SAkc8c8ZmGOFs=; b=37UavV/Y6lIPKEltH1AbsFithUC6OJcDhT+WKd4yiHnJNUabNpTs6H7nrobSrsTZBo jcsdLznou86w9Z1naCawzWmnqAJZcifNKPJfAVhAi+/RPsDZZYwdP6FD79ZfrymbUy/I K2Ve33LNSts1uToM740feVN2U6ULU7xM86k2aq/dGlr2T/ZsATu4cTcLTjZy6qNQMrrZ 11l/V5cfXl2U1OV+NZybT+V9JalGYxMV63jk3rAqovcUSmVaa6ThQ6kGfnXKIrj5wB+j zasIjgL5AeHyZzxHPKI0JKgw9yPs09+J3FQid+ccgONE7Zk7qDcrU0EW+dk1NjxLmmxG tcDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704258464; x=1704863264; 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=C38NvwcCeyU/k+g8J+mMKwfDhTmgD8SAkc8c8ZmGOFs=; b=r4JotLj80dYNXk6jGuhU+EQwHj4DAfkM2QbXA/9xJi1z+M+ktHFdQ4s9ymO1/mMz9J u91x0jzDSAodcycGBxiUjTQyoQLMiKMP7mMyrppC4+FGZ53066gAh0AInP6e78Hh4ohe VIqN0yFsP6pxtxsNm4uPz4Ap3Qfp4yL+9d8YYr7iA8YgvOlBAjSqju765lPHZDXuFaZk 6wgbPxxk9OMPEEe4x5+gml60XgVMGM5QY+7mOlRdlEeQZddv0FgvzMZgUz2WgnEQq1mN j+MqbJo21tZemxQVHt6hdbPr3TyWU1Jmy6h9oyxo/Dtd6ftbY1LR2SVTwcNOZMwbr2v2 P5pA== X-Gm-Message-State: AOJu0YyHnEDZOuHb3VcimPlvDw1B1MHnedck5MZp1JqE50zExiRhJcM4 5I2NZ9X2grJbjWWNe/EcFCpmtKpwKo+0/qL92rY= X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:e2bd:f1f6:8ea6:8d6c]) (user=irogers job=sendgmr) by 2002:a25:6b02:0:b0:dbd:b7cb:8a60 with SMTP id g2-20020a256b02000000b00dbdb7cb8a60mr421984ybc.10.1704258463984; Tue, 02 Jan 2024 21:07:43 -0800 (PST) Date: Tue, 2 Jan 2024 21:06:35 -0800 In-Reply-To: <20240103050635.391888-1-irogers@google.com> Message-Id: <20240103050635.391888-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: <20240103050635.391888-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog Subject: [PATCH v7 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 , 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, Guilherme Amadio Content-Type: text/plain; charset="UTF-8" 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; -- 2.43.0.472.g3155946c3a-goog