From owner-freebsd-arch@FreeBSD.ORG Wed Feb 5 04:55:40 2014 Return-Path: Delivered-To: freebsd-arch@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 10DE1B48 for ; Wed, 5 Feb 2014 04:55:40 +0000 (UTC) Received: from mho-01-ewr.mailhop.org (mho-03-ewr.mailhop.org [204.13.248.66]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id C0EB31C98 for ; Wed, 5 Feb 2014 04:55:39 +0000 (UTC) Received: from c-24-8-230-52.hsd1.co.comcast.net ([24.8.230.52] helo=damnhippie.dyndns.org) by mho-01-ewr.mailhop.org with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1WAuWP-000ILd-V7 for freebsd-arch@FreeBSD.org; Wed, 05 Feb 2014 04:55:38 +0000 Received: from [172.22.42.240] (revolution.hippie.lan [172.22.42.240]) by damnhippie.dyndns.org (8.14.3/8.14.3) with ESMTP id s154tYc2065449 for ; Tue, 4 Feb 2014 21:55:35 -0700 (MST) (envelope-from ian@FreeBSD.org) X-Mail-Handler: Dyn Standard SMTP by Dyn X-Originating-IP: 24.8.230.52 X-Report-Abuse-To: abuse@dyndns.com (see http://www.dyndns.com/services/sendlabs/outbound_abuse.html for abuse reporting information) X-MHO-User: U2FsdGVkX1942q61qUETa3TjK1kKAMIO Subject: Malloc alignment in libstand / loader(8) From: Ian Lepore To: freebsd-arch Content-Type: multipart/mixed; boundary="=-xc5zpUDqlEDhTKoyb6bT" Date: Tue, 04 Feb 2014 21:55:34 -0700 Message-ID: <1391576134.1196.21.camel@revolution.hippie.lan> Mime-Version: 1.0 X-Mailer: Evolution 2.32.1 FreeBSD GNOME Team Port X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Feb 2014 04:55:40 -0000 --=-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 #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--