Subject: unaligned

From: Philip Blundell <[email-masked]>
Date: Wed, 01 Jul 1998 19:56:03 +0100

As a brief distraction from the joys of uname, I'd like to talk about 
unaligned accesses.

Currently we don't trap on unaligned accesses and let the CPU do its own 
thing.  ARM2 and ARM3 cpus _can't_ trap these accesses, and compatibility was 
the original rationale for doing things that way.  However, since the majority 
of machines running Linux these days are almost certainly based on newer CPUs, 
it might be time to think again.

The advantage of trapping unaligned accesses is that it reduces the number of 
ARM-specific hacks that are needed.  Various bits of the kernel assume that 
unaligned accesses will be fixed up to do the right thing; the networking code 
in particular relies on this for all cases to work.  It's possible to fudge 
most things to work without but there is a cost in terms of both performance 
and neatness of code.  Also, user-space programs sometimes don't take enough 
care over unaligned accesses.  Even if we decide not to emulate them for that 
case it would still be a useful diagnostic to allow the process to receive 
SIGBUS if it performed a bad access. 

The disadvantage is that (a) we lose backwards compatibility, and (b) we have 
to use -mshort-load-bytes to stop GCC trying to be too clever.  In practice we 
have to do (b) anyway for the kernel so this is no hardship.  The move to ELF 
and 32-bit binaries also means that backwards compatibility doesn't need to be 
too much of a concern; it would be possible to arrange for accesses to be 
trapped or not on a per-process basis, so a.out binaries and ELF ones that so 
desired could be run in non-trapping mode while the rest would trap.

26-bit machines would obviously have to go on much as they are.  In the kernel 
this means that the fudges that are currently #ifdef __arm__ would just become 
#if defined(__arm__) && defined(__APCS_26__).

What do people think?

p.

unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Alan Cox <[email-masked]>
Date: Wed, 1 Jul 1998 22:56:46 +0100 (BST)

> ARM-specific hacks that are needed.  Various bits of the kernel assume that 

Its also a performance win big time to make the traps rare and to avoid 
handling the entire world badly

egcs supports generating code that loads attribute(unaligned) fields
with "safe" instructions. What I discussed on the phone with Russ was
tweaking that a bit so its inheritable from variables - ie so we can
write

	struct iphdr __unaligned *x=(struct iphdr __unaligned *)skb->h.raw;

for the platforms its a problem

Alan

---

From: Philip Blundell <[email-masked]>
Date: Wed, 01 Jul 1998 23:37:52 +0100

>handling the entire world badly

Sure, but I think there are places where the traps will be handy.

>for the platforms its a problem

That looks like a handy trick - it would be good for the ethernet header 
situation for example.  But loading a 32-bit word a byte at a time (which is 
the only safe way) is quite a big hit - it takes something like eight 
instructions and an extra register.  I'm not convinced we want to do that for 
all the IP headers just on the offchance - the unaligned cases are usually 
slowish or rare ones anyway, like PPP or IP-in-weirdo-protocol encapsulation.  
Anybody who cares about performance will make sure the IP header is aligned 
anyway.

p.

---

From: Alan Cox <[email-masked]>
Date: Wed, 1 Jul 1998 23:53:08 +0100 (BST)

> Anybody who cares about performance will make sure the IP header is aligned 

Anyone who cares about performance will not be running an ARM2/ARM3.
Basically apart from the ethernet header quirk fix which is sane there is
no ARM2/3 alignment  handling crud going into the net code for 2.2 unless
theres a way to make it not occur on other platforms and not occur cleanly
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Phil Norman <[email-masked]>
Date: Thu, 2 Jul 1998 09:00:58 +0100 (BST)

> Anyone who cares about performance will not be running an ARM2/ARM3.

No, that's the wrong way round.  People running an ARM2/ARM3 care MORE
about performance.  Please don't assume that anyone not running a
high-spec machine (if you can call any Acorns high-spec; please don't
flame for that one) is doing so out of choice.

-- 
Rule of programming #5: If a C program gives more than 50 compiler
        errors, you've missed out a semicolon.

Phil Norman, mailing from Oregan Networks.
email:	[email-masked]
URL:	http://newton.ex.ac.uk/general/ug/norman

---

From: Philip Blundell <[email-masked]>
Date: Thu, 02 Jul 1998 09:42:40 +0100

>about performance.  Please don't assume that anyone not running a

Then it's up to them to optimise the code.  The ARM2 is a ten-year-old design
and very much in the minority these days.  It's not reasonable to cripple
every other processor for the sake of that one.

p.

---

From: Philip Blundell <[email-masked]>
Date: Thu, 02 Jul 1998 09:41:31 +0100

>Anyone who cares about performance will not be running an ARM2/ARM3.

Of course.  I thought you were saying that you thought the __unaligned__ trick 
was a better solution than alignment traps (which ARM3 doesn't have either).

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Thu, 2 Jul 1998 10:42:24 +0100 (BST)

> every other processor for the sake of that one.

There is already some code around that implements the unaligned access traps,
and I'm waiting to receive it.

Hence, as far as I am concerned, the unaligned access situation is settled
for ARM6 and up.  However, this does cause certain problems with the older
machines.

Since the kernel is complied differently for the ARM2/ARM3 machines, the
use of Alan's '__unaligned' proposal seems to be the best solution *if*
you need to do it.  The only time that you *need* to do it is if you're
running something like AX.25 or IPX on one of these machines, which I
think is highly unlikely.

The only area therefore that I feel is worthy of discussion is: should
we allow user code to perform unaligned accesses?

I feel that although it may improve performance a little to do this, but
userland should not be so dependent on the alignment of structures.  If
it is, then it is bad programming practice, and the code itself should
be fixed.  After all, userland doesn't access hardware - that's the kernel's
job.

Take DOOM for instance: ok, it's a game, but it uses structures to access
a WAD file, and it expects the structures to be of certain size and packed
the way it wants them to be.  Since the reading of the WAD file is *not*
in the main game loop, it doesn't matter if it takes a couple of ms longer
to read the file, especially when reading the WAD file is expensive anyway.
The fixes for this are quite trivial (I've done them already for the version
on the FTP site).
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.uk.linux.org/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

---

From: Matthew Wilcox <[email-masked]>
Date: Thu, 2 Jul 1998 11:12:11 +0100 (BST)

Philip Blundell
> thing.  ARM2 and ARM3 cpus _can't_ trap these accesses, and compatibility
> was the original rationale for doing things that way.  However, since the
> majority of machines running Linux these days are almost certainly based on
> newer CPUs, it might be time to think again.

> The disadvantage is that (a) we lose backwards compatibility, and (b) we
> have to use -mshort-load-bytes to stop GCC trying to be too clever.  In
> practice we have to do (b) anyway for the kernel so this is no hardship.

Do we actually have to do this?  Can the kernel not fix up its own aborts?
Okay, there would be a problem if it attempted to take an abort while in
abort mode, but to the best of my knowledge, that wouldn't actually happen.

> The move to ELF and 32-bit binaries also means that backwards compatibility
> doesn't need to be too much of a concern; it would be possible to arrange
> for accesses to be trapped or not on a per-process basis, so a.out binaries
> and ELF ones that so desired could be run in non-trapping mode while the
> rest would trap.
> 
> 26-bit machines would obviously have to go on much as they are.  In the
> kernel this means that the fudges that are currently #ifdef __arm__ would
> just become #if defined(__arm__) && defined(__APCS_26__).

I've often thought it would make more sense to actually have 2 distinct
Linux ports - a arm26 and arm32 port.  There's precedence with the sparc
and sparc64 ports.  It would clean up a fair bit of stuff, and there's no
way you can compile a kernel that will run on both processors.  And maybe
we should consider the arm26 stuff as similar to the ELKS - fun, but not
something which should complicate or otherwise hinder the `serious' stuff.

-- 
Set Alias$Case Set Alias$[ |||| |MSet Alias$Otherwise Set Alias$[ \ Matthew
"" |MSet Alias$When If %0=%%0 Then Set Alias$[ "" ||MIf %0=%%0    \ Wilcox
Then Set Alias$Otherwise Set Alias$[ |||||||||||||||| ||MIf       \
%0=%%0 Then Set Alias$When Set Alias$[ ||||||||||||||||
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Thu, 02 Jul 1998 11:33:34 +0100

>Do we actually have to do this?  Can the kernel not fix up its own aborts?

It can, yes.  The problem with GCC without -mshort-load-bytes is that the 
behaviour it expects is precisely the behaviour you get if you _don't_ fix up 
unaligned traps.  This allows you to optimise halfword accesses.  If you do 
trap and emulate these accesses then this optimisation stops working - but at 
the moment we still have to disable the optimisation because it breaks in some 
situations.

>and sparc64 ports.  It would clean up a fair bit of stuff, and there's no

Actually they're pretty separate in all but name anyway.  A lot of the code is 
already segregated.

>something which should complicate or otherwise hinder the `serious' stuff.

Yes, that's definitely the case.

p.

---

From: Alan Cox <[email-masked]>
Date: Thu, 2 Jul 1998 12:04:15 +0100 (BST)

> flame for that one) is doing so out of choice.

Oh I don't doubt that people are running museum pieces and they care about
performance however its not an option to cripple the performance of real
machines for the old old CPUs. Where it doesnt impact other processors
I really dont care how many clever stunts are pulled.

The beauty of teaching egcs __unaligned for the ARM2/3 is you get all
the other stuff working as well as Russell's clever stunts in PPP and IP
to make those work and nobody else pays anything for the cause.

In theory ARM2/3 people can opt to run only IP and not suffer too
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Thu, 02 Jul 1998 12:07:55 +0100

>In pretty much every other platform we don't fix up user space alignment
>traps.

Alpha does, and I thought others did too.

p.

---

From: Philip Blundell <[email-masked]>
Date: Thu, 02 Jul 1998 11:35:57 +0100

>we allow user code to perform unaligned accesses?

I think we might as well make it at least an option.  It doesn't really cost 
us anything.

>userland should not be so dependent on the alignment of structures.  If

That's precisely the reason it should be allowed to have unaligned accesses 
trapped.  User code often doesn't know about the ARM's alignment restrictions.
OK, this code is badly written, but it's often hard to spot the problem when 
it happens.  As I said, maybe trapping these accesses and delivering SIGBUS 
would be sufficient.

p.

---

From: Alan Cox <[email-masked]>
Date: Thu, 2 Jul 1998 11:50:21 +0100 (BST)

> think is highly unlikely.

Its basically a way of saying "Go away here is how you handle it" to whoever
is strange enough to want to fix the ARM2/3 code

In pretty much every other platform we don't fix up user space alignment
traps. In fact we do the reverse - we emulate things like byte instructions
the later Alpha CPU's have on the old Alpha or so it seems from the code. 
Encourage people to write to the faster cpus.

Alan

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Thu, 2 Jul 1998 12:57:33 +0100 (BST)

> it happens.  As I said, maybe trapping these accesses and delivering SIGBUS 

That is what I was thinking about doing, however, here are a few interesting
points to note:

1) The kernel may be able to handle unaligned accesses correctly.

2) If you allow a user program to perform unaligned accesses, and get the
   right result, then it allows people to write such programs.  If these
   programs are then run on a CPU without unaligned accesses enabled, then
   the errors could go undetected.
   However, since we're *all* (;)) going to be using the RPM format, and
   we're not going to use Slackware (are we), it won't cause a problem
   because you can't install an ARM6 RPM on an ARM3 machine.  I don't think
   so! (I'm sorry, am I presuming too much here?)

3) These is a small catch here: user programs already use unaligned accesses,
   and they do expect a certain action to happen.  For example, a simple test
   case on GCC 2.7.2.2:

   struct {
	unsigned short t1;
	unsigned short t2;
   } *v;

   int test ()
   {
        return v->t1 * v->t2;
   }

   Produces: gcc -S test.c -o -

   _test:
        mov     ip, sp
        stmfd   sp!, {fp, ip, lr, pc}
        ldr     r3, [pc, #LC0 - . - 8]
        sub     fp, ip, #4
        ldr     r3, [r3, #0]
        ldr     r2, [r3, #0]    @ movhi
        mov     r2, r2, asl #16
        mov     r2, r2, lsr #16
        ldr     r3, [r3, #2]    @ movhi  <---------------
        mov     r3, r3, asl #16
        mov     r3, r3, lsr #16
        mul     r0, r3, r2
        ldmea   fp, {fp, sp, pc}^
        .comm   _v, 4   @ 4

   an unaligned access that will be SIGBUS'd.  This means that potentially
   turning on the unaligned access trap could have a huge unwanted impact on
   the user programs.

   Ok, so someone's going to say that GCC 2.8.1 can use -mload-short-bytes,
   *but* there are a lot of binaries out there at the moment which have been
   compiled by GCC 2.7.2.2.

Unaligned access is not as clear-cut as it ought to be, and I believe that it
will be some time before we can use the unaligned access trap to full advantage.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.uk.linux.org/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

---

From: Paul Koning <[email-masked]>
Date: Thu, 2 Jul 1998 09:47:40 -0400

>> I feel that although it may improve performance a little to do
 >> this, but userland should not be so dependent on the alignment of
 >> structures.  If it is, then it is bad programming practice, and
 >> the code itself should be fixed.  After all, userland doesn't
 >> access hardware - that's the kernel's job.

As far as I know, there's a rule about structure alignment in C.  It
says that things are aligned according to what's in the struct.  For
example, a struct containing short ints is aligned to (at least) an
even address.  The compiler makes this happen when it allocates
things, AND it is entitled to assume it is true when using pointers to 
structs of that type.

If the assumption is not met, you have to tell the compiler (e.g., by
"packed" though "unaligned" is a good addition).  Then the compiler is 
obliged to generate code that doesn't assume alignment.

If the programmer omits "packed" or the like, but passes an odd
pointer, that's a bug and the fault lies with the programmer.
Unfortunately, bugs of that kind are quite common because some popular 
machines let the programmer get away with them.  Those of us using
machines that don't do this (I write a lot of MIPS code in daily life) 
learn or suffer...

	paul

---

From: Alan Cox <[email-masked]>
Date: Thu, 2 Jul 1998 15:03:22 +0100 (BST)

> things, AND it is entitled to assume it is true when using pointers to 

Yep. Actually the rule is the compiler can do what it damn well pleases
with the fields so long as the operations work. In all sane universes
that means padding to natural alignments

> obliged to generate code that doesn't assume alignment.

__attribute(packed) doesnt oblige the compiler to generate safe code
to access fields. Current egcs is the first to do this.

Alan

---

From: Philip Blundell <[email-masked]>
Date: Thu, 02 Jul 1998 15:20:50 +0100

>even address.  The compiler makes this happen when it allocates

That's true.  However, there are also ABI rules, and on the ARM the ABI forces 
32-bit alignment even for a structure in which all the elements are smaller 
than that.  This is the sort of thing that people don't expect.

(We've been through this a few weeks ago, actually.)

p.