This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] powerpc: New feature - HWCAP/HWCAP2 bits in the TCB


On 07/01/2015 03:12 PM, Steven Munroe wrote:
> If you think about the requirements for a while it becomes clear. As the
> HWCAP cache would have to be defined and initialized in either libgcc or
> libc, accept will be none local from any user library. So all the local
> TLC access optimization's are disallowed. Add the requirement to support
> dl_open() libraries leaves the general dynamic TLS model as the ONLY
> safe option.

That's not true anymore? Alan Modra added pseudo-TLS descriptors to POWER
just recently[1], which means __tls_get_addr call is elided and the offset
returned immediately via a linker stub for use with tp+offset. However,
I agree that even Alan's great work here is still going to be several
more instructions than a raw tp+offset access. However, it would be
interesting to discuss with Alan if his changes are sufficiently good
that the out-of-order execution hides the latency of this additional
instructions and his methods are a sufficient win that you *can* use
TLS variables?

> Now there were a lot of suggestions to just force the HWCAP TLS
> variables into initial exec or local exec TLS model with an attribute.
> This would resolve to direct TLS offset in some special reserved TLS
> space?

It does. Since libc.so is always seen by the linker it can always allocate
static TLS space for that library when it computes the maximum size of
static TLS space.

> How does that work with a library loaded with dl_open()? How does that
> work with a library linked with one toolchain / GLIBC on Distro X and
> run on a system with a different toolchain and GLIBC on Distro Y? With
> different versions of GLIBC? Will HWCAP get the same TLS offset? Do we
> end up with .text relocations that we are also trying to avoid?

(1) Interaction with dlopen?

The two variables in question are always in libc.so.6, and therefore are
always loaded first by DT_NEEDED, and there is always static storage
reserved for that library.

There are 2 scenarios which are problematic.

(a) A static application accessing NSS / ICONV / IDN must dynamically
    load libc.so.6, and there must be enough reserve static TLS space
    for the allocated IE TLS variables or the dynamic loader will abort
    the load indicating that there is not enough space to load any more
    static TLS using DSOs. This is solved today by providing surplus
    static TLS storage space.

(b) Use of dlmopen to load multiple libc.so.6's. In this case you could
    load libc.so.6 into alternate namespaces and eventually run out of
    surplus static TLS. We have never seen this in common practice because
    there are very few users of dlmopen, and to be honest the interface
    is poorly documented and fraught with problems.

Therefore in the average scenario it will work to use static TLS, or
IE TLS variables in glibc in the average case. I consider the above
cases to be outside the normal realm of user applications.

e.g.
extern __thread int foo __attribute__((tls_model("initial-exec")));

(2) Distro to distro compatibility?

With my Red Hat on:

Let me start by saying you have absolutely no guarantee here at all
provided by any distribution. As the Fedora and RHEL glibc maintainer
your vendor is far outside the scope of support and such a scenario is
never possible. You can wish it, but it's not true unless you remain
very very low level and very very simple interfaces. That is to say
that you have no guarantee that a library linked by a vendor with one
toolchain in distro X will work in distro Y. If you need to do that
then build in a container, chroot or VM with distro Y tools. No vendor
I've ever talked to expects or even supports such a scenario.

With my hacker hat on:

Generally for simple features it just works as long as both distros
have the same version of glibc. However, we're talking only about
the glibc parts of the problem. Compatibility with other libraries
is another issue.

(3) Different versions of glibc?

Sure it works, as long as all the versions have the same feature and
are newer than the version in which you introduced the change. That's
what backwards compatibility is for.

(4) Will HWCAP get the same TLS offset? 

That's up to the static linker. You don't care anymore though, the gcc
builtin will reference the IE TLS variables like it would normally as
part of the shared implementation, and that variable is resolved to glibc
and normal library versioning hanppens. The program will now require that
glibc or newer and you'll get proper error messages about that.

(5) Do we end up with .text relocations that we are also trying to avoid?

You should not. The offset is known at link time and inserted by the
static linker.

> Again the TCB avoids all of this as it provides a fixed offset defined
> by the ABI and does not require any up-calls or indirection. And also
> will work in any library without induced hazards. This clearly works
> across distros including previous version of GLIBC as the words where
> previously reserved by the ABI. Application libraries that need to run
> on older distros can add a __built_cpu_init() to their library init or
> if threaded to their thread create function.

You get a crash since previous glibc's don't fill in the data?
And that crash gives you only some information to debug the problem,
namely that you ran code for a processors you didn't support.

I've suggested to Carlos that this is a problem with the use of the
TCB. If one uses the TCB, one should add a dummy symbol that is versioned
and tracks when you added the feature, and thus you can depend upon it,
but not call it, and that way you get the right versioning. The same
problem happened with stack canaries and it's still painfully annoying
at the distribution level.

It is true that you could use LD_PRELOAD to run __builtin_cpu_init()
on older systems, but you need to *know* that, and use that. What
provides this function? libgcc?

Do you want to use the IBM Advance Toolchain for POWER to be able to 
support this feature across all distributions at the same time by not
requiring any particular glibc version and by doing the initialization
out of band via __builtin_cpu_init() for older glibc? It will still result
in a weird crash of the application if the user doesn't know any better.

It is certainly a benefit to using the TCB, that this kind of use case
is supported. However, in doing so you adversely impact the distribution
maintainers for the benefit of?

Cheers,
Carlos.

[1] https://sourceware.org/ml/libc-alpha/2015-03/msg00580.html


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]