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
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_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

View File

@ -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 \

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->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_command_t *cmd, void *conf)
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_command_t *cmd, void *conf)
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_command_t *cmd, void *conf)
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_command_t *cmd, void *conf)
}
u_long
uint64_t
ngx_get_cpu_affinity(ngx_uint_t n)
{
ngx_core_conf_t *ccf;

View File

@ -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 *cycle, char *sig);
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);

View File

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

View File

@ -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,22 +913,9 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
}
}
#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)

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