tools: Make some callers of xc_domain_getinfo() use xc_domain_getinfolist()

xc_domain_getinfo() is slow and prone to races because N hypercalls are
needed to find information about N domains. xc_domain_getinfolist() finds
the same information in a single hypercall as long as a big enough buffer
is provided. Plus, xc_domain_getinfo() is disappearing on a future patch
so migrate the callers interested in more than 1 domain to the the *list()
version.

Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com>
Acked-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Alejandro Vallejo authored and Andrew Cooper committed 2023-04-28 14:34:40 +01:00
1 parent 8e974df445
commit 4af349a404
3 files changed
+30 -17

No files matched your search

+13
View File
@@ -468,6 +468,19 @@ typedef struct xc_dominfo {
typedef xen_domctl_getdomaininfo_t xc_domaininfo_t; typedef xen_domctl_getdomaininfo_t xc_domaininfo_t;
static inline unsigned int dominfo_shutdown_reason(const xc_domaininfo_t *info)
{
return (info->flags >> XEN_DOMINF_shutdownshift) & XEN_DOMINF_shutdownmask;
}
static inline bool dominfo_shutdown_with(const xc_domaininfo_t *info,
unsigned int expected_reason)
{
/* The reason doesn't make sense unless the domain is actually shutdown */
return (info->flags & XEN_DOMINF_shutdown) &&
(dominfo_shutdown_reason(info) == expected_reason);
}
typedef union typedef union
{ {
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
+14 -14
View File
@@ -342,7 +342,7 @@ static PyObject *pyxc_domain_getinfo(XcObject *self,
uint32_t first_dom = 0; uint32_t first_dom = 0;
int max_doms = 1024, nr_doms, i; int max_doms = 1024, nr_doms, i;
size_t j; size_t j;
xc_dominfo_t *info; xc_domaininfo_t *info;
static char *kwd_list[] = { "first_dom", "max_doms", NULL }; static char *kwd_list[] = { "first_dom", "max_doms", NULL };
@@ -350,11 +350,11 @@ static PyObject *pyxc_domain_getinfo(XcObject *self,
&first_dom, &max_doms) ) &first_dom, &max_doms) )
return NULL; return NULL;
info = calloc(max_doms, sizeof(xc_dominfo_t)); info = calloc(max_doms, sizeof(*info));
if (info == NULL) if (info == NULL)
return PyErr_NoMemory(); return PyErr_NoMemory();
nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info); nr_doms = xc_domain_getinfolist(self->xc_handle, first_dom, max_doms, info);
if (nr_doms < 0) if (nr_doms < 0)
{ {
@@ -368,21 +368,21 @@ static PyObject *pyxc_domain_getinfo(XcObject *self,
info_dict = Py_BuildValue( info_dict = Py_BuildValue(
"{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" "{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
",s:L,s:L,s:L,s:i,s:i,s:i}", ",s:L,s:L,s:L,s:i,s:i,s:i}",
"domid", (int)info[i].domid, "domid", (int)info[i].domain,
"online_vcpus", info[i].nr_online_vcpus, "online_vcpus", info[i].nr_online_vcpus,
"max_vcpu_id", info[i].max_vcpu_id, "max_vcpu_id", info[i].max_vcpu_id,
"hvm", info[i].hvm, "hvm", !!(info[i].flags & XEN_DOMINF_hvm_guest),
"dying", info[i].dying, "dying", !!(info[i].flags & XEN_DOMINF_dying),
"crashed", info[i].crashed, "crashed", dominfo_shutdown_with(&info[i], SHUTDOWN_crash),
"shutdown", info[i].shutdown, "shutdown", !!(info[i].flags & XEN_DOMINF_shutdown),
"paused", info[i].paused, "paused", !!(info[i].flags & XEN_DOMINF_paused),
"blocked", info[i].blocked, "blocked", !!(info[i].flags & XEN_DOMINF_blocked),
"running", info[i].running, "running", !!(info[i].flags & XEN_DOMINF_running),
"mem_kb", (long long)info[i].nr_pages*(XC_PAGE_SIZE/1024), "mem_kb", (long long)info[i].tot_pages * (XC_PAGE_SIZE / 1024),
"cpu_time", (long long)info[i].cpu_time, "cpu_time", (long long)info[i].cpu_time,
"maxmem_kb", (long long)info[i].max_memkb, "maxmem_kb", (long long)(info[i].max_pages << (XC_PAGE_SHIFT - 10)),
"ssidref", (int)info[i].ssidref, "ssidref", (int)info[i].ssidref,
"shutdown_reason", info[i].shutdown_reason, "shutdown_reason", dominfo_shutdown_reason(&info[i]),
"cpupool", (int)info[i].cpupool); "cpupool", (int)info[i].cpupool);
pyhandle = PyList_New(sizeof(xen_domain_handle_t)); pyhandle = PyList_New(sizeof(xen_domain_handle_t));
if ( (pyhandle == NULL) || (info_dict == NULL) ) if ( (pyhandle == NULL) || (info_dict == NULL) )
+3 -3
View File
@@ -775,7 +775,7 @@ static void global_init_domain(int domid, int idx)
static int indexof(int domid) static int indexof(int domid)
{ {
int idx; int idx;
xc_dominfo_t dominfo[NDOMAINS]; xc_domaininfo_t dominfo[NDOMAINS];
xc_interface *xc_handle; xc_interface *xc_handle;
int ndomains; int ndomains;
@@ -797,7 +797,7 @@ static int indexof(int domid)
// call domaininfo hypercall to try and garbage collect unused entries // call domaininfo hypercall to try and garbage collect unused entries
xc_handle = xc_interface_open(0,0,0); xc_handle = xc_interface_open(0,0,0);
ndomains = xc_domain_getinfo(xc_handle, 0, NDOMAINS, dominfo); ndomains = xc_domain_getinfolist(xc_handle, 0, NDOMAINS, dominfo);
xc_interface_close(xc_handle); xc_interface_close(xc_handle);
// for each domain in our data, look for it in the system dominfo structure // for each domain in our data, look for it in the system dominfo structure
@@ -808,7 +808,7 @@ static int indexof(int domid)
int jdx; int jdx;
for (jdx=0; jdx<ndomains; jdx++) { for (jdx=0; jdx<ndomains; jdx++) {
if (dominfo[jdx].domid == domid) if (dominfo[jdx].domain == domid)
break; break;
} }
if (jdx == ndomains) // we didn't find domid in the dominfo struct if (jdx == ndomains) // we didn't find domid in the dominfo struct
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.