From aac1e59ebb205d0ae5a0480900bab22ae34729d9 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 11 Aug 2010 12:43:25 +0200 Subject: lscpu: support offline CPUs # echo 0 >/sys/devices/system/cpu/cpu3/online # echo 0 >/sys/devices/system/cpu/cpu2/online # grep processor /proc/cpuinfo processor : 0 processor : 1 # lscpu lscpu: error: cannot open /sys/devices/system/cpu/cpu2/cache/index0/shared_cpu_map: No such file or directory This patch also add a new "On-line CPU(s):" line to the lscpu(1) output. Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=623012 Signed-off-by: Karel Zak --- sys-utils/lscpu.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 9 deletions(-) (limited to 'sys-utils/lscpu.c') diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index 74f5e781c..eff655c4d 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -101,6 +101,7 @@ struct lscpu_desc { int mode; /* rm, lm or/and tm */ int ncpus; /* number of CPUs */ + cpu_set_t *online; /* mask with online CPUs */ int nnodes; /* number of NUMA modes */ cpu_set_t **nodemaps; /* array with NUMA nodes */ @@ -125,6 +126,10 @@ static size_t sysrootlen; static char pathbuf[PATH_MAX]; static int maxcpus; /* size in bits of kernel cpu mask */ +#define is_cpu_online(_d, _cpu) \ + ((_d) && (_d)->online ? \ + CPU_ISSET_S((_cpu), CPU_ALLOC_SIZE(maxcpus), (_d)->online) : 0) + static FILE *path_fopen(const char *mode, int exit_on_err, const char *path, ...) __attribute__ ((__format__ (__printf__, 3, 4))); static void path_getstr(char *result, size_t len, const char *path, ...) @@ -235,17 +240,14 @@ xstrdup(const char *str) } static cpu_set_t * -path_cpuset(const char *path, ...) +path_cpuparse(int islist, const char *path, va_list ap) { FILE *fd; - va_list ap; cpu_set_t *set; size_t setsize, len = maxcpus * 7; char buf[len]; - va_start(ap, path); fd = path_vfopen("r", 1, path, ap); - va_end(ap); if (!fgets(buf, len, fd)) err(EXIT_FAILURE, _("failed to read: %s"), pathbuf); @@ -259,8 +261,38 @@ path_cpuset(const char *path, ...) if (!set) err(EXIT_FAILURE, _("failed to callocate cpu set")); - if (cpumask_parse(buf, set, setsize)) - errx(EXIT_FAILURE, _("failed to parse CPU mask %s"), buf); + if (islist) { + if (cpulist_parse(buf, set, setsize)) + errx(EXIT_FAILURE, _("failed to parse CPU list %s"), buf); + } else { + if (cpumask_parse(buf, set, setsize)) + errx(EXIT_FAILURE, _("failed to parse CPU mask %s"), buf); + } + return set; +} + +static cpu_set_t * +path_cpuset(const char *path, ...) +{ + va_list ap; + cpu_set_t *set; + + va_start(ap, path); + set = path_cpuparse(0, path, ap); + va_end(ap); + + return set; +} + +static cpu_set_t * +path_cpulist(const char *path, ...) +{ + va_list ap; + cpu_set_t *set; + + va_start(ap, path); + set = path_cpuparse(1, path, ap); + va_end(ap); return set; } @@ -365,6 +397,9 @@ read_basicinfo(struct lscpu_desc *desc) /* we are reading some /sys snapshot instead of the real /sys, * let's use any crazy number... */ maxcpus = desc->ncpus > 2048 ? desc->ncpus : 2048; + + /* get mask for online CPUs */ + desc->online = path_cpulist(_PATH_SYS_SYSTEM "/cpu/online"); } static int @@ -523,7 +558,8 @@ read_topology(struct lscpu_desc *desc, int num) "/cpu%d/topology/thread_siblings", num); core_siblings = path_cpuset(_PATH_SYS_CPU "/cpu%d/topology/core_siblings", num); - if (num == 0) { + + if (!desc->coremaps) { int ncores, nsockets, nthreads; size_t setsize = CPU_ALLOC_SIZE(maxcpus); @@ -563,7 +599,7 @@ read_cache(struct lscpu_desc *desc, int num) char buf[256]; int i; - if (num == 0) { + if (!desc->ncaches) { while(path_exist(_PATH_SYS_SYSTEM "/cpu/cpu%d/cache/index%d", num, desc->ncaches)) desc->ncaches++; @@ -670,6 +706,9 @@ print_parsable(struct lscpu_desc *desc) for (i = 0; i < desc->ncpus; i++) { + if (!is_cpu_online(desc, i)) + continue; + /* #CPU */ printf("%d", i); @@ -734,6 +773,7 @@ print_readable(struct lscpu_desc *desc) { char buf[512]; int i; + size_t setsize = CPU_ALLOC_SIZE(maxcpus); print_s(_("Architecture:"), desc->arch); @@ -757,6 +797,7 @@ print_readable(struct lscpu_desc *desc) } print_n(_("CPU(s):"), desc->ncpus); + print_n(_("On-line CPU(s):"), CPU_COUNT_S(setsize, desc->online)); if (desc->nsockets) { print_n(_("Thread(s) per core:"), desc->nthreads / desc->ncores); @@ -806,7 +847,7 @@ print_readable(struct lscpu_desc *desc) print_s(buf, cpulist_create( setbuf, setbuflen, desc->nodemaps[i], - CPU_ALLOC_SIZE(maxcpus))); + setsize)); } } } @@ -861,6 +902,8 @@ int main(int argc, char *argv[]) read_basicinfo(desc); for (i = 0; i < desc->ncpus; i++) { + if (!is_cpu_online(desc, i)) + continue; read_topology(desc, i); read_cache(desc, i); } -- cgit v1.2.3-55-g7522