# HG changeset patch # User Vladimir Homutov # Date 1455793129 -10800 # Node ID 7296b38f641626f68d8681bf63910cefb2e65d6d # Parent 6812ca9a800247d2428f487d9b4938a2b499b7d8 Core: added support for more than 64 CPUs in worker_cpu_affinity. diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -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]; + + for (i = 0, j = n; /* void */ ; i++) { - if (mask == 0) { - return 0; - } + if (CPU_ISSET(i % CPU_SETSIZE, mask) && j-- == 0) { + break; + } - for (i = 0; /* void */ ; i++) { - if ((mask & ((uint64_t) 1 << (i % 64))) && n-- == 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 --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -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 --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -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 --git a/src/os/unix/ngx_setaffinity.c b/src/os/unix/ngx_setaffinity.c --- a/src/os/unix/ngx_setaffinity.c +++ b/src/os/unix/ngx_setaffinity.c @@ -10,29 +10,20 @@ #if (NGX_HAVE_CPUSET_SETAFFINITY) -#include - 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 --git a/src/os/unix/ngx_setaffinity.h b/src/os/unix/ngx_setaffinity.h --- a/src/os/unix/ngx_setaffinity.h +++ b/src/os/unix/ngx_setaffinity.h @@ -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 + +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 --git a/src/os/win32/ngx_process.h b/src/os/win32/ngx_process.h --- a/src/os/win32/ngx_process.h +++ b/src/os/win32/ngx_process.h @@ -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;