eal/linux: enhanced error handling for affinity

Message ID 20240422134917.3740545-1-ferruh.yigit@amd.com (mailing list archive)
State Superseded
Delegated to: Thomas Monjalon
Headers
Series eal/linux: enhanced error handling for affinity |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/intel-Functional success Functional PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/github-robot: build success github build: passed
ci/iol-abi-testing success Testing PASS
ci/iol-unit-amd64-testing success Testing PASS
ci/iol-sample-apps-testing success Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-unit-arm64-testing success Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-compile-arm64-testing success Testing PASS
ci/iol-compile-amd64-testing success Testing PASS

Commit Message

Ferruh Yigit April 22, 2024, 1:49 p.m. UTC
  From: Jianyue Wu <jianyue.wu@nokia-sbell.com>

Improve the robustness of setting thread affinity in DPDK
by adding detailed error logging.

Changes:
1. Set `errno` to 0 before calling `pthread_setaffinity_np()` to ensure
clean error status.
2. Check the return value of `pthread_setaffinity_np()` and log an error
if the call fails.
3. Include the current thread name, the intended CPU set, and a detailed
error message in the log.

Sample prints:
EAL: Cannot set affinity for thread dpdk-test with cpus 0,
ret: 22, errno: 0, error description: Success
EAL: Cannot set affinity for thread dpdk-worker1 with cpus 1,
ret: 22, errno: 0, error description: Success

Signed-off-by: Jianyue Wu <jianyue.wu@nokia-sbell.com>
---
 .mailmap                  |  1 +
 lib/eal/unix/rte_thread.c | 51 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 50 insertions(+), 2 deletions(-)
  

Comments

Patrick Robb April 26, 2024, 9:31 p.m. UTC | #1
Recheck-request: iol-compile-amd64-testing

The DPDK Community Lab updated to the latest Alpine image yesterday, which
resulted in all Alpine builds failing. The failure is unrelated to your
patch, and this recheck should remove the fail on Patchwork, as we have
disabled Alpine testing for now.
  

Patch

diff --git a/.mailmap b/.mailmap
index 3843868716bd..66cff91f30a9 100644
--- a/.mailmap
+++ b/.mailmap
@@ -639,6 +639,7 @@  Jianfeng Tan <jianfeng.tan@intel.com>
 Jiangu Zhao <zhaojg@arraynetworks.com.cn>
 Jianwei Ma <jianwei.ma@intel.com>
 Jianwei Mei <jianweix.mei@intel.com>
+Jianyue Wu <jianyue.wu@nokia-sbell.com>
 Jiaqi Min <jiaqix.min@intel.com>
 Jiawei Wang <jiaweiw@nvidia.com> <jiaweiw@mellanox.com>
 Jiawei Zhu <zhujiawei12@huawei.com>
diff --git a/lib/eal/unix/rte_thread.c b/lib/eal/unix/rte_thread.c
index 1b4c73f58e91..56bc7995eb5f 100644
--- a/lib/eal/unix/rte_thread.c
+++ b/lib/eal/unix/rte_thread.c
@@ -5,6 +5,7 @@ 
 
 #include <errno.h>
 #include <pthread.h>
+#include <sched.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
@@ -114,6 +115,35 @@  thread_start_wrapper(void *arg)
 	return (void *)(uintptr_t)thread_func(thread_args);
 }
 
+/* Function to convert cpu_set_t to a string. */
+static void cpuset_to_string(const cpu_set_t *cpuset,
+			char *cpus_str, size_t cpus_str_size) {
+	int cpu;
+	// Track the current position in the string
+	size_t offset = 0;
+
+	// Clear the string buffer
+	memset(cpus_str, 0, cpus_str_size);
+	cpus_str_size = RTE_MAX_LCORE < cpus_str_size ?
+		RTE_MAX_LCORE : cpus_str_size;
+
+	// Iterate over each CPU core, and check if it is included in the set
+	for (cpu = 0; cpu < RTE_MAX_LCORE && offset < cpus_str_size - 1; ++cpu) {
+		if (CPU_ISSET(cpu, cpuset)) {
+			// Append the current CPU number to the string
+			int written = snprintf(cpus_str + offset, cpus_str_size - offset,
+				"%s%d", (offset > 0 ? "," : ""), cpu);
+			if (written > 0)
+				offset += written;
+			if (offset >= cpus_str_size - 1)
+				break;
+			}
+	}
+
+	// Ensure the string is properly terminated
+	cpus_str[cpus_str_size - 1] = '\0';
+}
+
 int
 rte_thread_create(rte_thread_t *thread_id,
 		const rte_thread_attr_t *thread_attr,
@@ -369,8 +399,25 @@  int
 rte_thread_set_affinity_by_id(rte_thread_t thread_id,
 		const rte_cpuset_t *cpuset)
 {
-	return pthread_setaffinity_np((pthread_t)thread_id.opaque_id,
-		sizeof(*cpuset), cpuset);
+	int ret;
+	char cpus_str[RTE_MAX_LCORE + 1] = {'\0'};
+	char thread_name[RTE_MAX_THREAD_NAME_LEN] = {'\0'};
+
+	errno = 0;
+	ret = pthread_setaffinity_np((pthread_t)thread_id.opaque_id,
+				sizeof(*cpuset), cpuset);
+	if (ret != 0) {
+		if (pthread_getname_np((pthread_t)thread_id.opaque_id,
+					thread_name, sizeof(thread_name)) != 0)
+			EAL_LOG(ERR, "pthread_getname_np failed!");
+		cpuset_to_string(cpuset, cpus_str, sizeof(cpus_str));
+		EAL_LOG(ERR, "Cannot set affinity for thread %s with cpus %s, "
+			"ret: %d, errno: %d, error description: %s",
+			thread_name, cpus_str,
+			ret, errno, strerror(errno));
+	}
+
+	return ret;
 }
 
 int