public inbox for linux-perf-users@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] perf session: print all machines in session dump
@ 2026-01-25 20:06 Hrishikesh Suresh
  2026-01-26 21:17 ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 2+ messages in thread
From: Hrishikesh Suresh @ 2026-01-25 20:06 UTC (permalink / raw)
  To: Peter Zijlstra, Arnaldo Carvalho de Melo, Namhyung Kim
  Cc: Hrishikesh Suresh, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark, Chun-Tse Shao,
	Blake Jones, Dmitry Vyukov, Leo Yan, linux-perf-users,
	linux-kernel

perf_session__fprintf() prints only host. This has been changed to print
details of host and all guests, by traversing through the RB-Tree. These
are visible when using high verbosity (-vvvv) in KVM environments, during
perf report dumps.

Testing -
- Test 1: Record the local machine and guest VM using 'perf kvm record' and
generate the report using 'perf kvm report -vvvv -D'. The dump should show
the threads and other details related to local and guest machine.
    - 1 Ubuntu VM running on Fedora host
    - VM is running a noisy program =>
	$ dd if=/dev/urandom of=/dev/null
    - On host run =>
	$ sudo ./perf kvm --guestvmlinux=/tmp/shared/guest_vmlinux \
                        --guestkallsyms=/tmp/shared/guest_kallsyms \
                        --guestmodules=/tmp/shared/guest_modules \
                        record -a -g -o perf.data.guest
      and exit after a few seconds.
      [ perf record: Woken up 9 times to write data ]
      [ perf record: Captured and wrote 3.150 MB perf.data.guest \
	(29311 samples) ]
    - Generate dump =>
	$ sudo ./perf kvm --guestkallsyms /tmp/shared/guest_kallsyms \
                        report -vvvv -D -i perf.data.guest > output.txt
    - Check for threads associated with guest machine.
      $ grep "Thread 0" output.txt
      Thread 0 swapper
      Thread 0 [guest/0]
    PASS

- Test 2: Record the local machine and guest VM using 'perf kvm record' and
generate the report using 'perf kvm report'. The functions running on
guest VM should be seen in the report.
    - Same setup as Test 1 but the test looks at the performance profile,
      to check if the function names are visible.
    - Peek into profile using =>
	$ sudo ./perf kvm  --guestkallsyms /tmp/shared/guest_kallsyms \
                                    report -i perf.data.guest
    - Samples: 29K of event 'cycles', Event count (approx.): 28711693142
Children   Self  Command  Shared Object            Symbol
35.69%   35.69%  :5820    [guest.kernel.kallsyms]  [g] chacha_permute
11.56%   11.56%  :5820    [guest.kernel.kallsyms]  [g] entry_SYSRETQ_unsXXX
11.12%   11.12%  :5820    [guest.kernel.kallsyms]  [g] syscall_return_viXXX
 7.36%    7.36%  :5820    [guest.kernel.kallsyms]  [g] entry_SYSCALL_64_XXX
 6.07%    6.07%  :5820    [guest.kernel.kallsyms]  [g] chacha_block_generic
 5.40%    5.40%  :5820    [guest.kernel.kallsyms]  [g] _copy_to_iter
 ....
    PASS

- Test 3: Record the local and 2 guest VMs using 'perf kvm record' and
generate the report using 'perf kvm report -vvvv -D'. The dump should show
the threads and other details related to local and guest machines.
    - 1 Ubuntu and 1 Alpine VMs running on Fedora host.
    - Find PIDs of qemu instances and use them during record and report
	$ pgrep qemu
        5816
        25098
    - Record the activity =>
	$ sudo ./perf kvm record -p 5816,25098 -a -g -o perf.data.guests
        Warning:
        PID/TID switch overriding SYSTEM
        [ perf record: Woken up 325927 times to write data ]
        [ perf record: Captured and wrote 3.692 MB perf.data.guests \
	  (57389 samples) ]
    - Generate dump =>
	$ sudo ./perf kvm report -vvvv -D -i perf.data.guests > output.txt
    - Check if the threads related to the local machine and guest VMs
      are present =>
	$ grep "Thread 0" output.txt
        Thread 0 swapper
        Thread 0 [guest/0]
      NOTE: Threads from Ubuntu and Alpine VMs are bundled together and
      appear as one guest machine.
      Looking into output.txt =>
	Threads: 6
	Thread 0 [guest/0]
	Thread 5816 :5816
	Thread 25098 :25098
	Thread 5819 :5819
	Thread 5820 :5820
	Thread 25103 :25103
      To conclude, information is collected for both VMs and not listed
      as two different guest machines.
    PASS

