comparison src/core/nginx.c @ 6335:96c4297375bc

Core: worker_cpu_affinity auto. If enabled, workers are bound to available CPUs, each worker to once CPU in order. If there are more workers than available CPUs, remaining are bound in a loop, starting again from the first available CPU. The optional mask parameter defines which CPUs are available for automatic binding. In collaboration with Vladimir Homutov.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 11 Jan 2016 19:23:17 +0300
parents 7ac57369036c
children 0f203a2af17c
comparison
equal deleted inserted replaced
6334:b31928ca3870 6335:96c4297375bc
959 * set by ngx_pcalloc() 959 * set by ngx_pcalloc()
960 * 960 *
961 * ccf->pid = NULL; 961 * ccf->pid = NULL;
962 * ccf->oldpid = NULL; 962 * ccf->oldpid = NULL;
963 * ccf->priority = 0; 963 * ccf->priority = 0;
964 * ccf->cpu_affinity_auto = 0;
964 * ccf->cpu_affinity_n = 0; 965 * ccf->cpu_affinity_n = 0;
965 * ccf->cpu_affinity = NULL; 966 * ccf->cpu_affinity = NULL;
966 */ 967 */
967 968
968 ccf->daemon = NGX_CONF_UNSET; 969 ccf->daemon = NGX_CONF_UNSET;
1000 ngx_conf_init_value(ccf->worker_processes, 1); 1001 ngx_conf_init_value(ccf->worker_processes, 1);
1001 ngx_conf_init_value(ccf->debug_points, 0); 1002 ngx_conf_init_value(ccf->debug_points, 0);
1002 1003
1003 #if (NGX_HAVE_CPU_AFFINITY) 1004 #if (NGX_HAVE_CPU_AFFINITY)
1004 1005
1005 if (ccf->cpu_affinity_n 1006 if (!ccf->cpu_affinity_auto
1007 && ccf->cpu_affinity_n
1006 && ccf->cpu_affinity_n != 1 1008 && ccf->cpu_affinity_n != 1
1007 && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes) 1009 && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
1008 { 1010 {
1009 ngx_log_error(NGX_LOG_WARN, cycle->log, 0, 1011 ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
1010 "the number of \"worker_processes\" is not equal to " 1012 "the number of \"worker_processes\" is not equal to "
1271 ccf->cpu_affinity_n = cf->args->nelts - 1; 1273 ccf->cpu_affinity_n = cf->args->nelts - 1;
1272 ccf->cpu_affinity = mask; 1274 ccf->cpu_affinity = mask;
1273 1275
1274 value = cf->args->elts; 1276 value = cf->args->elts;
1275 1277
1276 for (n = 1; n < cf->args->nelts; n++) { 1278 if (ngx_strcmp(value[1].data, "auto") == 0) {
1279
1280 if (cf->args->nelts > 3) {
1281 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1282 "invalid number of arguments in "
1283 "\"worker_cpu_affinity\" directive");
1284 return NGX_CONF_ERROR;
1285 }
1286
1287 ccf->cpu_affinity_auto = 1;
1288 mask[0] = (uint64_t) -1 >> (64 - ngx_min(64, ngx_ncpu));
1289 n = 2;
1290
1291 } else {
1292 n = 1;
1293 }
1294
1295 for ( /* void */ ; n < cf->args->nelts; n++) {
1277 1296
1278 if (value[n].len > 64) { 1297 if (value[n].len > 64) {
1279 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 1298 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1280 "\"worker_cpu_affinity\" supports up to 64 CPUs only"); 1299 "\"worker_cpu_affinity\" supports up to 64 CPUs only");
1281 return NGX_CONF_ERROR; 1300 return NGX_CONF_ERROR;
1321 1340
1322 1341
1323 uint64_t 1342 uint64_t
1324 ngx_get_cpu_affinity(ngx_uint_t n) 1343 ngx_get_cpu_affinity(ngx_uint_t n)
1325 { 1344 {
1345 uint64_t mask;
1346 ngx_uint_t i;
1326 ngx_core_conf_t *ccf; 1347 ngx_core_conf_t *ccf;
1327 1348
1328 ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, 1349 ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
1329 ngx_core_module); 1350 ngx_core_module);
1330 1351
1331 if (ccf->cpu_affinity == NULL) { 1352 if (ccf->cpu_affinity == NULL) {
1332 return 0; 1353 return 0;
1354 }
1355
1356 if (ccf->cpu_affinity_auto) {
1357 mask = ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
1358
1359 if (mask == 0) {
1360 return 0;
1361 }
1362
1363 for (i = 0; /* void */ ; i++) {
1364 if ((mask & ((uint64_t) 1 << (i % 64))) && n-- == 0) {
1365 break;
1366 }
1367
1368 /* void */
1369 }
1370
1371 return (uint64_t) 1 << (i % 64);
1333 } 1372 }
1334 1373
1335 if (ccf->cpu_affinity_n > n) { 1374 if (ccf->cpu_affinity_n > n) {
1336 return ccf->cpu_affinity[n]; 1375 return ccf->cpu_affinity[n];
1337 } 1376 }