All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
To: jbeulich@suse.com, keir@xen.org, ian.jackson@eu.citrix.com,
	stefano.stabellini@eu.citrix.com, ian.campbell@citrix.com,
	wei.liu2@citrix.com
Cc: andrew.cooper3@citrix.com, dario.faggioli@citrix.com,
	boris.ostrovsky@oracle.com, ufimtseva@gmail.com,
	xen-devel@lists.xen.org
Subject: [PATCH v2 4/4] libxl: Add interface for querying hypervisor about PCI topology
Date: Mon,  5 Jan 2015 21:18:57 -0500	[thread overview]
Message-ID: <1420510737-22813-5-git-send-email-boris.ostrovsky@oracle.com> (raw)
In-Reply-To: <1420510737-22813-1-git-send-email-boris.ostrovsky@oracle.com>

.. and use this new interface to display it along with CPU topology
and NUMA information when 'xl info -n' command is issued

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
---
 tools/libxc/include/xenctrl.h |    2 +
 tools/libxc/xc_misc.c         |   18 ++++++++++
 tools/libxl/libxl.c           |   58 +++++++++++++++++++++++++++++++++
 tools/libxl/libxl.h           |    4 ++
 tools/libxl/libxl_freebsd.c   |   12 +++++++
 tools/libxl/libxl_internal.h  |    5 +++
 tools/libxl/libxl_linux.c     |   71 +++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_netbsd.c    |   12 +++++++
 tools/libxl/libxl_types.idl   |    7 ++++
 tools/libxl/libxl_utils.c     |    8 +++++
 tools/libxl/xl_cmdimpl.c      |   39 ++++++++++++++++++----
 11 files changed, 229 insertions(+), 7 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 0cb6743..3c5824a 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1227,6 +1227,7 @@ 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_pcitopoinfo_t xc_pcitopoinfo_t;
 typedef xen_sysctl_numainfo_t xc_numainfo_t;
 
 typedef uint32_t xc_cpu_to_node_t;
