Mercurial > hg > nginx
comparison src/core/nginx.c @ 6402:7296b38f6416
Core: added support for more than 64 CPUs in worker_cpu_affinity.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Thu, 18 Feb 2016 13:58:49 +0300 |
parents | 50fb3fd79f76 |
children | 0ff7eff48c7e |
comparison
equal
deleted
inserted
replaced
6401:6812ca9a8002 | 6402:7296b38f6416 |
---|---|
1268 ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 1268 ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
1269 { | 1269 { |
1270 #if (NGX_HAVE_CPU_AFFINITY) | 1270 #if (NGX_HAVE_CPU_AFFINITY) |
1271 ngx_core_conf_t *ccf = conf; | 1271 ngx_core_conf_t *ccf = conf; |
1272 | 1272 |
1273 u_char ch; | 1273 u_char ch, *p; |
1274 uint64_t *mask; | |
1275 ngx_str_t *value; | 1274 ngx_str_t *value; |
1276 ngx_uint_t i, n; | 1275 ngx_uint_t i, n; |
1276 ngx_cpuset_t *mask; | |
1277 | 1277 |
1278 if (ccf->cpu_affinity) { | 1278 if (ccf->cpu_affinity) { |
1279 return "is duplicate"; | 1279 return "is duplicate"; |
1280 } | 1280 } |
1281 | 1281 |
1282 mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(uint64_t)); | 1282 mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(ngx_cpuset_t)); |
1283 if (mask == NULL) { | 1283 if (mask == NULL) { |
1284 return NGX_CONF_ERROR; | 1284 return NGX_CONF_ERROR; |
1285 } | 1285 } |
1286 | 1286 |
1287 ccf->cpu_affinity_n = cf->args->nelts - 1; | 1287 ccf->cpu_affinity_n = cf->args->nelts - 1; |
1297 "\"worker_cpu_affinity\" directive"); | 1297 "\"worker_cpu_affinity\" directive"); |
1298 return NGX_CONF_ERROR; | 1298 return NGX_CONF_ERROR; |
1299 } | 1299 } |
1300 | 1300 |
1301 ccf->cpu_affinity_auto = 1; | 1301 ccf->cpu_affinity_auto = 1; |
1302 mask[0] = (uint64_t) -1 >> (64 - ngx_min(64, ngx_ncpu)); | 1302 |
1303 CPU_ZERO(&mask[0]); | |
1304 for (i = 0; i < (ngx_uint_t) ngx_min(ngx_ncpu, CPU_SETSIZE); i++) { | |
1305 CPU_SET(i, &mask[0]); | |
1306 } | |
1307 | |
1303 n = 2; | 1308 n = 2; |
1304 | 1309 |
1305 } else { | 1310 } else { |
1306 n = 1; | 1311 n = 1; |
1307 } | 1312 } |
1308 | 1313 |
1309 for ( /* void */ ; n < cf->args->nelts; n++) { | 1314 for ( /* void */ ; n < cf->args->nelts; n++) { |
1310 | 1315 |
1311 if (value[n].len > 64) { | 1316 if (value[n].len > CPU_SETSIZE) { |
1312 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1317 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1313 "\"worker_cpu_affinity\" supports up to 64 CPUs only"); | 1318 "\"worker_cpu_affinity\" supports up to %d CPUs only", |
1319 CPU_SETSIZE); | |
1314 return NGX_CONF_ERROR; | 1320 return NGX_CONF_ERROR; |
1315 } | 1321 } |
1316 | 1322 |
1317 mask[n - 1] = 0; | 1323 i = 0; |
1318 | 1324 CPU_ZERO(&mask[n - 1]); |
1319 for (i = 0; i < value[n].len; i++) { | 1325 |
1320 | 1326 for (p = value[n].data + value[n].len - 1; |
1321 ch = value[n].data[i]; | 1327 p >= value[n].data; |
1328 p--) | |
1329 { | |
1330 ch = *p; | |
1322 | 1331 |
1323 if (ch == ' ') { | 1332 if (ch == ' ') { |
1324 continue; | 1333 continue; |
1325 } | 1334 } |
1326 | 1335 |
1327 mask[n - 1] <<= 1; | 1336 i++; |
1328 | 1337 |
1329 if (ch == '0') { | 1338 if (ch == '0') { |
1330 continue; | 1339 continue; |
1331 } | 1340 } |
1332 | 1341 |
1333 if (ch == '1') { | 1342 if (ch == '1') { |
1334 mask[n - 1] |= 1; | 1343 CPU_SET(i - 1, &mask[n - 1]); |
1335 continue; | 1344 continue; |
1336 } | 1345 } |
1337 | 1346 |
1338 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 1347 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1339 "invalid character \"%c\" in \"worker_cpu_affinity\"", | 1348 "invalid character \"%c\" in \"worker_cpu_affinity\"", |
1351 | 1360 |
1352 return NGX_CONF_OK; | 1361 return NGX_CONF_OK; |
1353 } | 1362 } |
1354 | 1363 |
1355 | 1364 |
1356 uint64_t | 1365 ngx_cpuset_t * |
1357 ngx_get_cpu_affinity(ngx_uint_t n) | 1366 ngx_get_cpu_affinity(ngx_uint_t n) |
1358 { | 1367 { |
1359 uint64_t mask; | 1368 #if (NGX_HAVE_CPU_AFFINITY) |
1360 ngx_uint_t i; | 1369 ngx_uint_t i, j; |
1370 ngx_cpuset_t *mask; | |
1361 ngx_core_conf_t *ccf; | 1371 ngx_core_conf_t *ccf; |
1372 | |
1373 static ngx_cpuset_t result; | |
1362 | 1374 |
1363 ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, | 1375 ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, |
1364 ngx_core_module); | 1376 ngx_core_module); |
1365 | 1377 |
1366 if (ccf->cpu_affinity == NULL) { | 1378 if (ccf->cpu_affinity == NULL) { |
1367 return 0; | 1379 return NULL; |
1368 } | 1380 } |
1369 | 1381 |
1370 if (ccf->cpu_affinity_auto) { | 1382 if (ccf->cpu_affinity_auto) { |
1371 mask = ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; | 1383 mask = &ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; |
1372 | 1384 |
1373 if (mask == 0) { | 1385 for (i = 0, j = n; /* void */ ; i++) { |
1374 return 0; | 1386 |
1375 } | 1387 if (CPU_ISSET(i % CPU_SETSIZE, mask) && j-- == 0) { |
1376 | |
1377 for (i = 0; /* void */ ; i++) { | |
1378 if ((mask & ((uint64_t) 1 << (i % 64))) && n-- == 0) { | |
1379 break; | 1388 break; |
1380 } | 1389 } |
1381 | 1390 |
1391 if (i == CPU_SETSIZE && j == n) { | |
1392 /* empty mask */ | |
1393 return NULL; | |
1394 } | |
1395 | |
1382 /* void */ | 1396 /* void */ |
1383 } | 1397 } |
1384 | 1398 |
1385 return (uint64_t) 1 << (i % 64); | 1399 CPU_ZERO(&result); |
1400 CPU_SET(i % CPU_SETSIZE, &result); | |
1401 | |
1402 return &result; | |
1386 } | 1403 } |
1387 | 1404 |
1388 if (ccf->cpu_affinity_n > n) { | 1405 if (ccf->cpu_affinity_n > n) { |
1389 return ccf->cpu_affinity[n]; | 1406 return &ccf->cpu_affinity[n]; |
1390 } | 1407 } |
1391 | 1408 |
1392 return ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; | 1409 return &ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; |
1410 | |
1411 #else | |
1412 | |
1413 return NULL; | |
1414 | |
1415 #endif | |
1393 } | 1416 } |
1394 | 1417 |
1395 | 1418 |
1396 static char * | 1419 static char * |
1397 ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 1420 ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |