[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