MINOR: config: make MAX_PROCS configurable at build time

For some embedded systems, it's pointless to have 32- or even 64- large
arrays of processes when it's known that much fewer processes will be
used in the worst case. Let's introduce this MAX_PROCS define which
contains the highest number of processes allowed to run at once. It
still defaults to LONGBITS but may be lowered.
This commit is contained in:
Willy Tarreau 2019-02-07 10:39:36 +01:00
parent 980855bd95
commit ff9c9140f4
9 changed files with 32 additions and 14 deletions

View File

@ -22,6 +22,14 @@
#ifndef _COMMON_DEFAULTS_H
#define _COMMON_DEFAULTS_H
/* MAX_PROCS defines the highest limit for the global "nbproc" value. It
* defaults to the number of bits in a long integer but may be lowered to save
* resources on embedded systems.
*/
#ifndef MAX_PROCS
#define MAX_PROCS LONGBITS
#endif
/*
* BUFSIZE defines the size of a read and write buffer. It is the maximum
* amount of bytes which can be stored by the proxy for each stream. However,

View File

@ -173,8 +173,8 @@ struct global {
struct vars vars; /* list of variables for the process scope. */
#ifdef USE_CPU_AFFINITY
struct {
unsigned long proc[LONGBITS]; /* list of CPU masks for the 32/64 first processes */
unsigned long thread[LONGBITS][MAX_THREADS]; /* list of CPU masks for the 32/64 first threads per process */
unsigned long proc[MAX_PROCS]; /* list of CPU masks for the 32/64 first processes */
unsigned long thread[MAX_PROCS][MAX_THREADS]; /* list of CPU masks for the 32/64 first threads per process */
} cpu_map;
#endif
};

View File

@ -166,7 +166,7 @@ struct bind_conf {
int is_ssl; /* SSL is required for these listeners */
int generate_certs; /* 1 if generate-certificates option is set, else 0 */
unsigned long bind_proc; /* bitmask of processes allowed to use these listeners */
unsigned long bind_thread[LONGBITS]; /* bitmask of threads (per processes) allowed to use these listeners */
unsigned long bind_thread[MAX_PROCS]; /* bitmask of threads (per processes) allowed to use these listeners */
struct { /* UNIX socket permissions */
uid_t uid; /* -1 to leave unchanged */
gid_t gid; /* -1 to leave unchanged */

View File

@ -490,9 +490,9 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
}
global.nbproc = atol(args[1]);
all_proc_mask = nbits(global.nbproc);
if (global.nbproc < 1 || global.nbproc > LONGBITS) {
if (global.nbproc < 1 || global.nbproc > MAX_PROCS) {
ha_alert("parsing [%s:%d] : '%s' must be between 1 and %d (was %d).\n",
file, linenum, args[0], LONGBITS, global.nbproc);
file, linenum, args[0], MAX_PROCS, global.nbproc);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
@ -942,7 +942,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
ha_alert("parsing [%s:%d] : %s expects a process number "
" ('all', 'odd', 'even', a number from 1 to %d or a range), "
" followed by a list of CPU ranges with numbers from 0 to %d.\n",
file, linenum, args[0], LONGBITS, LONGBITS - 1);
file, linenum, args[0], MAX_PROCS, LONGBITS - 1);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
@ -950,7 +950,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
if ((slash = strchr(args[1], '/')) != NULL)
*slash = 0;
if (parse_process_number(args[1], &proc, LONGBITS, &autoinc, &errmsg)) {
if (parse_process_number(args[1], &proc, MAX_PROCS, &autoinc, &errmsg)) {
ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
@ -989,7 +989,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
goto out;
}
for (i = n = 0; i < LONGBITS; i++) {
for (i = n = 0; i < MAX_PROCS; i++) {
/* No mapping for this process */
if (!(proc & (1UL << i)))
continue;

View File

@ -922,7 +922,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
set = 0;
break;
}
if (parse_process_number(args[cur_arg], &set, LONGBITS, NULL, &errmsg)) {
if (parse_process_number(args[cur_arg], &set, MAX_PROCS, NULL, &errmsg)) {
ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;

View File

@ -2296,7 +2296,7 @@ int check_config_validity()
mask >>= global.nbthread;
}
for (nbproc = 0; nbproc < LONGBITS; nbproc++) {
for (nbproc = 0; nbproc < MAX_PROCS; nbproc++) {
if (!bind_conf->bind_proc || (bind_conf->bind_proc & (1UL << nbproc)))
bind_conf->bind_thread[nbproc] = new_mask;
}

View File

@ -359,7 +359,7 @@ static int stats_parse_global(char **args, int section_type, struct proxy *curpx
set = 0;
break;
}
if (parse_process_number(args[cur_arg], &set, LONGBITS, NULL, err)) {
if (parse_process_number(args[cur_arg], &set, MAX_PROCS, NULL, err)) {
memprintf(err, "'%s %s' : %s", args[0], args[1], *err);
return -1;
}

View File

@ -2739,6 +2739,16 @@ int main(int argc, char **argv)
setvbuf(stdout, NULL, _IONBF, 0);
/* this can only safely be done here, though it's optimized away by
* the compiler.
*/
if (MAX_PROCS < 1 || MAX_PROCS > LONGBITS) {
ha_alert("MAX_PROCS value must be between 1 and %d inclusive; "
"HAProxy was built with value %d, please fix it and rebuild.\n",
LONGBITS, MAX_PROCS);
exit(1);
}
/* process all initcalls in order of potential dependency */
RUN_INITCALLS(STG_PREPARE);
RUN_INITCALLS(STG_LOCK);
@ -3059,7 +3069,7 @@ int main(int argc, char **argv)
#ifdef USE_CPU_AFFINITY
if (proc < global.nbproc && /* child */
proc < LONGBITS && /* only the first 32/64 processes may be pinned */
proc < MAX_PROCS && /* only the first 32/64 processes may be pinned */
global.cpu_map.proc[proc]) /* only do this if the process has a CPU map */
#ifdef __FreeBSD__
{

View File

@ -962,7 +962,7 @@ static int bind_parse_process(char **args, int cur_arg, struct proxy *px, struct
if ((slash = strchr(args[cur_arg + 1], '/')) != NULL)
*slash = 0;
if (parse_process_number(args[cur_arg + 1], &proc, LONGBITS, NULL, err)) {
if (parse_process_number(args[cur_arg + 1], &proc, MAX_PROCS, NULL, err)) {
memprintf(err, "'%s' : %s", args[cur_arg], *err);
return ERR_ALERT | ERR_FATAL;
}
@ -977,7 +977,7 @@ static int bind_parse_process(char **args, int cur_arg, struct proxy *px, struct
conf->bind_proc |= proc;
if (thread) {
for (i = 0; i < LONGBITS; i++)
for (i = 0; i < MAX_PROCS; i++)
if (!proc || (proc & (1UL << i)))
conf->bind_thread[i] |= thread;
}