RFR(xxs): 8213236: A partial removed/deleted JavaThread cannot transition
Robbin Ehn
robbin.ehn at oracle.com
Thu Nov 1 16:49:48 UTC 2018
Hi Dan,
On 01/11/2018 16:58, Daniel D. Daugherty wrote:
> On 11/1/18 7:57 AM, Robbin Ehn wrote:
>> Hi all please review,
>>
>> In 8212933 we moved the cancellation of a handshake to the VM thread, for sanity
>> an assert was added to make sure the JavaThread do not cancel. (technically this
>> works also, but to keep a simple model it should be done by the VM thread)
>>
>> A JavaThread that is terminated but not yet free should not follow the safepoint
>> protocol. Since the VM thread running the safepoint cannot see such a thread
>> it's confusing and error-prone doing safepoint checks and transitions from a
>> thread not 'attached' to the VM.
>>
>> Issue:
>> https://bugs.openjdk.java.net/browse/JDK-8213236
>
> I updated the bug to be a bit more clear about what the problem is.
> Please let me know if my analysis is correct or not...
Yes, that is correct, thanks!
>
>
>>
>> Code:
>> diff -r 13ad2bfee99e src/hotspot/share/runtime/vmThread.cpp
>> --- a/src/hotspot/share/runtime/vmThread.cpp Thu Nov 01 09:57:57 2018 +0100
>> +++ b/src/hotspot/share/runtime/vmThread.cpp Thu Nov 01 12:40:47 2018 +0100
>> @@ -319,7 +319,9 @@
>> // Notify the VMThread that the last non-daemon JavaThread has terminated,
>> // and wait until operation is performed.
>> void VMThread::wait_for_vm_thread_exit() {
>> - { MutexLocker mu(VMOperationQueue_lock);
>> + assert(Thread::current()->is_Java_thread(), "Should be a JavaThread");
>> + assert(((JavaThread*)Thread::current())->is_terminated(), "Should be off
>> threadslist");
>
> This should be "should be terminated". is_terminated()
> doesn't necessarily mean the JavaThread is not on the
> global ThreadsList.
If the thread ask itself or if you hold Threads_locks it is implicit the same.
When we do exit we first take Threads_lock, remove our self from the global
list, set state terminated and then unlock Threads_lock.
But I'm perfectly fine with "should be terminated" instead.
>
>
>> + { MutexLockerEx mu(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag);
>
> Yup. I agree with this addition of Mutex::_no_safepoint_check_flag.
>
> However, I think there is one more:
>
> src/hotspot/share/runtime/thread.cpp:
> before_exit(thread);
>
> thread->exit(true);
>
> // Stop VM thread.
> {
> // 4945125 The vm thread comes to a safepoint during exit.
> // GC vm_operations can get caught at the safepoint, and the
> // heap is unparseable if they are caught. Grab the Heap_lock
> // to prevent this. The GC vm_operations will not be able to
> // queue until after the vm thread is dead. After this point,
> // we'll never emerge out of the safepoint before the VM exits.
>
> MutexLocker ml(Heap_lock);
>
> VMThread::wait_for_vm_thread_exit();
>
> You fixed the one in wait_for_vm_thread_exit(), but I think
> that this: "MutexLocker ml(Heap_lock)" is also a problem.
Silly me missed that one :)
Yes, but it is used in vm op prolog meaning that VM thread takes it.
So if we hold it we can deadlock with vm thread.
E.g.
vmGCOperations.cpp L290
vm_operations_g1.cpp L214
I don't understand this comment:
"GC vm_operations can get caught at the safepoint, and the heap is unparseable
if they are caught."
I don't think we should grab Heap_lock at all and we should just remove it.
If there is a problem with "unparseable heap", taking Heap_lock seems to the
wrong solution.
/Robbin
>
> Dan
>
>
>
>> _should_terminate = true;
>> VMOperationQueue_lock->notify();
>> }
>>
>> Passes t1-2.
>>
>> Thanks Robbin
>
More information about the hotspot-runtime-dev
mailing list