Skip to content

Commit

Permalink
MINOR: startup: tune.renice.{startup,runtime} allow to change priorities
Browse files Browse the repository at this point in the history
This commit introduces the tune.renice.startup and tune.renice.runtime
global keywords that allows to change the priority with setpriority().

tune.renice.startup is parsed and applied in the worker or the standalone
process for configuration parsing. If this keyword is used alone, the
nice value is changed to the previous one after configuration parsing.

tune.renice.runtime is applied after configuration parsing, so in the
worker or a standalone process. Combined with tune.renice.startup it
allows to have a different nice value during configuration parsing and
during runtime.

The feature was discussed in github issue haproxy#1919.

Example:

   global
        tune.renice.startup 15
        tune.renice.runtime 0
  • Loading branch information
wlallemand committed Nov 4, 2024
1 parent 2092199 commit e75a019
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 0 deletions.
22 changes: 22 additions & 0 deletions doc/configuration.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,8 @@ The following keywords are supported in the "global" section :
- tune.quic.retry-threshold
- tune.quic.socket-owner
- tune.quic.zero-copy-fwd-send
- tune.renice.runtime
- tune.renice.startup
- tune.rcvbuf.backend
- tune.rcvbuf.client
- tune.rcvbuf.frontend
Expand Down Expand Up @@ -4060,6 +4062,26 @@ tune.quic.zero-copy-fwd-send { on | off }

See also: tune.disable-zero-copy-forwarding

tune.renice.runtime <number>
This configuration option takes a value between -20 and 19. It applies a
scheduling priority as documented in man 2 setpriority. This priority is
applied after the configuration parsing, which means only the worker or the
standalone process will apply it. It is usually configured to set a higher
priority than a process doing configuration parsing (tune.renice.startup).

See also: tune.renice.startup

tune.renice.startup <number>
This configuration option takes a value between -20 and 19. It applies a
scheduling priority as documented in man 2 setpriority. This priority is
applied before applying the rest of the configuration which can be useful if
you want to lower the priority for configuration parsing. This is applied on
the standalone process or the worker before configuration parsing. Once the
configuration is parsed, the previous priority is restored unless
tune.renice.runtime is used.

See also: tune.renice.runtime

tune.rcvbuf.backend <number>
tune.rcvbuf.frontend <number>
For the kernel socket receive buffer size on non-connected sockets to this
Expand Down
2 changes: 2 additions & 0 deletions include/haproxy/global-t.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ struct global {
int pool_low_count; /* max number of opened fd before we stop using new idle connections */
int pool_high_count; /* max number of opened fd before we start killing idle connections when creating new connections */
size_t pool_cache_size; /* per-thread cache size per pool (defaults to CONFIG_HAP_POOL_CACHE_SIZE) */
int renice_startup; /* startup nice()+100 value during startup; 0 = unset */
int renice_runtime; /* startup nice()+100 value during runtime; 0 = unset */
unsigned short idle_timer; /* how long before an empty buffer is considered idle (ms) */
unsigned short no_zero_copy_fwd; /* Flags to disable zero-copy fast-forwarding (global & per-protocols) */
int nb_stk_ctr; /* number of stick counters, defaults to MAX_SESS_STKCTR */
Expand Down
51 changes: 51 additions & 0 deletions src/cfgparse-global.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <grp.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <unistd.h>

Expand Down Expand Up @@ -1540,6 +1541,54 @@ static int cfg_parse_global_parser_pause(char **args, int section_type,
return 0;
}

/* config parser for global "tune.renice.startup" and "tune.renice.runtime",
* accepts -20 to +19 inclusive, stored as 80..119.
*/
static int cfg_parse_tune_renice(char **args, int section_type, struct proxy *curpx,
const struct proxy *defpx, const char *file, int line,
char **err)
{
int prio;
char *stop;

if (too_many_args(1, args, err, NULL))
return -1;

prio = strtol(args[1], &stop, 10);
if ((*stop != '\0') || (prio < -20 || prio > 19)) {
memprintf(err, "'%s' only supports values between -20 and 19 inclusive (was given %s)", args[0], args[1]);
return -1;
}

/* 'runtime' vs 'startup' */
if (args[0][12] == 'r') {
/* runtime is executed once parsing is done */

global.tune.renice_runtime = prio + 100;
} else if (args[0][12] == 's') {
/* startup is executed during cfg parsing */

global.tune.renice_startup = prio + 100;
if (setpriority(PRIO_PROCESS, 0, prio) == -1)
ha_warning("couldn't set the startup nice value to %d: %s\n", prio, strerror(errno));

/* try to store the previous priority in the runtime priority */
prio = getpriority(PRIO_PROCESS, 0);
if (prio == -1) {
ha_warning("couldn't get the runtime nice value: %s\n", strerror(errno));
} else {
/* if there wasn't a renice runtime option set */
if (global.tune.renice_runtime == 0)
global.tune.renice_runtime = prio + 100;
}

} else {
BUG_ON(1, "Triggered in cfg_parse_tune_renice() by unsupported keyword.\n");
}

return 0;
}

static struct cfg_kw_list cfg_kws = {ILH, {
{ CFG_GLOBAL, "prealloc-fd", cfg_parse_prealloc_fd },
{ CFG_GLOBAL, "force-cfg-parser-pause", cfg_parse_global_parser_pause, KWF_EXPERIMENTAL },
Expand All @@ -1563,6 +1612,8 @@ static struct cfg_kw_list cfg_kws = {ILH, {
{ CFG_GLOBAL, "tune.bufsize", cfg_parse_global_tune_opts },
{ CFG_GLOBAL, "tune.maxrewrite", cfg_parse_global_tune_opts },
{ CFG_GLOBAL, "tune.idletimer", cfg_parse_global_tune_opts },
{ CFG_GLOBAL, "tune.renice.startup", cfg_parse_tune_renice },
{ CFG_GLOBAL, "tune.renice.runtime", cfg_parse_tune_renice },
{ CFG_GLOBAL, "tune.rcvbuf.client", cfg_parse_global_tune_opts },
{ CFG_GLOBAL, "tune.rcvbuf.server", cfg_parse_global_tune_opts },
{ CFG_GLOBAL, "tune.sndbuf.client", cfg_parse_global_tune_opts },
Expand Down
9 changes: 9 additions & 0 deletions src/haproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -3942,6 +3942,15 @@ int main(int argc, char **argv)
}
}

/* applies the renice value in the worker or standalone after configuration parsing
* but before chaning identity */
if (!master && global.tune.renice_runtime) {
if (setpriority(PRIO_PROCESS, 0, global.tune.renice_runtime - 100) == -1) {
ha_warning("[%s.main()] couldn't set the runtime nice value to %d: %s\n",
argv[0], global.tune.renice_runtime - 100, strerror(errno));
}
}

/* Must chroot and setgid/setuid in the children */
/* chroot if needed */
if (global.chroot != NULL) {
Expand Down

0 comments on commit e75a019

Please sign in to comment.