libxl/libxc: Move libxl_get_cpu_topology()'s hypercall buffer management to libxc

xc_cputopoinfo() is not expected to be used on a hot path and therefore
hypercall buffer management can be pushed into libxc. This will simplify
life for callers.

Also update error reporting macros.

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Boris Ostrovsky authored and Ian Campbell committed 2015-05-13 15:03:37 +01:00
1 parent b3c8f22904
commit 250f0b43af
5 files changed
+61 -75

No files matched your search

+3 -2
View File
@@ -1238,7 +1238,7 @@ int xc_readconsolering(xc_interface *xch,
int xc_send_debug_keys(xc_interface *xch, char *keys);
typedef xen_sysctl_physinfo_t xc_physinfo_t;
typedef xen_sysctl_cputopoinfo_t xc_cputopoinfo_t;
typedef xen_sysctl_cputopo_t xc_cputopo_t;
typedef xen_sysctl_numainfo_t xc_numainfo_t;
typedef uint32_t xc_cpu_to_node_t;
@@ -1249,7 +1249,8 @@ typedef uint64_t xc_node_to_memfree_t;
typedef uint32_t xc_node_to_node_dist_t;
int xc_physinfo(xc_interface *xch, xc_physinfo_t *info);
int xc_cputopoinfo(xc_interface *xch, xc_cputopoinfo_t *info);
int xc_cputopoinfo(xc_interface *xch, unsigned *max_cpus,
xc_cputopo_t *cputopo);
int xc_numainfo(xc_interface *xch, xc_numainfo_t *info);
int xc_sched_id(xc_interface *xch,
+16 -7
View File
@@ -203,22 +203,31 @@ int xc_physinfo(xc_interface *xch,
return 0;
}
int xc_cputopoinfo(xc_interface *xch,
xc_cputopoinfo_t *put_info)
int xc_cputopoinfo(xc_interface *xch, unsigned *max_cpus,
xc_cputopo_t *cputopo)
{
int ret;
DECLARE_SYSCTL;
DECLARE_HYPERCALL_BOUNCE(cputopo, *max_cpus * sizeof(*cputopo),
XC_HYPERCALL_BUFFER_BOUNCE_OUT);
if ( (ret = xc_hypercall_bounce_pre(xch, cputopo)) )
goto out;
sysctl.u.cputopoinfo.num_cpus = *max_cpus;
set_xen_guest_handle(sysctl.u.cputopoinfo.cputopo, cputopo);
sysctl.cmd = XEN_SYSCTL_cputopoinfo;
memcpy(&sysctl.u.cputopoinfo, put_info, sizeof(*put_info));
if ( (ret = do_sysctl(xch, &sysctl)) != 0 )
return ret;
goto out;
memcpy(put_info, &sysctl.u.cputopoinfo, sizeof(*put_info));
*max_cpus = sysctl.u.cputopoinfo.num_cpus;
return 0;
out:
xc_hypercall_bounce_post(xch, cputopo);
return ret;
}
int xc_numainfo(xc_interface *xch,
+12 -25
View File
@@ -5102,37 +5102,28 @@ int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo)
libxl_cputopology *libxl_get_cpu_topology(libxl_ctx *ctx, int *nb_cpu_out)
{
GC_INIT(ctx);
xc_cputopoinfo_t tinfo;
DECLARE_HYPERCALL_BUFFER(xen_sysctl_cputopo_t, cputopo);
xc_cputopo_t *cputopo;
libxl_cputopology *ret = NULL;
int i;
unsigned num_cpus;
/* Setting buffer to NULL makes the hypercall return number of CPUs */
set_xen_guest_handle(tinfo.cputopo, HYPERCALL_BUFFER_NULL);
if (xc_cputopoinfo(ctx->xch, &tinfo) != 0)
/* Setting buffer to NULL makes the call return number of CPUs */
if (xc_cputopoinfo(ctx->xch, &num_cpus, NULL))
{
LIBXL__LOG(ctx, XTL_ERROR, "Unable to determine number of CPUS");
ret = NULL;
LOGE(ERROR, "Unable to determine number of CPUS");
goto out;
}
cputopo = xc_hypercall_buffer_alloc(ctx->xch, cputopo,
sizeof(*cputopo) * tinfo.num_cpus);
if (cputopo == NULL) {
LIBXL__LOG_ERRNOVAL(ctx, XTL_ERROR, ENOMEM,
"Unable to allocate hypercall arguments");
goto fail;
}
set_xen_guest_handle(tinfo.cputopo, cputopo);
cputopo = libxl__zalloc(gc, sizeof(*cputopo) * num_cpus);
if (xc_cputopoinfo(ctx->xch, &tinfo) != 0) {
LIBXL__LOG_ERRNO(ctx, XTL_ERROR, "CPU topology info hypercall failed");
goto fail;
if (xc_cputopoinfo(ctx->xch, &num_cpus, cputopo)) {
LOGE(ERROR, "CPU topology info hypercall failed");
goto out;
}
ret = libxl__zalloc(NOGC, sizeof(libxl_cputopology) * tinfo.num_cpus);
ret = libxl__zalloc(NOGC, sizeof(libxl_cputopology) * num_cpus);
for (i = 0; i < tinfo.num_cpus; i++) {
for (i = 0; i < num_cpus; i++) {
#define V(map, i, invalid) ( cputopo[i].map == invalid) ? \
LIBXL_CPUTOPOLOGY_INVALID_ENTRY : cputopo[i].map
ret[i].core = V(core, i, XEN_INVALID_CORE_ID);
@@ -5141,11 +5132,7 @@ libxl_cputopology *libxl_get_cpu_topology(libxl_ctx *ctx, int *nb_cpu_out)
#undef V
}
fail:
xc_hypercall_buffer_free(ctx->xch, cputopo);
if (ret)
*nb_cpu_out = tinfo.num_cpus;
*nb_cpu_out = num_cpus;
out:
GC_FREE;
+22 -29
View File
@@ -355,20 +355,17 @@ static void signal_int_handler(int signo)
int i, j, k;
struct timeval tv;
int cx_cap = 0, px_cap = 0;
DECLARE_HYPERCALL_BUFFER(xen_sysctl_cputopo_t, cputopo);
xc_cputopoinfo_t info = { 0 };
xc_cputopo_t *cputopo;
unsigned max_cpus;
set_xen_guest_handle(info.cputopo, HYPERCALL_BUFFER_NULL);
if ( xc_cputopoinfo(xc_handle, &info) != 0 )
if ( xc_cputopoinfo(xc_handle, &max_cpus, NULL) != 0 )
{
fprintf(stderr, "failed to discover number of CPUs: %s\n",
strerror(errno));
goto out;
}
cputopo = xc_hypercall_buffer_alloc(xc_handle, cputopo,
sizeof(*cputopo) * info.num_cpus);
cputopo = calloc(max_cpus, sizeof(*cputopo));
if ( cputopo == NULL )
{
fprintf(stderr, "failed to allocate hypercall buffers\n");
@@ -453,28 +450,26 @@ static void signal_int_handler(int signo)
printf(" Avg freq\t%d\tKHz\n", avgfreq[i]);
}
set_xen_guest_handle(info.cputopo, cputopo);
if ( cx_cap && !xc_cputopoinfo(xc_handle, &info) )
if ( cx_cap && !xc_cputopoinfo(xc_handle, &max_cpus, cputopo) )
{
uint32_t socket_ids[MAX_NR_CPU];
uint32_t core_ids[MAX_NR_CPU];
uint32_t socket_nr = 0;
uint32_t core_nr = 0;
if ( info.num_cpus > MAX_NR_CPU )
info.num_cpus = MAX_NR_CPU;
if ( max_cpus > MAX_NR_CPU )
max_cpus = MAX_NR_CPU;
/* check validity */
for ( i = 0; i < info.num_cpus; i++ )
for ( i = 0; i < max_cpus; i++ )
{
if ( cputopo[i].core == XEN_INVALID_CORE_ID ||
cputopo[i].socket == XEN_INVALID_SOCKET_ID )
break;
}
if ( i >= info.num_cpus )
if ( i >= max_cpus )
{
/* find socket nr & core nr per socket */
for ( i = 0; i < info.num_cpus; i++ )
for ( i = 0; i < max_cpus; i++ )
{
for ( j = 0; j < socket_nr; j++ )
if ( cputopo[i].socket == socket_ids[j] )
@@ -501,7 +496,7 @@ static void signal_int_handler(int signo)
unsigned int n;
uint64_t res;
for ( j = 0; j < info.num_cpus; j++ )
for ( j = 0; j < max_cpus; j++ )
{
if ( cputopo[j].socket == socket_ids[i] )
break;
@@ -520,7 +515,7 @@ static void signal_int_handler(int signo)
}
for ( k = 0; k < core_nr; k++ )
{
for ( j = 0; j < info.num_cpus; j++ )
for ( j = 0; j < max_cpus; j++ )
{
if ( cputopo[j].socket == socket_ids[i] &&
cputopo[j].core == core_ids[k] )
@@ -558,7 +553,7 @@ static void signal_int_handler(int signo)
free(sum);
free(avgfreq);
out:
xc_hypercall_buffer_free(xc_handle, cputopo);
free(cputopo);
xc_interface_close(xc_handle);
exit(0);
}
@@ -965,12 +960,11 @@ void scaling_governor_func(int argc, char *argv[])
void cpu_topology_func(int argc, char *argv[])
{
DECLARE_HYPERCALL_BUFFER(xen_sysctl_cputopo_t, cputopo);
xc_cputopoinfo_t info = { 0 };
int i, rc = ENOMEM;
xc_cputopo_t *cputopo;
unsigned max_cpus;
int i, rc;
set_xen_guest_handle(info.cputopo, HYPERCALL_BUFFER_NULL);
if ( xc_cputopoinfo(xc_handle, &info) )
if ( xc_cputopoinfo(xc_handle, &max_cpus, NULL) != 0 )
{
rc = errno;
fprintf(stderr, "failed to discover number of CPUs (%d - %s)\n",
@@ -978,16 +972,15 @@ void cpu_topology_func(int argc, char *argv[])
goto out;
}
cputopo = xc_hypercall_buffer_alloc(xc_handle, cputopo,
sizeof(*cputopo) * info.num_cpus);
cputopo = calloc(max_cpus, sizeof(*cputopo));
if ( cputopo == NULL )
{
rc = ENOMEM;
fprintf(stderr, "failed to allocate hypercall buffers\n");
goto out;
}
set_xen_guest_handle(info.cputopo, cputopo);
if ( xc_cputopoinfo(xc_handle, &info) )
if ( xc_cputopoinfo(xc_handle, &max_cpus, cputopo) )
{
rc = errno;
fprintf(stderr, "Cannot get Xen CPU topology (%d - %s)\n",
@@ -996,7 +989,7 @@ void cpu_topology_func(int argc, char *argv[])
}
printf("CPU\tcore\tsocket\tnode\n");
for ( i = 0; i < info.num_cpus; i++ )
for ( i = 0; i < max_cpus; i++ )
{
if ( cputopo[i].core == XEN_INVALID_CORE_ID )
continue;
@@ -1005,7 +998,7 @@ void cpu_topology_func(int argc, char *argv[])
}
rc = 0;
out:
xc_hypercall_buffer_free(xc_handle, cputopo);
free(cputopo);
if ( rc )
exit(rc);
}
+8 -12
View File
@@ -1220,30 +1220,26 @@ static PyObject *pyxc_getcpuinfo(XcObject *self, PyObject *args, PyObject *kwds)
static PyObject *pyxc_topologyinfo(XcObject *self)
{
xc_cputopoinfo_t tinfo = { 0 };
unsigned i;
xc_cputopo_t *cputopo = NULL;
unsigned i, num_cpus;
PyObject *ret_obj = NULL;
PyObject *cpu_to_core_obj, *cpu_to_socket_obj, *cpu_to_node_obj;
DECLARE_HYPERCALL_BUFFER(xen_sysctl_cputopo_t, cputopo);
set_xen_guest_handle(tinfo.cputopo, HYPERCALL_BUFFER_NULL);
if ( xc_cputopoinfo(self->xc_handle, &tinfo) != 0 )
if ( xc_cputopoinfo(self->xc_handle, &num_cpus, NULL) != 0 )
goto out;
cputopo = xc_hypercall_buffer_alloc(self->xc_handle, cputopo,
sizeof(*cputopo) * tinfo.num_cpus);
cputopo = calloc(num_cpus, sizeof(*cputopo));
if ( cputopo == NULL )
goto out;
set_xen_guest_handle(tinfo.cputopo, cputopo);
if ( xc_cputopoinfo(self->xc_handle, &tinfo) != 0 )
if ( xc_cputopoinfo(self->xc_handle, &num_cpus, cputopo) != 0 )
goto out;
/* Construct cpu-to-* lists. */
cpu_to_core_obj = PyList_New(0);
cpu_to_socket_obj = PyList_New(0);
cpu_to_node_obj = PyList_New(0);
for ( i = 0; i < tinfo.num_cpus; i++ )
for ( i = 0; i < num_cpus; i++ )
{
if ( cputopo[i].core == XEN_INVALID_CORE_ID )
{
@@ -1279,7 +1275,7 @@ static PyObject *pyxc_topologyinfo(XcObject *self)
}
}
ret_obj = Py_BuildValue("{s:i}", "max_cpu_index", tinfo.num_cpus + 1);
ret_obj = Py_BuildValue("{s:i}", "max_cpu_index", num_cpus + 1);
PyDict_SetItemString(ret_obj, "cpu_to_core", cpu_to_core_obj);
Py_DECREF(cpu_to_core_obj);
@@ -1291,7 +1287,7 @@ static PyObject *pyxc_topologyinfo(XcObject *self)
Py_DECREF(cpu_to_node_obj);
out:
xc_hypercall_buffer_free(self->xc_handle, cputopo);
free(cputopo);
return ret_obj ? ret_obj : pyxc_error_to_exception(self->xc_handle);
}
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.