Re: [PATCHv2 4/6] qemu: add architecture-specific CPU info handling

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

 




On 03/05/2018 06:44 AM, Viktor Mihajlovski wrote:
> Extract architecture specific data from query-cpus[-fast] if
> available. A new function qemuMonitorJSONExtractCPUArchInfo()
> uses a call-back table to find and call architecture-specific
> extraction handlers.
> 
> Initially, there's a handler for s390 cpu info to
> set the halted property depending on the s390 cpu state
> returned by QEMU. With this it's still possible to report
> the halted condition even when using query-cpus-fast.
> 
> Signed-off-by: Viktor Mihajlovski <mihajlov@xxxxxxxxxxxxxxxxxx>
> ---
>  src/qemu/qemu_monitor.c      |  4 +--
>  src/qemu/qemu_monitor_json.c | 79 ++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 79 insertions(+), 4 deletions(-)
> 
> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> index 22b2091..5840e25 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -2076,7 +2076,7 @@ qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
>  virBitmapPtr
>  qemuMonitorGetCpuHalted(qemuMonitorPtr mon,
>                          size_t maxvcpus,
> -                        bool fast ATTRIBUTE_UNUSED)
> +                        bool fast)
>  {
>      struct qemuMonitorQueryCpusEntry *cpuentries = NULL;
>      size_t ncpuentries = 0;
> @@ -2088,7 +2088,7 @@ qemuMonitorGetCpuHalted(qemuMonitorPtr mon,
>  
>      if (mon->json)
>          rc = qemuMonitorJSONQueryCPUs(mon, &cpuentries, &ncpuentries, false,
> -                                      false);
> +                                      fast);
>      else
>          rc = qemuMonitorTextQueryCPUs(mon, &cpuentries, &ncpuentries);
>  
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 6a5fb12..1924cfe 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -1451,15 +1451,85 @@ int qemuMonitorJSONSystemReset(qemuMonitorPtr mon)
>  }
>  
>  
> -/*
> +/**
> + * qemuMonitorJSONExtractCPUS390Info:
> + * @jsoncpu: pointer to a single JSON cpu entry
> + * @cpu: pointer to a single cpu entry
> + *
> + * Derive the legacy cpu info 'halted' information
> + * from the more accurate s390 cpu state. @cpu is
> + * modified only on success.
> + *
> + * Note: the 'uninitialized' s390 cpu state can't be
> + *       mapped to halted yes/no.
> + *
> + * A s390 cpu entry could look like this
> + *  { "arch": "s390",
> + *    "cpu-index": 0,
> + *    "qom-path": "/machine/unattached/device[0]",
> + *    "thread_id": 3081,
> + *    "cpu-state": "operating" }
> + *
> + */
> +static void
> +qemuMonitorJSONExtractCPUS390Info(virJSONValuePtr jsoncpu,
> +                                  struct qemuMonitorQueryCpusEntry *cpu)
> +{
> +    const char *cpu_state = virJSONValueObjectGetString(jsoncpu, "cpu-state");
> +
> +    if (STREQ_NULLABLE(cpu_state, "operating") ||
> +        STREQ_NULLABLE(cpu_state, "load"))
> +        cpu->halted = false;
> +    else if (STREQ_NULLABLE(cpu_state, "stopped") ||
> +             STREQ_NULLABLE(cpu_state, "check-stop"))
> +        cpu->halted = true;

Realistically, since false is the default, then only "stopped" and
"check-stop" need to be checked... Even 'uninitialized' would show up as
false since it's not checked.

Perhaps you should create and carry up the calling stack a copy of the
cpu-state that way eventually it could be printed in a 'stats' output as
well...

I suppose another concern is that some future halted state is created
and this code does account for that leading to incorrect reporting and
well some other issues since @halted is used for various decisions.

> +}
> +
> +/**
> + * qemuMonitorJSONExtractCPUArchInfo:
> + * @arch: virtual CPU's architecture
> + * @jsoncpu: pointer to a single JSON cpu entry
> + * @cpu: pointer to a single cpu entry
>   *
> + * Extracts architecure specific virtual CPU data for a single
> + * CPU from the QAPI response using an architecture specific
> + * function.
> + *
> + */
> +static void
> +qemuMonitorJSONExtractCPUArchInfo(const char *arch,
> +                                  virJSONValuePtr jsoncpu,
> +                                  struct qemuMonitorQueryCpusEntry *cpu)
> +{
> +    if (STREQ_NULLABLE(arch, "s390"))
> +        qemuMonitorJSONExtractCPUS390Info(jsoncpu, cpu);
> +}
> +
> +/**
> + * qemuMonitorJSONExtractCPUArchInfo:

^^ This is still qemuMonitorJSONExtractCPUInfo

> + * @data: JSON response data
> + * @entries: filled with detected cpu entries on success
> + * @nentries: number of entries returned
> + * @fast: true if this is a response from query-cpus-fast
> + *
> + * The JSON response @data will have the following format
> + * in case @fast == false
>   * [{ "arch": "x86",
>   *    "current": true,
>   *    "CPU": 0,
>   *    "qom_path": "/machine/unattached/device[0]",
>   *    "pc": -2130415978,
>   *    "halted": true,
> - *    "thread_id": 2631237},
> + *    "thread_id": 2631237,
> + *    ...},
> + *    {...}
> + *  ]
> + * and for @fast == true
> + * [{ "arch": "x86",
> + *    "cpu-index": 0,
> + *    "qom-path": "/machine/unattached/device[0]",
> + *    "thread_id": 2631237,
> + *    ...},

May as well show the whole example and even provide a s390 example so
that it's more obvious...

>   *    {...}
>   *  ]
>   */
> @@ -1486,6 +1556,7 @@ qemuMonitorJSONExtractCPUInfo(virJSONValuePtr data,
>          int thread = 0;
>          bool halted = false;
>          const char *qom_path;
> +        const char *arch;
>          if (!entry) {
>              ret = -2;
>              goto cleanup;
> @@ -1511,6 +1582,10 @@ qemuMonitorJSONExtractCPUInfo(virJSONValuePtr data,
>          cpus[i].halted = halted;
>          if (VIR_STRDUP(cpus[i].qom_path, qom_path) < 0)
>              goto cleanup;
> +
> +        /* process optional architecture-specific data */
> +        arch = virJSONValueObjectGetString(entry, "arch");
> +        qemuMonitorJSONExtractCPUArchInfo(arch, entry, cpus + i);

Since you're passing @entry anyway, you could fetch @arch in
qemuMonitorJSONExtractCPUArchInfo and since it's only valid for "fast ==
true", calling should be gated on that; otherwise, this would be called
for both fast options.

BTW: Rather than "cpus[i]" and "cpus + i", could we just create a
local/stack "cpu" and use it?


John

>      }
>  
>      VIR_STEAL_PTR(*entries, cpus);
> 

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux