mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 22:31:28 +02:00
In github bug #1517, Mike Lothian reported instant crashes on startup on RHEL8 + gcc-11 that appeared with 2.4 when allocating a proxy. The analysis brought us down to the THREAD_ALIGN() entries that were placed inside the "server" struct to avoid false sharing of cache lines. It turns out that some modern gcc make use of aligned vector operations to manipulate some fields (e.g. memset() etc) and that these structures allocated using malloc() are not necessarily aligned, hence the crash. The compiler is allowed to do that because the structure claims to be aligned. The problem is in fact that the alignment propagates to other structures that embed it. While most of these structures are used as statically allocated variables, some are dynamic and cannot use that. A deeper analysis showed that struct server does this, propagates to struct proxy, which propagates to struct spoe_config, all of which are allocated using malloc/calloc. A better approach would consist in usins posix_memalign(), but this one is not available everywhere and will either need to be reimplemented less efficiently (by always wasting 64 bytes before the area), or a few functions will have to be specifically written to deal with the few structures that are dynamically allocated. But the deeper problem that remains is that it is difficult to track structure alignment, as there's no available warning to check this. For the long term we'll probably have to create a macro such as "struct_malloc()" etc which takes a type and enforces an alignment based on the one of this type. This also means propagating that to pools as well, and it's not a tiny task. For now, let's get rid of the forced alignment in struct server, and replace it with extra padding. By punching 63-byte holes, we can keep areas on separate cache lines. Doing so moderately increases the size of the "server" structure (~+6%) but that's the best short-term option and it's easily backportable. This will have to be backported as far as 2.4. Thanks to Mike for the detailed report.