From: Willy Tarreau Date: Sat, 10 Apr 2021 14:53:05 +0000 (+0200) Subject: MINOR: global: declare a read_mostly section X-Git-Tag: v2.4-dev17~159 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f459640ef6492f8e06967c23305f48e06858df11;p=thirdparty%2Fhaproxy.git MINOR: global: declare a read_mostly section Some variables are mostly read (mostly pointers) but they tend to be merged with other ones in the same cache line, slowing their access down in multi-thread setups. This patch declares an empty, aligned variable in a section called "read_mostly". This will force a cache-line alignment on this section so that any variable declared in it will be certain to avoid false sharing with other ones. The section will be eliminated at link time if not used. A __read_mostly attribute was added to compiler.h to ease use of this section. --- diff --git a/include/haproxy/compiler.h b/include/haproxy/compiler.h index c18331962f..72557674c4 100644 --- a/include/haproxy/compiler.h +++ b/include/haproxy/compiler.h @@ -88,6 +88,9 @@ #endif // USE_OBSOLETE_LINKER +/* use this attribute on a variable to move it to the read_mostly section */ +#define __read_mostly HA_SECTION("read_mostly") + /* This allows gcc to know that some locations are never reached, for example * after a longjmp() in the Lua code, hence that some errors caught by such * methods cannot propagate further. This is important with gcc versions 6 and diff --git a/src/haproxy.c b/src/haproxy.c index 407ce424d2..3d5e85f168 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -135,6 +135,16 @@ /* array of init calls for older platforms */ DECLARE_INIT_STAGES; +/* create a read_mostly section to hold variables which are accessed a lot + * but which almost never change. The purpose is to isolate them in their + * own cache lines where they don't risk to be perturbated by write accesses + * to neighbor variables. We need to create an empty aligned variable for + * this. The fact that the variable is of size zero means that it will be + * eliminated at link time if no other variable uses it, but alignment will + * be respected. + */ +empty_t __read_mostly_align HA_SECTION("read_mostly") ALIGNED(64); + /* list of config files */ static struct list cfg_cfgfiles = LIST_HEAD_INIT(cfg_cfgfiles); int pid; /* current process id */