-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libmpathutil: explicitly annotate {get,put}_multipath_config as weak #86
Conversation
Why would you want to use |
All functions being assumed to be weak by default comes at great cost in terms of performance, yet in 99% of instances it has no value. More details by someone who knows much more than I do: https://maskray.me/blog/2021-05-16-elf-interposition-and-bsymbolic |
How do you infer that we're doing that? All we do is rely on the standard ELF symbol resolution mechanism, which does not assume that all symbols are weak.
Please provide numbers showing how much speed-up you observe on a given plaform. To my understanding, PLT symbol lookups are mainly expensive when the function is first used (because this requires a call to the dynamic linker). Subsequent calls only add the overhead of one indirect jump (How to Write Shared Libraries, §1.5.5). For multipathd, the startup-time overhead should be negligible, as it's a long-running process. Interactive calls to multipath or multipathd -k start up fast, they need no optimization IMO. multipath is called frequently from udev rules (as By using symbol versioning, we already restrict the number of non-local symbols in libmultipath and libmpathutil to ~190 and ~80, respectively, which is not overwhelmingly much for modern CPUs. I have read the blog article that you linked, but I'd be lying if I said I understand everything. There's a large zoo of compiler and linker options that interact with each other in hard-to-understand ways. The author of that article seems to be specialized in proposing even more such options, which make it even more difficult to understand what's going on. Unless I see proof that this has measurable performance benefits in real-world scenarions, I'd rather stick with the easily understandable default symbol lookup, which does not require the I also read Linus' post, which is much easier to understand, and I agree that he's got a point. There has been a paradigm shift during the last ~15 years with "disk" space getting larger, faster, and cheaper all the time. The arguments pro DSO are getting weaker, while those against DSO are getting stronger. Maybe some day we should reconsider just linking multipathd and multipath statically. The only library that's actually used by external code is libmpathpersist, and I suppose we could fix that somehow, too. I'd prefer that to us supporting fancy hard-to-grok compiler and linker options. |
From the blogpost: For a shared object, a default visibility Compiling with just
As you can see, the symbol is
I'm not arguing for this option for multipath-tools specifically, I completely agree with your assessments here. I'm just trying to make a small contribution towards making entire systems buildable with
The
I hope that makes the parts relevant to this patch clear.
I'd argue this is easy enough to understand too: functions are by default direct bound. Functions marked as weak are treated as weak. In the default you describe, every function is weak unless it has non-default visibility (not really an option for DSOs, CMIIW). But you're the boss either way.
Sure, if there is no DSO there is no problem. I don't exactly know a lot about the current issues of your project, so I wanted to submit a patch that doesn't really question the status quo all that much. Completely fine with dropping this if that's the road you'd like to go down.
I agree the blogpost is daunting, but the manpage does a decent job: https://man.archlinux.org/man/extra/lld/ld.lld.1.en#Bsymbolic-non-weak-functions |
It sure can, this is intended, as you certainly understood.
This makes no sense to me.
What systems are you talking about? Are there any distributions that have this plan? Which? Also, the blog article states:
So distributions can actually use
Which "standard" are you talking about? The only standard that I'm aware of is the ELF standard, which our code complies to.
preemptible != weak. The difference is explained in the ELF standard, §III.1, section "Symbol Table". For dynamic linking, it only affects the linker's behavior for undefined symbols. For static linking, it has additional effects. Btw, have you verified whether with your patch, but without
Fair enough, but "pretty great cost" is vague. I described previously which would be the only cases worth optimizing in this manner. I'd still like to see numbers for our code. Speed improvement for kernel compilation doesn't matter here.
Again, which distributions are planning to do this?
AFAICS, this is not standard compliant, either, at least not if "standard" refers to the ELF standard.
I do understand what the option does, and why it provides a (theoretical, as far we're concerned) performance benefit. But there are tons of other options with vaguely similar effects. I'm pretty sure that multipath-tools can't support arbitrary combinations of these. We currently have a similar problem: our code doesn't work with LTO (#18). Unlike
Only supported by clang? Is there any plan to enable this in the GNU toolchain as well? All this said, I will consult with some tool chain experts to find out what they think about re-introducing the "weak" attribute for these symbols; in particular, whether that could have undesirable consequences with other compiler or linker options. I'm also open to opinions of @cvaroqui, @bmarzins, and other regular contributors to this project. If the campaign of the blog author is successful, and major distributions start using this option by default, we will certainly need to adapt to it in some way. |
In practice, yes.
None currently (at least any that I know of), admittedly. This patch came out of an experiment to see how much of the proposed plan in the blogpost is possible with current code, with Buildroot (you can add additional linker flags there). If anyone wants to follow up on this, I propose they not do that since testsuites should absolutely be run for making sure everything works, & Buildroot just does not support that all that well (unsurprisingly).
I did say you can ignore those sections (in the blogpost) because they're not relevant to what I'm proposing here, right in the section you quoted. Note how I mentioned
Again, I'll agree on that point, it doesn't really matter all that much for
This is true, yes (technically no, but yes in practice). However, the argument for Again, this is meant as a general statement for all code within a distro, not just multipath-tools. You are free to disagree with that statement; maybe you think all symbols being preemptible (what I would personally consider ludicrous) is a good default, or that it matters to strictly conform to the standard despite its inefficiencies.
This is not true. It changes the semantics of
I agree, however I do believe
lld, not Clang. You can use ld.lld with GCC, it's a fairly GNU-compatible linker. But more realistically, it is supported by mold, which is fairly popular among Gentoo users. You might consider the binutils patches a "plan" of sorts, however the ML postings of these were basically ignored. So no obvious objections, just a patch that nobody noticed.
I hope so! :) |
Forgot to respond to this earlier, but yes, it works. I just ran the testsuite & it's all green. |
I'll be the first to admit that I'm not a linker wizard, but IIRC adding "attribute((weak))" won't have any effect on how the multipath tools are currently linked. I did a little bit of testing with it (using our standard build flags), and everything appears to work as expected. If it really is harmless to add, then I have no objections to adding it. But for this to work correctly with -Bsymbolic-non-weak-functions, wouldn't the definitions in libmultipath also need to be weak. Otherwise libmultipath will use its default definition, which wouldn't match with what multipathd uses. Does multipathd really work with -Bsymbolic-non-weak-functions set? Am I misunderstanding something?
libmpathvalid is also designed to be used by external code and links to libmulitpath. Actually to me, these libraries seem to be where statically linking libmultipath would be the most useful. I've never been a fan of how we expose so much of libmultipath to anyone who wants to use one of our libraries build on top of it. Even with libmultipath.version, we still need to expose a lot of poorly named functions that could easily get interposed. For instance, if some program that links to libmpathvalid or libmpathpersist has its own function named "init_config", things will not work correctly since the libmultipath function won't get used (I suppose this is another place where -Bsymbolic-non-weak-functions would fix things) |
Thank you for the catch, fixed. |
…onfig as weak When linking libmultipath & libmpathutil with -Bsymbolic-non-weak-functions, multipathd segfaults because the weak nature of these symbols is not recognized. Add the necessary attributes to make that clear to the linker. Fixes: opensvc#26 # sort of Tested-by: ns <[email protected]>
I've played around with this, too, and it seems to behave as advertized (last version, with @bmarzins fix included). IOW, re-introducing the "weak" attribute probably won't hurt us. I'm still kind of sceptical about using |
We can't easily do this though, as we'd again be in license compatibility troubles, unless we completely avoid linking with GPL 3.0 code, or other code that isn't fully compatible to GPL-v2.0-only, for that matter. |
I'll merge this patch in the forthcoming release. I shall add that this does not imply that we (the multipath-tools upstream developers) make any promises wrt support of But both @bmarzins and myself have experimented with it and didn't find any regressions, so I'm applying it for now. |
When linking libmpathutil with -Bsymbolic-non-weak-functions, multipathd segfaults because the weak nature of these symbols is not recognized.
Add the necessary attributes to make that clear to the linker.
Fixes: #26 # sort of
Tested-by: ns [email protected]