--- src/libplpa/plpa_map.c | 69 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 11 deletions(-) diff --quilt old/src/libplpa/plpa_map.c new/src/libplpa/plpa_map.c --- old/src/libplpa/plpa_map.c +++ new/src/libplpa/plpa_map.c @@ -122,6 +122,7 @@ #include #include #include +#include #include #include #include @@ -173,8 +174,11 @@ static void load_cache(const char *sysfs { int i, j, k, invalid_entry, fd; char path[PATH_MAX], buf[8]; + PLPA_NAME(cpu_set_t) valid_processors; PLPA_NAME(cpu_set_t) *cores_on_sockets; int found; + DIR *dir; + struct dirent dentry, *dentryp = NULL; /* Check for the parent directory */ sprintf(path, "%s/devices/system/cpu", sysfs_mount); @@ -182,17 +186,45 @@ static void load_cache(const char *sysfs return; } - /* Go through and find the max processor ID */ - for (num_processors = max_processor_id = i = 0; - i < PLPA_BITMASK_CPU_MAX; ++i) { - sprintf(path, "%s/devices/system/cpu/cpu%d", sysfs_mount, i); - if (0 != access(path, (R_OK | X_OK))) { - max_processor_id = i - 1; - break; - } - ++num_processors; + dir = opendir(path); + if (NULL == dir) { + return; } + /* Catch all entries of format "cpu%d", count them and maintain + max_processor_id */ + num_processors = 0; + PLPA_CPU_ZERO(&valid_processors); + do { + int ret = readdir_r(dir, &dentry, &dentryp); + if (0 != ret) { + closedir(dir); + clear_cache(); + return; + } + + if (dentryp) { + int cpuid; + + ret = sscanf(dentryp->d_name, "cpu%d", &cpuid); + if (1 != ret) { + continue; + } + + ++num_processors; + if (cpuid >= PLPA_BITMASK_CPU_MAX) { + closedir(dir); + clear_cache(); + return; + } else if (cpuid > max_processor_id) { + max_processor_id = cpuid; + } + PLPA_CPU_SET(cpuid, &valid_processors); + } + + } while (NULL != dentryp); + closedir(dir); + /* If we found no processors, then we have no topology info */ if (0 == num_processors) { clear_cache(); @@ -208,7 +240,11 @@ static void load_cache(const char *sysfs return; } for (i = 0; i <= max_processor_id; ++i) { - map_processor_id_to_tuple[i].processor_id = i; + if (PLPA_CPU_ISSET(i, &valid_processors)) { + map_processor_id_to_tuple[i].processor_id = i; + } else { + map_processor_id_to_tuple[i].processor_id = -1; + } map_processor_id_to_tuple[i].socket = -1; map_processor_id_to_tuple[i].core = -1; } @@ -220,6 +256,12 @@ static void load_cache(const char *sysfs /* Build a cached map of (socket,core) tuples */ for (found = 0, i = 0; i <= max_processor_id; ++i) { + + /* Check for invalid processor ID */ + if (map_processor_id_to_tuple[i].processor_id < 0) { + continue; + } + sprintf(path, "%s/devices/system/cpu/cpu%d/topology/core_id", sysfs_mount, i); fd = open(path, O_RDONLY); @@ -271,6 +313,10 @@ static void load_cache(const char *sysfs /* Find the max core number on each socket */ for (i = 0; i <= max_processor_id; ++i) { + if (map_processor_id_to_tuple[i].processor_id < 0 || + map_processor_id_to_tuple[i].socket < 0) { + continue; + } if (map_processor_id_to_tuple[i].core > max_core_id[map_processor_id_to_tuple[i].socket]) { max_core_id[map_processor_id_to_tuple[i].socket] = @@ -496,7 +542,8 @@ int PLPA_NAME(map_to_socket_core)(int pr } /* Check for some invalid entries */ - if (processor_id < 0 || processor_id > max_processor_id) { + if (processor_id < 0 || processor_id > max_processor_id || + map_processor_id_to_tuple[processor_id].processor_id < 0) { return ENOENT; } ret = map_processor_id_to_tuple[processor_id].socket;