Re: [PATCH] trace-cmd: Add support for non-qemu VMs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Apr 26, 2021 at 2:44 PM Joel Fernandes <joelaf@xxxxxxxxxx> wrote:
>
> Hi Tzvetomir, Thanks for the patch. I replied below:
>
> On Mon, Apr 26, 2021 at 6:35 AM Tzvetomir Stoyanov (VMware)
> <tz.stoyanov@xxxxxxxxx> wrote:
> >
> > Current host-guest tracing implementation assumes that qemu runs the VMs
> > and uses qemu specific logic to collect various information:
> >  - PID of the process, running the guest VM. In case of KVM, this PID
> >    is used  to get the KVM guest TSC clock parameters, needed for better
> >    host and guest trace timestamps synchronization.
> >  - PIDs of each thread, running a guest virtual CPU. This is used for
> >    better trace visualisation. It helps to map the host task to a vCPU
> >    and to visualise them together.
> > In case qemu is not used to run the VMs, host-guest tracing fails. As
> > that information is not mandatory, we can easily support non-qemu VMs.
> > Changes, proposed by the patch:
> >  - if PID of the process, running the guest VM, is not available - fail
> >    back to a PTP-like algorithm for trace timestamps synchronization.
> >  - if PIDs of the threads, running guest virtual CPUs, are not available
> >    write -1 in the trace file metadata.
>
> This does not seem to be working still.

Turns out I did not rebuild properly. The PTP sync is working fine on
crosvm and I can indeed see that the vCPU events are time-synced with
host ones.

Tested-By: Joel Fernandes <joelaf@xxxxxxxxxx>

thanks,

- Joel


