Broken dbus

Jay Estabrook Jay.Estabrook at hp.com
Sun Apr 27 14:26:47 UTC 2008


[NOTE: the below does NOT offer any insight into the problem
 with dbus and hal, but DOES offer some perspective on the
 unaligned accesses both have (had :-) attributed to them.]

In general, ie not just Alpha, many architectures take a hit
when accessing data types NOT on their "natural" boundary.

Some architectures "fix" them up invisibly, ie via microcode
or some such; you don't see the unaligned accesses as such,
but you may notice things running slower IF you have a lot
of them, as the fixup usually takes more time.

Others, like Alpha, actually take an exception trap into the
kernel, which fixes them up via software. The operation DOES
succeed, but there is a penalty.

For example, on Alpha, a 32-bit load on a 16-bit boundary address
will trap into the kernel. Again, IF this happens frequently, it
can have a major performance impact, and not just be annoying
because of the messages... ;-}

The occurrence can often be attributed to either compiler assumptions
(dbus), or poor programming practice (hal).

Compilers may assume (gcc does) that a pointer to a data struct will
be on an appropriate boundary for a data struct; that is, in the Alpha
case, on an 8-byte (quadword) boundary. Fields within a struct, by
default, will appear on a natural boundary offset from the start of
the struct, regardless of type of intervening fields (unless one
explicitly "packs" the struct via an "attribute(packed)" declaration).

In the dbus case, a single char was being stored at the start of a
data struct; however, the data struct was NOT always on a natural
boundary. Something like:

    vp->byt = 0;

where vp was assigned via a cast from an arbitrary address.

The code generated to store the byte, because it was default
Alpha instructions (ie no byte/short mem ops), was using 32-bit mem
load/store operations, and taking an exception on EACH ONE.

By casting the whole address as a (char *), one can force the
compiler to generate code that will work WITHOUT faulting in ALL
cases (it will use "unaligned load/store" instructions). Like so:

    *((char *)&vp->byt) = 0;

The poor programming practice (hal) arises from assuming that all
architectures have a natural boundary of 32-bits. Something like
the following are indicative:

   pointer = (void *)((((char *)address) + 3) & ~3);

Better is:

   #define SZM (sizeof(void*)-1)
   pointer = (void *)((((char *)address) + SZM) & ~SZM);

because it should work on ALL architectures regardless of the
size of a pointer. This operation is typically used to round
up an arbitrary address to what is believed to be the next
"natural" boundary.

Anyway, enough for now...

--Jay++

Kazuyoshi Furutaka wrote:
> From: Steven Moix <steven.moix at axianet.ch>
> Subject: Broken dbus
> Date: Sun, 27 Apr 2008 10:09:25 +0200
> 
>> PS: What are "unaligned accesses"?
> 
> See "1.2 Known Bugs And Workarounds" of
>   http://www.alphalinux.org/faq/FAQ-1.html
> 
> The first thing I did to compile old fortran
> programs developped using VAX fortran on AXP
> systems was to add the ALIGN=NATURAL option
> (at that time I was a grad student...)
> 
> I don't know how the unaligned access affect
> the dbus issue, though.
> 
> Yours,
> Kazuyoshi
> --
> Kazuyoshi Furutaka
> furutaka at jb3.so-net.ne.jp
> 
> _______________________________________________
> axp-list mailing list
> axp-list at redhat.com
> https://www.redhat.com/mailman/listinfo/axp-list
> 




More information about the axp-list mailing list