worker_cpu_affinity: cleaned up Linux implementation, added FreeBSD support.

This commit is contained in:
Ruslan Ermilov 2012-03-21 13:58:51 +00:00
parent d4b1e5f58b
commit fbd32d4d19
9 changed files with 119 additions and 28 deletions

View File

@ -134,3 +134,11 @@ END
exit 1 exit 1
fi fi
fi fi
# cpuset_setaffinity()
if [ $version -ge 701000 ]; then
echo " + cpuset_setaffinity() found"
have=NGX_HAVE_CPUSET_SETAFFINITY . auto/have
fi

View File

@ -128,8 +128,9 @@ ngx_feature_run=no
ngx_feature_incs="#include <sched.h>" ngx_feature_incs="#include <sched.h>"
ngx_feature_path= ngx_feature_path=
ngx_feature_libs= ngx_feature_libs=
ngx_feature_test="long mask = 0; ngx_feature_test="cpu_set_t mask;
sched_setaffinity(0, 32, (cpu_set_t *) &mask)" CPU_ZERO(&mask);
sched_setaffinity(0, sizeof(cpu_set_t), &mask)"
. auto/feature . auto/feature

View File

@ -145,6 +145,7 @@ UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \
src/os/unix/ngx_channel.h \ src/os/unix/ngx_channel.h \
src/os/unix/ngx_shmem.h \ src/os/unix/ngx_shmem.h \
src/os/unix/ngx_process.h \ src/os/unix/ngx_process.h \
src/os/unix/ngx_setaffinity.h \
src/os/unix/ngx_setproctitle.h \ src/os/unix/ngx_setproctitle.h \
src/os/unix/ngx_atomic.h \ src/os/unix/ngx_atomic.h \
src/os/unix/ngx_gcc_atomic_x86.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_shmem.c \
src/os/unix/ngx_process.c \ src/os/unix/ngx_process.c \
src/os/unix/ngx_daemon.c \ src/os/unix/ngx_daemon.c \
src/os/unix/ngx_setaffinity.c \
src/os/unix/ngx_setproctitle.c \ src/os/unix/ngx_setproctitle.c \
src/os/unix/ngx_posix_init.c \ src/os/unix/ngx_posix_init.c \
src/os/unix/ngx_user.c \ src/os/unix/ngx_user.c \

View File

@ -983,15 +983,15 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
ngx_conf_init_value(ccf->worker_processes, 1); ngx_conf_init_value(ccf->worker_processes, 1);
ngx_conf_init_value(ccf->debug_points, 0); ngx_conf_init_value(ccf->debug_points, 0);
#if (NGX_HAVE_SCHED_SETAFFINITY) #if (NGX_HAVE_CPU_AFFINITY)
if (ccf->cpu_affinity_n if (ccf->cpu_affinity_n
&& ccf->cpu_affinity_n != 1 && ccf->cpu_affinity_n != 1
&& ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes) && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
{ {
ngx_log_error(NGX_LOG_WARN, cycle->log, 0, ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
"number of the \"worker_processes\" is not equal to " "the number of \"worker_processes\" is not equal to "
"the number of the \"worker_cpu_affinity\" mask, " "the number of \"worker_cpu_affinity\" masks, "
"using last mask for remaining worker processes"); "using last mask for remaining worker processes");
} }
@ -1242,11 +1242,11 @@ ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char * static char *
ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 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; ngx_core_conf_t *ccf = conf;
u_char ch; u_char ch;
u_long *mask; uint64_t *mask;
ngx_str_t *value; ngx_str_t *value;
ngx_uint_t i, n; ngx_uint_t i, n;
@ -1254,7 +1254,7 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return "is duplicate"; 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) { if (mask == NULL) {
return NGX_CONF_ERROR; return NGX_CONF_ERROR;
} }
@ -1266,9 +1266,9 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
for (n = 1; n < cf->args->nelts; n++) { 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, 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; return NGX_CONF_ERROR;
} }
@ -1311,7 +1311,7 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
} }
u_long uint64_t
ngx_get_cpu_affinity(ngx_uint_t n) ngx_get_cpu_affinity(ngx_uint_t n)
{ {
ngx_core_conf_t *ccf; ngx_core_conf_t *ccf;

View File

@ -86,7 +86,7 @@ typedef struct {
int priority; int priority;
ngx_uint_t cpu_affinity_n; ngx_uint_t cpu_affinity_n;
u_long *cpu_affinity; uint64_t *cpu_affinity;
char *username; char *username;
ngx_uid_t user; ngx_uid_t user;
@ -124,7 +124,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);
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, 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);

View File

@ -9,6 +9,7 @@
#define _NGX_PROCESS_H_INCLUDED_ #define _NGX_PROCESS_H_INCLUDED_
#include <ngx_setaffinity.h>
#include <ngx_setproctitle.h> #include <ngx_setproctitle.h>

View File

@ -62,7 +62,7 @@ ngx_int_t ngx_threads_n;
#endif #endif
u_long cpu_affinity; uint64_t cpu_affinity;
static u_char master_process[] = "master process"; static u_char master_process[] = "master process";
@ -913,23 +913,10 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
} }
} }
#if (NGX_HAVE_SCHED_SETAFFINITY)
if (cpu_affinity) { if (cpu_affinity) {
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, ngx_setaffinity(cpu_affinity, cycle->log);
"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);
}
} }
#endif
#if (NGX_HAVE_PR_SET_DUMPABLE) #if (NGX_HAVE_PR_SET_DUMPABLE)
/* allow coredump after setuid() in Linux 2.4.x */ /* allow coredump after setuid() in Linux 2.4.x */

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) Nginx, Inc.
*/
#include <ngx_config.h>
#include <ngx_core.h>
#if (NGX_HAVE_CPUSET_SETAFFINITY)
#include <sys/cpuset.h>
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

View File

@ -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_ */