[nginx] Core: added support for more than 64 CPUs in worker_cpu_...

Vladimir Homutov vl at nginx.com
Thu Feb 18 11:11:18 UTC 2016


details:   http://hg.nginx.org/nginx/rev/7296b38f6416
branches:  
changeset: 6402:7296b38f6416
user:      Vladimir Homutov <vl at nginx.com>
date:      Thu Feb 18 13:58:49 2016 +0300
description:
Core: added support for more than 64 CPUs in worker_cpu_affinity.

diffstat:

 src/core/nginx.c                |  73 ++++++++++++++++++++++++++--------------
 src/core/ngx_cycle.h            |   4 +-
 src/os/unix/ngx_process_cycle.c |   2 +-
 src/os/unix/ngx_setaffinity.c   |  46 ++++++++-----------------
 src/os/unix/ngx_setaffinity.h   |  16 ++++++++-
 src/os/win32/ngx_process.h      |   3 +
 6 files changed, 84 insertions(+), 60 deletions(-)

diffs (304 lines):

diff -r 6812ca9a8002 -r 7296b38f6416 src/core/nginx.c
--- a/src/core/nginx.c	Tue Feb 16 17:49:14 2016 +0300
+++ b/src/core/nginx.c	Thu Feb 18 13:58:49 2016 +0300
@@ -1270,16 +1270,16 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx
 #if (NGX_HAVE_CPU_AFFINITY)
     ngx_core_conf_t  *ccf = conf;
 
-    u_char            ch;
-    uint64_t         *mask;
+    u_char            ch, *p;
     ngx_str_t        *value;
     ngx_uint_t        i, n;
+    ngx_cpuset_t     *mask;
 
     if (ccf->cpu_affinity) {
         return "is duplicate";
     }
 
-    mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(uint64_t));
+    mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(ngx_cpuset_t));
     if (mask == NULL) {
         return NGX_CONF_ERROR;
     }
@@ -1299,7 +1299,12 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx
         }
 
         ccf->cpu_affinity_auto = 1;
-        mask[0] = (uint64_t) -1 >> (64 - ngx_min(64, ngx_ncpu));
+
+        CPU_ZERO(&mask[0]);
+        for (i = 0; i < (ngx_uint_t) ngx_min(ngx_ncpu, CPU_SETSIZE); i++) {
+            CPU_SET(i, &mask[0]);
+        }
+
         n = 2;
 
     } else {
@@ -1308,30 +1313,34 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx
 
     for ( /* void */ ; n < cf->args->nelts; n++) {
 
-        if (value[n].len > 64) {
+        if (value[n].len > CPU_SETSIZE) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                         "\"worker_cpu_affinity\" supports up to 64 CPUs only");
+                         "\"worker_cpu_affinity\" supports up to %d CPUs only",
+                         CPU_SETSIZE);
             return NGX_CONF_ERROR;
         }
 
-        mask[n - 1] = 0;
+        i = 0;
+        CPU_ZERO(&mask[n - 1]);
 
