From owner-svn-src-head@FreeBSD.ORG Tue Nov 4 21:49:45 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id BA8B0BF7; Tue, 4 Nov 2014 21:49:45 +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)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 796E6330; Tue, 4 Nov 2014 21:49:45 +0000 (UTC) Received: from [73.34.117.227] (helo=ilsoft.org) by mho-01-ewr.mailhop.org with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1Xllys-000Nyg-1p; Tue, 04 Nov 2014 21:49:38 +0000 Received: from [172.22.42.240] (revolution.hippie.lan [172.22.42.240]) by ilsoft.org (8.14.9/8.14.9) with ESMTP id sA4Lnatx002979; Tue, 4 Nov 2014 14:49:36 -0700 (MST) (envelope-from ian@FreeBSD.org) X-Mail-Handler: Dyn Standard SMTP by Dyn X-Originating-IP: 73.34.117.227 X-Report-Abuse-To: abuse@dyndns.com (see http://www.dyndns.com/services/sendlabs/outbound_abuse.html for abuse reporting information) X-MHO-User: U2FsdGVkX190fxrvstcrYzSVYYUIWdik X-Authentication-Warning: paranoia.hippie.lan: Host revolution.hippie.lan [172.22.42.240] claimed to be [172.22.42.240] Subject: Re: svn commit: r274088 - head/sys/kern From: Ian Lepore To: Bruce Evans In-Reply-To: <20141105071445.O2183@besplex.bde.org> References: <201411041129.sA4BTnwX030600@svn.freebsd.org> <20141104114041.GA21297@dft-labs.eu> <20141105023323.O1105@besplex.bde.org> <1415123429.1200.75.camel@revolution.hippie.lan> <20141105071445.O2183@besplex.bde.org> Content-Type: text/plain; charset="us-ascii" Date: Tue, 04 Nov 2014 14:49:36 -0700 Message-ID: <1415137776.1200.113.camel@revolution.hippie.lan> Mime-Version: 1.0 X-Mailer: Evolution 2.32.1 FreeBSD GNOME Team Port Content-Transfer-Encoding: 7bit Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Nov 2014 21:49:45 -0000 On Wed, 2014-11-05 at 07:46 +1100, Bruce Evans wrote: > On Tue, 4 Nov 2014, Ian Lepore wrote: > > > On Wed, 2014-11-05 at 03:19 +1100, Bruce Evans wrote: > >> [...] > >> Another unsuitable alignment is by the MD ALIGNBYTES macro. This is > >> (sizeof(register_t) - 1) on all arches except mips 32-bit where it is 7 > >> sparc64 where it is 15. On arm, it is 3, but arm also has > >> STACKALIGNBYTES = 7. The register size is really too small to use for > >> malloc() on 32-bit arches. Its technical correctness depends on no > >> C objects having more than 32-bit alignment. On i386, int64_t and > >> double should have 64-bit alignment, but this is not required unless > >> CFLAGS includes -malign-double which breaks the ABI in userland and > >> is irrelevant for the kernel. > >> > > > > In arm/include/_align.h we have: > > > > /* > > * Round p (pointer or byte index) up to a correctly-aligned value > > * for all data types (int, long, ...). [more words snipped] > > */ > > #define _ALIGNBYTES (sizeof(int) - 1) > > > > So that's clearly wrong, because int64_t and double types require 8-byte > > alignment. > > Do they really, except to be optimal? arm64 doesn't seem to be in > -current yet. I know little about arm, but seem to remember that it > uses 4-byte alignment to a fault and pads out arrays of chars to that. > That would make even less sense if some types actually require 8-byte > alignment. > Yep, they do. There are instructions on newer 32-bit arm that operate on 64-bit memory operands and adjacent pairs of registers, and they require 64-bit memory alignment to avoid a fault. Also (unrelated to the ALIGN stuff), the compiler will generate such instructions when operating on pairs of 32-bit values, when it knows the alignment of the memory operand makes it safe to do so. Last year we embraced the newer EABI spec. It requires the stack to be 8-byte aligned at all times except within a leaf function, and the compiler is aware of that. > > When it comes to fixing it, I could: > > > > * include _types.h and use sizeof(__int64_t) > > * use sizeof(long long) > > * use sizeof(double) > > * just hardcode '7' with a comment that says why > > > > What are the pros and cons of the various options? Is one of them > > preferable? Is there something even better I overlooked? > > Just hard-code '7' as '(8 - 1)' without even a comment :-). Except > most arches (not arm) already have an excessively verbose comment that > has been been blindly copied so that it is now wrong in some cases. You > would get this by copying bugs from other arches. For sparc64, it is: > > % * from: @(#)param.h 5.8 (Berkeley) 6/28/91 > % * $FreeBSD: head/sys/sparc64/include/_align.h 196994 2009-09-08 20:45:40Z phk $ > % */ > > The headers are convoluted and pessimized by splitting off this tiny header > for namespace reasons. When I fixed the namespace bugs for i386, I > intentionally didn't split off this header, but used ifdefs instead. > (machine/_align.h is also used in sys/socket.h. Keeping the 2 definitions > in it in a separate file just allows sys/socket.h to include this file. > It used to direct machine/param.h to define only these 2 things.) > > % > % #ifndef _SPARC64_INCLUDE__ALIGN_H_ > % #define _SPARC64_INCLUDE__ALIGN_H_ > % > % /* > % * Round p (pointer or byte index) up to a correctly-aligned value > % * for all data types (int, long, ...). The result is unsigned int > % * and must be cast to any desired pointer type. > % */ > % #define _ALIGNBYTES 0xf > % #define _ALIGN(p) (((u_long)(p) + _ALIGNBYTES) & ~_ALIGNBYTES) > > Note that the result type is not unsigned int as claimed in the comment. > It is only that on 32-bit arches. > > Also, the type of _ALIGNEDBYTES is a bit fragile. It is signed 32-bit int. > So ~ALIGNBYTES is 32 bits. It has value -16, not 0xFFFFFFF0 (the latter > is large and unsigned. Then promotion of ~ALIGNBYTES to match the other > operand changes its type to u_long and its value to 0xFFFFFFFFFFFFFFF0. > The original type had to be signed int and the arithmetic normal 2's > complement for the promotion to give the right mask. Even forming > ~_ALIGNBYTES requires magic for toggling the sign bit. Since this is > the implementation, it can know what happens, but using magic makes its > correctness harder to understand. > > _ALIGNBYTES should probably have type u_long to begin with to reduce the > magic. > > % > % #endif /* !_SPARC64_INCLUDE__ALIGN_H_ */ > > Bruce > So bottom line, define _ALIGNBYTES as (8UL - 1) to minimize the magic? -- Ian