]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Only pick CPUs that are part of the existing CPU affinity set when
authorMark Andrews <marka@isc.org>
Tue, 17 Nov 2020 03:59:01 +0000 (14:59 +1100)
committerMark Andrews <marka@isc.org>
Tue, 22 Dec 2020 22:21:29 +0000 (09:21 +1100)
assigning a thread to a CPU.

(cherry picked from commit 698d9285d40c3a7f26d81764bd9d5eaff7748fb2)

lib/isc/pthreads/thread.c

index b17b36d2d670a5645c18a7adec418f9f1997660d..6477aa876f22468796e6ac6278041fa68a31cee6 100644 (file)
@@ -128,40 +128,92 @@ isc_thread_yield(void) {
 #endif /* if defined(HAVE_SCHED_YIELD) */
 }
 
+#if defined(HAVE_CPUSET_SETAFFINITY) || defined(HAVE_PTHREAD_SETAFFINITY_NP)
+#if defined(HAVE_CPUSET_SETAFFINITY)
+static int
+getaffinity(cpuset_t *set) {
+       return (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
+                                  sizeof(*set), set));
+}
+static int
+issetaffinity(int cpu, cpuset_t *set) {
+       return ((cpu >= CPU_SETSIZE) ? -1 : CPU_ISSET(cpu, set) ? 1 : 0);
+}
+static int
+setaffinity(int cpu, cpuset_t *set) {
+       CPU_ZERO(set);
+       CPU_SET(cpu, set);
+       return (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
+                                  sizeof(*set), set));
+}
+#elif defined(__NetBSD__)
+static int
+getaffinity(cpuset_t *set) {
+       return (pthread_getaffinity_np(pthread_self(), cpuset_size(set), set));
+}
+static int
+issetaffinity(int cpu, cpuset_t *set) {
+       return (cpuset_isset(cpu, set));
+}
+static int
+setaffinity(int cpu, cpuset_t *set) {
+       cpuset_zero(set);
+       cpuset_set(cpu, set);
+       return (pthread_setaffinity_np(pthread_self(), cpuset_size(set), set));
+}
+#else /* linux ? */
+static int
+getaffinity(cpu_set_t *set) {
+       return (pthread_getaffinity_np(pthread_self(), sizeof(*set), set));
+}
+static int
+issetaffinity(int cpu, cpu_set_t *set) {
+       return ((cpu >= CPU_SETSIZE) ? -1 : CPU_ISSET(cpu, set) ? 1 : 0);
+}
+static int
+setaffinity(int cpu, cpu_set_t *set) {
+       CPU_ZERO(set);
+       CPU_SET(cpu, set);
+       return (pthread_setaffinity_np(pthread_self(), sizeof(*set), set));
+}
+#endif
+#endif
+
 isc_result_t
 isc_thread_setaffinity(int cpu) {
+#if defined(HAVE_CPUSET_SETAFFINITY) || defined(HAVE_PTHREAD_SETAFFINITY_NP)
+       int cpu_id = -1, cpu_aff_ok_counter = -1, n;
 #if defined(HAVE_CPUSET_SETAFFINITY)
-       cpuset_t cpuset;
-       CPU_ZERO(&cpuset);
-       CPU_SET(cpu, &cpuset);
-       if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
-                              sizeof(cpuset), &cpuset) != 0)
-       {
+       cpuset_t _set, *set = &_set;
+#define cpuset_destroy(x) ((void)0)
+#elif defined(__NetBSD__)
+       cpuset_t *set = cpuset_create();
+       if (set == NULL) {
                return (ISC_R_FAILURE);
        }
-#elif defined(HAVE_PTHREAD_SETAFFINITY_NP)
-#if defined(__NetBSD__)
-       cpuset_t *cset;
-       cset = cpuset_create();
-       if (cset == NULL) {
+#else /* linux? */
+       cpu_set_t _set, *set = &_set;
+#define cpuset_destroy(x) ((void)0)
+#endif
+
+       if (getaffinity(set) != 0) {
+               cpuset_destroy(set);
                return (ISC_R_FAILURE);
        }
-       cpuset_set(cpu, cset);
-       if (pthread_setaffinity_np(pthread_self(), cpuset_size(cset), cset) !=
-           0) {
-               cpuset_destroy(cset);
-               return (ISC_R_FAILURE);
+       while (cpu_aff_ok_counter < cpu) {
+               cpu_id++;
+               if ((n = issetaffinity(cpu_id, set)) > 0) {
+                       cpu_aff_ok_counter++;
+               } else if (n < 0) {
+                       cpuset_destroy(set);
+                       return (ISC_R_FAILURE);
+               }
        }
-       cpuset_destroy(cset);
-#else  /* linux? */
-       cpu_set_t set;
-       CPU_ZERO(&set);
-       CPU_SET(cpu, &set);
-       if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &set) !=
-           0) {
+       if (setaffinity(cpu_id, set) != 0) {
+               cpuset_destroy(set);
                return (ISC_R_FAILURE);
        }
-#endif /* __NetBSD__ */
+       cpuset_destroy(set);
 #elif defined(HAVE_PROCESSOR_BIND)
        if (processor_bind(P_LWPID, P_MYID, cpu, NULL) != 0) {
                return (ISC_R_FAILURE);