# HG changeset patch # User Ruslan Ermilov # Date 1332338331 0 # Node ID f31162fefe01e02a4c68bb3bc635d8aea366c786 # Parent 4c1e6cef1453541608921855c96509e7dac88dbd worker_cpu_affinity: cleaned up Linux implementation, added FreeBSD support. diff --git a/auto/os/freebsd b/auto/os/freebsd --- a/auto/os/freebsd +++ b/auto/os/freebsd @@ -134,3 +134,11 @@ END exit 1 fi fi + + +# cpuset_setaffinity() + +if [ $version -ge 701000 ]; then + echo " + cpuset_setaffinity() found" + have=NGX_HAVE_CPUSET_SETAFFINITY . auto/have +fi diff --git a/auto/os/linux b/auto/os/linux --- a/auto/os/linux +++ b/auto/os/linux @@ -128,8 +128,9 @@ ngx_feature_run=no ngx_feature_incs="#include " ngx_feature_path= ngx_feature_libs= -ngx_feature_test="long mask = 0; - sched_setaffinity(0, 32, (cpu_set_t *) &mask)" +ngx_feature_test="cpu_set_t mask; + CPU_ZERO(&mask); + sched_setaffinity(0, sizeof(cpu_set_t), &mask)" . auto/feature diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -145,6 +145,7 @@ UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \ src/os/unix/ngx_channel.h \ src/os/unix/ngx_shmem.h \ src/os/unix/ngx_process.h \ + src/os/unix/ngx_setaffinity.h \ src/os/unix/ngx_setproctitle.h \ src/os/unix/ngx_atomic.h \ src/os/unix/ngx_gcc_atomic_x86.h \ @@ -179,6 +180,7 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/unix/ngx_shmem.c \ src/os/unix/ngx_process.c \ src/os/unix/ngx_daemon.c \ + src/os/unix/ngx_setaffinity.c \ src/os/unix/ngx_setproctitle.c \ src/os/unix/ngx_posix_init.c \ src/os/unix/ngx_user.c \ diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -983,15 +983,15 @@ ngx_core_module_init_conf(ngx_cycle_t *c ngx_conf_init_value(ccf->worker_processes, 1); ngx_conf_init_value(ccf->debug_points, 0); -#if (NGX_HAVE_SCHED_SETAFFINITY) +#if (NGX_HAVE_CPU_AFFINITY) if (ccf->cpu_affinity_n && ccf->cpu_affinity_n != 1 && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes) { ngx_log_error(NGX_LOG_WARN, cycle->log, 0, - "number of the \"worker_processes\" is not equal to " - "the number of the \"worker_cpu_affinity\" mask, " + "the number of \"worker_processes\" is not equal to " + "the number of \"worker_cpu_affinity\" masks, " "using last mask for remaining worker processes"); } @@ -1242,11 +1242,11 @@ ngx_set_priority(ngx_conf_t *cf, ngx_com static char * ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { -#if (NGX_HAVE_SCHED_SETAFFINITY) +#if (NGX_HAVE_CPU_AFFINITY) ngx_core_conf_t *ccf = conf; u_char ch; - u_long *mask; + uint64_t *mask; ngx_str_t *value; ngx_uint_t i, n; @@ -1254,7 +1254,7 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx return "is duplicate"; } - mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(long)); + mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(uint64_t)); if (mask == NULL) { return NGX_CONF_ERROR; } @@ -1266,9 +1266,9 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx for (n = 1; n < cf->args->nelts; n++) { - if (value[n].len > 32) { + if (value[n].len > 64) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"worker_cpu_affinity\" supports up to 32 CPU only"); + "\"worker_cpu_affinity\" supports up to 64 CPUs only"); return NGX_CONF_ERROR; } @@ -1311,7 +1311,7 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx } -u_long +uint64_t ngx_get_cpu_affinity(ngx_uint_t n) { ngx_core_conf_t *ccf; 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 @@ -86,7 +86,7 @@ typedef struct { int priority; ngx_uint_t cpu_affinity_n; - u_long *cpu_affinity; + uint64_t *cpu_affinity; char *username; ngx_uid_t user; @@ -124,7 +124,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); -u_long ngx_get_cpu_affinity(ngx_uint_t n); +uint64_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.h b/src/os/unix/ngx_process.h --- a/src/os/unix/ngx_process.h +++ b/src/os/unix/ngx_process.h @@ -9,6 +9,7 @@ #define _NGX_PROCESS_H_INCLUDED_ +#include #include 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 @@ -62,7 +62,7 @@ ngx_int_t ngx_threads_n; #endif -u_long cpu_affinity; +uint64_t cpu_affinity; static u_char master_process[] = "master process"; @@ -913,23 +913,10 @@ ngx_worker_process_init(ngx_cycle_t *cyc } } -#if (NGX_HAVE_SCHED_SETAFFINITY) - if (cpu_affinity) { - ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, - "sched_setaffinity(0x%08Xl)", cpu_affinity); - - if (sched_setaffinity(0, sizeof(cpu_affinity), - (cpu_set_t *) &cpu_affinity) - == -1) - { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "sched_setaffinity(0x%08Xl) failed", cpu_affinity); - } + ngx_setaffinity(cpu_affinity, cycle->log); } -#endif - #if (NGX_HAVE_PR_SET_DUMPABLE) /* allow coredump after setuid() in Linux 2.4.x */ diff --git a/src/os/unix/ngx_setaffinity.c b/src/os/unix/ngx_setaffinity.c new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_setaffinity.c @@ -0,0 +1,69 @@ + +/* + * Copyright (C) Nginx, Inc. + */ + + +#include +#include + + +#if (NGX_HAVE_CPUSET_SETAFFINITY) + +#include + +void +ngx_setaffinity(uint64_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); + } + i++; + cpu_affinity >>= 1; + } while (cpu_affinity); + + if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, + sizeof(cpuset_t), &mask) == -1) + { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + "cpuset_setaffinity() failed"); + } +} + +#elif (NGX_HAVE_SCHED_SETAFFINITY) + +void +ngx_setaffinity(uint64_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); + + 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) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + "sched_setaffinity() failed"); + } +} + +#endif diff --git a/src/os/unix/ngx_setaffinity.h b/src/os/unix/ngx_setaffinity.h new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_setaffinity.h @@ -0,0 +1,23 @@ + +/* + * Copyright (C) Nginx, Inc. + */ + +#ifndef _NGX_SETAFFINITY_H_INCLUDED_ +#define _NGX_SETAFFINITY_H_INCLUDED_ + + +#if (NGX_HAVE_SCHED_SETAFFINITY || NGX_HAVE_CPUSET_SETAFFINITY) + +#define NGX_HAVE_CPU_AFFINITY 1 + +void ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log); + +#else + +#define ngx_setaffinity(cpu_affinity, log) + +#endif + + +#endif /* _NGX_SETAFFINITY_H_INCLUDED_ */