@@ -1238,6 +1239,7 @@ 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_pcitopoinfo(xc_interface *xch, xc_pcitopoinfo_t *info);
 int xc_numainfo(xc_interface *xch, xc_numainfo_t *info);
 
 int xc_sched_id(xc_interface *xch,
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index be68291..e33a312 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -195,6 +195,24 @@ int xc_cputopoinfo(xc_interface *xch,
     return 0;
 }
 
+int xc_pcitopoinfo(xc_interface *xch,
+                   xc_pcitopoinfo_t *put_info)
+{
+    int ret;
+    DECLARE_SYSCTL;
+
+    sysctl.cmd = XEN_SYSCTL_pcitopoinfo;
+
+    memcpy(&sysctl.u.pcitopoinfo, put_info, sizeof(*put_info));
+
+    if ( (ret = do_sysctl(xch, &sysctl)) != 0 )
+        return ret;
+
+    memcpy(put_info, &sysctl.u.pcitopoinfo, sizeof(*put_info));
+
+    return 0;
+}
+
 int xc_numainfo(xc_interface *xch,
                 xc_numainfo_t *put_info)
 {
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index cd87614..888f068 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -5121,6 +5121,64 @@ libxl_cputopology *libxl_get_cpu_topology(libxl_ctx *ctx, int *nb_cpu_out)
     return ret;
 }
 
+libxl_pcitopology *libxl_get_pci_topology(libxl_ctx *ctx, int *num_devs)
+{
+    GC_INIT(ctx);
+    xc_pcitopoinfo_t tinfo;
+    DECLARE_HYPERCALL_BUFFER(xen_sysctl_pcitopo_t, pcitopo);
+    libxl_pcitopology *ret = NULL;
+    int i, rc;
+
+    tinfo.num_devs = libxl__pci_numdevs(gc);
+    if (tinfo.num_devs <= 0) {
+        LIBXL__LOG(ctx, XTL_ERROR, "Unable to determine number of PCI devices");
+        goto out;
+    }
+
+    pcitopo = xc_hypercall_buffer_alloc(ctx->xch, pcitopo,
+                                        sizeof(*pcitopo) * tinfo.num_devs);
+    if (pcitopo == NULL) {
+        LIBXL__LOG_ERRNOVAL(ctx, XTL_ERROR, ENOMEM,
+                            "Unable to allocate hypercall arguments");
+        goto out;
+    }
+
+    rc = libxl__pci_topology_init(gc, pcitopo, tinfo.num_devs);
+    if (rc) {
+        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "Cannot initialize PCI"
+                            " hypercall structure");
+        goto fail;
+    }
+
+    tinfo.first_dev = 0;
+
+    set_xen_guest_handle(tinfo.pcitopo, pcitopo);
+
+    if (xc_pcitopoinfo(ctx->xch, &tinfo) != 0) {
+        LIBXL__LOG_ERRNO(ctx, XTL_ERROR, "PCI topology info hypercall failed");
+        goto fail;
+    }
+
+    ret = libxl__zalloc(NOGC, sizeof(libxl_pcitopology) * tinfo.num_devs);
+
+    for (i = 0; i < tinfo.num_devs; i++) {
+        ret[i].seg = pcitopo[i].pcidev.seg;
+        ret[i].bus = pcitopo[i].pcidev.bus;
+        ret[i].devfn = pcitopo[i].pcidev.devfn;
+        ret[i].node = (pcitopo[i].node ==  INVALID_TOPOLOGY_ID) ?
+            LIBXL_PCITOPOLOGY_INVALID_ENTRY :  pcitopo[i].node;
+    }
+
+    *num_devs = tinfo.num_devs;
+
+ fail:
+    xc_hypercall_buffer_free(ctx->xch, pcitopo);
+
+ out:
+    GC_FREE;
+    return ret;
+}
+
 libxl_numainfo *libxl_get_numainfo(libxl_ctx *ctx, int *nr)
 {
     GC_INIT(ctx);
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 0a123f1..eb83f0a 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1070,6 +1070,10 @@ void libxl_vminfo_list_free(libxl_vminfo *list, int nb_vm);
 libxl_cputopology *libxl_get_cpu_topology(libxl_ctx *ctx, int *nb_cpu_out);
 void libxl_cputopology_list_free(libxl_cputopology *, int nb_cpu);
 
+#define LIBXL_PCITOPOLOGY_INVALID_ENTRY (~(uint32_t)0)
+libxl_pcitopology *libxl_get_pci_topology(libxl_ctx *ctx, int *num_dev);
+void libxl_pcitopology_list_free(libxl_pcitopology *, int num_dev);
+
 #define LIBXL_NUMAINFO_INVALID_ENTRY (~(uint32_t)0)
 libxl_numainfo *libxl_get_numainfo(libxl_ctx *ctx, int *nr);
 void libxl_numainfo_list_free(libxl_numainfo *, int nr);
diff --git a/tools/libxl/libxl_freebsd.c b/tools/libxl/libxl_freebsd.c
index e8b88b3..3cb11cd 100644
--- a/tools/libxl/libxl_freebsd.c
+++ b/tools/libxl/libxl_freebsd.c
@@ -131,3 +131,15 @@ libxl_device_model_version libxl__default_device_model(libxl__gc *gc)
 {
     return LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN;
 }
+
+int libxl__pci_numdevs(libxl__gc *gc)
+{
+    return ERROR_NI;
+}
+
+int libxl__pci_topology_init(libxl__gc *gc,
+                             xen_sysctl_pcitopo_t *pcitopo,
+                             int numdev)
+{
+    return ERROR_NI;
+}
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 9695f18..453e652 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1168,6 +1168,11 @@ _hidden int libxl__try_phy_backend(mode_t st_mode);
 
 _hidden char *libxl__devid_to_localdev(libxl__gc *gc, int devid);
 
+_hidden int libxl__pci_numdevs(libxl__gc *gc);
+_hidden int libxl__pci_topology_init(libxl__gc *gc,
+                                     xen_sysctl_pcitopo_t *pcitopo,
+                                     int numdev);
+
 /* from libxl_pci */
 
 _hidden int libxl__device_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, int starting);
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c
index ea5d8c1..07428c0 100644
--- a/tools/libxl/libxl_linux.c
+++ b/tools/libxl/libxl_linux.c
@@ -279,3 +279,74 @@ libxl_device_model_version libxl__default_device_model(libxl__gc *gc)
 {
     return LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN;
 }
