From patchwork Thu Feb 29 06:32:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 208212 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2097:b0:108:e6aa:91d0 with SMTP id gs23csp209585dyb; Wed, 28 Feb 2024 22:34:15 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXZjFHMEU1vwGmythbFjWM4Ez83aWrJlXNF8tAzAQfQqemXBAwsyRyHfbDLgm+CVUnXDL7HS/mDc5iMydUNEzZRYAQ8Ow== X-Google-Smtp-Source: AGHT+IEJQnWVuU8msITsQRFoT5GnQ9DMVGh/ASaB3pii0wfuKliQ2+iIyCrpjJaqxqoxqL+e3WHe X-Received: by 2002:a17:906:6bd8:b0:a44:44ff:5dd5 with SMTP id t24-20020a1709066bd800b00a4444ff5dd5mr446618ejs.21.1709188455626; Wed, 28 Feb 2024 22:34:15 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709188455; cv=pass; d=google.com; s=arc-20160816; b=Un2TPRH7Cw9Rek+2L5JIiUVkP8wnF90HzRapuDzmzToHbBaiiujpo12LTtcUEoJgTD hT4qQ+baHGfUmBJmWqlLUvlNbs9uSZb05wy7zhX+SBT1K3lda7jsHamO0B9nYEs1PI92 tJufh2w7dbyn0fc/IHxMXfFKlyD9cgClkWyWlScgUGcOx3+Djtkfk0DZggLyUkSzhxUm Npk595zdkZFkDX3GOXKWpLZViVitZ8d8/u+/3pb2KbuJdxs7KGhoAQbVlxQfnBQIL+15 vr5q0M3v6gn+Gn/qnKRxlp0EhUbmmZyWHPWxXaH4itmF2u+hzzPL1dqCqgAJVOUsZNdx glYQ== 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=eHNbX5Xyi/VqeebJOw+lK9eWaYZye24FQe0AyXZlgyM=; fh=PNUKULeG9/C87hYSBckf3Qqec26ArMTCNQSbpXWGPLo=; b=CtiLxux5t2pLKLkEVI1F77T3reHgAIw6wZqhDvE24wB4Fh+PdX2Y7RdxdeUwI3zkpJ ZZKm5l092MaC9SVEFY2gVW4t0GJT+GdvPDWNdz3a4fsp3Y7YF9E56KrUrwpieK1WoNp9 0+exgmyze2xhmXdhpmEFouNc07u4MY05VHjSCYukVlhlD0JM4oi++K2YoIYLFDmLZyJt YaMfWruwuKSXCL3mdfTESqI6bZojGOwfw0Tb0zZzQywvUXbOQG8GzymT3NFyZmAI2mmy RQjdATOg0hf7UoPJXBnHdfDQrA+xBAUF7dfu0pLKOoEHB/CIV/diM4B5xPw9GXKEcxM5 4Nhw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b="si/v60O4"; 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-86173-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86173-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id p2-20020a17090628c200b00a430f28eb9fsi298893ejd.323.2024.02.28.22.34.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:34:15 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-86173-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="si/v60O4"; 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-86173-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86173-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 38B7D1F231F0 for ; Thu, 29 Feb 2024 06:34:15 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A1E71446D3; Thu, 29 Feb 2024 06:33:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="si/v60O4" 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 DE45036B0A for ; Thu, 29 Feb 2024 06:33:05 +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=1709188387; cv=none; b=N7XJ4qmtX8SlG2tXkviw06WHTraG7UafwyAI9sbMMiSnVwcNIpbBN+/NXwCEkX7lfahAuBY952+US2ygZxemB0FosecCtIDZnH39RUIPZQ0SI0ZbVs8z1lmCqL7lQGXIyhWrI/10O4hFhxumuL0X87MuUnKDgXGaxjVqopPlHNg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709188387; c=relaxed/simple; bh=soASIs7D8iQcX2U2s2M4JC6RaqIvyHatWg6UktdKnSI=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=jwEpkgqlAo0ZTIXRroAIlBGFW/jCSkbsRhqTNoht8tWUd+alEmv3RA17dfg5UuTmGRNidWueRV6RVTEfh+JlI3XFkRaQEDNuoV/2LAuwxQehgvKR0+pd5D435nhpprMsvKOr4rEsGOmVlDvgruBi1JwflbAljfl68DGRemTaRtg= 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=si/v60O4; 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-608d6ffc64eso8227417b3.0 for ; Wed, 28 Feb 2024 22:33:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709188385; x=1709793185; 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=eHNbX5Xyi/VqeebJOw+lK9eWaYZye24FQe0AyXZlgyM=; b=si/v60O4T4V4NmN75HXUfiMGRA9yqMoIC6MhzoEKci3e3TsIm5gsdGpa2QMiFDMMl+ zM0a143rYO7SbCCbaaVEspF6PKF/ZyIsiFkXMLpc0KCMSMMiNvxckdBRkvciWMeJjaUP IM2M6rrVRWWTLLZkF75NcuPqsdCstzYZSJLk7XgJZ1pSe1Mk7GpohBbXTJwiq2nVRg29 V61ypgV4lCsIAjylpjlcNsevdSQoByXqhwdSzF3FawkaR4jYMm2X0yOf9tCmkB62JWJY nk6E+A6le+CAMBn36CeMfaxP6V0Y1w5jZB7u8rOwIg2P5UTESCLjcF9Cbm/snbySb+vU I3SQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709188385; x=1709793185; 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=eHNbX5Xyi/VqeebJOw+lK9eWaYZye24FQe0AyXZlgyM=; b=Ui+v3lhhzDBWvxZASAGx9p03TtIvb2ftEw/hRvDjaTQc/83Otu58ArpBa1XjEYBD/O an0sWRzmSwlmGaqsMO69azpxiv7dDQdNSoVxjaw86ZjaBf4OrkwB0xbKlom4Z9wbaOcI IA/+7vxCLDUHnWzNeZgv+EsiH36NjZI2uk3jykMxzLrSjYdjwTqgqlsb3aj1JrSfIX0s Ya6XXqf69lPXsK6/HI4Qb+ba4sMOul4bcJ4WCeNwCFAn0NTOADLV9uraySb24EyIj8cM ra8n5Rb8rGv+U+ZmAkeAjccMq1WlA4V8SDruGHGp6+eSKit+0JtG15Kj97vIzh+2hdfM laJg== X-Forwarded-Encrypted: i=1; AJvYcCW5oyZuDPyTekv8i9HTFyGo0QFI46mlqO7cDEjFbfb+odRM1Ke0LTX2mgjIheE5rHVjRbWyh0xJh1eWYYwMKaMJj03I0LC0uP1e5htZ X-Gm-Message-State: AOJu0Yx/XM8iuhh3RG7gPx5KW6AAbWYRim5lQYDCPPTd3sutz3d1bWKd uljIPMw5jWjRH7ABloC0krCtLfeCRs/s6XD0Iw64wapbp31QKatTtCOjoVnRrSOvdg54gsh7sxv Eoi1LSg== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:77dc:144c:334e:e2dd]) (user=irogers job=sendgmr) by 2002:a0d:c346:0:b0:609:3a1f:e852 with SMTP id f67-20020a0dc346000000b006093a1fe852mr169734ywd.2.1709188384986; Wed, 28 Feb 2024 22:33:04 -0800 (PST) Date: Wed, 28 Feb 2024 22:32:48 -0800 In-Reply-To: <20240229063253.561838-1-irogers@google.com> Message-Id: <20240229063253.561838-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: <20240229063253.561838-1-irogers@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Subject: [PATCH v3 2/7] perf trace: Ignore thread hashing in summary From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Oliver Upton , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792213994220854534 X-GMAIL-MSGID: 1792213994220854534 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 Thu Feb 29 06:32:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 208213 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2097:b0:108:e6aa:91d0 with SMTP id gs23csp209702dyb; Wed, 28 Feb 2024 22:34:36 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUJc1n/rQTBYoMCvzr7wf/7m9ca9UO0dTs6HNf2TydVL4cYn7FBKLHZlMRGZfGIY5zgSamp2kHLhXBv0+duCBDkaD0amA== X-Google-Smtp-Source: AGHT+IHXMcBD4rKM1YYriUMYaZRNPGQkNXSvd6KBXPTis6Zwgd1xZAPr+i7v+VAqQHFcNUhitejj X-Received: by 2002:a17:906:d8b4:b0:a3e:b263:d769 with SMTP id qc20-20020a170906d8b400b00a3eb263d769mr719806ejb.4.1709188476161; Wed, 28 Feb 2024 22:34:36 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709188476; cv=pass; d=google.com; s=arc-20160816; b=oAgeczHOjfJ2pxfVqUzrIngYq8ZwznEEpMBKUiu2VUgoxMEcXLk5avF76jf+x8Rop7 ngw1LOk8yRQ9MIBa0yQBR/8QO/loNcvKLj1jBaOecsTjWrWa96rAnWSTK5AVDrwMK5T/ EI6yHXW3luw6em35uoBnx45wkH8lbPNpdtzdbMClL8aDWnMu8DCnx92VJzvjAh7M6USR QNYbq8FDW+bNzdnOR3CpJOPj94Nw86hcsyLzaXC9MCAbuzn+RMxsyRKbflojU7R/KeiN mt+jIB0S+hcByBgIjlk3MQ9CCB9hJVmWKQ1+Oe2BQ8VjISljbxC9ngTWHMXvH2Tl21RV sbaA== 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=TRPVI6egL+2XI2pKzd6EAQy7fDTiYP04TRmL/KfQbAc=; fh=QkoBxTvclpGyP2epznlBD+n2QbtFOHrIF5SqqV6awew=; b=DMMYcdpO78K7mc4BhkPG67Le7246oNnpTsafWJqHN8nr1MIa/bls1Ra9vLmUTGprwh wMmF65Iz2Z7zLFKQqgc5Gq4lYHSJT5UAsaPSa100c6+wdMzaTlBqPh26mp4m7r2n0jdZ X9LBgQEUs7wyF6Cd0El2XKpV8pkFvXAuJNKcWIAhmfmjKSs1g4uUdm+uzHQqB4TyxqoK NCuMoyObPwx3zYl4rdqmLOFbFMJx7XiKsQop3CbJgKkw9pypo52etXUTq9CLqmACJN6G yJK4PCU7cOaHRorv+zQV/WqOdqP/mXPV0pLNsUXpzpc07DTrWzw6CveWCauzxZsqK/bF 9oiw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=swNltk97; 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-86175-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86175-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id gv12-20020a170906f10c00b00a442d5afc56si286207ejb.658.2024.02.28.22.34.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:34:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-86175-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=swNltk97; 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-86175-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86175-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 C1F181F23554 for ; Thu, 29 Feb 2024 06:34:35 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9D3394503B; Thu, 29 Feb 2024 06:33:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="swNltk97" 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 2F71740BFD for ; Thu, 29 Feb 2024 06:33:08 +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=1709188389; cv=none; b=MutkpWa7Of+Ew+u/iEwdR7KrC4eY3SoTZvjkko2LCazxdAgIjd54dmeJrt86rQ8Ai547fexeiISlJ3oCR9a+QqsuGwN5sG992j+e6M9sgzghcC1va3bGR3UdpuwPAUrG2aEIo6SfPntLpZrJxd/48WsGTT8j4taV6OZJSqecIEw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709188389; c=relaxed/simple; bh=BBmU04u6tU5hlUeOKBhv7F/E4iRu0Xd0+OelCnDu9d4=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=jTL2VVgIm43vJ4yoCxxD4mGYlP2NLfNR6bKFZM5JujlSO/9z+7A+2m+sJ9MxwbHA6QXuz7SqfaVziFIrjP8gEoEe0M4TI9EUrmWeEIUrwCndpM/CKs7ixUe/nySiL0hjJBuRrEPhFXdWmZM04LcnerewebwSEghoiisF/nKyYJ4= 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=swNltk97; 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-608ab197437so10327977b3.1 for ; Wed, 28 Feb 2024 22:33:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709188387; x=1709793187; 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=TRPVI6egL+2XI2pKzd6EAQy7fDTiYP04TRmL/KfQbAc=; b=swNltk97i/QW+2O36YEmdnIcd3//4jY4e14/4GfBAao8Za5doN+8lzRqz1hze1Xh3t l2unn8Dq8ZyiE7h7TQSDwwjxpD5amWq5wqB4bxsz0eVvaiY1szsx3b/HCte8Jozj/aux mnfQU2SmQgJoY/PN2BfYMSPrVsyUyeF9Py8Gq+5NOiy1SIrsXVr48iNkdiXN9zXQuQlX pDmHOy9+0olyUAhvsyStlM4nznCSrKUj+WGv/gGUDNA642CkRnazJtFKS1IuUGrbkvh8 1KVMwAuxw1Oxym/igt1d+iC2D+zwmjFriLQyhPxA+jxeSkhzCSOBiy+CzoI+LsqXGq4k mqaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709188387; x=1709793187; 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=TRPVI6egL+2XI2pKzd6EAQy7fDTiYP04TRmL/KfQbAc=; b=UuBYlihLLjOBO1n9pjtvyrf5lcxoZyErN418VG1XnYedhc9oE+gMq+9NKJGLVMQEl+ cU//rahST3iu6nscigdIua7sRRZmRPFetBUKkae7ZuET+p8/L/+LWS4HXHruJEw9m5SY FjloxZPAfahODyD0ryw8TnPS1iw+NuP3hy3BiwR45lgEF65yYhgV4bhIW689UmKzED5y KRjsVgrf/VHfTJ3m44Q8bobov9l/rGqv9MGNaTFQlVuNq1Oc5/n8jLlv9c8uNcrws/Fj 5HtZhgPmM29CxGngNfE9hL0Rkh4SDpk5/3JNUHKdMP0TCeBFy9Xi2YSOamZUqjNcXXKn S5hQ== X-Forwarded-Encrypted: i=1; AJvYcCW6wJ2aptOH/yaoPOwK9PHosmShiqqIRpadRblttQE2Tt1r74HwnT+Yc2lDcDqkdZCUu59/WUltqPZuRuq0jaMxMfmhwV9tb1U91Yv2 X-Gm-Message-State: AOJu0YxK05Li+95Kqu9KmSPL1mY1wsxST0CEllwBpFWJBWNIo3OV7WOp c/zwda603HsXdFaepO8S5SlK9dUPLB52Bi5ZZahld9oIZdzrnlLI6tNUXPiq+nzEGFCP55PdXN+ YtMDCVg== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:77dc:144c:334e:e2dd]) (user=irogers job=sendgmr) by 2002:a05:690c:f8f:b0:608:ba07:3093 with SMTP id df15-20020a05690c0f8f00b00608ba073093mr304530ywb.1.1709188387308; Wed, 28 Feb 2024 22:33:07 -0800 (PST) Date: Wed, 28 Feb 2024 22:32:49 -0800 In-Reply-To: <20240229063253.561838-1-irogers@google.com> Message-Id: <20240229063253.561838-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: <20240229063253.561838-1-irogers@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Subject: [PATCH v3 3/7] perf machine: Move fprintf to for_each loop and a callback From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Oliver Upton , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792214015641664551 X-GMAIL-MSGID: 1792214015641664551 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 Thu Feb 29 06:32:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 208214 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2097:b0:108:e6aa:91d0 with SMTP id gs23csp210001dyb; Wed, 28 Feb 2024 22:35:32 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWUzWCvJj7GF9aNTPm9ixkHyG7AJkHRKCYBV1S4AaeXtxNwfivvVQYPhv3+KAc8SoWATkPT6iilAmxaUpjTwKHC7sQJiw== X-Google-Smtp-Source: AGHT+IE4c7b41zn1JvpF8CeWm6FwrRo3BBzcR6TBUI2g2wzg+r/syjPbkXQ82Xqz1MBQgy4s1+Mm X-Received: by 2002:ac8:5c47:0:b0:42e:3fa6:28a6 with SMTP id j7-20020ac85c47000000b0042e3fa628a6mr1383659qtj.3.1709188531956; Wed, 28 Feb 2024 22:35:31 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709188531; cv=pass; d=google.com; s=arc-20160816; b=GFf8yhpsLTksqf8ySaKBCqxDzhtt+StKgJtu7EhCINQtyHRe0GkLDBOCvG9N6t12AV 4NLLsNCeurtILibocv4aiCf1CKVuRZgVu8E7RbZ6ob0e2JSPGW4aQep2dAMhmDqj4UEt 9eR4vimjezwgKyPMQIKXsBFMlfxrjF/Rj1kcbS3/tPCxuEjouR93awZqUDafMEqKqOgX lDGnUFgiV1I9Nb+Ja/lZ+rloWDUo8WVCF/0LXAYwaFSjwXPexdaIfDRp0c3ZUSI6cZS7 2CVq4oj3erkEnfHw7UOry/9hnfp1+yP6DaU1ilDsFxlGLIWiCsjxof6L9pjbk+oXM8Zx fBRA== 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=+8VQY322jdwwX/8Cmv7X0ShLKhsaVmRjGE9HT8Sz4rY=; fh=w1vSP7L5E5HDTKjo67I65VPtiTTPwpRz9BDfG+yZ2+Y=; b=uuuL1eX71MRKcQZhzslVFfRk+JLXQovh0FEQs4n9bMxXwWbfZ2q5c8L3jjUvNxpDI8 sWdxAc7O2l1rBJXu+lO3TMAyUIt/EwR/mFc6VJ+W/t1tjqGcQieFPTo5PzhjgVIypxo1 vgh7LbF07vTcr2bOhDKNxuZPoSSiOkjYxlo4wFS1JfMZ3TUN+538q2psGhhXJfmyRRfS cJXRuLxFnHIvrOCH+tPasH3lQW5aDp5mnRqDftgJuPRThurbkSMK8Lhg+CcnkoYHP4Ob 9WqtzffxyILy1QgE6zsGNHGFTw0ky1xj/xdzieE1WRdM2VhsCVVAwpbxO/XPF/RdPCNI x1lQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=IY4qbCRo; 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-86176-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86176-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id d6-20020ac85446000000b0042e75c14eb4si762141qtq.806.2024.02.28.22.35.31 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:35:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-86176-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=IY4qbCRo; 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-86176-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86176-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 D8DF81C20D82 for ; Thu, 29 Feb 2024 06:35:15 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5EADE47F47; Thu, 29 Feb 2024 06:33:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="IY4qbCRo" 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 87601446C9 for ; Thu, 29 Feb 2024 06:33:10 +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=1709188392; cv=none; b=LzCWbAknsdFlJ8jC6dKN0JYE6X/fn9UVK1Hyfq5GpE10ILbPU2ACLhcGz9iPeXwR4g6YBKa5ntsYUMFiHwyL2M6414fl/RVhdqM928cS9EhA4NgSNxS3IQNtNgm8kRs2XSKoLz3sFnEB3bBxKAVBo4XRweYlXh16A3hJ2iHELs0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709188392; c=relaxed/simple; bh=gHFeIibfkee+Lj08lHjIrlKGGCYxpVSxPhBka+CmMEA=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=kZgkWCyYS0ht889mr2eioPLg/IlJbuJ+Jxv7m01jp/UAvVOfqk+oMeT+TVSFzTM3GAXy70qDM+SngaB+I7GGyh64jK6yyxYS8POXKRUHL6t9apvbzalYePMuo2mEyYfmg825feOkrd1MtrKYBFHGbjUIe/GKOhWY1DIN+1GDntE= 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=IY4qbCRo; 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-6087ffdac8cso8752017b3.2 for ; Wed, 28 Feb 2024 22:33:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709188389; x=1709793189; 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=+8VQY322jdwwX/8Cmv7X0ShLKhsaVmRjGE9HT8Sz4rY=; b=IY4qbCRo87ZT06xZZXCB4Tz84c29oTkCQB//bLbzTwL3iKobjBcRGHCEg6uEqjdgZd EQh0ucrnsZl5kssLCh/Q2WMyHyChZqKO3kSQyRK2UsFkSF49fF3NmduwJM/RMrhX2OYX trA/yvUCF5U61jamJHHOOrFAY4YbljH+uZaxqkteu5kKUjMQThLk4dyhdOgiW9ThAOzW l3n56ksv2r/lATh0hPE4DQSyBoP5fHJskyJUI5JtCG4BdnuvlO1BaWCknQh7v+92lF7M 4bZvgd8+Es60hDqTOiPJph1L9dcrpk+H67MxvvwKRRcRqj4TMTNmTTs/hxjBrahw45Vl RzNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709188389; x=1709793189; 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=+8VQY322jdwwX/8Cmv7X0ShLKhsaVmRjGE9HT8Sz4rY=; b=xAmIxHSC7RC5Yn7zrMqI73Im6f/cZ9hJQ5JJtvhIEIkJd/NY2h+M5ZMIs0xKBYbmX2 M4AZWP06O4qSZVeojegLacIJ9vBfaORqtXjLl05OVDX2Pn+GRVXXSWgfh9y+sJ7gm7ky 3zgWTW5f+JDctQgxJPY1GJEQ4tNw/bDUWxnVhLTd8RA5ctT7CTYZJuKlfwRfqRSNs06W rDfuP9Nen8M5OrHKBUSnZgwUrgD1/vje5tS2SD64WFDMHl0rlmOUehAX/0YIIQ2cNDGh XDQVcq5OoVZFo5yVBXuEsr0eRLNzquZ/Dpp/cGbLMdsg8N/3a9DZq2c8PLDX8Iy4gC50 Bq0Q== X-Forwarded-Encrypted: i=1; AJvYcCWxJoi+FlACPeOewjTPJ+luP1GbYATvsR+A4/8UUFIFbuBSv/SSXwBWJzGwQFhW2u1HHt7RMOXkkbOGr2NTX5dhd1O1XQ9DyHPiSxGF X-Gm-Message-State: AOJu0YwlWgMLltyPTimxD61ZH5EF5urXdrDSxbrdPxPcn+WkdbBYS4WE eBp+YzjRvdgUB8jpilKDEeCaohTLC8iQfuQ6SnlEMr86EngiyXnlAQtZ11ebkzokGEii2PW44Pe vTHRvpA== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:77dc:144c:334e:e2dd]) (user=irogers job=sendgmr) by 2002:a81:9953:0:b0:608:321d:62f8 with SMTP id q80-20020a819953000000b00608321d62f8mr319298ywg.7.1709188389665; Wed, 28 Feb 2024 22:33:09 -0800 (PST) Date: Wed, 28 Feb 2024 22:32:50 -0800 In-Reply-To: <20240229063253.561838-1-irogers@google.com> Message-Id: <20240229063253.561838-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: <20240229063253.561838-1-irogers@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Subject: [PATCH v3 4/7] perf machine: Move machine's threads into its own abstraction From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Oliver Upton , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792214074022127390 X-GMAIL-MSGID: 1792214074022127390 Move thread_rb_node into the machine.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. As the lock is now encapsulated in threads, the findnew function requires holding it (as it already did in machine). Rather than do conditionals with locks based on whether the thread should be created (which could potentially be error prone with a read lock match with a write unlock), have a separate threads__find that won't create the thread and only holds the read lock. This effectively duplicates the findnew logic, with the existing findnew logic only operating under a write lock assuming creation is necessary as a previous find failed. The creation may still fail with the write lock due to another thread. The duplication is removed in a later next patch that delegates the implementation to hashtable. Signed-off-by: Ian Rogers --- tools/perf/util/bpf_lock_contention.c | 4 +- tools/perf/util/machine.c | 402 ++++++++++++++------------ tools/perf/util/machine.h | 26 +- tools/perf/util/thread.c | 2 +- tools/perf/util/thread.h | 6 - 5 files changed, 238 insertions(+), 202 deletions(-) diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index 31ff19afc20c..e631127a655f 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,7 +302,7 @@ int lock_contention_read(struct lock_contention *con) return -1; if (con->aggr_mode == LOCK_AGGR_TASK) { - struct thread *idle = __machine__findnew_thread(machine, + 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..d161f5932efa 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -43,8 +43,16 @@ #include #include -static void __machine__remove_thread(struct machine *machine, struct thread_rb_node *nd, - struct thread *th, bool lock); +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 struct dso *machine__kernel_dso(struct machine *machine) { @@ -58,35 +66,18 @@ static void dsos__init(struct dsos *dsos) init_rwsem(&dsos->lock); } -static void machine__threads_init(struct machine *machine) +void threads__init(struct threads *threads) { - int i; + for (int i = 0; i < THREADS__TABLE_SIZE; i++) { + struct threads_table_entry *table = &threads->table[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; + table->entries = RB_ROOT_CACHED; + init_rwsem(&table->lock); + table->nr = 0; + table->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 +111,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; @@ -219,29 +210,51 @@ static void dsos__exit(struct dsos *dsos) exit_rwsem(&dsos->lock); } -void machine__delete_threads(struct machine *machine) +static void __threads_table_entry__set_last_match(struct threads_table_entry *table, + struct thread *th); + +void threads__remove_all_threads(struct threads *threads) { - struct rb_node *nd; - int i; + for (int i = 0; i < THREADS__TABLE_SIZE; i++) { + struct threads_table_entry *table = &threads->table[i]; + struct rb_node *nd; - for (i = 0; i < THREADS__TABLE_SIZE; i++) { - struct threads *threads = &machine->threads[i]; - down_write(&threads->lock); - nd = rb_first_cached(&threads->entries); + 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); - __machine__remove_thread(machine, trb, trb->thread, false); + thread__put(trb->thread); + rb_erase_cached(&trb->rb_node, &table->entries); + RB_CLEAR_NODE(&trb->rb_node); + --table->nr; + + free(trb); } - up_write(&threads->lock); + assert(table->nr == 0); + up_write(&table->lock); } } -void machine__exit(struct machine *machine) +void machine__delete_threads(struct machine *machine) { - int i; + threads__remove_all_threads(&machine->threads); +} +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); + } +} + +void machine__exit(struct machine *machine) +{ if (machine == NULL) return; @@ -254,12 +267,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 +534,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; @@ -565,78 +573,88 @@ static void machine__update_thread_pid(struct machine *machine, * 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) +static struct thread *__threads_table_entry__get_last_match(struct threads_table_entry *table, + pid_t tid) { - struct thread *th; + struct thread *th, *res = NULL; - th = threads->last_match; + th = table->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; + if (thread__tid(th) == tid) + res = thread__get(th); } - - return NULL; + return res; } -static struct thread* -threads__get_last_match(struct threads *threads, struct machine *machine, - int pid, int tid) +static void __threads_table_entry__set_last_match(struct threads_table_entry *table, + struct thread *th) { - struct thread *th = NULL; - - if (perf_singlethreaded) - th = __threads__get_last_match(threads, machine, pid, tid); - - return th; + thread__put(table->last_match); + table->last_match = thread__get(th); } -static void -__threads__set_last_match(struct threads *threads, struct thread *th) +static void threads_table_entry__set_last_match(struct threads_table_entry *table, + struct thread *th) { - thread__put(threads->last_match); - threads->last_match = thread__get(th); + down_write(&table->lock); + __threads_table_entry__set_last_match(table, th); + up_write(&table->lock); } -static void -threads__set_last_match(struct threads *threads, struct thread *th) +struct thread *threads__find(struct threads *threads, pid_t tid) { - if (perf_singlethreaded) - __threads__set_last_match(threads, th); + 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; } -/* - * 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) +struct thread *threads__findnew(struct threads *threads, pid_t pid, pid_t tid, bool *created) { - struct rb_node **p = &threads->entries.rb_root.rb_node; + struct threads_table_entry *table = threads__table(threads, tid); + struct rb_node **p; struct rb_node *parent = NULL; - struct thread *th; + struct thread *res = NULL; struct thread_rb_node *nd; bool leftmost = true; - th = threads__get_last_match(threads, machine, pid, tid); - if (th) - return th; - + *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__set_last_match(threads, th); - machine__update_thread_pid(machine, th, pid); - return thread__get(th); + __threads_table_entry__set_last_match(table, th); + res = thread__get(th); + goto out_unlock; } if (tid < thread__tid(th)) @@ -646,74 +664,76 @@ static struct thread *____machine__findnew_thread(struct machine *machine, leftmost = false; } } + 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; +} - if (!create) - return NULL; - - th = thread__new(pid, tid); - if (th == NULL) - return NULL; +/* + * Caller must eventually drop thread->refcnt returned with a successful + * lookup/new thread inserted. + */ +static struct thread *__machine__findnew_thread(struct machine *machine, + pid_t pid, + pid_t tid, + bool create) +{ + struct thread *th = threads__find(&machine->threads, tid); + bool created; - nd = malloc(sizeof(*nd)); - if (nd == NULL) { - thread__put(th); - return NULL; + if (th) { + machine__update_thread_pid(machine, th, pid); + return th; } - 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); + if (!create) 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 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,13 +1147,17 @@ static int machine_fprintf_cb(struct thread *thread, void *data) return 0; } -static size_t machine__threads_nr(const struct machine *machine) +size_t threads__nr(struct threads *threads) { size_t nr = 0; - for (int i = 0; i < THREADS__TABLE_SIZE; i++) - nr += machine->threads[i].nr; + 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; } @@ -1143,7 +1167,7 @@ size_t machine__fprintf(struct machine *machine, FILE *fp) .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 +2093,42 @@ 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) +void threads__remove(struct threads *threads, struct thread *thread) { - 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); + struct rb_node **p; + struct threads_table_entry *table = threads__table(threads, thread__tid(thread)); + pid_t tid = thread__tid(thread); - thread__put(nd->thread); - rb_erase_cached(&nd->rb_node, &threads->entries); - RB_CLEAR_NODE(&nd->rb_node); - --threads->nr; + down_write(&table->lock); + if (table->last_match && RC_CHK_EQUAL(table->last_match, thread)) + __threads_table_entry__set_last_match(table, NULL); - free(nd); + 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 (lock) - up_write(&threads->lock); + if (tid < thread__tid(th)) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + up_write(&table->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, @@ -3228,27 +3258,31 @@ int thread__resolve_callchain(struct thread *thread, return ret; } -int machine__for_each_thread(struct machine *machine, - int (*fn)(struct thread *thread, void *p), - void *priv) +int threads__for_each_thread(struct threads *threads, + int (*fn)(struct thread *thread, void *data), + void *data) { - struct threads *threads; - struct rb_node *nd; - int rc = 0; - int i; + for (int i = 0; i < THREADS__TABLE_SIZE; i++) { + struct threads_table_entry *table = &threads->table[i]; + struct rb_node *nd; - for (i = 0; i < THREADS__TABLE_SIZE; i++) { - threads = &machine->threads[i]; - for (nd = rb_first_cached(&threads->entries); nd; - nd = rb_next(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); - rc = fn(trb->thread, priv); if (rc != 0) return rc; } } - return rc; + return 0; + +} + +int machine__for_each_thread(struct machine *machine, + int (*fn)(struct thread *thread, void *p), + void *priv) +{ + 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..5b425b70140e 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -31,13 +31,28 @@ struct vdso_info; #define THREADS__TABLE_BITS 8 #define THREADS__TABLE_SIZE (1 << THREADS__TABLE_BITS) -struct threads { +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); + struct machine { struct rb_node rb_node; pid_t pid; @@ -48,7 +63,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 +84,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 +229,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 df344262eaee..8b4a3c69bad1 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 @@ -29,11 +28,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; From patchwork Thu Feb 29 06:32:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 208215 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2097:b0:108:e6aa:91d0 with SMTP id gs23csp210040dyb; Wed, 28 Feb 2024 22:35:38 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUHtGIEXz17F8e6FCtWDWfTNwhsLuyCDhzBg5UsE+s95NVOmjQjHaGKrYoyT7FOBGGAdmvVn/NWGDN+N9mZZsiRBenemg== X-Google-Smtp-Source: AGHT+IGPkkeetarPmHIy6DHwd8YZ4ECosFpJSYvth6Zpt56F0YblaYcjacsbMjDBq5vE1RLurS8w X-Received: by 2002:a50:9e8e:0:b0:566:16e4:b6b3 with SMTP id a14-20020a509e8e000000b0056616e4b6b3mr833405edf.36.1709188538397; Wed, 28 Feb 2024 22:35:38 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709188538; cv=pass; d=google.com; s=arc-20160816; b=w51ace11GBHwquqBIrYnz66Xhbo7bAYphZqeRkH4qa088uDECaNRv4gYg4rSp7quL7 Uzb1GWqyiTjhFj7lSTov2WrgTg24t2zLJWVM0U2Gl/da+E58RS/tMEaHE46zKKX5v4jK 0ztm7vhcdqkg68YNS8qooqVrIaQyF9ZV1Tojgoh1gve4U9Onuz6/xFHWb7HzEgRqU4ia LReGr7jepSc+lFMqjxedo2qw9s2Fsz3nUc6SZb2aZQDiS02vo7K0I0x8+XIwOnHjV3YJ uvmWz5E1psrHvmsesYKMJZDgUG9wBY75UrAi5SDhimUgVAlllNYrWqYi2OEUvJpxwFzg c4Sw== 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=PYOa0NqpO7ZIYSUdRBhLyKWtB8fWkZj/AlMU1wCBYqA=; fh=T6FVeTOriXTzBnWcwgsoYUwyHiQZ+jCeljV0aD9Uz8A=; b=WL/pNAL5+IIegdPYT4Qe23qo9irb0f7RztXZ41cJw/bAPzRXM+h1IspoZy2y2lWEsX oR2BaBjWIMXfxDTfBk3w9loaQrSTXD7infpzpi5V+BbjT+rKj3RoZaUj04wnf+wAvXfi EvoKSpnQ4hf5GXYWeZglmhBPiQAFLum+lQoSlSb/c22ituYo/scAoILHwxNIVbDid8NO GH39d2lNSXVfKZnwdDGCN0me4YgS71ONBnKpF+j7wmfP2juy4hOypzd9MXn3utQkkW7P KJvASUabgroZh2hTwpKlqmip1ELxnK537DOUjYixKEs1LAuO3qPmrogMOcxMF0iP4E9X 1FBQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=RXsBAlXE; 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-86177-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86177-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id z9-20020a50cd09000000b00565fb062591si303041edi.631.2024.02.28.22.35.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:35:38 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-86177-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=RXsBAlXE; 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-86177-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86177-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 D52061F235CF for ; Thu, 29 Feb 2024 06:35:37 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1E49B481C4; Thu, 29 Feb 2024 06:33:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="RXsBAlXE" 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 EDDE845948 for ; Thu, 29 Feb 2024 06:33:12 +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=1709188395; cv=none; b=Mt5ubLmB4zk4R/FHy5N+FoUBOCMc1gx3edDL0GWGMdT1u9wIU0GroWSGk9uX4PMlvSobgd1R8D/kOBgQKE/BIsT7EdZ6AXiSKgA5IUKIT8MLyXyg4LZlRcQqWvpg9hgU28E0TqgWL7NqVPF6kngQapt5oc1h2BvwSA42qCX2X/A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709188395; c=relaxed/simple; bh=tsGNnw8n28aQmn4X55h9KDhXmlV0IWqCpT0aGC2QFwU=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=W4Hy7g7U0dK2LVoyizzJTuz+xtU7W3DsanfUaAO6abOYL9D9d2JFBHUUkwi2exyvIwBDtXd74d5gOJWir80BNb3J/VYC5L5FBvicWxz6x/1QWsJflQWpSuPWTM0LIOiwTLE9S9ZCzF7Qrvqq8XCTqA3qERmEyjWjWUe8zpORJaM= 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=RXsBAlXE; 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-dce775fa8adso1152969276.1 for ; Wed, 28 Feb 2024 22:33:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709188392; x=1709793192; 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=PYOa0NqpO7ZIYSUdRBhLyKWtB8fWkZj/AlMU1wCBYqA=; b=RXsBAlXELmx2e1nMu8/HKFbYdC0aPTBK5t6d+Ojs4U7m00jjvGbK+PxZ3gsd+Ijpbg +mhqc38OKoG9temsL0AX/NWoTU0Vw+nqOwLhd6DSfULZU0qclH1G/qClZ3ZHiMDl5YuM BGAI3v8w68jgsGI8hMGxn5zSc1K8eSyCqEmd4B1/7gp10te3zW18HLIVCnZj8wyUoLkH mScJaSv4j5yr+yBFOXUEZZrfxyfIKZc0TYrE569CJX7KbNuNgQGf8kKotRU8vBWub7fi RsmFUjkNED/dl2npsmDkaB3W8muTB9AWmP207BiWu1Bx8HmOehIMh0FXVMwYQeZt8WlF WzBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709188392; x=1709793192; 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=PYOa0NqpO7ZIYSUdRBhLyKWtB8fWkZj/AlMU1wCBYqA=; b=PvGgLgKFPkx+nffN3yCk3qApu4xTbyjfQYq9tN9gVDnkzk5pd6in1fhNs8ImVscVuk FH2BTSFLskgzhKJ3zYN3haijTMqXMRmpCDfpyd/GG+rap/vBSSDXMpf65b281Ox64hh5 2d67mG6fO4qFAM/iEkaZj3hjPCk5ZWAN3ErXMHLzcM4t8wYXL2sgYqCug27JmLql99QI 1zzCDRE2PekZL4+5mKEpmif0SJdhyWaBFN26G1URI435f/axhMUCj8bSZNhPDr/CqgTJ 8sXv9hkfEVZ/vQSY6PcyCBfW49PlDVHjVaCdlUF+adJauoPPWZpwqWRh1k5wjOBGQi5l HKHg== X-Forwarded-Encrypted: i=1; AJvYcCU4rPsIWbbte9nLH3sCoQ/CjlNTSgfDAHepxMJO80TYZhgsYXCVqLl9ULT7l1HHoA65Lw1Ak6vpFEWUBkKE2otL5kEoi2SfolhasA8C X-Gm-Message-State: AOJu0YwfcdWhGwSLr0WybTI2WWf4YEF/A/UR+3gp0Ca5SwFIft6LAhTs c/3woaFkmTvoIUtKIOi816YdmgFaRcoSOWicy7ISnIhR9GEjyGxSbU+iaNPRWuPIGNE6imdD6tH xekS0rQ== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:77dc:144c:334e:e2dd]) (user=irogers job=sendgmr) by 2002:a05:6902:102b:b0:dc7:53a0:83ad with SMTP id x11-20020a056902102b00b00dc753a083admr380328ybt.5.1709188392039; Wed, 28 Feb 2024 22:33:12 -0800 (PST) Date: Wed, 28 Feb 2024 22:32:51 -0800 In-Reply-To: <20240229063253.561838-1-irogers@google.com> Message-Id: <20240229063253.561838-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: <20240229063253.561838-1-irogers@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Subject: [PATCH v3 5/7] perf threads: Move threads to its own files From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Oliver Upton , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792214081174276450 X-GMAIL-MSGID: 1792214081174276450 Move threads out of machine and into its own file. Signed-off-by: Ian Rogers --- tools/perf/util/Build | 1 + tools/perf/util/machine.c | 244 -------------------------------------- tools/perf/util/machine.h | 26 +--- tools/perf/util/threads.c | 244 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/threads.h | 35 ++++++ 5 files changed, 281 insertions(+), 269 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 2cbeeb79b6ef..e0a723e24503 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -72,6 +72,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/machine.c b/tools/perf/util/machine.c index d161f5932efa..527517db3182 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -43,17 +43,6 @@ #include #include -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 struct dso *machine__kernel_dso(struct machine *machine) { return map__dso(machine->vmlinux_map); @@ -66,18 +55,6 @@ static void dsos__init(struct dsos *dsos) init_rwsem(&dsos->lock); } -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; - } -} - static int machine__set_mmap_name(struct machine *machine) { if (machine__is_host(machine)) @@ -210,49 +187,11 @@ static void dsos__exit(struct dsos *dsos) exit_rwsem(&dsos->lock); } -static void __threads_table_entry__set_last_match(struct threads_table_entry *table, - struct thread *th); - -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 machine__delete_threads(struct machine *machine) { threads__remove_all_threads(&machine->threads); } -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); - } -} - void machine__exit(struct machine *machine) { if (machine == NULL) @@ -568,121 +507,6 @@ 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_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 { - p = &(*p)->rb_right; - leftmost = false; - } - } - 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; -} - /* * Caller must eventually drop thread->refcnt returned with a successful * lookup/new thread inserted. @@ -699,7 +523,6 @@ static struct thread *__machine__findnew_thread(struct machine *machine, machine__update_thread_pid(machine, th, pid); return th; } - if (!create) return NULL; @@ -1147,20 +970,6 @@ static int machine_fprintf_cb(struct thread *thread, void *data) return 0; } -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; -} - size_t machine__fprintf(struct machine *machine, FILE *fp) { struct machine_fprintf_cb_args args = { @@ -2093,39 +1902,6 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event return 0; } -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); -} - void machine__remove_thread(struct machine *machine, struct thread *th) { return threads__remove(&machine->threads, th); @@ -3258,26 +3034,6 @@ int thread__resolve_callchain(struct thread *thread, return ret; } -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; - -} - int machine__for_each_thread(struct machine *machine, int (*fn)(struct thread *thread, void *p), void *priv) diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 5b425b70140e..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,31 +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_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); - struct machine { struct rb_node rb_node; pid_t pid; 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 Thu Feb 29 06:32:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 208217 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2097:b0:108:e6aa:91d0 with SMTP id gs23csp211328dyb; Wed, 28 Feb 2024 22:39:48 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXeqbh9DCwzimbbmygqsFPRPX9/zL1tEVrBs3WYMmpVbuaZ57y8GbK0VxFyU6WGyHO1eruvzsVRENeFu/IKTwP7VT6llQ== X-Google-Smtp-Source: AGHT+IEQitqRhDrO+fJuZDLLFL//Cc1CN6pRIMxbNJx6evq04hY32835BF5sDGlzJO/6ZrFgh+bZ X-Received: by 2002:a05:6e02:dcb:b0:363:ad01:f052 with SMTP id l11-20020a056e020dcb00b00363ad01f052mr1551321ilj.24.1709188788655; Wed, 28 Feb 2024 22:39:48 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709188788; cv=pass; d=google.com; s=arc-20160816; b=N7z4D0lFYRkHC88V2I7gwF5n1EhjlqcBvbECtmVzouScPOTGyIdNGc3QTDT6mOSNbs g1OmnPD3L2265ObwuPuANjRZx5UMV1SGiQdkocU1VaHxMQvmCpScSz3EJbqaKZb5IZlR XrEmePe5qz3enarlnMhpdiTH8/qVPlJUvhBWsFJxxCALg3BtPAiV33XQ2un5hvdGJUjd v9EY88ubX64doGovhEjHCuNUkN+vg8WOE4E8Hg5bV+KIX51ziO44NG73q9kqni8uMibt 49zO0LkBPL+rnx0am4nwDiDRoEJDMjo+9rd/92ymSjQXR/lsTt+VupPoz7xCnVEmn2rH I2uA== 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=Lzq935DVwsBD/3GlNv8R9DsWFU45sAreOLDrveyoktg=; fh=AFIq/e1sSkoN6PLatuWMX0rX4IbiSUZwN91e01gVWSM=; b=fF7jOQ8Gf3nnSAszUw/ZVvt1PI3+N1+Nq1450mimCesQAGkMUWd92HAMGruGjBTIaz HvUzQsY+6pxNh09UxSFv1l7rQ5EZKZJcvmPCAvWKel9ocMecI8F7ZVmhQZ//+3MmZR3g Z/BBJ+9jVLKs5R3XCYgRN6PDz3yljgyzKBQCZSio6tQ8BudtlPYXwewWTQX8JTv5d3bz lq3bl1lWnwcJNdCZX5LBvEDX/6uiHV3qgJO9IIyy4IbrYIMUTIbG7fWROXHm4VRIX6l+ fq4ipSOuuiw1Sa8rW9KRDMV61Ej7hu71dAeuQdTbDsHjBba+2+LoczILiL315P0d571V 5PJA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=jx3tqIMa; 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-86178-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86178-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id v28-20020a63481c000000b005dca5caed4bsi751738pga.516.2024.02.28.22.39.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:39:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-86178-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=jx3tqIMa; 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-86178-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86178-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 0DCB1B260D1 for ; Thu, 29 Feb 2024 06:35:37 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 11A4E481BF; Thu, 29 Feb 2024 06:33:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="jx3tqIMa" 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 528B745957 for ; Thu, 29 Feb 2024 06:33:15 +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=1709188397; cv=none; b=twl36fscdWSPu++vACt1dVOeazrGb2k4uP4ktZ/IUSwtBFhG2me6jZSvYjB2KsLKhT3SW+gYL5TW7mMo5L78Ym61WRiInEyUGZhxWIVAtYIxBl4o8HaPJmvieAPH7GSqGsUIlWgytHG0CGn6ukQHUmhI5diIXZ4TTAmcP6iQGlA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709188397; c=relaxed/simple; bh=hShucPp/bdTejRddl6V+fFxtMi6g+GO8s+RiIxpwE8s=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=COeAiYEKP54vmuN5jLZEtkq4HBKL0/u+hqWIF/Zw77ekdTClqI5dNXRM1KdSZ1ub8WGhr0cDSh/aO5HxuwKz2saUh15qPTV+xMWtZr0JPW+LqxeR84u/pvSC2uXfLo4p2z9x1FHnAy5nxRTVvyimzIOTiTp/UMlJ069woONeDis= 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=jx3tqIMa; 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-60971264c48so3052807b3.0 for ; Wed, 28 Feb 2024 22:33:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709188394; x=1709793194; 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=Lzq935DVwsBD/3GlNv8R9DsWFU45sAreOLDrveyoktg=; b=jx3tqIMaHuylhTrc04K4UixFgMEH88z4Wa1ujnggLgkdhAmHhHkpO1lPeKBAiEMEhj CbU9QJGDPQdlcxRaNbQp0qPVHgQuIYATDTqqddkeVoEEH3ZP4vK+2/8ZdRp/qCWksiTO dWStPx/wYDa5E87TnGTT9yq3QOGFjl51sJ2wODbNk9BhnNaqJdSoVBY8PHjAv8MqCxpg 4wE7Jf+VUTHbkt4tvYe8OvyzpSTUhh4p8Z+9MN3Zj33JPGxJ6/qZXth+DiqedWRneHyV y26LhHaCOM5OPXzIVbmI6w/O3ttOgNmFT9xM9NtZHRBv57Zka6QLpNZM/H+xe8du3tJC oFUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709188394; x=1709793194; 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=Lzq935DVwsBD/3GlNv8R9DsWFU45sAreOLDrveyoktg=; b=d1SzOyHyYoWvvtOpVK+g5ev9fxxUSjcpZvj/Rm16u1u/ZaSVhLYdukvLzoz0IAKnav oUx5spY6MTcfROq3p2wquLh9iZPNJCYhXwhxwmuhLcq1h6dLtH4bOyy31T8SYFaj3a3q sgFHqUj2IY7USscCy3nJhnumO15fE4egRIdNcXHpJH5M4d0/3/ylpDJIDGPu/rus2HQ+ w/myA6viAsyoJTmhp8g1FW9s5I4CcYH+XamfHqCT+2E8fJRL2IFWwW3qzMmebr5pMdJk pg6gai/fPsLMnlHAJNjNWrArUPciev9SZIjjzeS6mzjZSf5cr6XZ6gzwDOwxZmZUu2IC k3YQ== X-Forwarded-Encrypted: i=1; AJvYcCUJ0y6L1Jk+SkbEUj9JlndjUxkWTHB2W6tZVq53bNpzcSWw0qQDwJv0I4eUn8+2qxifYCV2IF066GMbaFdjrPx2AwvYFFyA/4TK/Rd9 X-Gm-Message-State: AOJu0YwTS8CpdOya/TFOzBRAUmtTC+gx9vCy+u2q72ANRmzcnqY57lAC sb6OpbqXTh0LtstGASkK3AVTbFeV63N7c7GolwL6LvueVxC1dkTYo5XikyEv5VrCaDWMpl4f3Ez jc5MP+w== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:77dc:144c:334e:e2dd]) (user=irogers job=sendgmr) by 2002:a05:690c:3507:b0:608:e67f:4387 with SMTP id fq7-20020a05690c350700b00608e67f4387mr277019ywb.7.1709188394512; Wed, 28 Feb 2024 22:33:14 -0800 (PST) Date: Wed, 28 Feb 2024 22:32:52 -0800 In-Reply-To: <20240229063253.561838-1-irogers@google.com> Message-Id: <20240229063253.561838-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: <20240229063253.561838-1-irogers@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Subject: [PATCH v3 6/7] perf threads: Switch from rbtree to hashmap From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Oliver Upton , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792214343310478124 X-GMAIL-MSGID: 1792214343310478124 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 Thu Feb 29 06:32:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 208216 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2097:b0:108:e6aa:91d0 with SMTP id gs23csp210094dyb; Wed, 28 Feb 2024 22:35:48 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVq/Z4K+u8ulco2GwnGnF58cOAPGtYTJxPcL8zO22ncx4Mupx3Oc3aRnXB39b8JBslIfbBmqEWnj3RBcn+4x/d4aSg2mw== X-Google-Smtp-Source: AGHT+IFrLYxJMMEuGiOVzJrwIlNmjawCSM64u7r2ilojsjUmIRqyHPiT+z8UktJ9//KMnUmOoaMa X-Received: by 2002:a17:906:7c06:b0:a44:505f:bfa9 with SMTP id t6-20020a1709067c0600b00a44505fbfa9mr164003ejo.58.1709188548031; Wed, 28 Feb 2024 22:35:48 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709188548; cv=pass; d=google.com; s=arc-20160816; b=IYkywQHfyK0O37qbYCLQdGs+3LeCieT/admS5iqrJNkqEZQexWQMpxYAxxDrj5EGrO P+3AsQwquD7orvCyXU9C09KU2OvtfhioQAdj6D0gDf//yjt8HKIm8i5D5CT86fw50IFq 1tcp2XQDwwUqDZQswU6kzxv/sQ8EAm5xaNOXJ3pLx934Tw9Bsef9D4KVmODDUlrHXDTe jCB9dGNhJBDTPCsGaDpOXXy7PgNEH8f98CWLhVm9US8seYySgX7vnPa2O16pFJTYngMv 4+TFG1wt7xof7q4h8fOhTJ++nAtUZWGYdTk2JB+s+cavxgsiwho5AluUnpKGna4KkBhK PszA== 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=h3EeOnj2LJFuh4Gzgf1odB7yRFHxb61zXSqdlmTf/sY=; fh=GomGuibOhxdK0XyI5V4KUyK7yCiFqYRuvRImaXZmt+E=; b=qEpIMU7kdYvy2gkoZh59cZv2MDMprtRpRqwZ6P9D1tXTbFRlB8I4/T9cLZlSVisb+j Owu/bVFSoAO8cwRB1PlnfOehzXZCVRH4IYabZCmRy5mCL9l6U6uEwB3GyPnk6AdLspa6 873WBhaMNknfUI8VpS48snI5cBr6crsZ4S+xSGB39BowIU4dwYjlX5P0gQ+U2lgXKdpX T8ewM8EzSYuGyBluXRY0VMORwg1p5udAq2cKwuzhrydIXJm09TUOLUPIThvKsUzyaM1/ xQAgzpGW/SKnn09Me9KjPiFYTfbTtBgFGsFahP1aFwOsvukaKcWfJ3KAM997nwFojHTz wQWw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=YKbaYtCx; 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-86179-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86179-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id jt20-20020a170906ca1400b00a3ed86dc13bsi302496ejb.265.2024.02.28.22.35.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Feb 2024 22:35:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-86179-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=YKbaYtCx; 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-86179-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-86179-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 56B391F23686 for ; Thu, 29 Feb 2024 06:35:47 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 45CC6482E6; Thu, 29 Feb 2024 06:33:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="YKbaYtCx" 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 0693746449 for ; Thu, 29 Feb 2024 06:33:17 +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=1709188399; cv=none; b=ufs/UaIZj7IprPZjp0xxMnzL8h+NLteUVGRFcVjxRk0AmWo3pjY80tEQtIJU3pW5WuUn/qyw088S8/bqbkmDWeXWxUhX5DAfZKsOexL5iuRA9QuJ2AHVsqBxBgquP/V+qD8ni3oMSahLN2vMF9VdrBxMbVhkRQYI3ZHrIzQ2Wlk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709188399; c=relaxed/simple; bh=GIegngHqtLjHARUsBjYE1nUvvYzurvCdwBU55T25Zws=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=mCLt+WujZvI6pqg/VQtzzLVaTGHB7Eu4ugPFMV654YGc2ccgLpiewQGxv7BVrTO8Rweq1FgMDT3fh8firQOQYDxDc2BeUBphO/spWNVmOrkicRp0HujIKjUC1U/HjSrcwCX5oDmFGsXYxoggxRwLBG1Bmf34iUPArhhhYT2Lo+o= 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=YKbaYtCx; 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-dccc49ef73eso1053299276.2 for ; Wed, 28 Feb 2024 22:33:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709188397; x=1709793197; 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=h3EeOnj2LJFuh4Gzgf1odB7yRFHxb61zXSqdlmTf/sY=; b=YKbaYtCx+lHpwSTy4H1SVfzQA5K2rjaMGXeA/TxUBTq1htoEcqrrpgSqp+fAB89tIT sdUQQ7d4XFL7McpnXfYUIGJCUobTTlIk+gjU4W2fd7MKXpplEq3S9U84oWDaOlaRB04f CNh2DvhmC1PhzMghrFAe6BiDnh66URMhK5bquNuUhfFvipHm1Z6Pf7VHEYqa/EQHq7Kp UqS9iUlPcL5LJf0SndhQdg1WWWGZ4uZed5oOHSVrN6AiEPywH5uEC1DN05uqwWbV7s4W Ysda8asjM9a4AunDitegMEgWKXwrvtuGYezoRW6+qOckXeRE+5B1g92RIe7Zq4HbLXO9 Ulpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709188397; x=1709793197; 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=h3EeOnj2LJFuh4Gzgf1odB7yRFHxb61zXSqdlmTf/sY=; b=IAsXIRr9gxPYF6PKeq1LNuOR9AjRoBu+A/akxpRDOftaGU3fWq6IXf9q50MumyG6hq qX6AMm60OcboGLwBLKVZ53kUJBcNBZVq8sPwybeSVc/LNZjKw1Xs0FkZCKsHMd/CSZuo X1sPJCc5hNUuVQyO+D9WrfMeDzeVpeO96TOxnp1ub5Fyfx3+Q5RRpI1M78odA8KD5GvN ZWxMa0HIS9dxr+yuS3bpL+Nm6Uk4GRSHTn6Mh1wzKIxRKRDt0YqHCjFRa10sZ86wZO1O lTXy5fN4zyuSva9j9iSturpNbidof41v9f/BSTd1WuJHRcO6QcEqinWjhC8+H3bO8Ik8 nMDA== X-Forwarded-Encrypted: i=1; AJvYcCWzJQd/yOsBc+JmQhQBvWP1OryeRaEJ5Ev9Xl7MSuDnuqeqn2wbAsz3kDil2DXJWki/YZtIAEtyU5Y7S8LtrF6FJkRCoIHL564QSq1t X-Gm-Message-State: AOJu0YxPckFFz2sIo+klElvn9Vfty151Ku4hM+mkQx7NgpD3MCAJ/O/F qe5i+rlUdjraD18K/JUgar1m/ZT+OdAGInk+Wl4hFIHQjm4Sjc0EPXjBFNiRkgD8FeKMeW5u9eW x1I7FuQ== X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:77dc:144c:334e:e2dd]) (user=irogers job=sendgmr) by 2002:a05:6902:150d:b0:dc6:d890:1a97 with SMTP id q13-20020a056902150d00b00dc6d8901a97mr59458ybu.9.1709188396983; Wed, 28 Feb 2024 22:33:16 -0800 (PST) Date: Wed, 28 Feb 2024 22:32:53 -0800 In-Reply-To: <20240229063253.561838-1-irogers@google.com> Message-Id: <20240229063253.561838-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: <20240229063253.561838-1-irogers@google.com> X-Mailer: git-send-email 2.44.0.278.ge034bb2e1d-goog Subject: [PATCH v3 7/7] perf threads: Reduce table size from 256 to 8 From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Oliver Upton , Yang Jihong , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1792214090938882559 X-GMAIL-MSGID: 1792214090938882559 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 {