summaryrefslogtreecommitdiffstats
path: root/sys-utils/lscpu.c
diff options
context:
space:
mode:
authorAlexander Troosh2013-11-05 10:16:38 +0100
committerKarel Zak2013-11-05 12:46:03 +0100
commit4f64286321162f6919abc2cf3a0cc0472e68398c (patch)
tree1adfd0ddaffff866c01afcb36a8d7b8255b6b212 /sys-utils/lscpu.c
parentblockdev: don't use HDIO_GETGEO (diff)
downloadkernel-qcow2-util-linux-4f64286321162f6919abc2cf3a0cc0472e68398c.tar.gz
kernel-qcow2-util-linux-4f64286321162f6919abc2cf3a0cc0472e68398c.tar.xz
kernel-qcow2-util-linux-4f64286321162f6919abc2cf3a0cc0472e68398c.zip
lscpu: support non sequentially numbering of CPUs
lscpu don't work correctly on my system with: $ cat /sys/devices/system/cpu/possible 0-1,4-5,8-9,12-13 [kzak@redhat.com: - coding style, - add commit message - add real_cpu_num() macro, - fix functions where we need idx as well as CPU number] Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/lscpu.c')
-rw-r--r--sys-utils/lscpu.c133
1 files changed, 84 insertions, 49 deletions
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c
index 992726c45..8f14b3af2 100644
--- a/sys-utils/lscpu.c
+++ b/sys-utils/lscpu.c
@@ -161,6 +161,21 @@ struct lscpu_desc {
cpu_set_t *present; /* mask with present CPUs */
cpu_set_t *online; /* mask with online CPUs */
+ int nthreads; /* number of online threads */
+
+ int ncaches;
+ struct cpu_cache *caches;
+
+ /*
+ * All maps are sequentially indexed (0..ncpuspos), the array index
+ * does not have match with cpuX number as presented by kernel. You
+ * have to use real_cpu_num() to get the real cpuX number.
+ *
+ * For example, the possible system CPUs are: 1,3,5, it means that
+ * ncpuspos=3, so all arrays are in range 0..3.
+ */
+ int *idx2cpunum; /* mapping index to CPU num */
+
int nnodes; /* number of NUMA modes */
cpu_set_t **nodemaps; /* array with NUMA nodes */
@@ -179,11 +194,6 @@ struct lscpu_desc {
int ncores; /* number of all online cores */
cpu_set_t **coremaps; /* unique thread_siblings */
- int nthreads; /* number of online threads */
-
- int ncaches;
- struct cpu_cache *caches;
-
int *polarization; /* cpu polarization */
int *addresses; /* physical cpu addresses */
int *configured; /* cpu configured */
@@ -218,6 +228,8 @@ static int maxcpus; /* size in bits of kernel cpu mask */
((_d) && (_d)->present ? \
CPU_ISSET_S((_cpu), CPU_ALLOC_SIZE(maxcpus), (_d)->present) : 0)
+#define real_cpu_num(_d, _i) ((_d)->idx2cpunum[(_i)])
+
/*
* IDs
*/
@@ -417,7 +429,15 @@ read_basicinfo(struct lscpu_desc *desc, struct lscpu_modifier *mod)
if (path_exist(_PATH_SYS_SYSTEM "/cpu/possible")) {
cpu_set_t *tmp = path_read_cpulist(maxcpus, _PATH_SYS_SYSTEM "/cpu/possible");
+ int num, idx;
+
desc->ncpuspos = CPU_COUNT_S(setsize, tmp);
+ desc->idx2cpunum = xcalloc(desc->ncpuspos, sizeof(int));
+
+ for (num = 0, idx = 0; num < maxcpus; num++) {
+ if (CPU_ISSET(num, tmp))
+ desc->idx2cpunum[idx++] = num;
+ }
cpuset_free(tmp);
} else
err(EXIT_FAILURE, _("failed to determine number of CPUs: %s"),
@@ -671,9 +691,10 @@ static int add_cpuset_to_array(cpu_set_t **ary, int *items, cpu_set_t *set)
}
static void
-read_topology(struct lscpu_desc *desc, int num)
+read_topology(struct lscpu_desc *desc, int idx)
{
cpu_set_t *thread_siblings, *core_siblings, *book_siblings;
+ int num = real_cpu_num(desc, idx);
if (!path_exist(_PATH_SYS_CPU "/cpu%d/topology/thread_siblings", num))
return;
@@ -683,10 +704,9 @@ read_topology(struct lscpu_desc *desc, int num)
core_siblings = path_read_cpuset(maxcpus, _PATH_SYS_CPU
"/cpu%d/topology/core_siblings", num);
book_siblings = NULL;
- if (path_exist(_PATH_SYS_CPU "/cpu%d/topology/book_siblings", num)) {
+ if (path_exist(_PATH_SYS_CPU "/cpu%d/topology/book_siblings", num))
book_siblings = path_read_cpuset(maxcpus, _PATH_SYS_CPU
"/cpu%d/topology/book_siblings", num);
- }
if (!desc->coremaps) {
int nbooks, nsockets, ncores, nthreads;
@@ -739,10 +759,12 @@ read_topology(struct lscpu_desc *desc, int num)
if (book_siblings)
add_cpuset_to_array(desc->bookmaps, &desc->nbooks, book_siblings);
}
+
static void
-read_polarization(struct lscpu_desc *desc, int num)
+read_polarization(struct lscpu_desc *desc, int idx)
{
char mode[64];
+ int num = real_cpu_num(desc, idx);
if (desc->dispatching < 0)
return;
@@ -752,57 +774,65 @@ read_polarization(struct lscpu_desc *desc, int num)
desc->polarization = xcalloc(desc->ncpuspos, sizeof(int));
path_read_str(mode, sizeof(mode), _PATH_SYS_CPU "/cpu%d/polarization", num);
if (strncmp(mode, "vertical:low", sizeof(mode)) == 0)
- desc->polarization[num] = POLAR_VLOW;
+ desc->polarization[idx] = POLAR_VLOW;
else if (strncmp(mode, "vertical:medium", sizeof(mode)) == 0)
- desc->polarization[num] = POLAR_VMEDIUM;
+ desc->polarization[idx] = POLAR_VMEDIUM;
else if (strncmp(mode, "vertical:high", sizeof(mode)) == 0)
- desc->polarization[num] = POLAR_VHIGH;
+ desc->polarization[idx] = POLAR_VHIGH;
else if (strncmp(mode, "horizontal", sizeof(mode)) == 0)
- desc->polarization[num] = POLAR_HORIZONTAL;
+ desc->polarization[idx] = POLAR_HORIZONTAL;
else
- desc->polarization[num] = POLAR_UNKNOWN;
+ desc->polarization[idx] = POLAR_UNKNOWN;
}
static void
-read_address(struct lscpu_desc *desc, int num)
+read_address(struct lscpu_desc *desc, int idx)
{
+ int num = real_cpu_num(desc, idx);
+
if (!path_exist(_PATH_SYS_CPU "/cpu%d/address", num))
return;
if (!desc->addresses)
desc->addresses = xcalloc(desc->ncpuspos, sizeof(int));
- desc->addresses[num] = path_read_s32(_PATH_SYS_CPU "/cpu%d/address", num);
+ desc->addresses[idx] = path_read_s32(_PATH_SYS_CPU "/cpu%d/address", num);
}
static void
-read_configured(struct lscpu_desc *desc, int num)
+read_configured(struct lscpu_desc *desc, int idx)
{
+ int num = real_cpu_num(desc, idx);
+
if (!path_exist(_PATH_SYS_CPU "/cpu%d/configure", num))
return;
if (!desc->configured)
desc->configured = xcalloc(desc->ncpuspos, sizeof(int));
- desc->configured[num] = path_read_s32(_PATH_SYS_CPU "/cpu%d/configure", num);
+ desc->configured[idx] = path_read_s32(_PATH_SYS_CPU "/cpu%d/configure", num);
}
static void
-read_max_mhz(struct lscpu_desc *desc, int num)
+read_max_mhz(struct lscpu_desc *desc, int idx)
{
+ int num = real_cpu_num(desc, idx);
+
if (!path_exist(_PATH_SYS_CPU "/cpu%d/cpufreq/cpuinfo_max_freq", num))
return;
if (!desc->maxmhz)
desc->maxmhz = xcalloc(desc->ncpuspos, sizeof(char *));
- xasprintf(&(desc->maxmhz[num]), "%.4f",
+ xasprintf(&(desc->maxmhz[idx]), "%.4f",
(float)path_read_s32(_PATH_SYS_CPU
"/cpu%d/cpufreq/cpuinfo_max_freq", num) / 1000);
}
static void
-read_min_mhz(struct lscpu_desc *desc, int num)
+read_min_mhz(struct lscpu_desc *desc, int idx)
{
+ int num = real_cpu_num(desc, idx);
+
if (!path_exist(_PATH_SYS_CPU "/cpu%d/cpufreq/cpuinfo_min_freq", num))
return;
if (!desc->minmhz)
desc->minmhz = xcalloc(desc->ncpuspos, sizeof(char *));
- xasprintf(&(desc->minmhz[num]), "%.4f",
+ xasprintf(&(desc->minmhz[idx]), "%.4f",
(float)path_read_s32(_PATH_SYS_CPU
"/cpu%d/cpufreq/cpuinfo_min_freq", num) / 1000);
}
@@ -817,10 +847,11 @@ cachecmp(const void *a, const void *b)
}
static void
-read_cache(struct lscpu_desc *desc, int num)
+read_cache(struct lscpu_desc *desc, int idx)
{
char buf[256];
int i;
+ int num = real_cpu_num(desc, idx);
if (!desc->ncaches) {
while(path_exist(_PATH_SYS_SYSTEM "/cpu/cpu%d/cache/index%d",
@@ -903,12 +934,13 @@ read_nodes(struct lscpu_desc *desc)
}
static char *
-get_cell_data(struct lscpu_desc *desc, int cpu, int col,
+get_cell_data(struct lscpu_desc *desc, int idx, int col,
struct lscpu_modifier *mod,
char *buf, size_t bufsz)
{
size_t setsize = CPU_ALLOC_SIZE(maxcpus);
- size_t idx;
+ size_t i;
+ int cpu = real_cpu_num(desc, idx);
*buf = '\0';
@@ -918,23 +950,23 @@ get_cell_data(struct lscpu_desc *desc, int cpu, int col,
break;
case COL_CORE:
if (cpuset_ary_isset(cpu, desc->coremaps,
- desc->ncores, setsize, &idx) == 0)
- snprintf(buf, bufsz, "%zd", idx);
+ desc->ncores, setsize, &i) == 0)
+ snprintf(buf, bufsz, "%zd", i);
break;
case COL_SOCKET:
if (cpuset_ary_isset(cpu, desc->socketmaps,
- desc->nsockets, setsize, &idx) == 0)
- snprintf(buf, bufsz, "%zd", idx);
+ desc->nsockets, setsize, &i) == 0)
+ snprintf(buf, bufsz, "%zd", i);
break;
case COL_NODE:
if (cpuset_ary_isset(cpu, desc->nodemaps,
- desc->nnodes, setsize, &idx) == 0)
- snprintf(buf, bufsz, "%zd", idx);
+ desc->nnodes, setsize, &i) == 0)
+ snprintf(buf, bufsz, "%zd", i);
break;
case COL_BOOK:
if (cpuset_ary_isset(cpu, desc->bookmaps,
- desc->nbooks, setsize, &idx) == 0)
- snprintf(buf, bufsz, "%zd", idx);
+ desc->nbooks, setsize, &i) == 0)
+ snprintf(buf, bufsz, "%zd", i);
break;
case COL_CACHE:
{
@@ -946,8 +978,8 @@ get_cell_data(struct lscpu_desc *desc, int cpu, int col,
struct cpu_cache *ca = &desc->caches[j];
if (cpuset_ary_isset(cpu, ca->sharedmaps,
- ca->nsharedmaps, setsize, &idx) == 0) {
- int x = snprintf(p, sz, "%zd", idx);
+ ca->nsharedmaps, setsize, &i) == 0) {
+ int x = snprintf(p, sz, "%zd", i);
if (x <= 0 || (size_t) x + 2 >= sz)
return NULL;
p += x;
@@ -963,7 +995,7 @@ get_cell_data(struct lscpu_desc *desc, int cpu, int col,
}
case COL_POLARIZATION:
if (desc->polarization) {
- int x = desc->polarization[cpu];
+ int x = desc->polarization[idx];
snprintf(buf, bufsz, "%s",
mod->mode == OUTPUT_PARSABLE ?
@@ -973,17 +1005,17 @@ get_cell_data(struct lscpu_desc *desc, int cpu, int col,
break;
case COL_ADDRESS:
if (desc->addresses)
- snprintf(buf, bufsz, "%d", desc->addresses[cpu]);
+ snprintf(buf, bufsz, "%d", desc->addresses[idx]);
break;
case COL_CONFIGURED:
if (!desc->configured)
break;
if (mod->mode == OUTPUT_PARSABLE)
snprintf(buf, bufsz,
- desc->configured[cpu] ? _("Y") : _("N"));
+ desc->configured[idx] ? _("Y") : _("N"));
else
snprintf(buf, bufsz,
- desc->configured[cpu] ? _("yes") : _("no"));
+ desc->configured[idx] ? _("yes") : _("no"));
break;
case COL_ONLINE:
if (!desc->online)
@@ -997,11 +1029,11 @@ get_cell_data(struct lscpu_desc *desc, int cpu, int col,
break;
case COL_MAXMHZ:
if (desc->maxmhz)
- xstrncpy(buf, desc->maxmhz[cpu], bufsz);
+ xstrncpy(buf, desc->maxmhz[idx], bufsz);
break;
case COL_MINMHZ:
if (desc->minmhz)
- xstrncpy(buf, desc->minmhz[cpu], bufsz);
+ xstrncpy(buf, desc->minmhz[idx], bufsz);
break;
}
return buf;
@@ -1112,12 +1144,13 @@ print_parsable(struct lscpu_desc *desc, int cols[], int ncols,
*/
for (i = 0; i < desc->ncpuspos; i++) {
int c;
+ int cpu = real_cpu_num(desc, i);
- if (!mod->offline && desc->online && !is_cpu_online(desc, i))
+ if (!mod->offline && desc->online && !is_cpu_online(desc, cpu))
continue;
- if (!mod->online && desc->online && is_cpu_online(desc, i))
+ if (!mod->online && desc->online && is_cpu_online(desc, cpu))
continue;
- if (desc->present && !is_cpu_present(desc, i))
+ if (desc->present && !is_cpu_present(desc, cpu))
continue;
for (c = 0; c < ncols; c++) {
if (mod->compat && cols[c] == COL_CACHE) {
@@ -1159,12 +1192,13 @@ print_readable(struct lscpu_desc *desc, int cols[], int ncols,
for (i = 0; i < desc->ncpuspos; i++) {
int c;
struct tt_line *line;
+ int cpu = real_cpu_num(desc, i);
- if (!mod->offline && desc->online && !is_cpu_online(desc, i))
+ if (!mod->offline && desc->online && !is_cpu_online(desc, cpu))
continue;
- if (!mod->online && desc->online && is_cpu_online(desc, i))
+ if (!mod->online && desc->online && is_cpu_online(desc, cpu))
continue;
- if (desc->present && !is_cpu_present(desc, i))
+ if (desc->present && !is_cpu_present(desc, cpu))
continue;
line = tt_add_line(tt, NULL);
@@ -1252,8 +1286,9 @@ print_summary(struct lscpu_desc *desc, struct lscpu_modifier *mod)
err(EXIT_FAILURE, _("failed to callocate cpu set"));
CPU_ZERO_S(setsize, set);
for (i = 0; i < desc->ncpuspos; i++) {
- if (!is_cpu_online(desc, i) && is_cpu_present(desc, i))
- CPU_SET_S(i, setsize, set);
+ int cpu = real_cpu_num(desc, i);
+ if (!is_cpu_online(desc, cpu) && is_cpu_present(desc, cpu))
+ CPU_SET_S(cpu, setsize, set);
}
print_cpuset(mod->hex ? _("Off-line CPU(s) mask:") :
_("Off-line CPU(s) list:"),