+
+/* These two routines are "inspired" by pciutils */
+int libxl__pci_numdevs(libxl__gc *gc)
+{
+    DIR *dir;
+    struct dirent *entry;
+    int numdev = 0;
+
+    dir = opendir("/sys/bus/pci/devices");
+    if (!dir) {
+        LOGEV(ERROR, errno, "Cannot open /sys/bus/pci/devices");
+        return ERROR_FAIL;
+    }
+
+    while ((entry = readdir(dir))) {
+        /* ".", ".." or a special non-device perhaps */
+        if (entry->d_name[0] == '.')
+            continue;
+        numdev++;
+    }
+    closedir(dir);
+
+    return numdev;
+}
+
+int libxl__pci_topology_init(libxl__gc *gc,
+                             xen_sysctl_pcitopo_t *pcitopo,
+                             int numdev)
+{
+
+    DIR *dir;
+    struct dirent *entry;
+    int i;
+
+    dir = opendir("/sys/bus/pci/devices");
+    if (!dir) {
+        LOGEV(ERROR, errno, "Cannot open /sys/bus/pci/devices");
+        return ERROR_FAIL;
+    }
+
+    i = 0;
+    while ((entry = readdir(dir))) {
+        unsigned int dom, bus, dev, func;
+
+        /* ".", ".." or a special non-device perhaps */
+        if (entry->d_name[0] == '.')
+            continue;
+
+        if (i == numdev) {
+            LOGE(ERROR, "Too many devices\n");
+            closedir(dir);
+            return ERROR_FAIL;
+        }
+
+        if (sscanf(entry->d_name, "%x:%x:%x.%d", &dom, &bus, &dev, &func) < 4) {
+            LOGEV(ERROR, errno, "Error processing /sys/bus/pci/devices");
+            closedir(dir);
+            return ERROR_FAIL;
+        }
+
+        pcitopo[i].pcidev.seg = dom;
+        pcitopo[i].pcidev.bus = bus;
+        pcitopo[i].pcidev.devfn = ((dev & 0x1f) << 3) | (func & 7);
+
+        i++;
+    }
+
+    closedir(dir);
+
+    return 0;
+}
diff --git a/tools/libxl/libxl_netbsd.c b/tools/libxl/libxl_netbsd.c
index 898e160..743d439 100644
--- a/tools/libxl/libxl_netbsd.c
+++ b/tools/libxl/libxl_netbsd.c
@@ -95,3 +95,15 @@ libxl_device_model_version libxl__default_device_model(libxl__gc *gc)
 {
     return LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL;
 }
+
+int libxl__pci_numdevs(libxl__gc *gc)
+{
+    return ERROR_NI;
+}
+
+int libxl__pci_topology_init(libxl__gc *gc,
+                             xen_sysctl_pcitopo_t *pcitopo,
+                             int numdev)
+{
+    return ERROR_NI;
+}
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index f7fc695..e49b5f8 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -642,6 +642,13 @@ libxl_cputopology = Struct("cputopology", [
     ("node", uint32),
     ], dir=DIR_OUT)
 
