@@ -144,7 +144,9 @@ rte_eal_cpu_init(void)
unsigned lcore_id;
unsigned count = 0;
unsigned int socket_id, prev_socket_id;
+ unsigned int package_id, prev_package_id;
int lcore_to_socket_id[RTE_MAX_LCORE];
+ int lcore_to_package_id[RTE_MAX_LCORE];
/*
* Parse the maximum set of logical cores, detect the subset of running
@@ -160,6 +162,10 @@ rte_eal_cpu_init(void)
socket_id = eal_cpu_socket_id(lcore_id);
lcore_to_socket_id[lcore_id] = socket_id;
+ /* find physical package ID */
+ package_id = eal_cpu_package_id(lcore_id);
+ lcore_to_package_id[lcore_id] = package_id;
+
if (eal_cpu_detected(lcore_id) == 0) {
config->lcore_role[lcore_id] = ROLE_OFF;
lcore_config[lcore_id].core_index = -1;
@@ -174,6 +180,7 @@ rte_eal_cpu_init(void)
lcore_config[lcore_id].core_role = ROLE_RTE;
lcore_config[lcore_id].core_id = eal_cpu_core_id(lcore_id);
lcore_config[lcore_id].numa_id = socket_id;
+ lcore_config[lcore_id].package_id = package_id;
EAL_LOG(DEBUG, "Detected lcore %u as "
"core %u on NUMA node %u",
lcore_id, lcore_config[lcore_id].core_id,
@@ -199,14 +206,25 @@ rte_eal_cpu_init(void)
qsort(lcore_to_socket_id, RTE_DIM(lcore_to_socket_id),
sizeof(lcore_to_socket_id[0]), socket_id_cmp);
+ /* sort all package id's in ascending order */
+ qsort(lcore_to_package_id, RTE_DIM(lcore_to_package_id),
+ sizeof(lcore_to_package_id[0]), socket_id_cmp);
+
prev_socket_id = -1;
+ prev_package_id = -1;
config->numa_node_count = 0;
+ config->package_count = 0;
for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
socket_id = lcore_to_socket_id[lcore_id];
+ package_id = lcore_to_package_id[lcore_id];
if (socket_id != prev_socket_id)
config->numa_nodes[config->numa_node_count++] =
socket_id;
+ if (package_id != prev_package_id)
+ config->packages[config->package_count++] =
+ package_id;
prev_socket_id = socket_id;
+ prev_package_id = package_id;
}
EAL_LOG(INFO, "Detected NUMA nodes: %u", config->numa_node_count);
@@ -31,6 +31,7 @@ struct lcore_config {
volatile RTE_ATOMIC(enum rte_lcore_state_t) state; /**< lcore state */
unsigned int numa_id; /**< NUMA node ID for this lcore */
+ unsigned int package_id; /**< Physical package ID for this lcore */
unsigned int core_id; /**< core number on socket for this lcore */
int core_index; /**< relative index, starting from 0 */
uint8_t core_role; /**< role of core eg: OFF, RTE, SERVICE */
@@ -48,6 +49,8 @@ struct rte_config {
uint32_t lcore_count; /**< Number of available logical cores. */
uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
uint32_t numa_nodes[RTE_MAX_NUMA_NODES]; /**< List of detected NUMA nodes. */
+ uint32_t package_count; /**< Number of detected physical packages. */
+ uint32_t packages[RTE_MAX_NUMA_NODES]; /**< List of detected physical packages. */
uint32_t service_lcore_count;/**< Number of available service cores. */
enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
@@ -27,6 +27,17 @@ __rte_noreturn uint32_t eal_thread_loop(void *arg);
*/
unsigned eal_cpu_socket_id(unsigned cpu_id);
+/**
+ * Get the package id from cpu id.
+ * This function is private to EAL.
+ *
+ * @param cpu_id
+ * The logical process id.
+ * @return
+ * socket_id or SOCKET_ID_ANY
+ */
+unsigned eal_cpu_package_id(unsigned cpu_id);
+
/**
* Default buffer size to use with eal_thread_dump_affinity()
*/
@@ -41,6 +41,12 @@ eal_cpu_socket_id(__rte_unused unsigned cpu_id)
return 0;
}
+unsigned
+eal_cpu_package_id(__rte_unused unsigned cpu_id)
+{
+ return 0;
+}
+
/* Check if a cpu is present by the presence of the
* cpu information for it.
*/
@@ -13,6 +13,7 @@
#define SYS_CPU_DIR "/sys/devices/system/cpu/cpu%u"
#define CORE_ID_FILE "topology/core_id"
+#define PACKAGE_ID_FILE "topology/physical_package_id"
#define NUMA_NODE_PATH "/sys/devices/system/node"
/* Check if a cpu is present by the presence of the cpu information for it */
@@ -53,6 +54,33 @@ eal_cpu_socket_id(unsigned lcore_id)
return 0;
}
+/*
+ * Get CPU package ID for a logical core.
+ *
+ * This searches each nodeX directories in /sys for the symlink for the given
+ * lcore_id and returns the numa node where the lcore is found. If lcore is not
+ * found on any numa node, returns zero.
+ */
+unsigned
+eal_cpu_package_id(unsigned lcore_id)
+{
+ char path[PATH_MAX];
+ unsigned long id;
+
+ int len = snprintf(path, sizeof(path),
+ SYS_CPU_DIR "/%s", lcore_id, PACKAGE_ID_FILE);
+ if (len <= 0 || (unsigned)len >= sizeof(path))
+ goto err;
+ if (eal_parse_sysfs_value(path, &id) != 0)
+ goto err;
+ return (unsigned)id;
+
+err:
+ EAL_LOG(ERR, "Error reading package id value from %s "
+ "for lcore %u - assuming package 0", SYS_CPU_DIR, lcore_id);
+ return 0;
+}
+
/* Get the cpu core id value from the /sys/.../cpuX core_id value */
unsigned
eal_cpu_core_id(unsigned lcore_id)
@@ -233,6 +233,13 @@ eal_cpu_socket_id(unsigned int lcore_id)
return cpu_map.lcores[lcore_id].socket_id;
}
+unsigned
+eal_cpu_package_id(unsigned int lcore_id)
+{
+ /* FIXME: Windows does support reporting Package ID */
+ return cpu_map.lcores[lcore_id].socket_id;
+}
+
unsigned
eal_cpu_core_id(unsigned int lcore_id)
{