aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/odp_system_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linux-generic/odp_system_info.c')
-rw-r--r--platform/linux-generic/odp_system_info.c382
1 files changed, 287 insertions, 95 deletions
diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c
index 40ffca078..c31068492 100644
--- a/platform/linux-generic/odp_system_info.c
+++ b/platform/linux-generic/odp_system_info.c
@@ -1,27 +1,26 @@
-/* Copyright (c) 2013, Linaro Limited
- * All rights reserved.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2013-2018 Linaro Limited
+ * Copyright (c) 2020-2022 Nokia
*
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-/*
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
+ * Copyright(c) 2010-2014 Intel Corporation
+ * - lib/eal/common/eal_common_string_fns.c
+ * - lib/eal/linux/eal_hugepage_info.c
*/
#include <odp_posix_extensions.h>
#include <odp/api/system_info.h>
#include <odp/api/version.h>
-#include <odp_internal.h>
+#include <odp_global_data.h>
+#include <odp_sysinfo_internal.h>
+#include <odp_init_internal.h>
+#include <odp_libconfig_internal.h>
#include <odp_debug_internal.h>
+#include <odp_config_internal.h>
#include <odp/api/align.h>
#include <odp/api/cpu.h>
+
#include <errno.h>
-#include <pthread.h>
-#include <sched.h>
#include <string.h>
#include <stdio.h>
#include <inttypes.h>
@@ -39,19 +38,9 @@
"/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size"
/*
- * Report the number of logical CPUs detected at boot time
- */
-static int sysconf_cpu_count(void)
-{
- return odp_global_data.num_cpus_installed;
-}
-
-#if defined __x86_64__ || defined __i386__ || defined __OCTEON__ || \
-defined __powerpc__
-/*
* Analysis of /sys/devices/system/cpu/ files
*/
-static int systemcpu_cache_line_size(void)
+static int read_cache_line_size(void)
{
FILE *file;
char str[128];
@@ -60,7 +49,9 @@ static int systemcpu_cache_line_size(void)
file = fopen(CACHE_LNSZ_FILE, "rt");
if (file == NULL) {
/* File not found */
- return 0;
+ _ODP_WARN("Unable to read host CPU cache line size. "
+ "Using ODP_CACHE_LINE_SIZE instead.\n");
+ return ODP_CACHE_LINE_SIZE;
}
if (fgets(str, sizeof(str), file) != NULL) {
@@ -74,17 +65,6 @@ static int systemcpu_cache_line_size(void)
return size;
}
-#else
-/*
- * Use dummy data if not available from /sys/devices/system/cpu/
- */
-static int systemcpu_cache_line_size(void)
-{
- return 64;
-}
-#endif
-
-
static uint64_t default_huge_page_size(void)
{
char str[1024];
@@ -92,16 +72,18 @@ static uint64_t default_huge_page_size(void)
FILE *file;
file = fopen("/proc/meminfo", "rt");
+ if (!file)
+ return 0;
while (fgets(str, sizeof(str), file) != NULL) {
if (sscanf(str, "Hugepagesize: %8lu kB", &sz) == 1) {
- ODP_DBG("defaut hp size is %" PRIu64 " kB\n", sz);
+ _ODP_DBG("default hp size is %lu kB\n", sz);
fclose(file);
return (uint64_t)sz * 1024;
}
}
- ODP_ERR("unable to get default hp size\n");
+ _ODP_ERR("unable to get default hp size\n");
fclose(file);
return 0;
}
@@ -227,7 +209,7 @@ static char *get_hugepage_dir(uint64_t hugepage_sz)
while (fgets(buf, sizeof(buf), fd)) {
if (strsplit(buf, sizeof(buf), tokens,
_FIELDNAME_MAX, split_tok) != _FIELDNAME_MAX) {
- ODP_ERR("Error parsing %s\n", proc_mounts);
+ _ODP_ERR("Error parsing %s\n", proc_mounts);
break; /* return NULL */
}
@@ -241,11 +223,9 @@ static char *get_hugepage_dir(uint64_t hugepage_sz)
retval = strdup(tokens[MOUNTPT]);
break;
}
- }
- /* there is an explicit page size, so check it */
- else {
- pagesz =
- str_to_size(&pagesz_str[pagesize_opt_len]);
+ } else {
+ /* there is an explicit page size, so check it */
+ pagesz = str_to_size(&pagesz_str[pagesize_opt_len]);
if (pagesz == hugepage_sz) {
retval = strdup(tokens[MOUNTPT]);
break;
@@ -259,33 +239,61 @@ static char *get_hugepage_dir(uint64_t hugepage_sz)
}
/*
- * Analysis of /sys/devices/system/cpu/ files
+ * Analysis of /sys/devices/system/cpu/cpu%d/cpufreq/ files
*/
-static int systemcpu(system_info_t *sysinfo)
+static uint64_t read_cpufreq(const char *filename, int id)
{
- int ret;
+ char path[256], buffer[256], *endptr = NULL;
+ FILE *file;
+ uint64_t ret = 0;
- ret = sysconf_cpu_count();
- if (ret == 0) {
- ODP_ERR("sysconf_cpu_count failed.\n");
- return -1;
- }
+ snprintf(path, sizeof(path),
+ "/sys/devices/system/cpu/cpu%d/cpufreq/%s", id, filename);
- sysinfo->cpu_count = ret;
+ file = fopen(path, "r");
+ if (file == NULL)
+ return ret;
+ if (fgets(buffer, sizeof(buffer), file) != NULL)
+ ret = strtoull(buffer, &endptr, 0) * 1000;
- ret = systemcpu_cache_line_size();
+ fclose(file);
+
+ return ret;
+}
+
+static inline uint64_t cpu_hz_current(int id)
+{
+ uint64_t cur_hz = read_cpufreq("cpuinfo_cur_freq", id);
+
+ if (!cur_hz)
+ cur_hz = odp_cpu_arch_hz_current(id);
+
+ return cur_hz;
+}
+
+static inline uint64_t cpu_hz_static(int id)
+{
+ return odp_global_ro.system_info.cpu_hz[id];
+}
+
+/*
+ * Analysis of /sys/devices/system/cpu/ files
+ */
+static int system_cache_line(system_info_t *sysinfo)
+{
+ int ret;
+
+ ret = read_cache_line_size();
if (ret == 0) {
- ODP_ERR("systemcpu_cache_line_size failed.\n");
+ _ODP_ERR("read_cache_line_size failed.\n");
return -1;
}
sysinfo->cache_line_size = ret;
- if (ret != ODP_CACHE_LINE_SIZE) {
- ODP_ERR("Cache line sizes definitions don't match.\n");
- return -1;
- }
+ if (ret != ODP_CACHE_LINE_SIZE)
+ _ODP_WARN("Host CPU cache line size and ODP_CACHE_LINE_SIZE don't match.\n");
return 0;
}
@@ -303,33 +311,103 @@ static int system_hp(hugepage_info_t *hugeinfo)
return 0;
}
+static int read_config_file(void)
+{
+ const char *str;
+ int val = 0;
+
+ str = "system.cpu_mhz";
+ if (!_odp_libconfig_lookup_int(str, &val)) {
+ _ODP_ERR("Config option '%s' not found.\n", str);
+ return -1;
+ }
+ odp_global_ro.system_info.default_cpu_hz = (uint64_t)val * 1000000;
+
+ str = "system.cpu_mhz_max";
+ if (!_odp_libconfig_lookup_int(str, &val)) {
+ _ODP_ERR("Config option '%s' not found.\n", str);
+ return -1;
+ }
+ odp_global_ro.system_info.default_cpu_hz_max = (uint64_t)val * 1000000;
+
+ str = "system.cpu_hz_static";
+ if (!_odp_libconfig_lookup_int(str, &val)) {
+ _ODP_ERR("Config option '%s' not found.\n", str);
+ return -1;
+ }
+ odp_global_ro.system_info.cpu_hz_static = !!val;
+
+ return 0;
+}
+
+static void print_compiler_info(void)
+{
+ _ODP_PRINT("Compiler defines:\n");
+ _ODP_PRINT(" __GCC_ATOMIC_LLONG_LOCK_FREE: %d\n", __GCC_ATOMIC_LLONG_LOCK_FREE);
+ _ODP_PRINT(" __GCC_ATOMIC_LONG_LOCK_FREE: %d\n", __GCC_ATOMIC_LONG_LOCK_FREE);
+ _ODP_PRINT(" __GCC_ATOMIC_INT_LOCK_FREE: %d\n", __GCC_ATOMIC_INT_LOCK_FREE);
+ _ODP_PRINT(" __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16: ");
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+ _ODP_PRINT("1\n");
+#else
+ _ODP_PRINT("0\n");
+#endif
+ _ODP_PRINT("\n");
+}
+
/*
* System info initialisation
*/
-int odp_system_info_init(void)
+int _odp_system_info_init(void)
{
+ int num_cpus;
+ int i;
FILE *file;
- memset(&odp_global_data.system_info, 0, sizeof(system_info_t));
+ memset(&odp_global_ro.system_info, 0, sizeof(system_info_t));
- odp_global_data.system_info.page_size = ODP_PAGE_SIZE;
+ odp_global_ro.system_info.page_size = ODP_PAGE_SIZE;
- file = fopen("/proc/cpuinfo", "rt");
- if (file == NULL) {
- ODP_ERR("Failed to open /proc/cpuinfo\n");
+ /* Read default CPU Hz values from config file */
+ if (read_config_file())
return -1;
- }
- cpuinfo_parser(file, &odp_global_data.system_info);
+ /* Check that CONFIG_NUM_CPU_IDS is large enough */
+ num_cpus = get_nprocs_conf();
+ if (num_cpus > CONFIG_NUM_CPU_IDS)
+ _ODP_ERR("Unable to handle all %d "
+ "CPU IDs. Increase CONFIG_NUM_CPU_IDS value.\n",
+ num_cpus);
- fclose(file);
+ /* Read and save all CPU frequencies for static mode */
+ if (odp_global_ro.system_info.cpu_hz_static)
+ for (i = 0; i < CONFIG_NUM_CPU_IDS; i++)
+ odp_global_ro.system_info.cpu_hz[i] = cpu_hz_current(i);
- if (systemcpu(&odp_global_data.system_info)) {
- ODP_ERR("systemcpu failed\n");
- return -1;
+ /* By default, read max frequency from a cpufreq file */
+ for (i = 0; i < CONFIG_NUM_CPU_IDS; i++) {
+ uint64_t cpu_hz_max = read_cpufreq("cpuinfo_max_freq", i);
+
+ if (cpu_hz_max)
+ odp_global_ro.system_info.cpu_hz_max[i] = cpu_hz_max;
}
- system_hp(&odp_global_data.hugepage_info);
+ file = fopen("/proc/cpuinfo", "rt");
+ if (file != NULL) {
+ /* Read CPU model, and set max cpu frequency
+ * if not set from cpufreq. */
+ _odp_cpuinfo_parser(file, &odp_global_ro.system_info);
+ fclose(file);
+ } else {
+ _odp_dummy_cpuinfo(&odp_global_ro.system_info);
+ }
+
+ if (system_cache_line(&odp_global_ro.system_info))
+ return -1;
+
+ system_hp(&odp_global_ro.hugepage_info);
+
+ print_compiler_info();
return 0;
}
@@ -337,9 +415,9 @@ int odp_system_info_init(void)
/*
* System info termination
*/
-int odp_system_info_term(void)
+int _odp_system_info_term(void)
{
- free(odp_global_data.hugepage_info.default_huge_page_dir);
+ free(odp_global_ro.hugepage_info.default_huge_page_dir);
return 0;
}
@@ -351,14 +429,20 @@ int odp_system_info_term(void)
*/
uint64_t odp_cpu_hz(void)
{
- int id = sched_getcpu();
+ int id = odp_cpu_id();
- return odp_cpu_hz_current(id);
+ if (odp_global_ro.system_info.cpu_hz_static)
+ return cpu_hz_static(id);
+ return cpu_hz_current(id);
}
uint64_t odp_cpu_hz_id(int id)
{
- return odp_cpu_hz_current(id);
+ _ODP_ASSERT(id >= 0 && id < CONFIG_NUM_CPU_IDS);
+
+ if (odp_global_ro.system_info.cpu_hz_static)
+ return cpu_hz_static(id);
+ return cpu_hz_current(id);
}
uint64_t odp_cpu_hz_max(void)
@@ -368,20 +452,63 @@ uint64_t odp_cpu_hz_max(void)
uint64_t odp_cpu_hz_max_id(int id)
{
- if (id >= 0 && id < MAX_CPU_NUMBER)
- return odp_global_data.system_info.cpu_hz_max[id];
+ if (id >= 0 && id < CONFIG_NUM_CPU_IDS)
+ return odp_global_ro.system_info.cpu_hz_max[id];
else
return 0;
}
uint64_t odp_sys_huge_page_size(void)
{
- return odp_global_data.hugepage_info.default_huge_page_size;
+ return odp_global_ro.hugepage_info.default_huge_page_size;
+}
+
+static int pagesz_compare(const void *pagesz1, const void *pagesz2)
+{
+ const uint64_t val1 = *(const uint64_t *)pagesz1;
+ const uint64_t val2 = *(const uint64_t *)pagesz2;
+
+ if (val1 < val2)
+ return -1;
+ if (val1 > val2)
+ return 1;
+ return 0;
+}
+
+int odp_sys_huge_page_size_all(uint64_t size[], int num)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int pagesz_num = 0;
+ int saved = 0;
+
+ /* See: kernel.org: hugetlbpage.txt */
+ dir = opendir("/sys/kernel/mm/hugepages");
+ if (!dir) {
+ _ODP_PRINT("Failed to open /sys/kernel/mm/hugepages: %s\n", strerror(errno));
+ return 0;
+ }
+
+ while ((entry = readdir(dir)) != NULL) {
+ unsigned long sz;
+
+ if (sscanf(entry->d_name, "hugepages-%8lukB", &sz) == 1) {
+ if (size != NULL && saved < num)
+ size[saved++] = sz * 1024;
+ pagesz_num++;
+ }
+ }
+ closedir(dir);
+
+ if (size != NULL && saved > 1)
+ qsort(size, saved, sizeof(uint64_t), pagesz_compare);
+
+ return pagesz_num;
}
uint64_t odp_sys_page_size(void)
{
- return odp_global_data.system_info.page_size;
+ return odp_global_ro.system_info.page_size;
}
const char *odp_cpu_model_str(void)
@@ -391,47 +518,112 @@ const char *odp_cpu_model_str(void)
const char *odp_cpu_model_str_id(int id)
{
- if (id >= 0 && id < MAX_CPU_NUMBER)
- return odp_global_data.system_info.model_str[id];
+ if (id >= 0 && id < CONFIG_NUM_CPU_IDS)
+ return odp_global_ro.system_info.model_str[id];
else
return NULL;
}
int odp_sys_cache_line_size(void)
{
- return odp_global_data.system_info.cache_line_size;
+ return odp_global_ro.system_info.cache_line_size;
}
int odp_cpu_count(void)
{
- return odp_global_data.system_info.cpu_count;
+ return odp_global_ro.num_cpus_installed;
+}
+
+int odp_system_info(odp_system_info_t *info)
+{
+ system_info_t *sys_info = &odp_global_ro.system_info;
+
+ memset(info, 0, sizeof(odp_system_info_t));
+
+ info->cpu_arch = sys_info->cpu_arch;
+ info->cpu_isa_sw = sys_info->cpu_isa_sw;
+ info->cpu_isa_hw = sys_info->cpu_isa_hw;
+
+ return 0;
}
void odp_sys_info_print(void)
{
- int len;
+ int len, num_cpu;
int max_len = 512;
+ odp_cpumask_t cpumask;
+ char cpumask_str[ODP_CPUMASK_STR_SIZE];
char str[max_len];
+ memset(cpumask_str, 0, sizeof(cpumask_str));
+
+ num_cpu = odp_cpumask_all_available(&cpumask);
+ odp_cpumask_to_str(&cpumask, cpumask_str, ODP_CPUMASK_STR_SIZE);
+
len = snprintf(str, max_len, "\n"
"ODP system info\n"
"---------------\n"
- "ODP API version: %s\n"
- "ODP impl name: %s\n"
- "CPU model: %s\n"
- "CPU freq (hz): %" PRIu64 "\n"
- "Cache line size: %i\n"
- "CPU count: %i\n"
+ "ODP API version: %s\n"
+ "ODP impl name: %s\n"
+ "ODP impl details: %s\n"
+ "CPU model: %s\n"
+ "CPU freq (hz): %" PRIu64 "\n"
+ "Cache line size: %i\n"
+ "CPU count: %i\n"
+ "CPU mask: %s\n"
"\n",
odp_version_api_str(),
odp_version_impl_name(),
+ odp_version_impl_str(),
odp_cpu_model_str(),
odp_cpu_hz_max(),
odp_sys_cache_line_size(),
- odp_cpu_count());
+ num_cpu, cpumask_str);
str[len] = '\0';
- ODP_PRINT("%s", str);
+ _ODP_PRINT("%s", str);
- sys_info_print_arch();
+ _odp_sys_info_print_arch();
+}
+
+void odp_sys_config_print(void)
+{
+ /* Print ODP_CONFIG_FILE default and override values */
+ if (_odp_libconfig_print())
+ _ODP_ERR("Config file print failed\n");
+
+ _ODP_PRINT("\n\nodp_config_internal.h values:\n"
+ "-----------------------------\n");
+ _ODP_PRINT("CONFIG_NUM_CPU_IDS: %i\n", CONFIG_NUM_CPU_IDS);
+ _ODP_PRINT("CONFIG_INTERNAL_QUEUES: %i\n", CONFIG_INTERNAL_QUEUES);
+ _ODP_PRINT("CONFIG_MAX_PLAIN_QUEUES: %i\n", CONFIG_MAX_PLAIN_QUEUES);
+ _ODP_PRINT("CONFIG_MAX_SCHED_QUEUES: %i\n", CONFIG_MAX_SCHED_QUEUES);
+ _ODP_PRINT("CONFIG_MAX_QUEUES: %i\n", CONFIG_MAX_QUEUES);
+ _ODP_PRINT("CONFIG_QUEUE_MAX_ORD_LOCKS: %i\n", CONFIG_QUEUE_MAX_ORD_LOCKS);
+ _ODP_PRINT("CONFIG_MAX_DMA_SESSIONS: %i\n", CONFIG_MAX_DMA_SESSIONS);
+ _ODP_PRINT("CONFIG_INTERNAL_STASHES: %i\n", CONFIG_INTERNAL_STASHES);
+ _ODP_PRINT("CONFIG_MAX_STASHES: %i\n", CONFIG_MAX_STASHES);
+ _ODP_PRINT("CONFIG_PKTIO_ENTRIES: %i\n", CONFIG_PKTIO_ENTRIES);
+ _ODP_PRINT("CONFIG_BUFFER_ALIGN_MAX: %i\n", CONFIG_BUFFER_ALIGN_MAX);
+ _ODP_PRINT("CONFIG_PACKET_HEADROOM: %i\n", CONFIG_PACKET_HEADROOM);
+ _ODP_PRINT("CONFIG_PACKET_TAILROOM: %i\n", CONFIG_PACKET_TAILROOM);
+ _ODP_PRINT("CONFIG_PACKET_SEG_SIZE: %i\n", CONFIG_PACKET_SEG_SIZE);
+ _ODP_PRINT("CONFIG_PACKET_MAX_SEG_LEN: %i\n", CONFIG_PACKET_MAX_SEG_LEN);
+ _ODP_PRINT("CONFIG_PACKET_SEG_LEN_MIN: %i\n", CONFIG_PACKET_SEG_LEN_MIN);
+ _ODP_PRINT("CONFIG_PACKET_VECTOR_MAX_SIZE: %i\n", CONFIG_PACKET_VECTOR_MAX_SIZE);
+ _ODP_PRINT("CONFIG_INTERNAL_SHM_BLOCKS: %i\n", CONFIG_INTERNAL_SHM_BLOCKS);
+ _ODP_PRINT("CONFIG_SHM_BLOCKS: %i\n", CONFIG_SHM_BLOCKS);
+ _ODP_PRINT("CONFIG_BURST_SIZE: %i\n", CONFIG_BURST_SIZE);
+ _ODP_PRINT("CONFIG_INTERNAL_POOLS: %i\n", CONFIG_INTERNAL_POOLS);
+ _ODP_PRINT("CONFIG_POOLS: %i\n", CONFIG_POOLS);
+ _ODP_PRINT("CONFIG_POOL_MAX_NUM: %i\n", CONFIG_POOL_MAX_NUM);
+ _ODP_PRINT("CONFIG_POOL_CACHE_MAX_SIZE: %i\n", CONFIG_POOL_CACHE_MAX_SIZE);
+ _ODP_PRINT("CONFIG_POOL_STATISTICS: %i\n", CONFIG_POOL_STATISTICS);
+ _ODP_PRINT("CONFIG_IPSEC_MAX_NUM_SA: %i\n", CONFIG_IPSEC_MAX_NUM_SA);
+ _ODP_PRINT("CONFIG_TIMER_128BIT_ATOMICS: %i\n", CONFIG_TIMER_128BIT_ATOMICS);
+ _ODP_PRINT("CONFIG_TIMER_PROFILE_INLINE: %i\n", CONFIG_TIMER_PROFILE_INLINE);
+ _ODP_PRINT("CONFIG_ML_MAX_MODELS: %i\n", CONFIG_ML_MAX_MODELS);
+ _ODP_PRINT("CONFIG_ML_MAX_INPUTS: %i\n", CONFIG_ML_MAX_INPUTS);
+ _ODP_PRINT("CONFIG_ML_MAX_OUTPUTS: %i\n", CONFIG_ML_MAX_OUTPUTS);
+ _ODP_PRINT("\n");
}