+libxl_pcitopology = Struct("pcitopology", [
+    ("seg", uint16),
+    ("bus", uint8),
+    ("devfn", uint8),
+    ("node", uint32),
+    ], dir=DIR_OUT)
+
 libxl_sched_credit_params = Struct("sched_credit_params", [
     ("tslice_ms", integer),
     ("ratelimit_us", integer),
diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 7095b58..c31407f 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -877,6 +877,14 @@ void libxl_cputopology_list_free(libxl_cputopology *list, int nr)
     free(list);
 }
 
+void libxl_pcitopology_list_free(libxl_pcitopology *list, int nr)
+{
+    int i;
+    for (i = 0; i < nr; i++)
+        libxl_pcitopology_dispose(&list[i]);
+    free(list);
+}
+
 void libxl_numainfo_list_free(libxl_numainfo *list, int nr)
 {
     int i;
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 3737c7e..f2a3320 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -5195,12 +5195,14 @@ static void output_numainfo(void)
 
 static void output_topologyinfo(void)
 {
-    libxl_cputopology *info;
+    libxl_cputopology *cpuinfo;
+    libxl_pcitopology *pciinfo;
     int i, nr;
+    int valid_devs;
 
-    info = libxl_get_cpu_topology(ctx, &nr);
-    if (info == NULL) {
-        fprintf(stderr, "libxl_get_topologyinfo failed.\n");
+    cpuinfo = libxl_get_cpu_topology(ctx, &nr);
+    if (cpuinfo == NULL) {
+        fprintf(stderr, "libxl_get_cpu_topology failed.\n");
         return;
     }
 
@@ -5208,12 +5210,35 @@ static void output_topologyinfo(void)
     printf("cpu:    core    socket     node\n");
 
     for (i = 0; i < nr; i++) {
-        if (info[i].core != LIBXL_CPUTOPOLOGY_INVALID_ENTRY)
+        if (cpuinfo[i].core != LIBXL_CPUTOPOLOGY_INVALID_ENTRY)
             printf("%3d:    %4d     %4d     %4d\n", i,
-                   info[i].core, info[i].socket, info[i].node);
+                   cpuinfo[i].core, cpuinfo[i].socket, cpuinfo[i].node);
+    }
+
+    libxl_cputopology_list_free(cpuinfo, nr);
+
+    pciinfo = libxl_get_pci_topology(ctx, &nr);
+    if (cpuinfo == NULL) {
+        fprintf(stderr, "libxl_get_pci_topology failed.\n");
+        return;
     }
 
-    libxl_cputopology_list_free(info, nr);
+    printf("device topology        :\n");
+    printf("device           node\n");
+    for (i = 0; i < nr; i++) {
+        if (pciinfo[i].node != LIBXL_PCITOPOLOGY_INVALID_ENTRY) {
+            printf("%04x:%02x:%02x.%01x      %d\n", pciinfo[i].seg,
+                   pciinfo[i].bus,
+                   ((pciinfo[i].devfn >> 3) & 0x1f), (pciinfo[i].devfn & 7),
+                   pciinfo[i].node);
+            valid_devs++;
+        }
+    }
+
+    if (valid_devs == 0)
+        printf("No device topology data available\n");
+
+    libxl_pcitopology_list_free(pciinfo, nr);
 
     return;
 }
-- 
1.7.1

  parent reply	other threads:[~2015-01-06  2:18 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-06  2:18 [PATCH v2 0/4] Display IO topology when PXM data is available Boris Ostrovsky
2015-01-06  2:18 ` [PATCH v2 1/4] pci: Do not ignore device's PXM information Boris Ostrovsky
2015-01-06 11:55   ` Andrew Cooper
2015-01-07  9:01     ` Jan Beulich
2015-01-07  9:06   ` Jan Beulich
2015-01-07 14:42     ` Boris Ostrovsky
2015-01-07 14:47       ` Andrew Cooper
2015-01-07 15:07         ` Jan Beulich
2015-01-07 15:34           ` Boris Ostrovsky
2015-01-07 15:46             ` Jan Beulich
2015-01-07 15:06       ` Jan Beulich
2015-01-07 15:31         ` Boris Ostrovsky
2015-01-07 15:44           ` Jan Beulich
2015-01-06  2:18 ` [PATCH v2 2/4] sysctl: Make XEN_SYSCTL_topologyinfo sysctl a little more efficient Boris Ostrovsky
2015-01-06 13:41   ` Andrew Cooper
2015-01-06 14:45     ` Boris Ostrovsky
2015-01-07  9:12     ` Jan Beulich
2015-01-07 14:45       ` Boris Ostrovsky
2015-01-07 15:09         ` Jan Beulich
2015-01-16 15:56       ` Boris Ostrovsky
2015-01-16 16:06         ` Jan Beulich
2015-01-16 16:14           ` Boris Ostrovsky
2015-01-16 16:20             ` Jan Beulich
2015-01-16 16:34               ` Boris Ostrovsky
2015-01-16 16:42                 ` Jan Beulich
2015-01-16 16:16           ` Ian Campbell
2015-01-16 16:34             ` Jan Beulich
2015-01-16 16:38               ` Ian Campbell
2015-01-16 16:45                 ` Jan Beulich
2015-01-16 16:57                   ` Andrew Cooper
2015-01-16 17:07                     ` Boris Ostrovsky
2015-01-19  8:57                       ` Jan Beulich
2015-01-19 10:48                         ` Ian Campbell
2015-01-07 15:23     ` Jan Beulich
2015-01-19 17:26   ` Ian Campbell
2015-01-06  2:18 ` [PATCH v2 3/4] sysctl: Add sysctl interface for querying PCI topology Boris Ostrovsky
2015-01-06 16:55   ` Wei Liu
2015-01-06 18:15     ` Boris Ostrovsky
2015-01-07  9:21   ` Jan Beulich
2015-01-07 14:55     ` Boris Ostrovsky
2015-01-07 15:17       ` Jan Beulich
2015-01-07 15:54         ` Boris Ostrovsky
2015-01-07 16:52           ` Jan Beulich
2015-01-07 17:55           ` Dario Faggioli
2015-01-08  9:50             ` Jan Beulich
2015-01-08 15:49               ` Boris Ostrovsky
2015-01-08 15:54                 ` Jan Beulich
2015-01-06  2:18 ` Boris Ostrovsky [this message]
2015-01-06 17:08   ` [PATCH v2 4/4] libxl: Add interface for querying hypervisor about " Wei Liu
2015-01-07  9:04   ` Dario Faggioli
2015-01-07 14:15     ` Boris Ostrovsky
2015-01-07 14:45       ` Dario Faggioli
2015-01-19 17:32   ` Ian Campbell
2015-01-20 10:54     ` Roger Pau Monné
2015-01-20 10:56       ` Ian Campbell
2015-01-20 15:15     ` Boris Ostrovsky
2015-01-20 15:21       ` Ian Campbell
2015-01-20 16:04         ` Boris Ostrovsky
2015-01-20 16:15           ` Ian Campbell
2015-01-20 16:08     ` Egger, Christoph

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1420510737-22813-5-git-send-email-boris.ostrovsky@oracle.com \
    --to=boris.ostrovsky@oracle.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=dario.faggioli@citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=keir@xen.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=ufimtseva@gmail.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.