-        for (i = 0; i < value[n].len; i++) {
-
-            ch = value[n].data[i];
+        for (p = value[n].data + value[n].len - 1;
+             p >= value[n].data;
+             p--)
+        {
+            ch = *p;
 
             if (ch == ' ') {
                 continue;
             }
 
-            mask[n - 1] <<= 1;
+            i++;
 
             if (ch == '0') {
                 continue;
             }
 
             if (ch == '1') {
-                mask[n - 1] |= 1;
+                CPU_SET(i - 1, &mask[n - 1]);
                 continue;
             }
 
@@ -1353,43 +1362,57 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx
 }
 
 
-uint64_t
+ngx_cpuset_t *
 ngx_get_cpu_affinity(ngx_uint_t n)
 {
-    uint64_t          mask;
-    ngx_uint_t        i;
+#if (NGX_HAVE_CPU_AFFINITY)
+    ngx_uint_t        i, j;
+    ngx_cpuset_t     *mask;
     ngx_core_conf_t  *ccf;
 
+    static ngx_cpuset_t  result;
+
     ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
                                            ngx_core_module);
 
     if (ccf->cpu_affinity == NULL) {
-        return 0;
+        return NULL;
     }
 
     if (ccf->cpu_affinity_auto) {
-        mask = ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
+        mask = &ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
 
-        if (mask == 0) {
-            return 0;
-        }
+        for (i = 0, j = n; /* void */ ; i++) {
 
-        for (i = 0; /* void */ ; i++) {
-            if ((mask & ((uint64_t) 1 << (i % 64))) && n-- == 0) {
+            if (CPU_ISSET(i % CPU_SETSIZE, mask) && j-- == 0) {
                 break;
             }
 
+            if (i == CPU_SETSIZE && j == n) {
+                /* empty mask */
+                return NULL;
+            }
+
             /* void */
         }
 
-        return (uint64_t) 1 << (i % 64);
+        CPU_ZERO(&result);
+        CPU_SET(i % CPU_SETSIZE, &result);
+
+        return &result;
     }
 
     if (ccf->cpu_affinity_n > n) {
-        return ccf->cpu_affinity[n];
+        return &ccf->cpu_affinity[n];
     }
 
-    return ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
+    return &ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
+
+#else
+
+    return NULL;
+
+#endif
 }
 
 
diff -r 6812ca9a8002 -r 7296b38f6416 src/core/ngx_cycle.h
--- a/src/core/ngx_cycle.h	Tue Feb 16 17:49:14 2016 +0300
+++ b/src/core/ngx_cycle.h	Thu Feb 18 13:58:49 2016 +0300
@@ -94,7 +94,7 @@ typedef struct {
 
      ngx_uint_t               cpu_affinity_auto;
      ngx_uint_t               cpu_affinity_n;
-     uint64_t                *cpu_affinity;
+     ngx_cpuset_t            *cpu_affinity;
 
      char                    *username;
      ngx_uid_t                user;
@@ -121,7 +121,7 @@ ngx_int_t ngx_signal_process(ngx_cycle_t
 void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user);
 char **ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last);
 ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
-uint64_t ngx_get_cpu_affinity(ngx_uint_t n);
+ngx_cpuset_t *ngx_get_cpu_affinity(ngx_uint_t n);
 ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
     size_t size, void *tag);
 
diff -r 6812ca9a8002 -r 7296b38f6416 src/os/unix/ngx_process_cycle.c
--- a/src/os/unix/ngx_process_cycle.c	Tue Feb 16 17:49:14 2016 +0300
+++ b/src/os/unix/ngx_process_cycle.c	Thu Feb 18 13:58:49 2016 +0300
@@ -784,9 +784,9 @@ static void
 ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
 {
     sigset_t          set;
-    uint64_t          cpu_affinity;
     ngx_int_t         n;
     ngx_uint_t        i;
+    ngx_cpuset_t     *cpu_affinity;
     struct rlimit     rlmt;
     ngx_core_conf_t  *ccf;
     ngx_listening_t  *ls;
diff -r 6812ca9a8002 -r 7296b38f6416 src/os/unix/ngx_setaffinity.c
--- a/src/os/unix/ngx_setaffinity.c	Tue Feb 16 17:49:14 2016 +0300
+++ b/src/os/unix/ngx_setaffinity.c	Thu Feb 18 13:58:49 2016 +0300
@@ -10,29 +10,20 @@
 
 #if (NGX_HAVE_CPUSET_SETAFFINITY)
 
-#include <sys/cpuset.h>
-
 void
-ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log)
+ngx_setaffinity(ngx_cpuset_t *cpu_affinity, ngx_log_t *log)
 {
-    cpuset_t    mask;
     ngx_uint_t  i;
 
-    ngx_log_error(NGX_LOG_NOTICE, log, 0,
-                  "cpuset_setaffinity(0x%08Xl)", cpu_affinity);
-
-    CPU_ZERO(&mask);
-    i = 0;
-    do {
-        if (cpu_affinity & 1) {
-            CPU_SET(i, &mask);
+    for (i = 0; i < CPU_SETSIZE; i++) {
+        if (CPU_ISSET(i, cpu_affinity)) {
+            ngx_log_error(NGX_LOG_NOTICE, log, 0,
+                          "cpuset_setaffinity(): using cpu #%ui", i);
         }
-        i++;
-        cpu_affinity >>= 1;
-    } while (cpu_affinity);
+    }
 
     if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
-                           sizeof(cpuset_t), &mask) == -1)
+                           sizeof(cpuset_t), cpu_affinity) == -1)
     {
         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                       "cpuset_setaffinity() failed");
