svn commit: r296336 - in head/sys: dev/bhnd dev/pccard dev/pci isa kern sys x86/xen

Bruce Evans brde at optusnet.com.au
Thu Mar 3 16:19:50 UTC 2016


On Thu, 3 Mar 2016, Justin Hibbits wrote:

> On Thu, Mar 3, 2016 at 12:18 AM, Bruce Evans <brde at optusnet.com.au> wrote:
>> On Thu, 3 Mar 2016, Justin Hibbits wrote:
>>
>>> Log:
>>>  Replace all resource occurrences of '0UL/~0UL' with '0/~0'.
>>>
>>>  Summary:
>>>  The idea behind this is '~0ul' is well-defined, and casting to uintmax_t,
>>> on a
>>>  32-bit platform, will leave the upper 32 bits as 0.  The maximum range of
>>> a
>>>  resource is 0xFFF.... (all bits of the full type set).  By dropping the
>>> 'ul'
>>>  suffix, C type promotion rules apply, and the sign extension of ~0 on 32
>>> bit
>>>  platforms gets it to a type-independent 'unsigned max'.
>>
>> Why not use the correct signed value?  This value is -1, not the value, if
>> any, with all bits 1.  All bits 1 might be a trap representation, but it
>> ...
>> I don't like the plan to change the resource range type to uintmax_t.
>> 64 bits is just bloat for most 32-bit systems.  After fixing all the
>> hard-coded u_longs, you can just use a typdefed type which should be
>> uint32_t if possible.
>
> The change to uintmax_t has been on the horizon since rman was first
> introduced in 1998. There is a comment (was in sys/sys/rman.h, now in
> sys/kern/subr_rman.c) regarding switching to unsigned long long to
> support 36-bit addressing on IA32.

Hmm, I almost wrote a bit about u_long being correct in 1998, but the
impending breakage in C99 was known then and unsigned long long was
already de-facto breakage.

> My selfish reasoning for taking on
> the work now is supporting 36-bit addressing for PowerPC, where device
> resources are located at physical addresses >4GB.  Yes, it could be a
> machine dependent typedef, but what does that buy us in the grand
> scheme?  The data overhead is not large -- an extra 8 bytes per
> resource (resource_i), plus 12 (maybe up to 20 depending on how much
> padding is added) per resource_list_entry.  The code penalty is the
> added code to deal with using 2 registers (on RISC architectures) for
> each argument in resource related calls, plus the added math.  But
> much of this will get lost in the noise anyway.  Any runtime
> performance penalty is negligible, and only incurred at startup.
> After resource provisioning it's business as usual.

The initialization code is already quite large.

> ARMv7, PowerPC, i386, and MIPS32 all support 36-bit addresses.  New
> PowerPC Book-E (e6500 core) supports 40-bit physical address, as does
> MIPS with XPA. uint32_t typedef would be relevant in only 2 cases:
> i386 non-PAE, and armv4 (3, if armv7 becomes a separate arch from
> armv6, but I doubt that'll happen).

i386 non-PAE is perhaps 99% of i386 arches and 90% of all 32-bit arches.
i386 PAE is careful with most other typedefs to use uint64_t only when
needed.  It never uses uintmax_t for system types.

Using uintmax_t will give automatic bloat to uint128_t and beyond when
uintmax_t is expanded.  Of course, uintmax_t is too hard to expand because
expanding it would mainly give bloat and break ABIs.  This is the same
problem that led to adding the long long abomination and breaking long
and adding uintmax_t.  uintmax_t is already broken on at least amd64
since __int128_t exists there.  Just to avoid this problem, the type
should not be uintmax_t.  Then it is just as easy to make it the smallest
or fastest type that works as some larger type.  Almost any MD choice of
type except uintmax_t prevents the ABI changing.

Bruce


More information about the svn-src-all mailing list