Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 04 Feb 2014 21:55:34 -0700
From:      Ian Lepore <ian@FreeBSD.org>
To:        freebsd-arch <freebsd-arch@FreeBSD.org>
Subject:   Malloc alignment in libstand / loader(8)
Message-ID:  <1391576134.1196.21.camel@revolution.hippie.lan>

next in thread | raw e-mail | index | archive | help

--=-xc5zpUDqlEDhTKoyb6bT
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

On newer ARM chips, the device drivers used by loader(8) require that
I/O buffers be aligned on cache line sized boundaries.  The drivers are
part of u-boot which serves as a sort of load-time bios.

Attached is a patch that sets the malloc alignment in libstand to 64
bytes when compiled on ARM, and leaves it at 16 bytes for all other
platforms.  If there are no objections I'd like to commit this soon.

I've tested this on ARM, but have no way to test it on other platforms.
The changes should be a no-op on other platforms.

-- Ian


--=-xc5zpUDqlEDhTKoyb6bT
Content-Disposition: inline; filename="libstand_mallocalign.diff"
Content-Type: text/x-patch; name="libstand_mallocalign.diff"; charset="us-ascii"
Content-Transfer-Encoding: 7bit

Index: lib/libstand/zalloc.c
===================================================================
--- lib/libstand/zalloc.c	(revision 261446)
+++ lib/libstand/zalloc.c	(working copy)
@@ -71,6 +71,15 @@ __FBSDID("$FreeBSD$");
 #include "zalloc_defs.h"
 
 /*
+ * Objects in the pool must be aligned to at least the size of struct MemNode.
+ * They must also be aligned to MALLOCALIGN, which should normally be larger
+ * than the struct, so assert that to be so at compile time.
+ */
+typedef char assert_align[(sizeof(struct MemNode) <= MALLOCALIGN) ? 1 : -1];
+
+#define	MEMNODE_SIZE_MASK	MALLOCALIGN_MASK
+
+/*
  * znalloc() -	allocate memory (without zeroing) from pool.  Call reclaim
  *		and retry if appropriate, return NULL if unable to allocate
  *		memory.
Index: lib/libstand/zalloc_mem.h
===================================================================
--- lib/libstand/zalloc_mem.h	(revision 261446)
+++ lib/libstand/zalloc_mem.h	(working copy)
@@ -48,8 +48,6 @@ typedef struct MemPool {
     uintptr_t		mp_Used;
 } MemPool;
 
-#define MEMNODE_SIZE_MASK       ((sizeof(MemNode) <= 8) ? 7 : 15)
-
 #define ZNOTE_FREE	0
 #define ZNOTE_REUSE	1
 
Index: lib/libstand/sbrk.c
===================================================================
--- lib/libstand/sbrk.c	(revision 261446)
+++ lib/libstand/sbrk.c	(working copy)
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 
 #include <string.h>
 #include "stand.h"
+#include "zalloc_defs.h"
 
 static size_t	maxheap, heapsize = 0;
 static void	*heapbase;
@@ -40,8 +41,9 @@ static void	*heapbase;
 void
 setheap(void *base, void *top)
 {
-    /* Align start address to 16 bytes for the malloc code. Sigh. */
-    heapbase = (void *)(((uintptr_t)base + 15) & ~15);
+    /* Align start address for the malloc code.  Sigh. */
+    heapbase = (void *)(((uintptr_t)base + MALLOCALIGN_MASK) & 
+        ~MALLOCALIGN_MASK);
     maxheap = (char *)top - (char *)heapbase;
 }
 
Index: lib/libstand/zalloc_defs.h
===================================================================
--- lib/libstand/zalloc_defs.h	(revision 261446)
+++ lib/libstand/zalloc_defs.h	(working copy)
@@ -52,18 +52,26 @@
 #define BLKEXTENDMASK	(BLKEXTEND - 1)
 
 /*
- * required malloc alignment.  Just hardwire to 16.
+ * Required malloc alignment.
  *
- * Note: if we implement a more sophisticated realloc, we should ensure that
- * MALLOCALIGN is at least as large as MemNode.
+ * ARM platforms using the u-boot API drivers require that all I/O buffers be on
+ * a cache line sized boundary.  The worst case size for that is 64 bytes.  For
+ * all other platforms, 16 bytes works fine.  The size also must be at least
+ * sizeof(struct MemNode); this is asserted in zalloc.c.
  */
 
+#ifdef __arm__
+#define	MALLOCALIGN		64
+#else
+#define	MALLOCALIGN		16
+#endif
+#define	MALLOCALIGN_MASK	(MALLOCALIGN - 1)
+
 typedef struct Guard {
     size_t	ga_Bytes;
     size_t	ga_Magic;	/* must be at least 32 bits */
 } Guard;
 
-#define MALLOCALIGN	16
 #define GAMAGIC		0x55FF44FD
 #define GAFREE		0x5F54F4DF
 

--=-xc5zpUDqlEDhTKoyb6bT--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1391576134.1196.21.camel>