]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: use hypervisor generated topology information
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Wed, 10 Aug 2011 08:34:31 +0000 (10:34 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 18 Oct 2011 12:17:01 +0000 (14:17 +0200)
The readable output prints also informations like cores per socket etc.
On newer kernel versions on s390 this information is available via
/proc/sysinfo. However it does not contain the layout of the guest but
the layout of the real machine.
Nevertheless this is better than random guessing with completely broken
numbers like we have it now on s390. If the information is not available
we fall back to old mechanism with more or less random numbers.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/lscpu.c

index 9755be50ae23739c6befb0cf10cac7cd6ae39bc1..832b4efb5ce2b004c299555285a9c2ce55de80aa 100644 (file)
@@ -50,6 +50,7 @@
 #define _PATH_PROC_XENCAP      _PATH_PROC_XEN "/capabilities"
 #define _PATH_PROC_CPUINFO     "/proc/cpuinfo"
 #define _PATH_PROC_PCIDEVS     "/proc/bus/pci/devices"
+#define _PATH_PROC_SYSINFO     "/proc/sysinfo"
 
 /* virtualization types */
 enum {
@@ -989,13 +990,38 @@ print_readable(struct lscpu_desc *desc, int hex)
        }
 
        if (desc->nsockets) {
+               int cores_per_socket, sockets_per_book, books;
+
+               cores_per_socket = sockets_per_book = books = 0;
+               /* s390 detects its cpu topology via /proc/sysinfo, if present.
+                * Using simply the cpu topology masks in sysfs will not give
+                * usable results since everything is virtualized. E.g.
+                * virtual core 0 may have only 1 cpu, but virtual core 2 may
+                * five cpus.
+                * If the cpu topology is not exported (e.g. 2nd level guest)
+                * fall back to old calculation scheme.
+                */
+               if (path_exist(_PATH_PROC_SYSINFO)) {
+                       FILE *fd = path_fopen("r", 0, _PATH_PROC_SYSINFO);
+                       char buf[BUFSIZ];
+                       int t0, t1, t2;
+
+                       while (fgets(buf, sizeof(buf), fd) != NULL) {
+                               if (sscanf(buf, "CPU Topology SW:%d%d%d%d%d%d",
+                                          &t0, &t1, &t2, &books, &sockets_per_book,
+                                          &cores_per_socket) == 6)
+                                       break;
+                       }
+               }
                print_n(_("Thread(s) per core:"), desc->nthreads / desc->ncores);
-               print_n(_("Core(s) per socket:"), desc->ncores / desc->nsockets);
+               print_n(_("Core(s) per socket:"),
+                       cores_per_socket ?: desc->ncores / desc->nsockets);
                if (desc->nbooks) {
-                       print_n(_("Socket(s) per book:"), desc->nsockets / desc->nbooks);
-                       print_n(_("Book(s):"), desc->nbooks);
+                       print_n(_("Socket(s) per book:"),
+                               sockets_per_book ?: desc->nsockets / desc->nbooks);
+                       print_n(_("Book(s):"), books ?: desc->nbooks);
                } else {
-                       print_n(_("Socket(s):"), desc->nsockets);
+                       print_n(_("Socket(s):"), sockets_per_book ?: desc->nsockets);
                }
        }
        if (desc->nnodes)