From: Willy Tarreau Date: Thu, 7 Feb 2019 09:39:36 +0000 (+0100) Subject: MINOR: config: make MAX_PROCS configurable at build time X-Git-Tag: v2.0-dev1~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ff9c9140f4da4f14bef8c9a5955f9453d0f26c60;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/include/common/defaults.h b/include/common/defaults.h index b2c2583540..cdc66650bb 100644 --- a/include/common/defaults.h +++ b/include/common/defaults.h @@ -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, diff --git a/include/types/global.h b/include/types/global.h index 178b2c14da..b26553bc28 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -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 }; diff --git a/include/types/listener.h b/include/types/listener.h index df0dd367c3..9c0ebde069 100644 --- a/include/types/listener.h +++ b/include/types/listener.h @@ -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 */ diff --git a/src/cfgparse-global.c b/src/cfgparse-global.c index 820c7b6a06..e1835e7b68 100644 --- a/src/cfgparse-global.c +++ b/src/cfgparse-global.c @@ -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; diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 74218b5e65..5f44cfdf02 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -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; diff --git a/src/cfgparse.c b/src/cfgparse.c index 1afb49c89a..d7d18c6b12 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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; } diff --git a/src/cli.c b/src/cli.c index d1d1e9625d..3c2a55d75d 100644 --- a/src/cli.c +++ b/src/cli.c @@ -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; } diff --git a/src/haproxy.c b/src/haproxy.c index ce4cde3111..7c434b361f 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -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__ { diff --git a/src/listener.c b/src/listener.c index cb8cbda1d2..e9ace41f52 100644 --- a/src/listener.c +++ b/src/listener.c @@ -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; }