@@ -42,25 +33,18 @@ ngx_setaffinity(uint64_t cpu_affinity, n
 #elif (NGX_HAVE_SCHED_SETAFFINITY)
 
 void
-ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log)
+ngx_setaffinity(ngx_cpuset_t *cpu_affinity, ngx_log_t *log)
 {
-    cpu_set_t   mask;
     ngx_uint_t  i;
 
-    ngx_log_error(NGX_LOG_NOTICE, log, 0,
-                  "sched_setaffinity(0x%08Xl)", cpu_affinity);
+    for (i = 0; i < CPU_SETSIZE; i++) {
+        if (CPU_ISSET(i, cpu_affinity)) {
+            ngx_log_error(NGX_LOG_NOTICE, log, 0,
+                          "sched_setaffinity(): using cpu #%ui", i);
+        }
+    }
 
-    CPU_ZERO(&mask);
-    i = 0;
-    do {
-        if (cpu_affinity & 1) {
-            CPU_SET(i, &mask);
-        }
-        i++;
-        cpu_affinity >>= 1;
-    } while (cpu_affinity);
-
-    if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
+    if (sched_setaffinity(0, sizeof(cpu_set_t), cpu_affinity) == -1) {
         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                       "sched_setaffinity() failed");
     }
diff -r 6812ca9a8002 -r 7296b38f6416 src/os/unix/ngx_setaffinity.h
--- a/src/os/unix/ngx_setaffinity.h	Tue Feb 16 17:49:14 2016 +0300
+++ b/src/os/unix/ngx_setaffinity.h	Thu Feb 18 13:58:49 2016 +0300
@@ -11,12 +11,26 @@
 
 #define NGX_HAVE_CPU_AFFINITY 1
 
-void ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log);
+#if (NGX_HAVE_SCHED_SETAFFINITY)
+
+typedef cpu_set_t  ngx_cpuset_t;
+
+#elif (NGX_HAVE_CPUSET_SETAFFINITY)
+
+#include <sys/cpuset.h>
+
+typedef cpuset_t  ngx_cpuset_t;
+
+#endif
+
+void ngx_setaffinity(ngx_cpuset_t *cpu_affinity, ngx_log_t *log);
 
 #else
 
 #define ngx_setaffinity(cpu_affinity, log)
 
+typedef uint64_t  ngx_cpuset_t;
+
 #endif
 
 
diff -r 6812ca9a8002 -r 7296b38f6416 src/os/win32/ngx_process.h
--- a/src/os/win32/ngx_process.h	Tue Feb 16 17:49:14 2016 +0300
+++ b/src/os/win32/ngx_process.h	Thu Feb 18 13:58:49 2016 +0300
@@ -21,6 +21,9 @@ typedef DWORD               ngx_pid_t;
     (sizeof("ngx_cache_manager_mutex_") + NGX_INT32_LEN)
 
 
+typedef uint64_t            ngx_cpuset_t;
+
+
 typedef struct {
     HANDLE                  handle;
     ngx_pid_t               pid;



More information about the nginx-devel mailing list