Re: [PATCH 3/3] qemu_driver: use qemuMonitorQueryStats to extract halt poll time

2022-07-23 Thread Amneesh Singh
On Fri, Jul 22, 2022 at 07:09:57PM +0200, Paolo Bonzini wrote:
> On 7/22/22 17:43, Martin Kletzander wrote:
> > As mentioned before, all these failures do not have to exit the
> > function, but rather fallback to the old way.  You can even create
> > two new functions for the new and old implementations and then call
> > them from here to make the fallback easier to spot (and code).
> 
> More precisely, they should just "continue;" to the next iteration of
> the for loop, like
> 
> 
> if (!success_obj || !fail_obj)
> continue;
> 
> found = true;
> 
> and then go fall back if found is false at the end of the loop.
> 
> On the other hand, here:
> 
> if (virJSONValueGetNumberUlong(success_obj, &curHaltPollSuccess) 
> < 0)
> return 0;
> 
> if (virJSONValueGetNumberUlong(fail_obj, &curHaltPollFail) < 0)
> return 0;
> 
> I am not sure about falling back, because it is really an unexpected
> situation where the statistic exist but somehow the value cannot be
> parsed.
Then can we just "continue;" in case the value fails to parse as well?
> 
> Paolo
> 
> > I wanted to change this before pushing as well, but I feel like I'm
> > changing too much of your code.  And I also had to rebase this
> > (although trivially). Would you mind just changing these few last
> > things so that we can get it in before the rc0 freeze?
Alright, as soon as there is a viable check decided for the virJSONValueGet*
statements above, I will push a v4 with the changes you mentioned in
your reviews. Thank you both for taking the time to review.
> 


signature.asc
Description: PGP signature


Re: [PATCH 1/3] qemu_monitor: add qemuMonitorQueryStats

2022-07-23 Thread Amneesh Singh
On Fri, Jul 22, 2022 at 05:02:06PM +0200, Martin Kletzander wrote:
> On Fri, Jul 22, 2022 at 02:44:30PM +0200, Kristina Hanicova wrote:
> > On Thu, Jul 14, 2022 at 7:54 AM Amneesh Singh  wrote:
> > 
> > > Related: https://gitlab.com/libvirt/libvirt/-/issues/276
> > > 
> > > This patch adds an API for the "query-stats" QMP command.
> > > 
> > > The query returns a JSON containing the statistics based on the target,
> > > which can either be vCPU or VM, and the providers. The API deserializes
> > > the query result into an array of GHashMaps, which can later be used to
> > > extract all the query statistics. GHashMaps are used to avoid traversing
> > > the entire array to find the statistics you are looking for. This would
> > > be a singleton array if the target is a VM since the returned JSON is
> > > also a singleton array in that case.
> > > 
> > > Signed-off-by: Amneesh Singh 
> > > ---
> > >  src/qemu/qemu_monitor.c  |  70 +++
> > >  src/qemu/qemu_monitor.h  |  45 
> > >  src/qemu/qemu_monitor_json.c | 130 +++
> > >  src/qemu/qemu_monitor_json.h |   6 ++
> > >  4 files changed, 251 insertions(+)
> > > 
> > > diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> > > index fda5d2f3..a07e6017 100644
> > > --- a/src/qemu/qemu_monitor.c
> > > +++ b/src/qemu/qemu_monitor.c
> > > @@ -4541,3 +4541,73 @@ qemuMonitorMigrateRecover(qemuMonitor *mon,
> > > 
> > >  return qemuMonitorJSONMigrateRecover(mon, uri);
> > >  }
> > > +
> > > +VIR_ENUM_IMPL(qemuMonitorQueryStatsTarget,
> > > +  QEMU_MONITOR_QUERY_STATS_TARGET_LAST,
> > > +  "vm",
> > > +  "vcpu",
> > > +);
> > > +
> > > +VIR_ENUM_IMPL(qemuMonitorQueryStatsName,
> > > +  QEMU_MONITOR_QUERY_STATS_NAME_LAST,
> > > +  "halt_poll_success_ns",
> > > +  "halt_poll_fail_ns"
> > > +);
> > > +
> > > +VIR_ENUM_IMPL(qemuMonitorQueryStatsProvider,
> > > +  QEMU_MONITOR_QUERY_STATS_PROVIDER_LAST,
> > > +  "kvm",
> > > +);
> > > +
> > > +void
> > > +qemuMonitorQueryStatsProviderFree(qemuMonitorQueryStatsProvider 
> > > *provider)
> > > +{
> > > +virBitmapFree(provider->names);
> > > +g_free(provider);
> > > +}
> > > +
> > > +qemuMonitorQueryStatsProvider *
> > > +qemuMonitorQueryStatsProviderNew(qemuMonitorQueryStatsProviderType
> > > provider_type,
> > > + ...)
> > > +{
> > > +g_autoptr(qemuMonitorQueryStatsProvider) provider = NULL;
> > > +qemuMonitorQueryStatsNameType stat;
> > > +va_list name_list;
> > > +size_t sentinel = QEMU_MONITOR_QUERY_STATS_NAME_LAST;
> > > +
> > > +provider = g_new0(qemuMonitorQueryStatsProvider, 1);
> > > +provider->provider = provider_type;
> > > +provider->names = NULL;
> > > +
> > > +va_start(name_list, provider_type);
> > > +stat = va_arg(name_list, qemuMonitorQueryStatsNameType);
> > > +
> > > +if (stat != sentinel) {
> > > 
> > 
> > It would be better to compare 'stat' with QEMU_MONITOR_QUERY_STATS_NAME_LAST
> > directly without the additional variable 'sentinel'.
> > 
> > 
> > > +provider->names =
> > > virBitmapNew(QEMU_MONITOR_QUERY_STATS_NAME_LAST);
> > > +
> > > +while (stat != sentinel) {
> > > 
> > 
> > Same here.
> > 
> > 
> > This while cycle would be better outside the if case, such as:
> > 
> > if (stat != sentinel)
> >provider->names = virBitmapNew(QEMU_MONITOR_QUERY_STATS_NAME_LAST);
> > 
> > while (stat != sentinel) {
> >
> > }
> > 
> > Because the 'while' cycle has the same condition as the 'if' case.
> > 
> > 
> > > +if (virBitmapSetBit(provider->names, stat) < 0)
> > > +return NULL;
> > > +stat = va_arg(name_list, qemuMonitorQueryStatsNameType);
> > > +}
> > > +}
> > > +va_end(name_list);
> > > +
> > > +return g_steal_pointer(&provider);
> > > +}
> 
> Sorry for so many review e-mails from me on this one patch, but while fixing 
> few
> of the nitpicks I managed to rewrite the function quite a bit:
> 
> qemuMonitorQueryStatsProvider *provider = 
> g_new0(qemuMonitorQueryStatsProvider, 1);
> qemuMonitorQueryStatsNameType stat;
> va_list name_list;
> 
> /*
>  * This can be lowered later in case of the enum getting quite large, 
> hence
>  *  the virBitmapSetExpand below.
>  */
> provider->names = virBitmapNew(QEMU_MONITOR_QUERY_STATS_NAME_LAST);
> provider->type = provider_type;
> 
> va_start(name_list, provider_type);
> 
> while ((stat = va_arg(name_list, qemuMonitorQueryStatsNameType)) !=
>QEMU_MONITOR_QUERY_STATS_NAME_LAST)
> virBitmapSetBitExpand(provider->names, stat);
> 
> va_end(name_list);
> 
> return provider;
> 
> Let me know (both of you) if you are okay with me using this version.
Yes, that is absolutely fine, thanks for taking the time to review it. I
will keep the suggestions in mind the next time