diff --git a/NEWS b/NEWS index a2933ad12f..26dda1f12a 100644 --- a/NEWS +++ b/NEWS @@ -93,6 +93,8 @@ Version 2.0.0 + hwloc_obj_cpuset_snprintf() is deprecated in favor of hwloc_bitmap_snprintf(). + Functions diff_load_xml*(), diff_export_xml*() and diff_destroy() in hwloc/diff.h do not need a topology as first parameter anymore. + + hwloc_parse_cpumap_file () superseded by hwloc_linux_read_path_as_cpumask() + in hwloc/linux.h. * Tools - lstopo and hwloc-info have a new --filter option matching the new filtering API. - hwloc-distances was removed and replaced with lstopo --distances. diff --git a/doc/Makefile.am b/doc/Makefile.am index 948717652c..aff2a6a670 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -695,10 +695,10 @@ man3_glibc_sched_DATA = \ man3_linuxdir = $(man3dir) man3_linux_DATA = \ $(DOX_MAN_DIR)/man3/hwlocality_linux.3 \ - $(DOX_MAN_DIR)/man3/hwloc_linux_parse_cpumap_file.3 \ $(DOX_MAN_DIR)/man3/hwloc_linux_set_tid_cpubind.3 \ $(DOX_MAN_DIR)/man3/hwloc_linux_get_tid_cpubind.3 \ - $(DOX_MAN_DIR)/man3/hwloc_linux_get_tid_last_cpu_location.3 + $(DOX_MAN_DIR)/man3/hwloc_linux_get_tid_last_cpu_location.3 \ + $(DOX_MAN_DIR)/man3/hwloc_linux_read_path_as_cpumask.3 man3_linux_libnumadir = $(man3dir) man3_linux_libnuma_DATA = \ diff --git a/hwloc/topology-linux.c b/hwloc/topology-linux.c index 4480fab116..179fdbc082 100644 --- a/hwloc/topology-linux.c +++ b/hwloc/topology-linux.c @@ -678,7 +678,6 @@ hwloc__read_fd_as_cpumask(int fd, hwloc_bitmap_t set) return 0; } -/* FIXME: export to API? */ static __hwloc_inline int hwloc__read_path_as_cpumask(const char *maskpath, hwloc_bitmap_t set, int fsroot_fd) { @@ -707,6 +706,18 @@ hwloc__alloc_read_path_as_cpumask(const char *maskpath, int fsroot_fd) return set; } +int +hwloc_linux_read_path_as_cpumask(const char *maskpath, hwloc_bitmap_t set) +{ + int fd, err; + fd = open(maskpath, O_RDONLY); + if (fd < 0) + return -1; + err = hwloc__read_fd_as_cpumask(fd, set); + close(fd); + return err; +} + /***************************** ******* CpuBind Hooks ******* @@ -1977,71 +1988,6 @@ struct hwloc_linux_cpuinfo_proc { unsigned infos_count; }; -/* FIXME drop from API */ -int -hwloc_linux_parse_cpumap_file(FILE *file, hwloc_bitmap_t set) -{ - unsigned long *maps; - unsigned long map; - int nr_maps = 0; - static int _nr_maps_allocated = 8; /* Only compute the power-of-two above the kernel cpumask size once. - * Actually, it may increase multiple times if first read cpumaps start with zeroes. - */ - int nr_maps_allocated = _nr_maps_allocated; - int i; - - maps = malloc(nr_maps_allocated * sizeof(*maps)); - if (!maps) - return -1; - - /* reset to zero first */ - hwloc_bitmap_zero(set); - - /* parse the whole mask */ - while (fscanf(file, "%lx,", &map) == 1) /* read one kernel cpu mask and the ending comma */ - { - if (nr_maps == nr_maps_allocated) { - unsigned long *tmp = realloc(maps, 2*nr_maps_allocated * sizeof(*maps)); - if (!tmp) { - free(maps); - return -1; - } - maps = tmp; - nr_maps_allocated *= 2; - } - - if (!map && !nr_maps) - /* ignore the first map if it's empty */ - continue; - - maps[nr_maps++] = map; - } - - /* convert into a set */ -#if KERNEL_CPU_MASK_BITS == HWLOC_BITS_PER_LONG - for(i=0; i _nr_maps_allocated) - _nr_maps_allocated = nr_maps_allocated; - return 0; -} - static void hwloc_find_linux_cpuset_mntpnt(char **cgroup_mntpnt, char **cpuset_mntpnt, const char *root_path) { diff --git a/include/hwloc/cuda.h b/include/hwloc/cuda.h index 09c5b1a147..4e8bb1d8a4 100644 --- a/include/hwloc/cuda.h +++ b/include/hwloc/cuda.h @@ -96,7 +96,6 @@ hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, /* If we're on Linux, use the sysfs mechanism to get the local cpus */ #define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128 char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX]; - FILE *sysfile = NULL; int domainid, busid, deviceid; if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid)) @@ -108,15 +107,9 @@ hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, } sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domainid, busid, deviceid); - sysfile = fopen(path, "r"); - if (!sysfile) - return -1; - - if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0 + if (hwloc_linux_read_path_as_cpumask(path, set) < 0 || hwloc_bitmap_iszero(set)) hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); - - fclose(sysfile); #else /* Non-Linux systems simply get a full cpuset */ hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); diff --git a/include/hwloc/cudart.h b/include/hwloc/cudart.h index 65e007369f..4f1bc98ef9 100644 --- a/include/hwloc/cudart.h +++ b/include/hwloc/cudart.h @@ -93,7 +93,6 @@ hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse /* If we're on Linux, use the sysfs mechanism to get the local cpus */ #define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128 char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX]; - FILE *sysfile = NULL; int domain, bus, dev; if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev)) @@ -105,15 +104,9 @@ hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse } sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domain, bus, dev); - sysfile = fopen(path, "r"); - if (!sysfile) - return -1; - - if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0 + if (hwloc_linux_read_path_as_cpumask(path, set) < 0 || hwloc_bitmap_iszero(set)) hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); - - fclose(sysfile); #else /* Non-Linux systems simply get a full cpuset */ hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); diff --git a/include/hwloc/intel-mic.h b/include/hwloc/intel-mic.h index b8cf4d5985..6f6f9d1b3a 100644 --- a/include/hwloc/intel-mic.h +++ b/include/hwloc/intel-mic.h @@ -64,7 +64,6 @@ hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_un #define HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX 128 char path[HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX]; DIR *sysdir = NULL; - FILE *sysfile = NULL; struct dirent *dirent; unsigned pcibus, pcidev, pcifunc; @@ -81,17 +80,9 @@ hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_un while ((dirent = readdir(sysdir)) != NULL) { if (sscanf(dirent->d_name, "pci_%02x:%02x.%02x", &pcibus, &pcidev, &pcifunc) == 3) { sprintf(path, "/sys/class/mic/mic%d/pci_%02x:%02x.%02x/local_cpus", idx, pcibus, pcidev, pcifunc); - sysfile = fopen(path, "r"); - if (!sysfile) { - closedir(sysdir); - return -1; - } - - if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0 + if (hwloc_linux_read_path_as_cpumask(path, set) < 0 || hwloc_bitmap_iszero(set)) hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); - - fclose(sysfile); break; } } diff --git a/include/hwloc/linux.h b/include/hwloc/linux.h index 3990546515..c409e1c2af 100644 --- a/include/hwloc/linux.h +++ b/include/hwloc/linux.h @@ -32,13 +32,6 @@ extern "C" { * @{ */ -/** \brief Convert a linux kernel cpumap file \p file into hwloc CPU set. - * - * Might be used when reading CPU set from sysfs attributes such as topology - * and caches for processors, or local_cpus for devices. - */ -HWLOC_DECLSPEC int hwloc_linux_parse_cpumap_file(FILE *file, hwloc_cpuset_t set); - /** \brief Bind a thread \p tid on cpus given in cpuset \p set * * The behavior is exactly the same as the Linux sched_setaffinity system call, @@ -66,6 +59,15 @@ HWLOC_DECLSPEC int hwloc_linux_get_tid_cpubind(hwloc_topology_t topology, pid_t */ HWLOC_DECLSPEC int hwloc_linux_get_tid_last_cpu_location(hwloc_topology_t topology, pid_t tid, hwloc_bitmap_t set); +/** \brief Convert a linux kernel cpumask file \p path into a hwloc bitmap \p set. + * + * Might be used when reading CPU set from sysfs attributes such as topology + * and caches for processors, or local_cpus for devices. + * + * \note This function ignores the HWLOC_FSROOT environment variable. + */ +HWLOC_DECLSPEC int hwloc_linux_read_path_as_cpumask(const char *path, hwloc_bitmap_t set); + /** @} */ diff --git a/include/hwloc/nvml.h b/include/hwloc/nvml.h index 961d41a64b..0d50a9b8bc 100644 --- a/include/hwloc/nvml.h +++ b/include/hwloc/nvml.h @@ -60,7 +60,6 @@ hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, /* If we're on Linux, use the sysfs mechanism to get the local cpus */ #define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128 char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX]; - FILE *sysfile = NULL; nvmlReturn_t nvres; nvmlPciInfo_t pci; @@ -76,15 +75,9 @@ hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, } sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", pci.domain, pci.bus, pci.device); - sysfile = fopen(path, "r"); - if (!sysfile) - return -1; - - if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0 + if (hwloc_linux_read_path_as_cpumask(path, set) < 0 || hwloc_bitmap_iszero(set)) hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); - - fclose(sysfile); #else /* Non-Linux systems simply get a full cpuset */ hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); diff --git a/include/hwloc/opencl.h b/include/hwloc/opencl.h index 3449987110..d44475ceb9 100644 --- a/include/hwloc/opencl.h +++ b/include/hwloc/opencl.h @@ -69,7 +69,6 @@ hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse /* If we're on Linux + AMD OpenCL, use the AMD extension + the sysfs mechanism to get the local cpus */ #define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128 char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX]; - FILE *sysfile = NULL; cl_device_topology_amd amdtopo; cl_int clret; @@ -89,15 +88,9 @@ hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse } sprintf(path, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/local_cpus", amdtopo.pcie.bus, amdtopo.pcie.device, amdtopo.pcie.function); - sysfile = fopen(path, "r"); - if (!sysfile) - return -1; - - if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0 + if (hwloc_linux_read_path_as_cpumask(path, set) < 0 || hwloc_bitmap_iszero(set)) hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); - - fclose(sysfile); #else /* Non-Linux + AMD OpenCL systems simply get a full cpuset */ hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); diff --git a/include/hwloc/openfabrics-verbs.h b/include/hwloc/openfabrics-verbs.h index a66566fba9..174ab4a57d 100644 --- a/include/hwloc/openfabrics-verbs.h +++ b/include/hwloc/openfabrics-verbs.h @@ -67,7 +67,6 @@ hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, get the local cpus */ #define HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX 128 char path[HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX]; - FILE *sysfile = NULL; if (!hwloc_topology_is_thissystem(topology)) { errno = EINVAL; @@ -76,15 +75,9 @@ hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, sprintf(path, "/sys/class/infiniband/%s/device/local_cpus", ibv_get_device_name(ibdev)); - sysfile = fopen(path, "r"); - if (!sysfile) - return -1; - - if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0 + if (hwloc_linux_read_path_as_cpumask(path, set) < 0 || hwloc_bitmap_iszero(set)) hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); - - fclose(sysfile); #else /* Non-Linux systems simply get a full cpuset */ hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); diff --git a/include/hwloc/rename.h b/include/hwloc/rename.h index e1ae1e4ea1..7af149c633 100644 --- a/include/hwloc/rename.h +++ b/include/hwloc/rename.h @@ -433,10 +433,10 @@ extern "C" { /* linux.h */ -#define hwloc_linux_parse_cpumap_file HWLOC_NAME(linux_parse_cpumap_file) #define hwloc_linux_set_tid_cpubind HWLOC_NAME(linux_set_tid_cpubind) #define hwloc_linux_get_tid_cpubind HWLOC_NAME(linux_get_tid_cpubind) #define hwloc_linux_get_tid_last_cpu_location HWLOC_NAME(linux_get_tid_last_cpu_location) +#define hwloc_linux_read_path_as_cpumask HWLOC_NAME(linux_read_file_cpumask) /* openfabrics-verbs.h */