mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
sysctl: make XEN_SYSCTL_topologyinfo sysctl a little more efficient
A number of changes to XEN_SYSCTL_topologyinfo interface: * Instead of copying data for each field in xen_sysctl_topologyinfo separately put cpu/socket/node into a single structure and do a single copy for each processor. * A NULL cputopo handle passed is a request for maximum number of CPUs (num_cpus). If cputopo is valid and num_cpus is smaller than the number of CPUs in the system then -ENOBUFS is returned (and correct num_cpus is provided) * Do not use max_cpu_index, which is almost always used for calculating number CPUs (thus requiring adding or subtracting one), replace it with num_cpus. * There is no need to copy whole op in sysctl to user at the end, we only need num_cpus. * Rename xen_sysctl_topologyinfo and XEN_SYSCTL_topologyinfo to reflect the fact that these are used for CPU topology. Subsequent patch will add support for PCI topology sysctl. * Replace INVALID_TOPOLOGY_ID with "XEN_"-prefixed macros for each invalid type (core, socket, node). Update sysctl version to 0x0000000C Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Acked-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
1 parent
4fa6b0bacf
commit
2090f14c5c
7 files changed
+178
-181
No files matched your search
@@ -1226,7 +1226,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_topologyinfo_t xc_topologyinfo_t;
|
||||
typedef xen_sysctl_cputopoinfo_t xc_cputopoinfo_t;
|
||||
typedef xen_sysctl_numainfo_t xc_numainfo_t;
|
||||
|
||||
typedef uint32_t xc_cpu_to_node_t;
|
||||
@@ -1237,7 +1237,7 @@ 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_topologyinfo(xc_interface *xch, xc_topologyinfo_t *info);
|
||||
int xc_cputopoinfo(xc_interface *xch, xc_cputopoinfo_t *info);
|
||||
int xc_numainfo(xc_interface *xch, xc_numainfo_t *info);
|
||||
|
||||
int xc_sched_id(xc_interface *xch,
|
||||
|
||||
@@ -177,20 +177,20 @@ int xc_physinfo(xc_interface *xch,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xc_topologyinfo(xc_interface *xch,
|
||||
xc_topologyinfo_t *put_info)
|
||||
int xc_cputopoinfo(xc_interface *xch,
|
||||
xc_cputopoinfo_t *put_info)
|
||||
{
|
||||
int ret;
|
||||
DECLARE_SYSCTL;
|
||||
|
||||
sysctl.cmd = XEN_SYSCTL_topologyinfo;
|
||||
sysctl.cmd = XEN_SYSCTL_cputopoinfo;
|
||||
|
||||
memcpy(&sysctl.u.topologyinfo, put_info, sizeof(*put_info));
|
||||
memcpy(&sysctl.u.cputopoinfo, put_info, sizeof(*put_info));
|
||||
|
||||
if ( (ret = do_sysctl(xch, &sysctl)) != 0 )
|
||||
return ret;
|
||||
|
||||
memcpy(put_info, &sysctl.u.topologyinfo, sizeof(*put_info));
|
||||
memcpy(put_info, &sysctl.u.cputopoinfo, sizeof(*put_info));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+21
-34
@@ -5101,64 +5101,51 @@ 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_topologyinfo_t tinfo;
|
||||
DECLARE_HYPERCALL_BUFFER(xc_cpu_to_core_t, coremap);
|
||||
DECLARE_HYPERCALL_BUFFER(xc_cpu_to_socket_t, socketmap);
|
||||
DECLARE_HYPERCALL_BUFFER(xc_cpu_to_node_t, nodemap);
|
||||
xc_cputopoinfo_t tinfo;
|
||||
DECLARE_HYPERCALL_BUFFER(xen_sysctl_cputopo_t, cputopo);
|
||||
libxl_cputopology *ret = NULL;
|
||||
int i;
|
||||
int max_cpus;
|
||||
|
||||
max_cpus = libxl_get_max_cpus(ctx);
|
||||
if (max_cpus < 0)
|
||||
/* 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)
|
||||
{
|
||||
LIBXL__LOG(ctx, XTL_ERROR, "Unable to determine number of CPUS");
|
||||
ret = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
coremap = xc_hypercall_buffer_alloc
|
||||
(ctx->xch, coremap, sizeof(*coremap) * max_cpus);
|
||||
socketmap = xc_hypercall_buffer_alloc
|
||||
(ctx->xch, socketmap, sizeof(*socketmap) * max_cpus);
|
||||
nodemap = xc_hypercall_buffer_alloc
|
||||
(ctx->xch, nodemap, sizeof(*nodemap) * max_cpus);
|
||||
if ((coremap == NULL) || (socketmap == NULL) || (nodemap == NULL)) {
|
||||
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);
|
||||
|
||||
set_xen_guest_handle(tinfo.cpu_to_core, coremap);
|
||||
set_xen_guest_handle(tinfo.cpu_to_socket, socketmap);
|
||||
set_xen_guest_handle(tinfo.cpu_to_node, nodemap);
|
||||
tinfo.max_cpu_index = max_cpus - 1;
|
||||
if (xc_topologyinfo(ctx->xch, &tinfo) != 0) {
|
||||
LIBXL__LOG_ERRNO(ctx, XTL_ERROR, "Topology info hypercall failed");
|
||||
if (xc_cputopoinfo(ctx->xch, &tinfo) != 0) {
|
||||
LIBXL__LOG_ERRNO(ctx, XTL_ERROR, "CPU topology info hypercall failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (tinfo.max_cpu_index < max_cpus - 1)
|
||||
max_cpus = tinfo.max_cpu_index + 1;
|
||||
ret = libxl__zalloc(NOGC, sizeof(libxl_cputopology) * tinfo.num_cpus);
|
||||
|
||||
ret = libxl__zalloc(NOGC, sizeof(libxl_cputopology) * max_cpus);
|
||||
|
||||
for (i = 0; i < max_cpus; i++) {
|
||||
#define V(map, i) (map[i] == INVALID_TOPOLOGY_ID) ? \
|
||||
LIBXL_CPUTOPOLOGY_INVALID_ENTRY : map[i]
|
||||
ret[i].core = V(coremap, i);
|
||||
ret[i].socket = V(socketmap, i);
|
||||
ret[i].node = V(nodemap, i);
|
||||
for (i = 0; i < tinfo.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);
|
||||
ret[i].socket = V(socket, i, XEN_INVALID_SOCKET_ID);
|
||||
ret[i].node = V(node, i, XEN_INVALID_NODE_ID);
|
||||
#undef V
|
||||
}
|
||||
|
||||
fail:
|
||||
xc_hypercall_buffer_free(ctx->xch, coremap);
|
||||
xc_hypercall_buffer_free(ctx->xch, socketmap);
|
||||
xc_hypercall_buffer_free(ctx->xch, nodemap);
|
||||
xc_hypercall_buffer_free(ctx->xch, cputopo);
|
||||
|
||||
if (ret)
|
||||
*nb_cpu_out = max_cpus;
|
||||
*nb_cpu_out = tinfo.num_cpus;
|
||||
|
||||
out:
|
||||
GC_FREE;
|
||||
return ret;
|
||||
|
||||
+51
-55
@@ -355,16 +355,21 @@ static void signal_int_handler(int signo)
|
||||
int i, j, k;
|
||||
struct timeval tv;
|
||||
int cx_cap = 0, px_cap = 0;
|
||||
DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_core);
|
||||
DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_socket);
|
||||
DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_node);
|
||||
xc_topologyinfo_t info = { 0 };
|
||||
DECLARE_HYPERCALL_BUFFER(xen_sysctl_cputopo_t, cputopo);
|
||||
xc_cputopoinfo_t info = { 0 };
|
||||
|
||||
cpu_to_core = xc_hypercall_buffer_alloc(xc_handle, cpu_to_core, sizeof(*cpu_to_core) * MAX_NR_CPU);
|
||||
cpu_to_socket = xc_hypercall_buffer_alloc(xc_handle, cpu_to_socket, sizeof(*cpu_to_socket) * MAX_NR_CPU);
|
||||
cpu_to_node = xc_hypercall_buffer_alloc(xc_handle, cpu_to_node, sizeof(*cpu_to_node) * MAX_NR_CPU);
|
||||
set_xen_guest_handle(info.cputopo, HYPERCALL_BUFFER_NULL);
|
||||
if ( xc_cputopoinfo(xc_handle, &info) != 0 )
|
||||
{
|
||||
fprintf(stderr, "failed to discover number of CPUs: %s\n",
|
||||
strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( cpu_to_core == NULL || cpu_to_socket == NULL || cpu_to_node == NULL )
|
||||
cputopo = xc_hypercall_buffer_alloc(xc_handle, cputopo,
|
||||
sizeof(*cputopo) * info.num_cpus);
|
||||
|
||||
if ( cputopo == NULL )
|
||||
{
|
||||
fprintf(stderr, "failed to allocate hypercall buffers\n");
|
||||
goto out;
|
||||
@@ -448,47 +453,44 @@ static void signal_int_handler(int signo)
|
||||
printf(" Avg freq\t%d\tKHz\n", avgfreq[i]);
|
||||
}
|
||||
|
||||
set_xen_guest_handle(info.cpu_to_core, cpu_to_core);
|
||||
set_xen_guest_handle(info.cpu_to_socket, cpu_to_socket);
|
||||
set_xen_guest_handle(info.cpu_to_node, cpu_to_node);
|
||||
info.max_cpu_index = MAX_NR_CPU - 1;
|
||||
set_xen_guest_handle(info.cputopo, cputopo);
|
||||
|
||||
if ( cx_cap && !xc_topologyinfo(xc_handle, &info) )
|
||||
if ( cx_cap && !xc_cputopoinfo(xc_handle, &info) )
|
||||
{
|
||||
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.max_cpu_index > MAX_NR_CPU - 1 )
|
||||
info.max_cpu_index = MAX_NR_CPU - 1;
|
||||
if ( info.num_cpus > MAX_NR_CPU )
|
||||
info.num_cpus = MAX_NR_CPU;
|
||||
/* check validity */
|
||||
for ( i = 0; i <= info.max_cpu_index; i++ )
|
||||
for ( i = 0; i < info.num_cpus; i++ )
|
||||
{
|
||||
if ( cpu_to_core[i] == INVALID_TOPOLOGY_ID ||
|
||||
cpu_to_socket[i] == INVALID_TOPOLOGY_ID )
|
||||
if ( cputopo[i].core == XEN_INVALID_CORE_ID ||
|
||||
cputopo[i].socket == XEN_INVALID_SOCKET_ID )
|
||||
break;
|
||||
}
|
||||
if ( i > info.max_cpu_index )
|
||||
if ( i >= info.num_cpus )
|
||||
{
|
||||
/* find socket nr & core nr per socket */
|
||||
for ( i = 0; i <= info.max_cpu_index; i++ )
|
||||
for ( i = 0; i < info.num_cpus; i++ )
|
||||
{
|
||||
for ( j = 0; j < socket_nr; j++ )
|
||||
if ( cpu_to_socket[i] == socket_ids[j] )
|
||||
if ( cputopo[i].socket == socket_ids[j] )
|
||||
break;
|
||||
if ( j == socket_nr )
|
||||
{
|
||||
socket_ids[j] = cpu_to_socket[i];
|
||||
socket_ids[j] = cputopo[i].socket;
|
||||
socket_nr++;
|
||||
}
|
||||
|
||||
for ( j = 0; j < core_nr; j++ )
|
||||
if ( cpu_to_core[i] == core_ids[j] )
|
||||
if ( cputopo[i].core == core_ids[j] )
|
||||
break;
|
||||
if ( j == core_nr )
|
||||
{
|
||||
core_ids[j] = cpu_to_core[i];
|
||||
core_ids[j] = cputopo[i].core;
|
||||
core_nr++;
|
||||
}
|
||||
}
|
||||
@@ -499,9 +501,9 @@ static void signal_int_handler(int signo)
|
||||
unsigned int n;
|
||||
uint64_t res;
|
||||
|
||||
for ( j = 0; j <= info.max_cpu_index; j++ )
|
||||
for ( j = 0; j < info.num_cpus; j++ )
|
||||
{
|
||||
if ( cpu_to_socket[j] == socket_ids[i] )
|
||||
if ( cputopo[j].socket == socket_ids[i] )
|
||||
break;
|
||||
}
|
||||
printf("\nSocket %d\n", socket_ids[i]);
|
||||
@@ -518,10 +520,10 @@ static void signal_int_handler(int signo)
|
||||
}
|
||||
for ( k = 0; k < core_nr; k++ )
|
||||
{
|
||||
for ( j = 0; j <= info.max_cpu_index; j++ )
|
||||
for ( j = 0; j < info.num_cpus; j++ )
|
||||
{
|
||||
if ( cpu_to_socket[j] == socket_ids[i] &&
|
||||
cpu_to_core[j] == core_ids[k] )
|
||||
if ( cputopo[j].socket == socket_ids[i] &&
|
||||
cputopo[j].core == core_ids[k] )
|
||||
break;
|
||||
}
|
||||
printf("\t Core %d CPU %d\n", core_ids[k], j);
|
||||
@@ -556,9 +558,7 @@ static void signal_int_handler(int signo)
|
||||
free(sum);
|
||||
free(avgfreq);
|
||||
out:
|
||||
xc_hypercall_buffer_free(xc_handle, cpu_to_core);
|
||||
xc_hypercall_buffer_free(xc_handle, cpu_to_socket);
|
||||
xc_hypercall_buffer_free(xc_handle, cpu_to_node);
|
||||
xc_hypercall_buffer_free(xc_handle, cputopo);
|
||||
xc_interface_close(xc_handle);
|
||||
exit(0);
|
||||
}
|
||||
@@ -965,28 +965,29 @@ void scaling_governor_func(int argc, char *argv[])
|
||||
|
||||
void cpu_topology_func(int argc, char *argv[])
|
||||
{
|
||||
DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_core);
|
||||
DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_socket);
|
||||
DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_node);
|
||||
xc_topologyinfo_t info = { 0 };
|
||||
DECLARE_HYPERCALL_BUFFER(xen_sysctl_cputopo_t, cputopo);
|
||||
xc_cputopoinfo_t info = { 0 };
|
||||
int i, rc = ENOMEM;
|
||||
|
||||
cpu_to_core = xc_hypercall_buffer_alloc(xc_handle, cpu_to_core, sizeof(*cpu_to_core) * MAX_NR_CPU);
|
||||
cpu_to_socket = xc_hypercall_buffer_alloc(xc_handle, cpu_to_socket, sizeof(*cpu_to_socket) * MAX_NR_CPU);
|
||||
cpu_to_node = xc_hypercall_buffer_alloc(xc_handle, cpu_to_node, sizeof(*cpu_to_node) * MAX_NR_CPU);
|
||||
set_xen_guest_handle(info.cputopo, HYPERCALL_BUFFER_NULL);
|
||||
if ( xc_cputopoinfo(xc_handle, &info) )
|
||||
{
|
||||
rc = errno;
|
||||
fprintf(stderr, "failed to discover number of CPUs (%d - %s)\n",
|
||||
errno, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( cpu_to_core == NULL || cpu_to_socket == NULL || cpu_to_node == NULL )
|
||||
cputopo = xc_hypercall_buffer_alloc(xc_handle, cputopo,
|
||||
sizeof(*cputopo) * info.num_cpus);
|
||||
if ( cputopo == NULL )
|
||||
{
|
||||
fprintf(stderr, "failed to allocate hypercall buffers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
set_xen_guest_handle(info.cpu_to_core, cpu_to_core);
|
||||
set_xen_guest_handle(info.cpu_to_socket, cpu_to_socket);
|
||||
set_xen_guest_handle(info.cpu_to_node, cpu_to_node);
|
||||
info.max_cpu_index = MAX_NR_CPU-1;
|
||||
|
||||
if ( xc_topologyinfo(xc_handle, &info) )
|
||||
set_xen_guest_handle(info.cputopo, cputopo);
|
||||
if ( xc_cputopoinfo(xc_handle, &info) )
|
||||
{
|
||||
rc = errno;
|
||||
fprintf(stderr, "Cannot get Xen CPU topology (%d - %s)\n",
|
||||
@@ -994,22 +995,17 @@ void cpu_topology_func(int argc, char *argv[])
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( info.max_cpu_index > (MAX_NR_CPU-1) )
|
||||
info.max_cpu_index = MAX_NR_CPU-1;
|
||||
|
||||
printf("CPU\tcore\tsocket\tnode\n");
|
||||
for ( i = 0; i <= info.max_cpu_index; i++ )
|
||||
for ( i = 0; i < info.num_cpus; i++ )
|
||||
{
|
||||
if ( cpu_to_core[i] == INVALID_TOPOLOGY_ID )
|
||||
if ( cputopo[i].core == XEN_INVALID_CORE_ID )
|
||||
continue;
|
||||
printf("CPU%d\t %d\t %d\t %d\n",
|
||||
i, cpu_to_core[i], cpu_to_socket[i], cpu_to_node[i]);
|
||||
i, cputopo[i].core, cputopo[i].socket, cputopo[i].node);
|
||||
}
|
||||
rc = 0;
|
||||
out:
|
||||
xc_hypercall_buffer_free(xc_handle, cpu_to_core);
|
||||
xc_hypercall_buffer_free(xc_handle, cpu_to_socket);
|
||||
xc_hypercall_buffer_free(xc_handle, cpu_to_node);
|
||||
xc_hypercall_buffer_free(xc_handle, cputopo);
|
||||
if ( rc )
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
@@ -1220,78 +1220,66 @@ static PyObject *pyxc_getcpuinfo(XcObject *self, PyObject *args, PyObject *kwds)
|
||||
|
||||
static PyObject *pyxc_topologyinfo(XcObject *self)
|
||||
{
|
||||
#define MAX_CPU_INDEX 255
|
||||
xc_topologyinfo_t tinfo = { 0 };
|
||||
int i, max_cpu_index;
|
||||
xc_cputopoinfo_t tinfo = { 0 };
|
||||
unsigned i;
|
||||
PyObject *ret_obj = NULL;
|
||||
PyObject *cpu_to_core_obj, *cpu_to_socket_obj, *cpu_to_node_obj;
|
||||
DECLARE_HYPERCALL_BUFFER(xc_cpu_to_core_t, coremap);
|
||||
DECLARE_HYPERCALL_BUFFER(xc_cpu_to_socket_t, socketmap);
|
||||
DECLARE_HYPERCALL_BUFFER(xc_cpu_to_node_t, nodemap);
|
||||
DECLARE_HYPERCALL_BUFFER(xen_sysctl_cputopo_t, cputopo);
|
||||
|
||||
coremap = xc_hypercall_buffer_alloc(self->xc_handle, coremap, sizeof(*coremap) * (MAX_CPU_INDEX+1));
|
||||
if ( coremap == NULL )
|
||||
goto out;
|
||||
socketmap = xc_hypercall_buffer_alloc(self->xc_handle, socketmap, sizeof(*socketmap) * (MAX_CPU_INDEX+1));
|
||||
if ( socketmap == NULL )
|
||||
goto out;
|
||||
nodemap = xc_hypercall_buffer_alloc(self->xc_handle, nodemap, sizeof(*nodemap) * (MAX_CPU_INDEX+1));
|
||||
if ( nodemap == NULL )
|
||||
set_xen_guest_handle(tinfo.cputopo, HYPERCALL_BUFFER_NULL);
|
||||
if ( xc_cputopoinfo(self->xc_handle, &tinfo) != 0 )
|
||||
goto out;
|
||||
|
||||
set_xen_guest_handle(tinfo.cpu_to_core, coremap);
|
||||
set_xen_guest_handle(tinfo.cpu_to_socket, socketmap);
|
||||
set_xen_guest_handle(tinfo.cpu_to_node, nodemap);
|
||||
tinfo.max_cpu_index = MAX_CPU_INDEX;
|
||||
cputopo = xc_hypercall_buffer_alloc(self->xc_handle, cputopo,
|
||||
sizeof(*cputopo) * tinfo.num_cpus);
|
||||
if ( cputopo == NULL )
|
||||
goto out;
|
||||
|
||||
if ( xc_topologyinfo(self->xc_handle, &tinfo) != 0 )
|
||||
set_xen_guest_handle(tinfo.cputopo, cputopo);
|
||||
if ( xc_cputopoinfo(self->xc_handle, &tinfo) != 0 )
|
||||
goto out;
|
||||
|
||||
max_cpu_index = tinfo.max_cpu_index;
|
||||
if ( max_cpu_index > MAX_CPU_INDEX )
|
||||
max_cpu_index = MAX_CPU_INDEX;
|
||||
|
||||
/* 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 <= max_cpu_index; i++ )
|
||||
for ( i = 0; i < tinfo.num_cpus; i++ )
|
||||
{
|
||||
if ( coremap[i] == INVALID_TOPOLOGY_ID )
|
||||
if ( cputopo[i].core == XEN_INVALID_CORE_ID )
|
||||
{
|
||||
PyList_Append(cpu_to_core_obj, Py_None);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyObject *pyint = PyInt_FromLong(coremap[i]);
|
||||
PyObject *pyint = PyInt_FromLong(cputopo[i].core);
|
||||
PyList_Append(cpu_to_core_obj, pyint);
|
||||
Py_DECREF(pyint);
|
||||
}
|
||||
|
||||
if ( socketmap[i] == INVALID_TOPOLOGY_ID )
|
||||
if ( cputopo[i].socket == XEN_INVALID_SOCKET_ID )
|
||||
{
|
||||
PyList_Append(cpu_to_socket_obj, Py_None);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyObject *pyint = PyInt_FromLong(socketmap[i]);
|
||||
PyObject *pyint = PyInt_FromLong(cputopo[i].socket);
|
||||
PyList_Append(cpu_to_socket_obj, pyint);
|
||||
Py_DECREF(pyint);
|
||||
}
|
||||
|
||||
if ( nodemap[i] == INVALID_TOPOLOGY_ID )
|
||||
if ( cputopo[i].node == XEN_INVALID_NODE_ID )
|
||||
{
|
||||
PyList_Append(cpu_to_node_obj, Py_None);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyObject *pyint = PyInt_FromLong(nodemap[i]);
|
||||
PyObject *pyint = PyInt_FromLong(cputopo[i].node);
|
||||
PyList_Append(cpu_to_node_obj, pyint);
|
||||
Py_DECREF(pyint);
|
||||
}
|
||||
}
|
||||
|
||||
ret_obj = Py_BuildValue("{s:i}", "max_cpu_index", max_cpu_index);
|
||||
ret_obj = Py_BuildValue("{s:i}", "max_cpu_index", tinfo.num_cpus + 1);
|
||||
|
||||
PyDict_SetItemString(ret_obj, "cpu_to_core", cpu_to_core_obj);
|
||||
Py_DECREF(cpu_to_core_obj);
|
||||
@@ -1303,11 +1291,8 @@ static PyObject *pyxc_topologyinfo(XcObject *self)
|
||||
Py_DECREF(cpu_to_node_obj);
|
||||
|
||||
out:
|
||||
xc_hypercall_buffer_free(self->xc_handle, coremap);
|
||||
xc_hypercall_buffer_free(self->xc_handle, socketmap);
|
||||
xc_hypercall_buffer_free(self->xc_handle, nodemap);
|
||||
xc_hypercall_buffer_free(self->xc_handle, cputopo);
|
||||
return ret_obj ? ret_obj : pyxc_error_to_exception(self->xc_handle);
|
||||
#undef MAX_CPU_INDEX
|
||||
}
|
||||
|
||||
static PyObject *pyxc_numainfo(XcObject *self)
|
||||
@@ -1375,7 +1360,7 @@ static PyObject *pyxc_numainfo(XcObject *self)
|
||||
for ( j = 0; j <= max_node_index; j++ )
|
||||
{
|
||||
uint32_t dist = nodes_dist[i*(max_node_index+1) + j];
|
||||
if ( dist == INVALID_TOPOLOGY_ID )
|
||||
if ( dist == ~0u )
|
||||
{
|
||||
PyList_Append(node_to_node_dist_obj, Py_None);
|
||||
}
|
||||
|
||||
+47
-23
@@ -325,39 +325,63 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
|
||||
}
|
||||
break;
|
||||
|
||||
case XEN_SYSCTL_topologyinfo:
|
||||
case XEN_SYSCTL_cputopoinfo:
|
||||
{
|
||||
uint32_t i, max_cpu_index, last_online_cpu;
|
||||
xen_sysctl_topologyinfo_t *ti = &op->u.topologyinfo;
|
||||
unsigned int i, num_cpus;
|
||||
xen_sysctl_cputopoinfo_t *ti = &op->u.cputopoinfo;
|
||||
|
||||
last_online_cpu = cpumask_last(&cpu_online_map);
|
||||
max_cpu_index = min_t(uint32_t, ti->max_cpu_index, last_online_cpu);
|
||||
ti->max_cpu_index = last_online_cpu;
|
||||
|
||||
for ( i = 0; i <= max_cpu_index; i++ )
|
||||
num_cpus = cpumask_last(&cpu_online_map) + 1;
|
||||
if ( !guest_handle_is_null(ti->cputopo) )
|
||||
{
|
||||
if ( !guest_handle_is_null(ti->cpu_to_core) )
|
||||
if ( ti->num_cpus < num_cpus )
|
||||
{
|
||||
uint32_t core = cpu_online(i) ? cpu_to_core(i) : ~0u;
|
||||
if ( copy_to_guest_offset(ti->cpu_to_core, i, &core, 1) )
|
||||
break;
|
||||
ret = -ENOBUFS;
|
||||
i = num_cpus;
|
||||
}
|
||||
if ( !guest_handle_is_null(ti->cpu_to_socket) )
|
||||
|
||||
for ( i = 0; i < num_cpus; i++ )
|
||||
{
|
||||
uint32_t socket = cpu_online(i) ? cpu_to_socket(i) : ~0u;
|
||||
if ( copy_to_guest_offset(ti->cpu_to_socket, i, &socket, 1) )
|
||||
break;
|
||||
}
|
||||
if ( !guest_handle_is_null(ti->cpu_to_node) )
|
||||
{
|
||||
uint32_t node = cpu_online(i) ? cpu_to_node(i) : ~0u;
|
||||
if ( copy_to_guest_offset(ti->cpu_to_node, i, &node, 1) )
|
||||
xen_sysctl_cputopo_t cputopo;
|
||||
|
||||
if ( cpu_present(i) )
|
||||
{
|
||||
cputopo.core = cpu_to_core(i);
|
||||
if ( cputopo.core == BAD_APICID )
|
||||
cputopo.core = XEN_INVALID_CORE_ID;
|
||||
cputopo.socket = cpu_to_socket(i);
|
||||
if ( cputopo.socket == BAD_APICID )
|
||||
cputopo.socket = XEN_INVALID_SOCKET_ID;
|
||||
cputopo.node = cpu_to_node(i);
|
||||
if ( cputopo.node == NUMA_NO_NODE )
|
||||
cputopo.node = XEN_INVALID_NODE_ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
cputopo.core = XEN_INVALID_CORE_ID;
|
||||
cputopo.socket = XEN_INVALID_SOCKET_ID;
|
||||
cputopo.node = XEN_INVALID_NODE_ID;
|
||||
}
|
||||
|
||||
if ( copy_to_guest_offset(ti->cputopo, i, &cputopo, 1) )
|
||||
{
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
i = num_cpus;
|
||||
|
||||
ret = ((i <= max_cpu_index) || copy_to_guest(u_sysctl, op, 1))
|
||||
? -EFAULT : 0;
|
||||
if ( (!ret || (ret == -ENOBUFS)) && (ti->num_cpus != i) )
|
||||
{
|
||||
ti->num_cpus = i;
|
||||
if ( __copy_field_to_guest(u_sysctl, op,
|
||||
u.cputopoinfo.num_cpus) )
|
||||
{
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+31
-26
@@ -34,7 +34,7 @@
|
||||
#include "xen.h"
|
||||
#include "domctl.h"
|
||||
|
||||
#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000B
|
||||
#define XEN_SYSCTL_INTERFACE_VERSION 0x0000000C
|
||||
|
||||
/*
|
||||
* Read console content from Xen buffer ring.
|
||||
@@ -462,31 +462,36 @@ struct xen_sysctl_lockprof_op {
|
||||
typedef struct xen_sysctl_lockprof_op xen_sysctl_lockprof_op_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_lockprof_op_t);
|
||||
|
||||
/* XEN_SYSCTL_topologyinfo */
|
||||
#define INVALID_TOPOLOGY_ID (~0U)
|
||||
struct xen_sysctl_topologyinfo {
|
||||
/*
|
||||
* IN: maximum addressable entry in the caller-provided arrays.
|
||||
* OUT: largest cpu identifier in the system.
|
||||
* If OUT is greater than IN then the arrays are truncated!
|
||||
* If OUT is leass than IN then the array tails are not written by sysctl.
|
||||
*/
|
||||
uint32_t max_cpu_index;
|
||||
/* XEN_SYSCTL_cputopoinfo */
|
||||
#define XEN_INVALID_CORE_ID (~0U)
|
||||
#define XEN_INVALID_SOCKET_ID (~0U)
|
||||
#define XEN_INVALID_NODE_ID (~0U)
|
||||
|
||||
/*
|
||||
* If not NULL, these arrays are filled with core/socket/node identifier
|
||||
* for each cpu.
|
||||
* If a cpu has no core/socket/node information (e.g., cpu not present)
|
||||
* then the sentinel value ~0u is written to each array.
|
||||
* The number of array elements written by the sysctl is:
|
||||
* min(@max_cpu_index_IN,@max_cpu_index_OUT)+1
|
||||
*/
|
||||
XEN_GUEST_HANDLE_64(uint32) cpu_to_core;
|
||||
XEN_GUEST_HANDLE_64(uint32) cpu_to_socket;
|
||||
XEN_GUEST_HANDLE_64(uint32) cpu_to_node;
|
||||
struct xen_sysctl_cputopo {
|
||||
uint32_t core;
|
||||
uint32_t socket;
|
||||
uint32_t node;
|
||||
};
|
||||
typedef struct xen_sysctl_topologyinfo xen_sysctl_topologyinfo_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_topologyinfo_t);
|
||||
typedef struct xen_sysctl_cputopo xen_sysctl_cputopo_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cputopo_t);
|
||||
|
||||
/*
|
||||
* IN:
|
||||
* - a NULL 'cputopo' handle is a request for maximun 'num_cpus'.
|
||||
* - otherwise it's the number of entries in 'cputopo'
|
||||
*
|
||||
* OUT:
|
||||
* - If 'num_cpus' is less than the number Xen needs to write, -ENOBUFS shall
|
||||
* be returned and 'num_cpus' updated to reflect the intended number.
|
||||
* - On success, 'num_cpus' shall indicate the number of entries written, which
|
||||
* may be less than the maximum.
|
||||
*/
|
||||
struct xen_sysctl_cputopoinfo {
|
||||
uint32_t num_cpus;
|
||||
XEN_GUEST_HANDLE_64(xen_sysctl_cputopo_t) cputopo;
|
||||
};
|
||||
typedef struct xen_sysctl_cputopoinfo xen_sysctl_cputopoinfo_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cputopoinfo_t);
|
||||
|
||||
/* XEN_SYSCTL_numainfo */
|
||||
#define INVALID_NUMAINFO_ID (~0U)
|
||||
@@ -672,7 +677,7 @@ struct xen_sysctl {
|
||||
#define XEN_SYSCTL_pm_op 12
|
||||
#define XEN_SYSCTL_page_offline_op 14
|
||||
#define XEN_SYSCTL_lockprof_op 15
|
||||
#define XEN_SYSCTL_topologyinfo 16
|
||||
#define XEN_SYSCTL_cputopoinfo 16
|
||||
#define XEN_SYSCTL_numainfo 17
|
||||
#define XEN_SYSCTL_cpupool_op 18
|
||||
#define XEN_SYSCTL_scheduler_op 19
|
||||
@@ -683,7 +688,7 @@ struct xen_sysctl {
|
||||
struct xen_sysctl_readconsole readconsole;
|
||||
struct xen_sysctl_tbuf_op tbuf_op;
|
||||
struct xen_sysctl_physinfo physinfo;
|
||||
struct xen_sysctl_topologyinfo topologyinfo;
|
||||
struct xen_sysctl_cputopoinfo cputopoinfo;
|
||||
struct xen_sysctl_numainfo numainfo;
|
||||
struct xen_sysctl_sched_id sched_id;
|
||||
struct xen_sysctl_perfc_op perfc_op;
|
||||
|
||||