Hi, here a patch proposal for a solaris cpu affinity basic support (no NUMA (yet)).
Kind regards.
From e3afd3de4f8c4e1d4d0d1d98a8de814aed19ffa6 Mon Sep 17 00:00:00 2001 From: David Carlier <[email protected]> Date: Mon, 31 Jan 2022 19:31:53 +0000 Subject: [PATCH] MEDIUM: thread basic cpu affinity support for solaris based systems. focusing on being able to attribute threads to cpu for now (cpu locality not yet sure if possible w/o too convoluted code). Using here native API from both solaris and illumos. --- Makefile | 2 +- include/haproxy/cpuset-t.h | 5 +++++ src/cpuset.c | 19 ++++++++++++++----- src/thread.c | 13 ++++++++++++- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 57c7510a1..88acc7ac8 100644 --- a/Makefile +++ b/Makefile @@ -377,7 +377,7 @@ endif ifeq ($(TARGET),solaris) set_target_defaults = $(call default_opts, \ USE_POLL USE_TPROXY USE_LIBCRYPT USE_CRYPT_H USE_GETADDRINFO USE_THREAD \ - USE_RT USE_OBSOLETE_LINKER USE_EVPORTS USE_CLOSEFROM) + USE_RT USE_OBSOLETE_LINKER USE_EVPORTS USE_CLOSEFROM USE_CPU_AFFINITY) TARGET_CFLAGS = -DFD_SETSIZE=65536 -D_REENTRANT -D_XOPEN_SOURCE=600 -D__EXTENSIONS__ TARGET_LDFLAGS = -lnsl -lsocket endif diff --git a/include/haproxy/cpuset-t.h b/include/haproxy/cpuset-t.h index 5f812aa17..e362d9620 100644 --- a/include/haproxy/cpuset-t.h +++ b/include/haproxy/cpuset-t.h @@ -36,6 +36,11 @@ # define CPUSET_REPR unsigned long # define CPUSET_USE_ULONG +#elif defined(__sun) + +# define CPUSET_REPR int +# define CPUSET_USE_PSET + #else # error "No cpuset support implemented on this platform" diff --git a/src/cpuset.c b/src/cpuset.c index f7b66020e..a8aa6995d 100644 --- a/src/cpuset.c +++ b/src/cpuset.c @@ -12,7 +12,7 @@ void ha_cpuset_zero(struct hap_cpuset *set) #if defined(CPUSET_USE_CPUSET) || defined(CPUSET_USE_FREEBSD_CPUSET) CPU_ZERO(&set->cpuset); -#elif defined(CPUSET_USE_ULONG) +#elif defined(CPUSET_USE_ULONG) || defined(CPUSET_USE_PSET) set->cpuset = 0; #endif } @@ -26,7 +26,7 @@ int ha_cpuset_set(struct hap_cpuset *set, int cpu) CPU_SET(cpu, &set->cpuset); return 0; -#elif defined(CPUSET_USE_ULONG) +#elif defined(CPUSET_USE_ULONG) || defined(CPUSET_USE_PSET) set->cpuset |= (0x1 << cpu); return 0; #endif @@ -41,7 +41,7 @@ int ha_cpuset_clr(struct hap_cpuset *set, int cpu) CPU_CLR(cpu, &set->cpuset); return 0; -#elif defined(CPUSET_USE_ULONG) +#elif defined(CPUSET_USE_ULONG) || defined(CPUSET_USE_PSET) set->cpuset &= ~(0x1 << cpu); return 0; #endif @@ -55,7 +55,7 @@ void ha_cpuset_and(struct hap_cpuset *dst, struct hap_cpuset *src) #elif defined(CPUSET_USE_FREEBSD_CPUSET) CPU_AND(&dst->cpuset, &src->cpuset); -#elif defined(CPUSET_USE_ULONG) +#elif defined(CPUSET_USE_ULONG) || defined(CPUSET_USE_PSET) dst->cpuset &= src->cpuset; #endif } @@ -67,6 +67,8 @@ int ha_cpuset_count(const struct hap_cpuset *set) #elif defined(CPUSET_USE_ULONG) return my_popcountl(set->cpuset); +#elif defined(CPUSET_USE_PSET) + return __builtin_popcount(set->cpuset); #endif } @@ -91,6 +93,11 @@ int ha_cpuset_ffs(const struct hap_cpuset *set) return 0; return my_ffsl(set->cpuset); +#elif defined(CPUSET_USE_PSET) + if (!set->cpuset) + return 0; + + return __builtin_ffs(set->cpuset); #endif } @@ -103,7 +110,7 @@ void ha_cpuset_assign(struct hap_cpuset *dst, struct hap_cpuset *src) #elif defined(CPUSET_USE_FREEBSD_CPUSET) CPU_COPY(&src->cpuset, &dst->cpuset); -#elif defined(CPUSET_USE_ULONG) +#elif defined(CPUSET_USE_ULONG) || defined(CPUSET_USE_PSET) dst->cpuset = src->cpuset; #endif } @@ -115,6 +122,8 @@ int ha_cpuset_size() #elif defined(CPUSET_USE_ULONG) return LONGBITS; +#elif defined(CPUSET_USE_PSET) + return sizeof(int) * 8; #endif } diff --git a/src/thread.c b/src/thread.c index a04e914d9..87295f2c9 100644 --- a/src/thread.c +++ b/src/thread.c @@ -39,6 +39,9 @@ # include <mach/thread_act.h> # include <mach/thread_policy.h> # endif +# ifdef __sun +# include <sys/pset.h> +# endif # include <haproxy/cpuset.h> #endif @@ -250,17 +253,25 @@ void set_thread_cpu_affinity() ha_cpuset_and(&cpu_map.thread[tid], &cpu_map.proc); if (ha_cpuset_count(&cpu_map.thread[tid])) {/* only do this if the thread has a THREAD map */ -# if defined(__APPLE__) +# if defined(__APPLE__) || defined(__sun) /* Note: this API is limited to the first 32/64 CPUs */ unsigned long set = cpu_map.thread[tid].cpuset; int j; while ((j = ffsl(set)) > 0) { +# if defined(__APPLE__) thread_affinity_policy_data_t cpu_set = { j - 1 }; thread_port_t mthread; mthread = pthread_mach_thread_np(ha_pthread[tid]); thread_policy_set(mthread, THREAD_AFFINITY_POLICY, (thread_policy_t)&cpu_set, 1); +# else + psetid_t cpu_set; + pset_create(&cpu_set); + pset_assign(cpu_set, j - 1, NULL); + pset_bind(cpu_set, P_PID, getpid(), NULL); + pset_destroy(cpu_set); +# endif set &= ~(1UL << (j - 1)); } # else -- 2.35.1

