From nobody Sun Feb 8 00:26:59 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 65EB6192B94; Mon, 12 Aug 2024 19:44:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723491889; cv=none; b=Ku41FGlZYafXhieS2q9JbknU4BemvhzfjG+Fdl78+3ocCcwZlurVH+Cl80X0+QAvpXBedWO+Tnu2K0QYxalJdo3jsqRCCKAbaQ17+P89RA4abisnM8r202xnVN1BTzqWSclLDCypAk5KUQfiYHeeGljde+gU0Q3IzG4XYi2rk58= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723491889; c=relaxed/simple; bh=xmrmBEbnMGh2CK5MqpiPZ5Obe+6ba9uMuv9hj+CH/+c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QYMv+YZtBglNsP1ecJ+Y1TdFEj4J3rJIpbYBFdAIab2CHEi1yh6C6SBkO8l3chMMlQZ+0+X3K19zng3340GtnMwUFxP7eKBJph5ylNXoqmLBG7ThfIA0WENW2k+ldkvCSXKNZ8GySfpIFuPXsA33Xbrr+yhErkyng4AB5UDAJPg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FRZHNV46; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FRZHNV46" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9D742C4AF0D; Mon, 12 Aug 2024 19:44:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723491889; bh=xmrmBEbnMGh2CK5MqpiPZ5Obe+6ba9uMuv9hj+CH/+c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FRZHNV46z4zVR1GFmyL2QtxVOlu0p14cy/11aTBYy1g85bu9nmfeY6hJwv2Avt1Dp Cv3n3Bw/PTvTkLVWe+Ep4wKcv31fQXv4bqgFmwXd5gZcX+2qvf3EExkEEZHqOCwtnW cZYNNjr0CEYxgRq7uEpDyE7H5ErtETJayplZO9zQFQejHnAqF5VCHwLnLETtFqJvLk 6GAND14uDpAA2RXZ8tGN4pnc8DUFlEZs4wK+jJzCvaS/jRVhVKNIaj69tpY2anrzIO rc0YXbXE0U6I+2Lo1KiKGdv4aNmo/ZZ83hiPcLQjDiVnI7Jrn/NcWnNBEAbMXIRyHU as+aAjSFqJ7vA== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers , Kan Liang Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org Subject: [PATCH 1/3] perf annotate-data: Support folding in TUI browser Date: Mon, 12 Aug 2024 12:44:45 -0700 Message-ID: <20240812194447.2049187-2-namhyung@kernel.org> X-Mailer: git-send-email 2.46.0.76.ge559c4bf1a-goog In-Reply-To: <20240812194447.2049187-1-namhyung@kernel.org> References: <20240812194447.2049187-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Like in the hists browser, it should support folding current entry so that it can hide unwanted details in some data structures. The folded entries will be displayed with '+' sign, while unfolded entries will have '-' sign. Entries have no children will not show any signs. Annotate type: 'struct socket' (1 samples) Percent Offset Size Field - 100.00 0 128 struct socket { = =E2=97=86 0.00 0 4 socket_state state; = =E2=96=92 0.00 4 2 short int type; = =E2=96=92 0.00 8 8 long unsigned int flags; = =E2=96=92 0.00 16 8 struct file* file; = =E2=96=92 100.00 24 8 struct sock* sk; = =E2=96=92 0.00 32 8 struct proto_ops* ops; = =E2=96=92 - 0.00 64 64 struct socket_wq wq { = =E2=96=92 - 0.00 64 24 wait_queue_head_t wait { = =E2=96=92 + 0.00 64 4 spinlock_t lock; = =E2=96=92 - 0.00 72 16 struct list_head h= ead { =E2=96=92 0.00 72 8 struct list_head* n= ext; =E2=96=92 0.00 80 8 struct list_head* p= rev; =E2=96=92 }; = =E2=96=92 }; = =E2=96=92 0.00 88 8 struct fasync_struct* f= async_list; =E2=96=92 0.00 96 8 long unsigned int flags; = =E2=96=92 + 0.00 104 16 struct callback_head r= cu; =E2=96=92 }; = =E2=96=92 }; = =E2=96=92 This just adds the display logic for folding, actually folding action will be implemented in the next patch. Signed-off-by: Namhyung Kim --- tools/perf/ui/browsers/annotate-data.c | 235 ++++++++++++++++++++++--- 1 file changed, 212 insertions(+), 23 deletions(-) diff --git a/tools/perf/ui/browsers/annotate-data.c b/tools/perf/ui/browser= s/annotate-data.c index a937b55da736..04c73b67cd6c 100644 --- a/tools/perf/ui/browsers/annotate-data.c +++ b/tools/perf/ui/browsers/annotate-data.c @@ -14,6 +14,10 @@ #include "util/evlist.h" #include "util/sort.h" =20 +#define FOLDED_SIGN '+' +#define UNFOLD_SIGN '-' +#define NOCHLD_SIGN ' ' + struct annotated_data_browser { struct ui_browser b; struct list_head entries; @@ -24,7 +28,11 @@ struct browser_entry { struct list_head node; struct annotated_member *data; struct type_hist_entry *hists; - int indent; + struct browser_entry *parent; + struct list_head children; + int indent; /*indentation level, starts from 0 */ + int nr_entries; /* # of visible entries: self + descendents */ + bool folded; /* only can be false when it has children */ }; =20 static struct annotated_data_browser *get_browser(struct ui_browser *uib) @@ -65,13 +73,14 @@ static int get_member_overhead(struct annotated_data_ty= pe *adt, } =20 static int add_child_entries(struct annotated_data_browser *browser, + struct browser_entry *parent, struct annotated_data_type *adt, struct annotated_member *member, struct evsel *evsel, int indent) { struct annotated_member *pos; struct browser_entry *entry; - int nr_entries =3D 0; + struct list_head *parent_list; =20 entry =3D zalloc(sizeof(*entry)); if (entry =3D=3D NULL) @@ -84,36 +93,60 @@ static int add_child_entries(struct annotated_data_brow= ser *browser, } =20 entry->data =3D member; + entry->parent =3D parent; entry->indent =3D indent; if (get_member_overhead(adt, entry, evsel) < 0) { free(entry); return -1; } =20 - list_add_tail(&entry->node, &browser->entries); - nr_entries++; + INIT_LIST_HEAD(&entry->children); + if (parent) + parent_list =3D &parent->children; + else + parent_list =3D &browser->entries; =20 - list_for_each_entry(pos, &member->children, node) { - int nr =3D add_child_entries(browser, adt, pos, evsel, indent + 1); + list_add_tail(&entry->node, parent_list); =20 + list_for_each_entry(pos, &member->children, node) { + int nr =3D add_child_entries(browser, entry, adt, pos, evsel, + indent + 1); if (nr < 0) return nr; - - nr_entries +=3D nr; } =20 /* add an entry for the closing bracket ("}") */ if (!list_empty(&member->children)) { - entry =3D zalloc(sizeof(*entry)); - if (entry =3D=3D NULL) + struct browser_entry *bracket; + + bracket =3D zalloc(sizeof(*bracket)); + if (bracket =3D=3D NULL) return -1; =20 - entry->indent =3D indent; - list_add_tail(&entry->node, &browser->entries); - nr_entries++; + bracket->indent =3D indent; + bracket->parent =3D entry; + bracket->folded =3D true; + bracket->nr_entries =3D 1; + + INIT_LIST_HEAD(&bracket->children); + list_add_tail(&bracket->node, &entry->children); } =20 - return nr_entries; + /* fold child entries by default */ + entry->folded =3D true; + entry->nr_entries =3D 1; + return 0; +} + +static u32 count_visible_entries(struct annotated_data_browser *browser) +{ + int nr =3D 0; + struct browser_entry *entry; + + list_for_each_entry(entry, &browser->entries, node) + nr +=3D entry->nr_entries; + + return nr; } =20 static int annotated_data_browser__collect_entries(struct annotated_data_b= rowser *browser) @@ -123,9 +156,12 @@ static int annotated_data_browser__collect_entries(str= uct annotated_data_browser struct evsel *evsel =3D hists_to_evsel(he->hists); =20 INIT_LIST_HEAD(&browser->entries); + + add_child_entries(browser, /*parent=3D*/NULL, adt, &adt->self, evsel, + /*indent=3D*/0); + browser->b.entries =3D &browser->entries; - browser->b.nr_entries =3D add_child_entries(browser, adt, &adt->self, - evsel, /*indent=3D*/0); + browser->b.nr_entries =3D count_visible_entries(browser); return 0; } =20 @@ -140,9 +176,155 @@ static void annotated_data_browser__delete_entries(st= ruct annotated_data_browser } } =20 +static struct browser_entry *get_first_child(struct browser_entry *entry) +{ + if (list_empty(&entry->children)) + return NULL; + + return list_first_entry(&entry->children, struct browser_entry, node); +} + +static struct browser_entry *get_last_child(struct browser_entry *entry) +{ + if (list_empty(&entry->children)) + return NULL; + + return list_last_entry(&entry->children, struct browser_entry, node); +} + +static bool is_first_child(struct browser_entry *entry) +{ + /* This will be checked in a different way */ + if (entry->parent =3D=3D NULL) + return false; + + return get_first_child(entry->parent) =3D=3D entry; +} + +static bool is_last_child(struct browser_entry *entry) +{ + /* This will be checked in a different way */ + if (entry->parent =3D=3D NULL) + return false; + + return get_last_child(entry->parent) =3D=3D entry; +} + +static struct browser_entry *browser__prev_entry(struct ui_browser *uib, + struct browser_entry *entry) +{ + struct annotated_data_browser *browser =3D get_browser(uib); + struct browser_entry *first; + + first =3D list_first_entry(&browser->entries, struct browser_entry, node); + + while (entry !=3D first) { + if (is_first_child(entry)) + entry =3D entry->parent; + else { + entry =3D list_prev_entry(entry, node); + while (!entry->folded) + entry =3D get_last_child(entry); + } + + if (!uib->filter || !uib->filter(uib, &entry->node)) + return entry; + } + return first; +} + +static struct browser_entry *browser__next_entry(struct ui_browser *uib, + struct browser_entry *entry) +{ + struct annotated_data_browser *browser =3D get_browser(uib); + struct browser_entry *last; + + last =3D list_last_entry(&browser->entries, struct browser_entry, node); + while (!last->folded) + last =3D get_last_child(last); + + while (entry !=3D last) { + if (!entry->folded) + entry =3D get_first_child(entry); + else { + while (is_last_child(entry)) + entry =3D entry->parent; + + entry =3D list_next_entry(entry, node); + } + + if (!uib->filter || !uib->filter(uib, &entry->node)) + return entry; + } + return last; +} + +static void browser__seek(struct ui_browser *uib, off_t offset, int whence) +{ + struct annotated_data_browser *browser =3D get_browser(uib); + struct browser_entry *entry; + + if (uib->nr_entries =3D=3D 0) + return; + + switch (whence) { + case SEEK_SET: + entry =3D list_first_entry(&browser->entries, typeof(*entry), node); + if (uib->filter && uib->filter(uib, &entry->node)) + entry =3D browser__next_entry(uib, entry); + break; + case SEEK_CUR: + entry =3D list_entry(uib->top, typeof(*entry), node); + break; + case SEEK_END: + entry =3D list_last_entry(&browser->entries, typeof(*entry), node); + while (!entry->folded) + entry =3D get_last_child(entry); + if (uib->filter && uib->filter(uib, &entry->node)) + entry =3D browser__prev_entry(uib, entry); + break; + default: + return; + } + + assert(entry !=3D NULL); + + if (offset > 0) { + while (offset-- !=3D 0) + entry =3D browser__next_entry(uib, entry); + } else { + while (offset++ !=3D 0) + entry =3D browser__prev_entry(uib, entry); + } + + uib->top =3D &entry->node; +} + static unsigned int browser__refresh(struct ui_browser *uib) { - return ui_browser__list_head_refresh(uib); + struct browser_entry *entry, *next; + int row =3D 0; + + if (uib->top =3D=3D NULL || uib->top =3D=3D uib->entries) + browser__seek(uib, SEEK_SET, 0); + + entry =3D list_entry(uib->top, typeof(*entry), node); + + while (true) { + if (!uib->filter || !uib->filter(uib, &entry->node)) { + ui_browser__gotorc(uib, row, 0); + uib->write(uib, entry, row); + if (++row =3D=3D uib->rows) + break; + } + next =3D browser__next_entry(uib, entry); + if (next =3D=3D entry) + break; + + entry =3D next; + } + + return row; } =20 static int browser__show(struct ui_browser *uib) @@ -171,7 +353,7 @@ static int browser__show(struct ui_browser *uib) strcpy(title, "Percent"); =20 ui_browser__printf(uib, "%*s %10s %10s %10s %s", - 11 * (browser->nr_events - 1), "", + 2 + 11 * (browser->nr_events - 1), "", title, "Offset", "Size", "Field"); ui_browser__write_nstring(uib, "", uib->width); return 0; @@ -208,12 +390,12 @@ static void browser__write(struct ui_browser *uib, vo= id *entry, int row) struct evsel *leader =3D hists_to_evsel(he->hists); struct evsel *evsel; int idx =3D 0; + bool current =3D ui_browser__is_current_entry(uib, row); =20 if (member =3D=3D NULL) { - bool current =3D ui_browser__is_current_entry(uib, row); - /* print the closing bracket */ ui_browser__set_percent_color(uib, 0, current); + ui_browser__printf(uib, "%c ", NOCHLD_SIGN); ui_browser__write_nstring(uib, "", 11 * browser->nr_events); ui_browser__printf(uib, " %10s %10s %*s};", "", "", be->indent * 4, ""); @@ -221,6 +403,13 @@ static void browser__write(struct ui_browser *uib, voi= d *entry, int row) return; } =20 + ui_browser__set_percent_color(uib, 0, current); + + if (!list_empty(&be->children)) + ui_browser__printf(uib, "%c ", be->folded ? FOLDED_SIGN : UNFOLD_SIGN); + else + ui_browser__printf(uib, "%c ", NOCHLD_SIGN); + /* print the number */ for_each_group_evsel(evsel, leader) { struct type_hist *h =3D adt->histograms[evsel->core.idx]; @@ -237,13 +426,13 @@ static void browser__write(struct ui_browser *uib, vo= id *entry, int row) ui_browser__printf(uib, " %10d %10d %s%s", member->offset, member->size, member->type_name, - list_empty(&member->children) ? ";" : " {"); + list_empty(&member->children) || be->folded? ";" : " {"); } else { ui_browser__printf(uib, " %10d %10d %*s%s\t%s%s", member->offset, member->size, be->indent * 4, "", member->type_name, member->var_name ?: "", - list_empty(&member->children) ? ";" : " {"); + list_empty(&member->children) || be->folded ? ";" : " {"); } /* fill the rest */ ui_browser__write_nstring(uib, "", uib->width); @@ -297,7 +486,7 @@ int hist_entry__annotate_data_tui(struct hist_entry *he= , struct evsel *evsel, struct annotated_data_browser browser =3D { .b =3D { .refresh =3D browser__refresh, - .seek =3D ui_browser__list_head_seek, + .seek =3D browser__seek, .write =3D browser__write, .priv =3D he, .extra_title_lines =3D 1, --=20 2.46.0.76.ge559c4bf1a-goog From nobody Sun Feb 8 00:26:59 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D71B019307D; Mon, 12 Aug 2024 19:44:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723491889; cv=none; b=jlFEWEkf5YQOZS4mDngsD65FCyMtSOPYX9wyUCC24a1ngTFcvewM3AmKyTwpXWTPl7oWt0NhJfvElNvq8efmQ3Axpc8MNZCFK4jVde+VYXTVwfygndwW722dMetWtDJsa5vbGQI3SM9AMfE7zEJwsSL4yIxfz/3wbbNjhFBUmDQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723491889; c=relaxed/simple; bh=3WU1qCwUzfXdnhH/+P803xMWStHIejlFVKP55ZuK+/M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nT7/5ETIDOvMWr+wRm6VIyZudCyI8ucryb6cH1S3gAOMbh1lfS36dkitJcyHS2fQ7J0VO2xkDPW0iJ96ybu3glF+o6D5VY3/L0ozPJ1vEcXdWSHgSJ9q85lF5jZaAk87Fycj53SLw4qAIeJEEMlMeduaQMULNjkUU1Ud16ufXX0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K25wMMzR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="K25wMMzR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1F3F9C4AF0E; Mon, 12 Aug 2024 19:44:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723491889; bh=3WU1qCwUzfXdnhH/+P803xMWStHIejlFVKP55ZuK+/M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=K25wMMzRXOpv/VjOkm3HZH14fZrB+VcZPLtRNwfdjQ1S/4TfCVlzaU5ZdMP6VrCi9 Jj2cUF6aCZ0O6DmFsZoNY1h6PX8lX2QmJWo1eklWvNQPKx85gUdcaNbFErEt+9HEDc nlFDBUflkf1fJegKf5y02YEW/Guhim+KHz05OXKrrB8fsCNvNsLK5C6VjdvJRIBRAN 67Q8maQa2UuVC3YGczAdv5mpLOLIGvlSKlyQ7KtDt7+ZjR3zNCJuxEFxBRNGOFeP1K 84bR4re07K6TatDsFY/2YiYdE4ZzV9qboNJI/RSjcigR+rhMouLXKKlAAYtolXloBc OpBf8/medvr6g== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers , Kan Liang Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org Subject: [PATCH 2/3] perf annotate-data: Implement folding in TUI browser Date: Mon, 12 Aug 2024 12:44:46 -0700 Message-ID: <20240812194447.2049187-3-namhyung@kernel.org> X-Mailer: git-send-email 2.46.0.76.ge559c4bf1a-goog In-Reply-To: <20240812194447.2049187-1-namhyung@kernel.org> References: <20240812194447.2049187-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Like perf report, use 'e' or 'E' key to toggle folding the current entry so that it can control displaying child entries. Note I didn't add the 'c' and 'C' key to collapse the entry because it's also handled with the 'e'/'E' since it toggles the state. Signed-off-by: Namhyung Kim --- tools/perf/ui/browsers/annotate-data.c | 98 ++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 6 deletions(-) diff --git a/tools/perf/ui/browsers/annotate-data.c b/tools/perf/ui/browser= s/annotate-data.c index 04c73b67cd6c..a5c5ad63425e 100644 --- a/tools/perf/ui/browsers/annotate-data.c +++ b/tools/perf/ui/browsers/annotate-data.c @@ -18,12 +18,6 @@ #define UNFOLD_SIGN '-' #define NOCHLD_SIGN ' ' =20 -struct annotated_data_browser { - struct ui_browser b; - struct list_head entries; - int nr_events; -}; - struct browser_entry { struct list_head node; struct annotated_member *data; @@ -35,6 +29,13 @@ struct browser_entry { bool folded; /* only can be false when it has children */ }; =20 +struct annotated_data_browser { + struct ui_browser b; + struct list_head entries; + struct browser_entry *curr; + int nr_events; +}; + static struct annotated_data_browser *get_browser(struct ui_browser *uib) { return container_of(uib, struct annotated_data_browser, b); @@ -302,6 +303,7 @@ static void browser__seek(struct ui_browser *uib, off_t= offset, int whence) =20 static unsigned int browser__refresh(struct ui_browser *uib) { + struct annotated_data_browser *browser =3D get_browser(uib); struct browser_entry *entry, *next; int row =3D 0; =20 @@ -314,6 +316,8 @@ static unsigned int browser__refresh(struct ui_browser = *uib) if (!uib->filter || !uib->filter(uib, &entry->node)) { ui_browser__gotorc(uib, row, 0); uib->write(uib, entry, row); + if (uib->top_idx + row =3D=3D uib->index) + browser->curr =3D entry; if (++row =3D=3D uib->rows) break; } @@ -438,6 +442,78 @@ static void browser__write(struct ui_browser *uib, voi= d *entry, int row) ui_browser__write_nstring(uib, "", uib->width); } =20 +static void annotated_data_browser__fold(struct annotated_data_browser *br= owser, + struct browser_entry *entry, + bool recursive) +{ + struct browser_entry *child; + + if (list_empty(&entry->children)) + return; + if (entry->folded && !recursive) + return; + + if (recursive) { + list_for_each_entry(child, &entry->children, node) + annotated_data_browser__fold(browser, child, true); + } + + entry->nr_entries =3D 1; + entry->folded =3D true; +} + +static void annotated_data_browser__unfold(struct annotated_data_browser *= browser, + struct browser_entry *entry, + bool recursive) +{ + struct browser_entry *child; + int nr_entries; + + if (list_empty(&entry->children)) + return; + if (!entry->folded && !recursive) + return; + + nr_entries =3D 1; /* for self */ + list_for_each_entry(child, &entry->children, node) { + if (recursive) + annotated_data_browser__unfold(browser, child, true); + + nr_entries +=3D child->nr_entries; + } + + entry->nr_entries =3D nr_entries; + entry->folded =3D false; +} + +static void annotated_data_browser__toggle_fold(struct annotated_data_brow= ser *browser, + bool recursive) +{ + struct browser_entry *curr =3D browser->curr; + struct browser_entry *parent; + + parent =3D curr->parent; + while (parent) { + parent->nr_entries -=3D curr->nr_entries; + parent =3D parent->parent; + } + browser->b.nr_entries -=3D curr->nr_entries; + + if (curr->folded) + annotated_data_browser__unfold(browser, curr, recursive); + else + annotated_data_browser__fold(browser, curr, recursive); + + parent =3D curr->parent; + while (parent) { + parent->nr_entries +=3D curr->nr_entries; + parent =3D parent->parent; + } + browser->b.nr_entries +=3D curr->nr_entries; + + assert(browser->b.nr_entries =3D=3D count_visible_entries(browser)); +} + static int annotated_data_browser__run(struct annotated_data_browser *brow= ser, struct evsel *evsel __maybe_unused, struct hist_browser_timer *hbt) @@ -462,8 +538,18 @@ static int annotated_data_browser__run(struct annotate= d_data_browser *browser, "UP/DOWN/PGUP\n" "PGDN/SPACE Navigate\n" " Move to prev/next symbol\n" + "e Expand/Collapse current entry\n" + "E Expand/Collapse all children of the current\n" "q/ESC/CTRL+C Exit\n\n"); continue; + case 'e': + annotated_data_browser__toggle_fold(browser, + /*recursive=3D*/false); + break; + case 'E': + annotated_data_browser__toggle_fold(browser, + /*recursive=3D*/true); + break; case K_LEFT: case '<': case '>': --=20 2.46.0.76.ge559c4bf1a-goog From nobody Sun Feb 8 00:26:59 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 142A0193092; Mon, 12 Aug 2024 19:44:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723491890; cv=none; b=FTuy95n9Qwbe6nO8J+chDW/BTatSnYc+AHpFiYTUh7liDMd5u/kkX1cR5wRdhZXba477kT/QljYb9ASQWdN0jXZpgGV8vkNfQmmiWDQjA3DN8M1YgU7J72n54G42uSouv8/8t2UdljvPfnr+ZFZZAKbXuGu5XjDQrAn+32I2w7Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723491890; c=relaxed/simple; bh=QHewfVSyj7Ct3cw0t63ntx4CvJfX2M//3DZapaeY0HU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=jMH8P+CaKCWi/HEUkhko1RpL6vzLPzxsHPaRTyWpADegNkROAdF41fDahXXpH2BPW9GlhOftXzRf6v1llSHcGb4ztVBjbtQDcO5RI5nEobsjRKX1Ijxlv4HRGS32tXjArKMdUPfcuwsUPP5bglqBtMHLcPQ8qTW3nxrok3BqiE4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e4Md5gWg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="e4Md5gWg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 94AB0C4AF0D; Mon, 12 Aug 2024 19:44:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723491890; bh=QHewfVSyj7Ct3cw0t63ntx4CvJfX2M//3DZapaeY0HU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e4Md5gWgCwRnTQePXMH1DSm8L08RywlUbal8bqQsuFjhdimnyrAHkeGjTSEiGBQOx zdvjOmCNkikHWPLrmG1VujXs4PRULQlz1RnqkbWRgKrFlqYZiZFH/jrSBTuEl5M6sV YeUmPODYNRll6FfufEr43mJ2SgjynCNDBXzT7YvFELOiJI8uoTxeoN8AfdY/nY9n4Y qJwoFScJmGGWK70boRSf9YrZya5V0V5yGvgLHzcNqj7gLCqeGGYUs44If9ludydKIW 8lzCsmvVDpkYxXoF0YDyFEmttVYzlgeG/ukZqdkIjvX2SYIpsWRSmVDW7TFpejt5Lp Led/L+1vF3sXg== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers , Kan Liang Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org Subject: [PATCH 3/3] perf annotate-data: Show first-level children by default in TUI Date: Mon, 12 Aug 2024 12:44:47 -0700 Message-ID: <20240812194447.2049187-4-namhyung@kernel.org> X-Mailer: git-send-email 2.46.0.76.ge559c4bf1a-goog In-Reply-To: <20240812194447.2049187-1-namhyung@kernel.org> References: <20240812194447.2049187-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Now default is to fold everything but it only shows the name of the top-level data type which is not very useful. Instead just expand the top level entry so that it can show the layout at a higher level. Annotate type: 'struct task_struct' (4 samples) Percent Offset Size Field - 100.00 0 9792 struct task_struct { = =E2=97=86 + 0.50 0 24 struct thread_info thread_in= fo; =E2=96=92 0.00 24 4 unsigned int __state; = =E2=96=92 0.00 32 8 void* stack; = =E2=96=92 + 0.00 40 4 refcount_t usage; = =E2=96=92 0.00 44 4 unsigned int flags; = =E2=96=92 0.00 48 4 unsigned int ptrace; = =E2=96=92 0.00 52 4 int on_cpu; = =E2=96=92 + 0.00 56 16 struct __call_single_node w= ake_entry; =E2=96=92 0.00 72 4 unsigned int wakee_flips; = =E2=96=92 0.00 80 8 long unsigned int wakee_fli= p_decay_ts;=E2=96=92 0.00 88 8 struct task_struct* last_wake= e; =E2=96=92 0.00 96 4 int recent_used_cpu; = =E2=96=92 0.00 100 4 int wake_cpu; = =E2=96=92 0.00 104 4 int on_rq; = =E2=96=92 0.00 108 4 int prio; = =E2=96=92 0.00 112 4 int static_prio; = =E2=96=92 0.00 116 4 int normal_prio; = =E2=96=92 0.00 120 4 unsigned int rt_priority; = =E2=96=92 + 0.00 128 256 struct sched_entity se; = =E2=96=92 + 0.00 384 48 struct sched_rt_entity rt; = =E2=96=92 + 0.00 432 224 struct sched_dl_entity dl; = =E2=96=92 0.00 656 8 struct sched_class* sched_cla= ss; =E2=96=92 ... Signed-off-by: Namhyung Kim --- tools/perf/ui/browsers/annotate-data.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/perf/ui/browsers/annotate-data.c b/tools/perf/ui/browser= s/annotate-data.c index a5c5ad63425e..f563a3bb072c 100644 --- a/tools/perf/ui/browsers/annotate-data.c +++ b/tools/perf/ui/browsers/annotate-data.c @@ -596,9 +596,17 @@ int hist_entry__annotate_data_tui(struct hist_entry *h= e, struct evsel *evsel, } =20 ret =3D annotated_data_browser__collect_entries(&browser); - if (ret =3D=3D 0) - ret =3D annotated_data_browser__run(&browser, evsel, hbt); + if (ret < 0) + goto out; =20 + /* To get the top and current entry */ + browser__refresh(&browser.b); + /* Show the first-level child entries by default */ + annotated_data_browser__toggle_fold(&browser, /*recursive=3D*/false); + + ret =3D annotated_data_browser__run(&browser, evsel, hbt); + +out: annotated_data_browser__delete_entries(&browser); =20 return ret; --=20 2.46.0.76.ge559c4bf1a-goog