Linux-Trace-Devel Archive on lore.kernel.org
 help / color / Atom feed
From: Yordan Karadzhov <y.karadz@gmail.com>
To: Stefano De Venuto <stefano.devenuto99@gmail.com>, rostedt@goodmis.org
Cc: linux-trace-devel@vger.kernel.org, dfaggioli@suse.com
Subject: Re: [RFC] Simple tool for VMEnters/VMExits matching and trace validation
Date: Tue, 20 Apr 2021 11:12:59 +0300
Message-ID: <7edad92d-3297-fd42-9ac2-0334816fb524@gmail.com> (raw)
In-Reply-To: <20210416164653.2949-1-stefano.devenuto99@gmail.com>

Ciao Stefano,

First of all, I am very happy to see you progressing so fast in the 
development of your VMEnters/VMExits matching analysis. I have several 
comments concerning the code (see below).

On 16.04.21 г. 19:46, Stefano De Venuto wrote:
> Add a tool in examples/ that scans a merged host + guest trace and
> search for host events that are inside a vmentry/vmexit block (and
> vice-versa for guest events ouside the block) and report the found
> ones.
>
> It can be useful as a starting point for identifying issues of for
> checking the effectiveness of host/guest traces synchronization, or
> even for improving the placing of the tracepoints in the kernel.
>
> Signed-off-by: Stefano De Venuto <stefano.devenuto99@gmail.com>
> ---
>   examples/checker.c | 202 +++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 202 insertions(+)
>   create mode 100644 examples/checker.c
>
> diff --git a/examples/checker.c b/examples/checker.c
> new file mode 100644
> index 0000000..0b04343
> --- /dev/null
> +++ b/examples/checker.c
> @@ -0,0 +1,202 @@

The first problem is that this patch fails to apply. My guess is that 
you hand-edited the patch and removed some lines starting with "+". Note 
that the total number of additions and removals in the file is indicated 
in the line above. If this number does not match the number of lines 
starting with "+", the patch will fail to apply.

As a general advise - try to avoid hand-editing patches unless you are 
certain you know what you are doing.

Another general problem is that your patch seems to use CRLF for 
indicating new lines. This makes git produce a lot of warnings.

Please fix this in version 2.

> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "libkshark.h"
> +#include "libkshark-tepdata.h"
> +
> +#define KVM_ENTRY "kvm/kvm_entry"
> +#define KVM_EXIT "kvm/kvm_exit"
> +
> +struct custom_stream
> +{
> +	struct kshark_data_stream* original_stream;
> +	int* cpus;
> +};
> +
> +int is_guest(int stream_id,
> +	      struct kshark_host_guest_map* mapping,
> +	      int n_mapping, int* host)
> +{
> +	for (int i = 0; i < n_mapping; i++) {
> +		if (mapping[i].guest_id == stream_id) {
> +			*host = mapping[i].host_id;
> +			return 1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +void print_entry(struct kshark_entry* entry)
> +{
> +	struct kshark_data_stream* stream;
> +	char* event_name;
> +	int stream_id;
> +
> +	stream = kshark_get_stream_from_entry(entry);
> +	event_name = kshark_get_event_name(entry);
> +
> +	stream_id = stream->stream_id;
> +	printf("%d: %s-%d, %lld [%03d]:%s\t%s\n",
> +		stream->stream_id,
> +		kshark_get_task(entry),
> +		kshark_get_pid(entry),
> +		entry->ts,
> +		entry->cpu,
> +		event_name,
> +		kshark_get_info(entry));
> +
> +}
> +

Remove the empty line at the end of the function.


> +void print_entries(struct kshark_entry **entries, ssize_t n_entries)
> +{
> +	for (int i = 0; i < n_entries; ++i
> +		print_entry(entries[i]);
> +}
> +

This function looks like a dead code. It must be removed if you don't 
use it.

> +void free_data(struct kshark_context *kshark_ctx,
> +	       struct custom_stream** custom_streams,
> +	       struct kshark_entry** entries, int n_entries,
> +	       struct kshark_host_guest_map* host_guest_mapping,
> +	       int n_guest)
> +{
> +	struct custom_stream* custom_stream;
> +
> +	for (int i = 0; i < kshark_ctx->n_streams; i++) {
> +		custom_stream = custom_streams[i];
> +
> +		free(custom_stream->cpus);
> +		free(custom_stream);
> +	}
> +	free(custom_streams);
> +
> +	for (int i = 0; i < n_entries; i++)
> +		free(entries[i]);
> +	free(entries);
> +
> +	kshark_tracecmd_free_hostguest_map(host_guest_mapping, n_guest);
> +
> +	kshark_close_all(kshark_ctx);
> +	kshark_free(kshark_ctx);

kshark_free() calls kshark_close_all() internally. No need to have both.

Also, since this function is called "free_data" and kshark_free() has 
nothing to do with "data", it may be better to move the call of 
kshark_free() outside, and place it in main().


> +}
> +
> +int main(int argc, char **argv)
> +{
> +
Remove the empty line here.
> +	struct kshark_host_guest_map* host_guest_mapping;
> +	struct custom_stream** custom_streams;
> +	struct custom_stream* custom_stream;
> +	struct custom_stream* host_stream;
> +	struct kshark_data_stream* stream;
> +	struct kshark_context* kshark_ctx;
> +	struct kshark_entry** entries;
> +	struct kshark_entry* current;
> +	ssize_t n_entries;
> +	char* event_name;
> +	char* token;
> +	int n_guest;
> +	char* info;
> +	int host;
> +	int v_i;
> +	int sd;
> +
> +	kshark_ctx = NULL;
> +	if (!kshark_instance(&kshark_ctx))
> +		return 1;
> +
> +	custom_streams = malloc(sizeof(*custom_streams) * (argc-1));
> +
> +	for (int i = 1; i < argc; i++) {
> +		sd = kshark_open(kshark_ctx, argv[i]);
> +		if (sd < 0) {
> +			kshark_free(kshark_ctx);
> +			return 1;
> +		}
> +
> +		kshark_tep_init_all_buffers(kshark_ctx, sd);
> +
> +		custom_stream = malloc(sizeof(*custom_stream));
> +		custom_stream->original_stream = kshark_get_data_stream(kshark_ctx, sd);
> +		custom_stream->cpus = malloc(custom_stream->original_stream->n_cpus * sizeof(int));
> +		memset(custom_stream->cpus, -1, custom_stream->original_stream->n_cpus * sizeof(int));

Add a comment explaining why you are doing this.


> +
> +		custom_streams[i-1] = custom_stream;
> +	}
> +
> +	host_guest_mapping = NULL;
> +	n_guest = kshark_tracecmd_get_hostguest_mapping(&host_guest_mapping);
> +	if (n_guest < 0) {
> +	  printf("Failed mapping: %d\n", n_guest);
> +	  return 1;
> +	}
> +
> +	entries = NULL;
> +	n_entries = kshark_load_all_entries(kshark_ctx, &entries);
> +
> +	for (int i = 0; i < n_entries; ++i) {
> +		current = entries[i];
> +
> +		stream = kshark_get_stream_from_entry(current);
> +		event_name = kshark_get_event_name(current);
> +
> +		custom_stream = custom_streams[stream->stream_id];
> +
> +		if (!strcmp(event_name, KVM_ENTRY) || !strcmp(event_name, KVM_EXIT)) {
> +			if (!strcmp(event_name, KVM_ENTRY)) {
> +
> +				/*
> +				 * The recovering process of the vCPU field of the kvm_entry event
> +				 * is done by splitting the info field.
> +				 */
> +				info = kshark_get_info(current);
> +
> +				token = strtok(info, " ");
> +				token = strtok(NULL, " ");
> +
> +				/* Removing the last comma */
> +				token[strlen(token) - 1] = '\0';
> +
> +				custom_stream->cpus[current->cpu] = atoi(token);

It will be better if you make the recovering of the vCPU above a static 
helper function.


> +
> +				free(info);
> +			} else {
> +				custom_stream->cpus[current->cpu] = -1;
> +			}
> +
> +		} else {
> +
> +			/*
> +			 * If the event comes from a guest, recover the pCPU where the event was executed
> +			 * and check if it's NOT OUTSIDE a kvm_entry/kvm_exit block.
> +			 */
> +			if (is_guest(stream->stream_id, host_guest_mapping, n_guest, &host)) {
> +				host_stream = custom_streams[host];
> +
> +				for (v_i = 0; v_i < host_stream->original_stream->n_cpus; v_i++) {
> +					if (current->cpu == host_stream->cpus[v_i])
> +					break;
> +				}
> +
> +				if (v_i == host_stream->original_stream->n_cpus) {
> +					printf("%d G out:\t", i);
> +					print_entry(entries[i]);
> +				}
> +
> +			/*
> +			* If the event comes from a host, recover the CPU that executed the event
> +			* and check if it's NOT INSIDE a kvm_entry/kvm_exit block.
> +			*/
> +			} else {
> +				if (custom_stream->cpus[current->cpu] != -1) {
> +					printf("%d H in:\t", i);
> +					print_entry(entries[i]);
> +				}
> +			}
> +		}
> +	}
> +
> +	free_data(kshark_ctx, custom_streams, entries, n_entries, host_guest_mapping, n_guest);
> +}

I do not see how you build the tool. I guess you edited CMakeLists.txt. 
This must be part of the patch as well.

Looking forward to see version 2.

Best,
Yordan




  parent reply index

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-16 16:46 Stefano De Venuto
2021-04-16 17:47 ` Dario Faggioli
2021-04-16 20:48   ` Stefano De Venuto
2021-04-16 21:32     ` Steven Rostedt
2021-04-17  6:43       ` Dario Faggioli
2021-04-20  8:12 ` Yordan Karadzhov [this message]
2021-04-21  2:17   ` Steven Rostedt
2021-04-21  9:14     ` Yordan Karadzhov
2021-05-01  6:11     ` Stefano De Venuto
2021-05-01  6:11   ` Stefano De Venuto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7edad92d-3297-fd42-9ac2-0334816fb524@gmail.com \
    --to=y.karadz@gmail.com \
    --cc=dfaggioli@suse.com \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=stefano.devenuto99@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-Trace-Devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-trace-devel/0 linux-trace-devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-trace-devel linux-trace-devel/ https://lore.kernel.org/linux-trace-devel \
		linux-trace-devel@vger.kernel.org
	public-inbox-index linux-trace-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-trace-devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git