]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: fix threads-per-core calculation
authorKarel Zak <kzak@redhat.com>
Thu, 31 Mar 2011 10:55:13 +0000 (12:55 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 31 Mar 2011 10:55:13 +0000 (12:55 +0200)
On Thu, Mar 24, 2011 at 01:45:34PM +0100, Jan Engelhardt wrote:
> On a 24-thread/6-core SPARC T1, lscpu would wrongly output "5
> threads per core".
>
> It seems that the 6c T1 is simply an 8c T1 where 2c are disabled
> (offering a lesser model for a lower price, and all that marketing
> fluff). So the machine description header of the 6c T1 reports 32
> threads, but only goes on to provide 24 elements thereafter, which
> is why Linux will report threads 24-31 as "offline". So far so good.
>
> But lscpu would take the number of all (online and offline) threads
> (32) and divides it by the number of online cores (6), which yields
> an odd 5.33 threads/core.
>
> Simply pick the number of online threads.

Based on Jan's patch.

Reported-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/lscpu.c

index 79c6857e204a94c594bc91a501d87bc17364e737..c3bb536cd60e3428b8c25f103fb068066455ac01 100644 (file)
@@ -113,15 +113,15 @@ struct lscpu_desc {
 
        /* sockets -- based on core_siblings (internal kernel map of cpuX's
         * hardware threads within the same physical_package_id (socket)) */
-       int             nsockets;       /* number of all sockets */
+       int             nsockets;       /* number of all online sockets */
        cpu_set_t       **socketmaps;   /* unique core_siblings */
 
        /* cores -- based on thread_siblings (internel kernel map of cpuX's
         * hardware threads within the same core as cpuX) */
-       int             ncores;         /* number of all cores */
+       int             ncores;         /* number of all online cores */
        cpu_set_t       **coremaps;     /* unique thread_siblings */
 
-       int             nthreads;       /* number of threads */
+       int             nthreads;       /* number of online threads */
 
        int             ncaches;
        struct cpu_cache *caches;
@@ -415,8 +415,11 @@ read_basicinfo(struct lscpu_desc *desc)
                maxcpus = desc->ncpus > 2048 ? desc->ncpus : 2048;
 
        /* get mask for online CPUs */
-       if (path_exist(_PATH_SYS_SYSTEM "/cpu/online"))
+       if (path_exist(_PATH_SYS_SYSTEM "/cpu/online")) {
+               size_t setsize = CPU_ALLOC_SIZE(maxcpus);
                desc->online = path_cpulist(_PATH_SYS_SYSTEM "/cpu/online");
+               desc->nthreads = CPU_COUNT_S(setsize, desc->online);
+       }
 }
 
 static int
@@ -586,8 +589,13 @@ read_topology(struct lscpu_desc *desc, int num)
                ncores = CPU_COUNT_S(setsize, core_siblings) / nthreads;
                /* number of sockets */
                nsockets = desc->ncpus / nthreads / ncores;
-               /* all threads */
-               desc->nthreads = nsockets * ncores * nthreads;
+
+               /* all threads, see also read_basicinfo()
+                * -- this is fallback for kernels where is not
+                *    /sys/devices/system/cpu/online.
+                */
+               if (!desc->nthreads)
+                       desc->nthreads = nsockets * ncores * nthreads;
 
                desc->socketmaps = calloc(nsockets, sizeof(cpu_set_t *));
                if (!desc->socketmaps)