mirror of
https://github.com/nginx/nginx.git
synced 2025-06-29 18:50:39 +08:00
Core: added support for more than 64 CPUs in worker_cpu_affinity.
This commit is contained in:
parent
b5d7d3f024
commit
faa96e82d2
@ -1270,16 +1270,16 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
#if (NGX_HAVE_CPU_AFFINITY)
|
#if (NGX_HAVE_CPU_AFFINITY)
|
||||||
ngx_core_conf_t *ccf = conf;
|
ngx_core_conf_t *ccf = conf;
|
||||||
|
|
||||||
u_char ch;
|
u_char ch, *p;
|
||||||
uint64_t *mask;
|
|
||||||
ngx_str_t *value;
|
ngx_str_t *value;
|
||||||
ngx_uint_t i, n;
|
ngx_uint_t i, n;
|
||||||
|
ngx_cpuset_t *mask;
|
||||||
|
|
||||||
if (ccf->cpu_affinity) {
|
if (ccf->cpu_affinity) {
|
||||||
return "is duplicate";
|
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) {
|
if (mask == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
@ -1299,7 +1299,12 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ccf->cpu_affinity_auto = 1;
|
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;
|
n = 2;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -1308,30 +1313,34 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
for ( /* void */ ; n < cf->args->nelts; n++) {
|
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,
|
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;
|
return NGX_CONF_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
mask[n - 1] = 0;
|
i = 0;
|
||||||
|
CPU_ZERO(&mask[n - 1]);
|
||||||
|
|
||||||
for (i = 0; i < value[n].len; i++) {
|
for (p = value[n].data + value[n].len - 1;
|
||||||
|
p >= value[n].data;
|
||||||
ch = value[n].data[i];
|
p--)
|
||||||
|
{
|
||||||
|
ch = *p;
|
||||||
|
|
||||||
if (ch == ' ') {
|
if (ch == ' ') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mask[n - 1] <<= 1;
|
i++;
|
||||||
|
|
||||||
if (ch == '0') {
|
if (ch == '0') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch == '1') {
|
if (ch == '1') {
|
||||||
mask[n - 1] |= 1;
|
CPU_SET(i - 1, &mask[n - 1]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1353,43 +1362,57 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint64_t
|
ngx_cpuset_t *
|
||||||
ngx_get_cpu_affinity(ngx_uint_t n)
|
ngx_get_cpu_affinity(ngx_uint_t n)
|
||||||
{
|
{
|
||||||
uint64_t mask;
|
#if (NGX_HAVE_CPU_AFFINITY)
|
||||||
ngx_uint_t i;
|
ngx_uint_t i, j;
|
||||||
|
ngx_cpuset_t *mask;
|
||||||
ngx_core_conf_t *ccf;
|
ngx_core_conf_t *ccf;
|
||||||
|
|
||||||
|
static ngx_cpuset_t result;
|
||||||
|
|
||||||
ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
|
ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
|
||||||
ngx_core_module);
|
ngx_core_module);
|
||||||
|
|
||||||
if (ccf->cpu_affinity == NULL) {
|
if (ccf->cpu_affinity == NULL) {
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ccf->cpu_affinity_auto) {
|
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) {
|
for (i = 0, j = n; /* void */ ; i++) {
|
||||||
return 0;
|
|
||||||
|
if (CPU_ISSET(i % CPU_SETSIZE, mask) && j-- == 0) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; /* void */ ; i++) {
|
if (i == CPU_SETSIZE && j == n) {
|
||||||
if ((mask & ((uint64_t) 1 << (i % 64))) && n-- == 0) {
|
/* empty mask */
|
||||||
break;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* void */
|
/* void */
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uint64_t) 1 << (i % 64);
|
CPU_ZERO(&result);
|
||||||
|
CPU_SET(i % CPU_SETSIZE, &result);
|
||||||
|
|
||||||
|
return &result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ccf->cpu_affinity_n > n) {
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ typedef struct {
|
|||||||
|
|
||||||
ngx_uint_t cpu_affinity_auto;
|
ngx_uint_t cpu_affinity_auto;
|
||||||
ngx_uint_t cpu_affinity_n;
|
ngx_uint_t cpu_affinity_n;
|
||||||
uint64_t *cpu_affinity;
|
ngx_cpuset_t *cpu_affinity;
|
||||||
|
|
||||||
char *username;
|
char *username;
|
||||||
ngx_uid_t user;
|
ngx_uid_t user;
|
||||||
@ -121,7 +121,7 @@ ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig);
|
|||||||
void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user);
|
void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user);
|
||||||
char **ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last);
|
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);
|
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,
|
ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
|
||||||
size_t size, void *tag);
|
size_t size, void *tag);
|
||||||
|
|
||||||
|
@ -784,9 +784,9 @@ static void
|
|||||||
ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
|
ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
|
||||||
{
|
{
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
uint64_t cpu_affinity;
|
|
||||||
ngx_int_t n;
|
ngx_int_t n;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
|
ngx_cpuset_t *cpu_affinity;
|
||||||
struct rlimit rlmt;
|
struct rlimit rlmt;
|
||||||
ngx_core_conf_t *ccf;
|
ngx_core_conf_t *ccf;
|
||||||
ngx_listening_t *ls;
|
ngx_listening_t *ls;
|
||||||
|
@ -10,29 +10,20 @@
|
|||||||
|
|
||||||
#if (NGX_HAVE_CPUSET_SETAFFINITY)
|
#if (NGX_HAVE_CPUSET_SETAFFINITY)
|
||||||
|
|
||||||
#include <sys/cpuset.h>
|
|
||||||
|
|
||||||
void
|
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_uint_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < CPU_SETSIZE; i++) {
|
||||||
|
if (CPU_ISSET(i, cpu_affinity)) {
|
||||||
ngx_log_error(NGX_LOG_NOTICE, log, 0,
|
ngx_log_error(NGX_LOG_NOTICE, log, 0,
|
||||||
"cpuset_setaffinity(0x%08Xl)", cpu_affinity);
|
"cpuset_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 (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
|
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,
|
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
||||||
"cpuset_setaffinity() failed");
|
"cpuset_setaffinity() failed");
|
||||||
@ -42,25 +33,18 @@ ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log)
|
|||||||
#elif (NGX_HAVE_SCHED_SETAFFINITY)
|
#elif (NGX_HAVE_SCHED_SETAFFINITY)
|
||||||
|
|
||||||
void
|
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_uint_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < CPU_SETSIZE; i++) {
|
||||||
|
if (CPU_ISSET(i, cpu_affinity)) {
|
||||||
ngx_log_error(NGX_LOG_NOTICE, log, 0,
|
ngx_log_error(NGX_LOG_NOTICE, log, 0,
|
||||||
"sched_setaffinity(0x%08Xl)", cpu_affinity);
|
"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,
|
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
||||||
"sched_setaffinity() failed");
|
"sched_setaffinity() failed");
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,26 @@
|
|||||||
|
|
||||||
#define NGX_HAVE_CPU_AFFINITY 1
|
#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
|
#else
|
||||||
|
|
||||||
#define ngx_setaffinity(cpu_affinity, log)
|
#define ngx_setaffinity(cpu_affinity, log)
|
||||||
|
|
||||||
|
typedef uint64_t ngx_cpuset_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ typedef DWORD ngx_pid_t;
|
|||||||
(sizeof("ngx_cache_manager_mutex_") + NGX_INT32_LEN)
|
(sizeof("ngx_cache_manager_mutex_") + NGX_INT32_LEN)
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint64_t ngx_cpuset_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
ngx_pid_t pid;
|
ngx_pid_t pid;
|
||||||
|
Loading…
Reference in New Issue
Block a user