- Test 4: Check if any guest-related information is printed in
perf annotate. This test is included because the command calls
perf_session__fprintf() in its code path when using -vvvv option.
This could be explained by inability / lack of options for 'perf annotate'
to look into guest VM from host machine, due to no option to specify the
guest's kallsyms or modules. A similar explanation for 'perf mem' could
be used, as perf_session__fprintf() is also present in its code path.
    - Run annotate =>
	$ sudo ./perf annotate -i perf.data.guest -vvvv  > output.txt
    - Check for threads from local machine or guest VM =>
	$ grep "Thread 0" output.txt
        Thread 0 swapper

        Threads from local machine are found while threads from guest VM
	are not found. It is possibly because of a lack of a guest kallsyms
	option for DSO matching in perf annotate.
    PASS

- Test 5: Run kvm test available on perf path
    - $ sudo ./perf test kvm
        89: perf kvm tests                                            : Ok
    PASS

Signed-off-by: Hrishikesh Suresh <hrishikesh123s@gmail.com>
---
 tools/perf/util/session.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 4236503c8f6c..6c6dfeb4eb33 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2674,11 +2674,15 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
 
 size_t perf_session__fprintf(struct perf_session *session, FILE *fp)
 {
-	/*
-	 * FIXME: Here we have to actually print all the machines in this
-	 * session, not just the host...
-	 */
-	return machine__fprintf(&session->machines.host, fp);
+	struct rb_node *nd;
+	struct machine *pos;
+	size_t ret = machine__fprintf(&session->machines.host, fp);
+
+	for (nd = rb_first_cached(&session->machines.guests); nd; nd = rb_next(nd)) {
+		pos = rb_entry(nd, struct machine, rb_node);
+		ret += machine__fprintf(pos, fp);
+	}
+	return ret;
 }
 
 void perf_session__dump_kmaps(struct perf_session *session)
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] perf session: print all machines in session dump
  2026-01-25 20:06 [PATCH] perf session: print all machines in session dump Hrishikesh Suresh
@ 2026-01-26 21:17 ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 2+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-01-26 21:17 UTC (permalink / raw)
  To: Hrishikesh Suresh
  Cc: Peter Zijlstra, Namhyung Kim, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
	James Clark, Chun-Tse Shao, Blake Jones, Dmitry Vyukov, Leo Yan,
	linux-perf-users, linux-kernel

On Sun, Jan 25, 2026 at 09:06:52PM +0100, Hrishikesh Suresh wrote:
> +++ b/tools/perf/util/session.c
> @@ -2674,11 +2674,15 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
>  
>  size_t perf_session__fprintf(struct perf_session *session, FILE *fp)
>  {
> -	/*
> -	 * FIXME: Here we have to actually print all the machines in this
> -	 * session, not just the host...
> -	 */
> -	return machine__fprintf(&session->machines.host, fp);
> +	struct rb_node *nd;
> +	struct machine *pos;
> +	size_t ret = machine__fprintf(&session->machines.host, fp);
> +
> +	for (nd = rb_first_cached(&session->machines.guests); nd; nd = rb_next(nd)) {
> +		pos = rb_entry(nd, struct machine, rb_node);
> +		ret += machine__fprintf(pos, fp);
> +	}
> +	return ret;
>  }
>  
>  void perf_session__dump_kmaps(struct perf_session *session)

Simple enough, applying after the further simplifications below, to make
it more compact.

Thanks!

- Arnaldo

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index dcbe10d6a996970d..ae62d5c9889fe2f3 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2730,12 +2730,11 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
 
 size_t perf_session__fprintf(struct perf_session *session, FILE *fp)
 {
-	struct rb_node *nd;
-	struct machine *pos;
 	size_t ret = machine__fprintf(&session->machines.host, fp);
 
-	for (nd = rb_first_cached(&session->machines.guests); nd; nd = rb_next(nd)) {
-		pos = rb_entry(nd, struct machine, rb_node);
+	for (struct rb_node *nd = rb_first_cached(&session->machines.guests); nd; nd = rb_next(nd)) {
+		struct machine *pos = rb_entry(nd, struct machine, rb_node);
+
 		ret += machine__fprintf(pos, fp);
 	}
 	return ret;

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-01-26 21:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-25 20:06 [PATCH] perf session: print all machines in session dump Hrishikesh Suresh
2026-01-26 21:17 ` Arnaldo Carvalho de Melo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox