[libvirt] [PATCH 8/9] util: Extend virresctl API to retrieve multiple monitor statistics
Michal Privoznik
mprivozn at redhat.com
Tue May 28 09:01:52 UTC 2019
On 5/28/19 10:32 AM, Huaqiang,Wang wrote:
>
>
> On 2019年05月27日 23:26, Michal Privoznik wrote:
>> On 5/23/19 11:34 AM, Wang Huaqiang wrote:
>>> Export virResctrlMonitorGetStats and make
>>> virResctrlMonitorGetCacheOccupancy obsoleted.
>>>
>>> Signed-off-by: Wang Huaqiang <huaqiang.wang at intel.com>
>>> ---
>>> src/libvirt_private.syms | 1 +
>>> src/qemu/qemu_driver.c | 33 +++++++++++++++++++++++++--------
>>> src/util/virresctrl.c | 46
>>> +++++++++++++++++++++++++++-------------------
>>> src/util/virresctrl.h | 6 ++++++
>>> 4 files changed, 59 insertions(+), 27 deletions(-)
>>>
>>> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
>>> index 9099757..2e3d48c 100644
>>> --- a/src/libvirt_private.syms
>>> +++ b/src/libvirt_private.syms
>>> @@ -2771,6 +2771,7 @@ virResctrlMonitorDeterminePath;
>>> virResctrlMonitorFreeStats;
>>> virResctrlMonitorGetCacheOccupancy;
>>> virResctrlMonitorGetID;
>>> +virResctrlMonitorGetStats;
>>> virResctrlMonitorNew;
>>> virResctrlMonitorRemove;
>>> virResctrlMonitorSetAlloc;
>>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>>> index 4ea346c..bc19171 100644
>>> --- a/src/qemu/qemu_driver.c
>>> +++ b/src/qemu/qemu_driver.c
>>> @@ -19987,6 +19987,7 @@
>>> qemuDomainFreeResctrlMonData(virQEMUResctrlMonDataPtr resdata)
>>> /**
>>> * qemuDomainGetResctrlMonData:
>>> + * @driver: Pointer to qemu driver
>>> * @dom: Pointer for the domain that the resctrl monitors reside in
>>> * @resdata: Pointer of virQEMUResctrlMonDataPtr pointer for
>>> receiving the
>>> * virQEMUResctrlMonDataPtr array. Caller is responsible
>>> for
>>> @@ -20005,16 +20006,29 @@
>>> qemuDomainFreeResctrlMonData(virQEMUResctrlMonDataPtr resdata)
>>> * Returns -1 on failure, or 0 on success.
>>> */
>>> static int
>>> -qemuDomainGetResctrlMonData(virDomainObjPtr dom,
>>> +qemuDomainGetResctrlMonData(virQEMUDriverPtr driver,
>>> + virDomainObjPtr dom,
>>> virQEMUResctrlMonDataPtr **resdata,
>>> size_t *nresdata,
>>> virResctrlMonitorType tag)
>>> {
>>> virDomainResctrlDefPtr resctrl = NULL;
>>> virQEMUResctrlMonDataPtr res = NULL;
>>> + char **features = NULL;
>>> size_t i = 0;
>>> size_t j = 0;
>>> + if (tag == VIR_RESCTRL_MONITOR_TYPE_CACHE) {
>>> + features = driver->caps->host.cache.monitor->features;
>>
>>
>> No, we have virQEMUDriverGetCapabilities() which ensures that
>> driver->caps object doesn't go away while accessing this.
>>
>
> I can't refer 'driver->caps->host.cache.monitor->features' directly
> because this function (qemuDomainGetResctrlMonData)
> will be used for 'memory bandwidth' monitors also.
> at that time that the piece of code looks like:
> + if (tag == VIR_RESCTRL_MONITOR_TYPE_CACHE) {
> + if (driver->caps->host.cache.monitor)
> + features = driver->caps->host.cache.monitor->features;
> + if (tag == VIR_RESCTRL_MONITOR_TYPE_MEMBW) {
> + if(driver->caps->host.membw)
> + features = driver->caps->host.membw.monitor->features;
What I meant is that you can obtain virCaps object and then access it
instead:
virCapsPtr caps = virQEMUDriverGetCapabilities(driver, false);
if (tag == VIR_RES..)
features = caps->host.cache.monitor->features;
It's not safe to access driver->caps directly because another thread
might refresh those meanwhile. What may happen for instance is the
following:
Thread1:
fetches driver pointer
adds ->caps displacement
fetches value from that address (which is a long way of saying 'fetch
driver->caps')
Thread2:
Executes virQEMUDriverGetCapabilities(), which boils down to:
virObjectUnref(driver->caps);
driver->caps = caps;
Thread1:
resumes execution and tries to access ->host member.
This is where Thread1 would be accessing invalid memory because the
memory it's trying to access was freed meanwhile by Thread2.
Michal
More information about the libvir-list
mailing list