All of lore.kernel.org
 help / color / mirror / Atom feed
From: Slavomir Kaslev <kaslevs@vmware.com>
To: Tzvetomir Stoyanov <tstoyanov@vmware.com>
Cc: rostedt@goodmis.org, linux-trace-devel@vger.kernel.org
Subject: Re: [PATCH v4 6/7] trace-cmd: Find and store pids of tasks, which run virtual CPUs of given VM
Date: Fri, 22 Feb 2019 19:07:09 +0200	[thread overview]
Message-ID: <20190222170708.GB17098@box> (raw)
In-Reply-To: <20190222142836.12596-7-tstoyanov@vmware.com>

On Fri, Feb 22, 2019 at 04:28:35PM +0200, Tzvetomir Stoyanov wrote:
> In order to match host and guest events, a mapping between guest VCPU
> and the host task, running this VCPU is needed. Extended existing
> struct guest to hold such mapping and added logic in read_qemu_guests()
> function to initialize it. Implemented a new internal API,
> get_guest_vcpu_pids(), to retrieve VCPU-task mapping for given VM.
> 
> Signed-off-by: Tzvetomir Stoyanov <tstoyanov@vmware.com>
> ---
>  tracecmd/include/trace-local.h |  3 ++
>  tracecmd/trace-record.c        | 57 +++++++++++++++++++++++++++++++++-
>  2 files changed, 59 insertions(+), 1 deletion(-)
> 
> diff --git a/tracecmd/include/trace-local.h b/tracecmd/include/trace-local.h
> index d7bdb1f..ef6848f 100644
> --- a/tracecmd/include/trace-local.h
> +++ b/tracecmd/include/trace-local.h
> @@ -236,6 +236,9 @@ void show_instance_file(struct buffer_instance *instance, const char *name);
>  
>  int count_cpus(void);
>  
> +#define VCPUS_MAX	256

Is VCPUS_MAX intended to be used somewhere outside of trace-record.c? If not, I
think we should keep it there locally and not expose it.

