[Mesa-dev] [PATCH 2/2] util/ralloc: Make sizeof(linear_header) a multiple of 8

Matt Turner mattst88 at gmail.com
Mon Nov 12 21:25:52 UTC 2018


Prior to this patch sizeof(linear_header) was 20 bytes in a
non-debug build on 32-bit platforms. We do some pointer arithmetic to
calculate the next available location with

   ptr = (linear_size_chunk *)((char *)&latest[1] + latest->offset);

in linear_alloc_child(). The &latest[1] adds 20 bytes, so an allocation
would only be 4-byte aligned.

On 32-bit SPARC a 'sttw' instruction (which stores a consecutive pair of
4-byte registers to memory) requires an 8-byte aligned address. Such an
instruction is used to store to an 8-byte integer type, like intmax_t
which is used in glcpp's expression_value_t struct.

As a result of the 4-byte alignment returned by linear_alloc_child() we
would generate a SIGBUS (unaligned exception) on SPARC.

According to the GNU libc manual malloc() always returns memory that has
at least an alignment of 8-bytes [1]. I think our allocator should do
the same.

So, simple fix with two parts:

   (1) Increase SUBALLOC_ALIGNMENT to 8 unconditionally.
   (2) Mark linear_header with an aligned attribute, which will cause
       its sizeof to be rounded up to that alignment. (We already do
       this for ralloc_header)

With this done, all Mesa's unit tests now pass on SPARC.

[1] https://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html

Fixes: 47e17586924f ("glcpp: use the linear allocator for most objects")
Bug: https://bugs.gentoo.org/636326
---
 src/util/ralloc.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/util/ralloc.c b/src/util/ralloc.c
index 745b4cf1226..fc35661996d 100644
--- a/src/util/ralloc.c
+++ b/src/util/ralloc.c
@@ -552,10 +552,18 @@ ralloc_vasprintf_rewrite_tail(char **str, size_t *start, const char *fmt,
  */
 
 #define MIN_LINEAR_BUFSIZE 2048
-#define SUBALLOC_ALIGNMENT sizeof(uintptr_t)
+#define SUBALLOC_ALIGNMENT 8
 #define LMAGIC 0x87b9c7d3
 
-struct linear_header {
+struct
+#ifdef _MSC_VER
+ __declspec(align(8))
+#elif defined(__LP64__)
+ __attribute__((aligned(16)))
+#else
+ __attribute__((aligned(8)))
+#endif
+   linear_header {
 #ifndef NDEBUG
    unsigned magic;   /* for debugging */
 #endif
@@ -647,6 +655,8 @@ linear_alloc_child(void *parent, unsigned size)
    ptr = (linear_size_chunk *)((char*)&latest[1] + latest->offset);
    ptr->size = size;
    latest->offset += full_size;
+
+   assert((uintptr_t)&ptr[1] % SUBALLOC_ALIGNMENT == 0);
    return &ptr[1];
 }
 
-- 
2.16.4



More information about the mesa-dev mailing list