Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Oct 2012 15:41:06 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Andre Oppermann <andre@FreeBSD.org>
Cc:        src-committers@FreeBSD.org, John Baldwin <jhb@FreeBSD.org>, svn-src-all@FreeBSD.org, attilio@FreeBSD.org, svn-src-head@FreeBSD.org, Jim Harris <jim.harris@gmail.com>
Subject:   Re: svn commit: r242014 - head/sys/kern
Message-ID:  <20121025145158.R999@besplex.bde.org>
In-Reply-To: <50889EE0.8030105@freebsd.org>
References:  <201210241836.q9OIafqo073002@svn.freebsd.org> <201210241443.25988.jhb@freebsd.org> <CAJP=Hc9wLv02sX%2BWnzZtaKccSAFzqg8jT0oP13nLw1jMfwOEBQ@mail.gmail.com> <CAJ-FndDzBdq8q6J7QKqf=abi_702s_ia=pa3XbBv80rxbGb-SA@mail.gmail.com> <50884E9F.3090706@freebsd.org> <CAJ-FndBH2cjF2ukt4373BwMsoWEeLykBhPQNnXUgpJ=4jd3LJg@mail.gmail.com> <508855DA.1080903@freebsd.org> <50889EE0.8030105@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 25 Oct 2012, Andre Oppermann wrote:

> ...
> I spoke too soon.  Attilio is completely right in his assessment.
>
> It does work when done on the struct definition:
>
> struct mtx {
> 	...
> } __aligned(CACHE_LINE_SIZE);	/* works including .bss alignment & padding 
> */
>
> When creating a struct (in globals at least) it doesn't work:
>
> struct mtx __aligned(CACHE_LINE_SIZE) foo_mtx;	/* doesn't work */
>
>> It seems to come down to either a) fixing gcc+ld; or b) hacking
>> around it by magically padding the structs that require it.
>
> The question now becomes of whether we can (should?) make the latter
> case above work or find another workaround.

The latter case already works correctly.  The alignment directive only
specifies the alignment requirement for the start of the object.  The
size of the object is whatever it is, and there is no directive for
padding.

Consider an array of objects:

     struct mtx __aligned(CACHE_LINE_SIZE) foo_mtx[128];

This aligns the first element in the array.  There is no way that it
can do special alignment for other elements.  The elements must follow
each other, with no padding in between.  The struct size is whatever it
is and is already padded for the correct alignment as known at the
time of the struct declaration, and you can't change its size later.

I once wrote the following mistake which gave excessive alignment,
but also sort or what you want:

    static double __aligned(64)
    P1 = ...,
    P2 = ...,
    P3 = ...;

This was intended to align the first double to 64 bytes and have the
others follow with no padding, much like what would happen if the
variables were in an array (they are named Pn mainly because this looks
nicer than P[n]).  What it actually does is align all the variables to
64 bytes and waste a lot of space and cache resources.  The linker
might fill in the gaps, but at least with static variables in a small
program, it won't be able to find enough variables to fill them all.
With static variables in a large program, dummy variables could
probably be provided to fill in the gaps.

For global mutexes, I would try putting them all in the same struct
starting at a page boundary, a bit like pcpu, so that I can control
the layout of them all.

Bruce



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