RFR: 8203817: Monitor::try_lock() should not call check_prelock_state()
Erik Österlund
erik.osterlund at oracle.com
Fri May 25 14:02:15 UTC 2018
Hi Per,
Yes. Looks good to me.
Thanks,
/Erik
On 2018-05-25 15:23, Per Liden wrote:
> On 05/25/2018 01:47 PM, Per Liden wrote:
>> On 05/25/2018 11:45 AM, David Holmes wrote:
>>> On 25/05/2018 7:33 PM, Per Liden wrote:
>>>> Hi David,
>>>>
>>>> On 05/25/2018 09:51 AM, David Holmes wrote:
>>>>> Hi Erik,
>>>>>
>>>>> On 25/05/2018 5:17 PM, Erik Osterlund wrote:
>>>>>> Hi David,
>>>>>>
>>>>>> The change Per is proposing would make try_lock perform the same
>>>>>> checks that locking without safepoint checks does.
>>>>>
>>>>> Yet locking without a safepoint check also ensures
>>>>> _safepoint_check_required != Monitor::_safepoint_check_always. But
>>>>> try_lock does not and can be applied to both kinds of
>>>>> Monitors/Mutexes. Further it also has a stated, but not checked,
>>>>> precondition that the thread is not _thread_in_vm - though that
>>>>> may only be an issue if we were to block.
>>>>>
>>>>> I'm looking at the checks in check_prelock_state wondering which
>>>>> are only truly needed if we risk blocking? I think most of them,
>>>>> with the exception of is_crash_protected. Are we guaranteed never
>>>>> to run this JFR code on the WatcherThread?
>>>>>
>>>>> Though I'm also concerned about lock-ranking and deadlocks if we
>>>>> try_lock multiple locks. Notwithstanding the rank/deadlock code is
>>>>> far from ideal already.
>>>>>
>>>>> I don't mind removing checks/guards that really don't apply in the
>>>>> try_lock case, but I'm wary of removing all guards without being
>>>>> more sure of that.
>>>>
>>>> Ok, so how about we just avoid the bad parts, by doing this:
>>>>
>>>> http://cr.openjdk.java.net/~pliden/8203817/webrev.1
>>>
>>> That seems a reasonable compromise.
>>
>> Good! Thanks for looking at this David!
>
> Erik, are you also happy with this compromise?
>
> /Per
>
>>
>> /Per
>>
>>>
>>> There may still be possible deadlock issues if we use try-lock to
>>> acquire multiple locks, but we probably don't do that ... and as
>>> Erik noted there are issues with the ranking/deadlock detection anyway.
>>>
>>> Thanks,
>>> David
>>>
>>>> /Per
>>>>
>>>>>
>>>>> Thanks,
>>>>> David
>>>>> -----
>>>>>
>>>>>> Perhaps locking without safepont checks could perform more sanity
>>>>>> checks, but that is a separate issue. I think try_lock should
>>>>>> perform the same checks that locking without safepoint checks
>>>>>> does. The alternatives are then to
>>>>>>
>>>>>> 1) Remove checking the prelock state like Per suggests for
>>>>>> try_lock (then they do the same checks), or
>>>>>> 2) Overhaul the safepoint checking refactoring out the bits that
>>>>>> check the safepointing sanity chrcka from other deadlock checks
>>>>>> (and correct those to check for rank <= special, and not ==
>>>>>> special), remove the safepoint checking part from try_lock and
>>>>>> adding the deadlock checking parts to lock without safepoints.
>>>>>>
>>>>>> Doing #2 seems like a different RFE. In fact I believe that would
>>>>>> be https://bugs.openjdk.java.net/browse/JDK-8184732
>>>>>> <https://bugs.openjdk.java.net/browse/JDK-8184732?jql=text%20~%20%22deadlock%20check%22> that
>>>>>> I filed a while back.
>>>>>>
>>>>>> In summary, there is a whole bunch of problems in the deadlock
>>>>>> detection system, and #2 makes it hard to not get dragged down in
>>>>>> the rabbit hole. #1 is sufficient to make try_lock check as much
>>>>>> (or little) as locking without safepoint checking. And I think
>>>>>> that is enough for the scope of this change.
>>>>>>
>>>>>> Looks good to me.
>>>>>>
>>>>>> Thanks,
>>>>>> /Erik
>>>>>>
>>>>>> On 25 May 2018, at 08:53, David Holmes <david.holmes at oracle.com
>>>>>> <mailto:david.holmes at oracle.com>> wrote:
>>>>>>
>>>>>>> Hi Per,
>>>>>>>
>>>>>>> Exactly what condition(s) does JFR violate? This is throwing
>>>>>>> away all the checks that guard against incorrect monitor use.
>>>>>>> It's not just about whether you'd block trying to acquire the
>>>>>>> Monitor, it's also about whether it is safe to acquire it from
>>>>>>> that code/thread in the first place. (Though I think some of the
>>>>>>> checks in there should also be considering the value of
>>>>>>> _safepoint_check_required.)
>>>>>>>
>>>>>>> Thanks,
>>>>>>> David
>>>>>>>
>>>>>>>
>>>>>>> On 25/05/2018 4:39 PM, Per Liden wrote:
>>>>>>>> In debug builds, Monitor::try_lock() calls
>>>>>>>> check_prelock_state() to check the thread state, etc. The
>>>>>>>> intention is to verify that the call is made from the correct
>>>>>>>> context, a context where we're allowed to block and potentially
>>>>>>>> safepoint. Unlike Monitor::lock(), Monitor::try_lock() will
>>>>>>>> never block, hence the call to check_prelock_state() is overly
>>>>>>>> strict and we should remove it. Removing it would match the
>>>>>>>> behavior of all other non-blocking functions, like
>>>>>>>> Monitor::lock_without_safepoint_check(), which doesn't call
>>>>>>>> check_prelock_state() either (for a good reason).
>>>>>>>> The specific problem I've run into with this is related to JFR.
>>>>>>>> Monitor::try_lock() is by JFR to allow non-blocking event
>>>>>>>> generation, so that you can generate JFR events from "any"
>>>>>>>> context without risk blocking/safepointing (the logic is doing
>>>>>>>> something like, if try_lock() fails then put the event on a
>>>>>>>> different queue and let the next owner of the lock handle it).
>>>>>>>> The overly strict checks done by check_prelock_state() in
>>>>>>>> try_lock() breaks this logic, which in turn means that you
>>>>>>>> can't generate JFR event from "any" context as was intended.
>>>>>>>> The patch to fix this is a one-liner, just remove the call to
>>>>>>>> check_prelock_state().
>>>>>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8203817
>>>>>>>> Webrev: http://cr.openjdk.java.net/~pliden/8203817/webrev.0
>>>>>>>> /Per
More information about the hotspot-dev
mailing list