RFR: 8233073: Make BitMap accessors more memory ordering friendly
Erik Österlund
erik.osterlund at oracle.com
Mon Oct 28 15:29:35 UTC 2019
Hi,
I have need for accessors on BitMap being more explicitly memory
ordering aware, to fix a bug in ZGC for AArch64
(https://bugs.openjdk.java.net/browse/JDK-8233061).
In particular, I need failed bit sets to still have acquire semantics,
and I need a getter with acquire semantics.
My intention is to solve the problem by making the relevant BitMap
accessors accept explicitly passed in memory ordering parameters, and
utilize them. I draw the line of conservativeness at supporting
IRIW-consistent loads. Having spent a great deal of time finding a
single algorithm that breaks due to IRIW-consistency violations, and
knowing the complexity of algorithms that actually can break due to
that, I would be *very* surprised if we got anywhere close to that.
Therefore, acquiring loads are the most conservative loads I support.
This is explicitly stated in the API, so that anyone that actually
relies on IRIW consistency in the future can reconsider that, and add a
mode that fences before loads on nMCA machines.
The main points of controversy with this patch, where I expect people to
have wildly different opinions and hopefully get at least a little bit
upset are the following:
1) For the same reason that our implementation of Atomic::cmpxchg does
not supply both one ordering for success and one for failed CAS, unlike
the C++11 atomic counter part, I do not do so either in the par_set_bit
API. In the Atomic API, this was very much intentional, because it is
tricky to reason about the subtle effects of having relaxed failed CAS
and conservative success. In fact, it's a bug of precisely that nature I
am chasing. Therefore, I wish to transfer that same reasoning to the
par_set_bit API, and not allow passing in a weaker failing memory
ordering. A consequence of this is that I have made the uses of this API
more conservative for failed bit flips than it was in the past. However,
this new API allows relaxing the real pain point of the API: the success
case (with it's bi-directional full fencing semantics). So I expect it
can be applied to make RMO architectures happier where it really matters
in the end. However, I will not attempt to prove that relaxing these
calls is okay in various places with this patch: that is outside of my
scope, I'm merely adding API hooks for allowing that.
2) The default strength on the getter is memory_order_relaxed and not
memory_order_conservative. After looking at uses, I realize it's used
mostly in single threaded contexts by compiler code, and there is
seemingly only a single use in the VM that cares about having acquire
(ZGC, and it's broken today). While letting the frequency of uses decide
what is the default rather than what is safest is not something I would
normally do, it does feel like since the norm is so vastly in favour of
the relaxed variant, I don't want to let the one ZGC use case clutter
half the VM with explicitly relaxing the load. I am okay with reverting
that decision if people want me to.
CR:
http://cr.openjdk.java.net/~eosterlund/8233073/webrev.00/
Bug:
https://bugs.openjdk.java.net/browse/JDK-8233073
Thanks,
/Erik
More information about the hotspot-gc-dev
mailing list