mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-02 18:22:04 +00:00
MINOR: init: pre-allocate kernel data structures on init
The Linux kernel maintains data structures to track a processes' open file descriptors, and it expands these structures as necessary when FD usage grows (at every FD=2^X starting at 64). However when threading is in use, during expansion the kernel will pause (observed up to 47ms) while it waits for thread synchronization (see https://bugzilla.kernel.org/show_bug.cgi?id=217366). This change addresses the issue and avoids the random pauses by opening the maximum file descriptor during initialization, so that expansion will not occur while processing traffic.
This commit is contained in:
parent
6626195ff2
commit
425d7ad89d
@ -1107,6 +1107,7 @@ The following keywords are supported in the "global" section :
|
||||
- pidfile
|
||||
- pp2-never-send-local
|
||||
- presetenv
|
||||
- prealloc-fd
|
||||
- resetenv
|
||||
- set-dumpable
|
||||
- set-var
|
||||
@ -2084,6 +2085,12 @@ presetenv <name> <value>
|
||||
in the configuration file sees the new value. See also "setenv", "resetenv",
|
||||
and "unsetenv".
|
||||
|
||||
prealloc-fd
|
||||
Performs a one-time open of the maximum file descriptor which results in a
|
||||
pre-allocation of the kernel's data structures. This prevents short pauses
|
||||
when nbthread>1 and HAProxy opens a file descriptor which requires the kernel
|
||||
to expand its data structures.
|
||||
|
||||
resetenv [<name> ...]
|
||||
Removes all environment variables except the ones specified in argument. It
|
||||
allows to use a clean controlled environment before setting new values with
|
||||
|
@ -188,6 +188,7 @@ struct global {
|
||||
} unix_bind;
|
||||
struct proxy *cli_fe; /* the frontend holding the stats settings */
|
||||
int numa_cpu_mapping;
|
||||
int prealloc_fd;
|
||||
int cfg_curr_line; /* line number currently being parsed */
|
||||
const char *cfg_curr_file; /* config file currently being parsed or NULL */
|
||||
char *cfg_curr_section; /* config section name currently being parsed or NULL */
|
||||
|
@ -1357,3 +1357,21 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static int cfg_parse_prealloc_fd(char **args, int section_type, struct proxy *curpx,
|
||||
const struct proxy *defpx, const char *file, int line,
|
||||
char **err)
|
||||
{
|
||||
if (too_many_args(0, args, err, NULL))
|
||||
return -1;
|
||||
|
||||
global.prealloc_fd = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
{ CFG_GLOBAL, "prealloc-fd", cfg_parse_prealloc_fd },
|
||||
{ 0, NULL, NULL },
|
||||
}};
|
||||
|
||||
INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
|
||||
|
@ -3522,6 +3522,14 @@ int main(int argc, char **argv)
|
||||
global.maxsock);
|
||||
}
|
||||
|
||||
if (global.prealloc_fd && fcntl((int)limit.rlim_cur - 1, F_GETFD) == -1) {
|
||||
if (dup2(0, (int)limit.rlim_cur - 1) == -1)
|
||||
ha_warning("[%s.main()] Unable to preallocate file descriptor %lu : %s",
|
||||
argv[0], limit.rlim_cur-1, strerror(errno));
|
||||
else
|
||||
close((int)limit.rlim_cur - 1);
|
||||
}
|
||||
|
||||
/* update the ready date a last time to also account for final setup time */
|
||||
clock_update_date(0, 1);
|
||||
clock_adjust_now_offset();
|
||||
|
Loading…
Reference in New Issue
Block a user