> +int *get_guest_vcpu_pids(int cid);
> +
>  /* No longer in event-utils.h */
>  void __noreturn die(const char *fmt, ...); /* Can be overriden */
>  void *malloc_or_die(unsigned int size); /* Can be overridden */
> diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
> index c57ed6b..59f0197 100644
> --- a/tracecmd/trace-record.c
> +++ b/tracecmd/trace-record.c
> @@ -2752,6 +2752,7 @@ struct guest {
>  	char *name;
>  	int cid;
>  	int pid;
> +	int cpu_pid[VCPUS_MAX];
>  };
>  
>  static struct guest *guests;
> @@ -2772,9 +2773,10 @@ static char *get_qemu_guest_name(char *arg)
>  static void read_qemu_guests(void)
>  {
>  	static bool initialized;
> +	struct dirent *entry_t;
>  	struct dirent *entry;
>  	char path[PATH_MAX];
> -	DIR *dir;
> +	DIR *dir, *dir_t;
>  
>  	if (initialized)
>  		return;
> @@ -2830,6 +2832,49 @@ static void read_qemu_guests(void)
>  		if (!is_qemu)
>  			goto next;
>  

I think the following section should go into separate function since this one is
already getting too long. Then here we can just do:

		read_qemu_guest_vcpus(&guest);

Where read_qemu_guest_vcpus can be something like that:

static void read_qemu_guest_vcpus(struct guest *guest)
{
	struct dirent *entry;
	char path[PATH_MAX];
	size_t buf_len = 0;
	char *buf = NULL;
	int vcpu;
	DIR *dir;
	FILE *f;

	snprintf(path, sizeof(path), "/proc/%d/task", guest->pid);
	dir = opendir(path);
	if (!dir)
		return;

	for (entry = readdir(dir); entry; entry = readdir(dir)) {
		if (!(entry->d_type == DT_DIR && is_digits(entry->d_name)))
			continue;

		snprintf(path, sizeof(path), "/proc/%d/task/%s/comm",
			 guest->pid, entry->d_name);
		f = fopen(path, "r");
		if (!f)
			continue;

		if (getline(&buf, &buf_len, f) < 0)
			goto next;

		if (strncmp(buf, "CPU ", 4) != 0)
			goto next;

		vcpu = atoi(buf + 4);
		if (!(vcpu >= 0 && vcpu < VCPUS_MAX))
			goto next;

		guest->cpu_pid[vcpu] = atoi(entry->d_name);

next:
		fclose(f);
	}

	free(buf);
}

Thank you,

-- Slavi

> +		snprintf(path, sizeof(path), "/proc/%s/task", entry->d_name);
> +		dir_t = opendir(path);
> +		if (dir_t) {
> +			unsigned int vcpu;
> +			char *buf = NULL;
> +			char *cpu_str;
> +			FILE *ft;
> +			size_t n;
> +			int j;
> +
> +			for (entry_t = readdir(dir_t); entry_t; entry_t = readdir(dir_t)) {
> +				if (!(entry_t->d_type == DT_DIR &&
> +				    is_digits(entry_t->d_name)))
> +					continue;
> +				snprintf(path, sizeof(path),
> +					 "/proc/%s/task/%s/comm",
> +					 entry->d_name, entry_t->d_name);
> +				ft = fopen(path, "r");
> +				if (!ft)
> +					continue;
> +				getline(&buf, &n, ft);
> +				if (buf && strncmp(buf, "CPU ", 4) == 0) {
> +					cpu_str = buf;
> +					while (*cpu_str != '\0' &&
> +						isdigit(*cpu_str) == 0)
> +						cpu_str++;
> +					if (*cpu_str != '\0') {
> +						j = 0;
> +						while (cpu_str[j] != '\0' &&
> +						       isdigit(cpu_str[j]) != 0)
> +							j++;
> +						cpu_str[j] = '\0';
> +						vcpu = atoi(cpu_str);
> +						if (vcpu < VCPUS_MAX)
> +							guest.cpu_pid[vcpu] = atoi(entry_t->d_name);
> +					}
> +				}
> +				free(buf);
> +				fclose(ft);
> +				buf = NULL;
> +			}
> +		}
> +
>  		guests = realloc(guests, (guests_len + 1) * sizeof(*guests));
>  		if (!guests)
>  			die("Can not allocate guest buffer");
> @@ -2875,6 +2920,16 @@ static char *parse_guest_name(char *guest, int *cid, int *port)
>  	return guest;
>  }
>  
> +int *get_guest_vcpu_pids(int cid)
> +{
> +	int i;
> +
> +	for (i = 0; i < guests_len; i++)
> +		if (cid == guests[i].cid)
> +			return guests[i].cpu_pid;
> +	return NULL;
> +}
> +
>  static void set_prio(int prio)
>  {
>  	struct sched_param sp;
> -- 
> 2.20.1
> 

  reply	other threads:[~2019-02-22 17:07 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-22 14:28 [PATCH v4 0/7][POC] trace-cmd: Timetamps sync between host and guest machines, relying on vsock events Tzvetomir Stoyanov
2019-02-22 14:28 ` [PATCH v4 1/7] trace-cmd: Implemented new lib API: tracecmd_local_events_system() Tzvetomir Stoyanov
2019-02-22 15:51   ` Slavomir Kaslev
2019-02-22 19:22     ` Steven Rostedt
2019-02-22 14:28 ` [PATCH v4 2/7] trace-cmd: Added support for negative time offsets in trace.dat file Tzvetomir Stoyanov
2019-02-22 14:28 ` [PATCH v4 3/7] trace-cmd: Fix tracecmd_read_page_record() to read more than one event Tzvetomir Stoyanov
2019-02-22 16:09   ` Slavomir Kaslev
2019-02-22 14:28 ` [PATCH v4 4/7] trace-cmd: Added implementation of htonll() and ntohll() Tzvetomir Stoyanov
2019-02-22 14:28 ` [PATCH v4 5/7] trace-cmd: Refactored make_instances() and tracecmd_remove_instances() Tzvetomir Stoyanov
2019-02-22 14:28 ` [PATCH v4 6/7] trace-cmd: Find and store pids of tasks, which run virtual CPUs of given VM Tzvetomir Stoyanov
2019-02-22 17:07   ` Slavomir Kaslev [this message]
2019-02-22 19:25     ` Steven Rostedt
2019-02-22 14:28 ` [PATCH v4 7/7] trace-cmd [POC]: Implemented timestamps synch algorithm, using vsock events Tzvetomir Stoyanov

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=20190222170708.GB17098@box \
    --to=kaslevs@vmware.com \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=tstoyanov@vmware.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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.