> >
> > Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@xxxxxxxxx>
> > ---
> >  tracecmd/include/trace-local.h |  4 +--
> >  tracecmd/trace-record.c        | 36 ++++++++++++-------------
> >  tracecmd/trace-vm.c            | 48 ++++++++++++++++++++++++++++++++--
> >  3 files changed, 66 insertions(+), 22 deletions(-)
> >
> > diff --git a/tracecmd/include/trace-local.h b/tracecmd/include/trace-local.h
> > index 1218de12..04d8f32c 100644
> > --- a/tracecmd/include/trace-local.h
> > +++ b/tracecmd/include/trace-local.h
> > @@ -301,8 +301,8 @@ struct trace_guest {
> >         int cpu_max;
> >         int *cpu_pid;
> >  };
> > -struct trace_guest *get_guest_by_cid(unsigned int guest_cid);
> > -struct trace_guest *get_guest_by_name(char *name);
> > +struct trace_guest *trace_get_guest(unsigned int cid, const char *name);
> > +bool trace_have_guests_pid(void);
> >  void read_qemu_guests(void);
> >  int get_guest_pid(unsigned int guest_cid);
> >  int get_guest_vcpu_pid(unsigned int guest_cid, unsigned int guest_vcpu);
> > diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
> > index fd03a605..4636475f 100644
> > --- a/tracecmd/trace-record.c
> > +++ b/tracecmd/trace-record.c
> > @@ -3251,10 +3251,7 @@ static char *parse_guest_name(char *gname, int *cid, int *port)
> >                 *cid = atoi(gname);
> >
> >         read_qemu_guests();
> > -       if (*cid > 0)
> > -               guest = get_guest_by_cid(*cid);
> > -       else
> > -               guest = get_guest_by_name(gname);
> > +       guest = trace_get_guest(*cid, gname);
> >         if (guest) {
> >                 *cid = guest->cid;
> >                 return guest->name;
> > @@ -3723,14 +3720,14 @@ static int host_tsync(struct common_record_context *ctx,
> >
> >         if (!proto)
> >                 return -1;
> > -       guest = get_guest_by_cid(instance->cid);
> > +       guest = trace_get_guest(instance->cid, NULL);
> >         if (guest == NULL)
> >                 return -1;
> >
> >         instance->tsync = tracecmd_tsync_with_guest(top_instance.trace_id,
> >                                                     instance->tsync_loop_interval,
> >                                                     instance->cid, tsync_port,
> > -                                                   guest->pid, guest->cpu_max,
> > +                                                   guest->pid, instance->cpu_count,
> >                                                     proto, ctx->clock);
> >         if (!instance->tsync)
> >                 return -1;
> > @@ -3792,6 +3789,7 @@ static void connect_to_agent(struct common_record_context *ctx,
> >                         printf("Negotiated %s time sync protocol with guest %s\n",
> >                                 tsync_protos_reply,
> >                                 instance->name);
> > +                       instance->cpu_count = nr_cpus;
> >                         host_tsync(ctx, instance, tsync_port, tsync_protos_reply);
> >                 } else
> >                         warning("Failed to negotiate timestamps synchronization with the guest");
> > @@ -3975,21 +3973,19 @@ static void append_buffer(struct tracecmd_output *handle,
> >  static void
> >  add_guest_info(struct tracecmd_output *handle, struct buffer_instance *instance)
> >  {
> > -       struct trace_guest *guest = get_guest_by_cid(instance->cid);
> > +       struct trace_guest *guest = trace_get_guest(instance->cid, NULL);
> >         char *buf, *p;
> >         int size;
> > +       int pid;
> >         int i;
> >
> >         if (!guest)
> >                 return;
> > -       for (i = 0; i < guest->cpu_max; i++)
> > -               if (!guest->cpu_pid[i])
> > -                       break;
> >
> >         size = strlen(guest->name) + 1;
> > -       size +=  sizeof(long long);     /* trace_id */
> > -       size +=  sizeof(int);           /* cpu count */
> > -       size += i * 2 * sizeof(int);    /* cpu,pid pair */
> > +       size += sizeof(long long);      /* trace_id */
> > +       size += sizeof(int);            /* cpu count */
> > +       size += instance->cpu_count * 2 * sizeof(int);  /* cpu,pid pair */
> >
> >         buf = calloc(1, size);
> >         if (!buf)
> > @@ -4001,14 +3997,16 @@ add_guest_info(struct tracecmd_output *handle, struct buffer_instance *instance)
> >         memcpy(p, &instance->trace_id, sizeof(long long));
> >         p += sizeof(long long);
> >
> > -       memcpy(p, &i, sizeof(int));
> > +       memcpy(p, &instance->cpu_count, sizeof(int));
> >         p += sizeof(int);
> > -       for (i = 0; i < guest->cpu_max; i++) {
> > -               if (!guest->cpu_pid[i])
> > -                       break;
> > +       for (i = 0; i < instance->cpu_count; i++) {
> > +               if (i < guest->cpu_max)
> > +                       pid = guest->cpu_pid[i];
> > +               else
> > +                       pid = -1;
> >                 memcpy(p, &i, sizeof(int));
> >                 p += sizeof(int);
> > -               memcpy(p, &guest->cpu_pid[i], sizeof(int));
> > +               memcpy(p, &pid, sizeof(int));
> >                 p += sizeof(int);
> >         }
> >
> > @@ -6553,12 +6551,14 @@ static void set_tsync_params(struct common_record_context *ctx)
> >         /*
> >          * If no clock is configured &&
> >          * KVM time sync protocol is available &&
> > +        * there is information of each guest PID process &&
> >          * tsc-x86 clock is supported &&
> >          * TSC to nsec multiplier and shift are available:
> >          * force using the x86-tsc clock for this host-guest tracing session
> >          * and store TSC to nsec multiplier and shift.
> >          */
> >                 if (tsync_proto_is_supported("kvm") &&
> > +                   trace_have_guests_pid() &&
> >                     clock_is_supported(NULL, TSC_CLOCK) &&
> >                     !get_tsc_nsec(&shift, &mult) && mult) {
> >                         clock = strdup(TSC_CLOCK);
> > diff --git a/tracecmd/trace-vm.c b/tracecmd/trace-vm.c
> > index c8924ece..c0333b67 100644
> > --- a/tracecmd/trace-vm.c
> > +++ b/tracecmd/trace-vm.c
> > @@ -35,7 +35,7 @@ static int set_vcpu_pid_mapping(struct trace_guest *guest, int cpu, int pid)
> >         return 0;
> >  }
> >
> > -struct trace_guest *get_guest_by_cid(unsigned int guest_cid)
> > +static struct trace_guest *get_guest_by_cid(unsigned int guest_cid)
> >  {
> >         int i;
> >
> > @@ -48,7 +48,7 @@ struct trace_guest *get_guest_by_cid(unsigned int guest_cid)
> >         return NULL;
> >  }
> >
> > -struct trace_guest *get_guest_by_name(char *name)
> > +static struct trace_guest *get_guest_by_name(const char *name)
> >  {
> >         int i;
> >
> > @@ -61,6 +61,50 @@ struct trace_guest *get_guest_by_name(char *name)
> >         return NULL;
> >  }
> >
> > +bool trace_have_guests_pid(void)
> > +{
> > +       for (int i = 0; i < guests_len; i++) {
> > +               if (guests[i].pid < 0)
> > +                       return false;
> > +       }
> > +
> > +       return true;
> > +}
> > +
> > +static struct trace_guest *add_guest(unsigned int cid, const char *name)
> > +{
> > +       guests = realloc(guests, (guests_len + 1) * sizeof(*guests));
> > +       if (!guests)
> > +               die("allocating new guest");
> > +       memset(&guests[guests_len], 0, sizeof(struct trace_guest));
> > +       guests[guests_len].name = strdup(name);
> > +       if (!guests[guests_len].name)
> > +               die("allocating guest name");
> > +       guests[guests_len].cid = cid;
> > +       guests[guests_len].pid = -1;
> > +       guests_len++;
> > +
> > +       return &guests[guests_len - 1];
> > +}
> > +
> > +struct trace_guest *trace_get_guest(unsigned int cid, const char *name)
> > +{
> > +       struct trace_guest *guest = NULL;
> > +
> > +       if (name) {
> > +               guest = get_guest_by_name(name);
> > +               if (guest)
> > +                       return guest;
> > +       }
> > +
> > +       if (cid > 0) {
> > +               guest = get_guest_by_cid(cid);
> > +               if (!guest && name)
> > +                       guest = add_guest(cid, name);
> > +       }
> > +       return guest;
> > +}
> > +
> >  static char *get_qemu_guest_name(char *arg)
> >  {
> >         char *tok, *end = arg;
> > --
> > 2.30.2
> >



[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux