[RFC] arm : ALIGNMENT_TRAP and MTD

David Woodhouse dwmw2 at infradead.org
Tue Jun 27 09:25:16 EDT 2006


On Fri, 2006-06-23 at 16:35 +0900, Hyok S. Choi wrote:
> Dear MTD folks,
> 
> In ARM arch, we're merging my uClinux/ARM tree into mainline.
> While merging a certain CPU support codes, we found a bit doubt on the
> conditional including of MTD configuration file in arch/arm/Kconfig.
> The CPU core has no H/W based alignment mechanism, thus can not handle unaligned access.
> However as many uClinux archs do, many of the platforms had supported MTD drivers.
> 
> Currently, _only_ ARM arch includes MTD configuration file conditionally as follows:
> 
> if ALIGNMENT_TRAP
> source "drivers/mtd/Kconfig"
> endif

Historically, ARM was the only architecture which attempted to run Linux
without unaligned accesses "just working" -- either natively in the CPU
or through fixups. This situation was considered 'broken'. 

The problem manifests itself in the NOR chip drivers, but only if the
bus width is greater than 1 byte, and if a user of the MTD device writes
from a buffer which is not aligned in memory to that bus width.

JFFS2 does this, when garbage-collecting dirent nodes. Since the name
field is just an array of characters, it's stored in memory in the
'struct jffs2_full_dirent' without alignment constraints -- and it's
always an odd address because it comes after the single char used for
the 'type' field.

I did once add a couple of 'get_unaligned()' calls to the places in the
NOR flash chip drivers which matter, but Alan objected -- because
get_unaligned() should be reserved for the case where the datum is
_expected_ to be unaligned, not where it simply _might_ be unaligned.

These days, we support a number of architectures which just _cannot_ fix
up alignment errors. On FR-V without an MMU, for example, the alignment
trap is an imprecise exception. The networking code now works correctly
in that situation too, I believe -- I think the correct fix would be for
me to put back the get_unaligned() in a few places which I originally
added them, but then removed them again when Alan objected. 

However, the objection that get_unaligned() should be used only when the
datum is _expected_ to be unaligned is still a valid one. It'll lead to
suboptimal code on architectures where the CPU doesn't natively handle
misaligned loads, when the misaligned case is _not_ the common case.

I think what we should actually do, if we're going to accept that Linux
runs without alignment fixups, is introduce a new get_maybe_unaligned()
call which should be used if there is a low, but non-zero, probability
of the address being unaligned. It would still take the
dereference-and-fault path on most architectures, but those
architectures which _really_ cannot deal with an alignment trap can emit
the slow-path instead.

Actually, I think I'd rather see just a second argument to
get_unaligned() which gives an estimate of the probability that the
address is unaligned. Each architecture can make its own decision about
where the threshold should be between just dereferencing the pointer and
maybe taking a trap, and emitting the slow code to load it manually. It
depends on the relative costs of each, on any given architecture.

-- 
dwmw2





More information about the linux-mtd mailing list