RFR(s): 8209139: globalCounter bootstrap issue
Daniel D. Daugherty
daniel.daugherty at oracle.com
Thu Nov 8 14:01:39 UTC 2018
On 11/8/18 6:02 AM, David Holmes wrote:
> On 8/11/2018 8:42 PM, Robbin Ehn wrote:
>> On 11/8/18 11:19 AM, David Holmes wrote:
>>> On 8/11/2018 7:14 PM, Robbin Ehn wrote:
>>>> Hi David,
>>>>
>>>> On 11/7/18 10:03 PM, David Holmes wrote:
>>>>> Hi Robbin,
>>>>>
>>>>> I wrote two responses to this last night before deciding to "sleep
>>>>> on it". :)
>>>>
>>>> :)
>>>>
>>>>>
>>>>> Thanks for the extended explanations - I understand what you are
>>>>> doing more clearly now. I see Dan has made a few minor comments
>>>>> and I don't have anything additional to add. So Reviewed.
>>>>
>>>> Thanks!
>>>>
>>>> For reference:
>>>> Inc:
>>>> http://cr.openjdk.java.net/~rehn/8209139/v2/inc/webrev/
>>>
>>> Changes seem fine.
>>
>> Thanks!
>>
>>>
>>> One clarification. I had interpreted previous discussions as meaning
>>> that threads other than the initial thread might be able to grab a
>>> ThreadsListHandle before they have been added because they would get
>>> the bootstrap list. But that seems not to be the case in general -
>>> once an added thread exists (I'm not sure of the exact point where
>>> this happens) _java_threads_list will cease to point to the
>>> bootstrap list and will never point to it again - correct?
>>
>> Yes!
>>
>>> So it still seems to me you could simply initialize
>>> _java_threads_list to a zero length list and the check for "is
>>> bootstrap" would just be a check if the list length is zero - no?
>>> It's the only time you can ever have a zero length threads list.
>>
>> The problem is that if it's not the bootstrap list and you are not
>> SMR thread
>> you are not allowed to deference the pointer, that can crash.
>
> Ah I see - the list pointed to by _java_threads_list could be
> deallocated as soon as you've read it.
If the ThreadsList pointed to by _java_threads_list is not acquired
by a ThreadsListHandle, then that ThreadsList can be freed at any
point after it is manually copied.
Dan
>
> Thanks,
> David
>
> So if you
>> are not
>> a SMR thread we need to determine just on the pointer value that this
>> is the
>> bootstrap threadslist. With current patch that would not crash there,
>> but we
>> might crash later or hit the assert. I didn't want to add another way
>> we can
>> crash. The spot we can crash is on during
>> ThreadsSMRSupport::threads_do() in
>> verify_hazard_ptr_scanned(). This we should fix so we always hit the
>> assert after, which would make troubleshooting simpler for people not
>> so familiar to
>> the protocol.
>>
>> Thanks, Robbin
>>
>>>
>>> Thanks,
>>> David
>>>
>>>> Full:
>>>> http://cr.openjdk.java.net/~rehn/8209139/v2/full/webrev/
>>>>
>>>> /Robbin
>>>>
>>>>>
>>>>> My personal preference is to treat the early initialization in the
>>>>> initial thread as a special case - using "hacks" like the
>>>>> "Threads::number_of_threads() == 0" test. Allowing any thread to
>>>>> be able to access a ThreadsList (and by extension GlobalCounter)
>>>>> before it has properly initialized may turn out to be useful one
>>>>> day, but it may also mask bugs, as other threads should be
>>>>> following strict initialization protocols that don't permit
>>>>> non-trivial actions prior to being fully initialized.
>>>>>
>>>>> Thanks,
>>>>> David
>>>>>
>>>>> On 7/11/2018 9:53 PM, Robbin Ehn wrote:
>>>>>> Hi David,
>>>>>>
>>>>>> On 2018-11-07 12:10, David Holmes wrote:
>>>>>>> Hi Robbin,
>>>>>>>
>>>>>>> On 7/11/2018 8:01 PM, Robbin Ehn wrote:
>>>>>>>> Hi David,
>>>>>>>>
>>>>>>>> On 2018-11-07 10:40, David Holmes wrote:
>>>>>>>>> Hi Robbin,
>>>>>>>>>
>>>>>>>>> Can't you just use an _initialized flag ??
>>>>>>>>
>>>>>>>> I can, but I need to changes many places since the ThreadsList
>>>>>>>> is not expected
>>>>>>>> to be null. And I do not see how checking that flag instead
>>>>>>>> checking if the list
>>>>>>>> is the bootstrap would be better.
>>>>>>>
>>>>>>> From the bug there seemed to be only once place that needed
>>>>>>> this check. Where are all these other places?
>>>>>>
>>>>>> All potential cases that uses a ThreadsList before init.
>>>>>> These are very had to track down, so I don't know of any others.
>>>>>>
>>>>>> I'm adding that exception, so you may have a ThreadsList if you
>>>>>> are _not_ part
>>>>>> of the SMR protocol if that list is the bootstrap list.
>>>>>>
>>>>>>>
>>>>>>>> Or statically initialize
>>>>>>>>> _java_thread_list to a zero-length list?
>>>>>>>>
>>>>>>>> It's statically initialized to _bootstrap_list. Since I'm going
>>>>>>>> to need to check
>>>>>>>> for a bootstrap list in a non-SMR-thread I can't follow the
>>>>>>>> pointer because we
>>>>>>>> can crash. So I need to know which address to check for, this
>>>>>>>> is the
>>>>>>>> _bootstrap_list. And since it's static I can't free it.
>>>>>>>
>>>>>>> Not following. Can't you initialize _java_thread_list directly
>>>>>>> to a zero-length list and that will "just work" because you'll
>>>>>>> iterate zero items? There will only ever be one zero-length
>>>>>>> threads-list right?
>>>>>>
>>>>>> The iteration is not the problem, it is the protocol verification.
>>>>>> Right know you may only have a ThreadsList if you are part of
>>>>>> SMR-protocol,
>>>>>> which means the VM must have done it's init. With the above
>>>>>> exception to the
>>>>>> protocol the validation works for all cases we have today and all
>>>>>> cases we might
>>>>>> have in the future that I can think of.
>>>>>>
>>>>>> With this you can use ThreadsListHandle before init and you don't
>>>>>> need to pay
>>>>>> attention to if your code could ever possibly be run before init
>>>>>> or in the init
>>>>>> code. So I'm trying to create robustness because as SymbolTable
>>>>>> issue could pass t1-5 without that code path being executed.
>>>>>>
>>>>>> That why I tested with a ThreadsListHandle in the init code to
>>>>>> make sure we actually do create at least one there.
>>>>>>
>>>>>> /Robbin
>>>>>>
>>>>>>>
>>>>>>> Thanks,
>>>>>>> David
>>>>>>> -----
>>>>>>>
>>>>>>>>> This seems overly elaborate.
>>>>>>>>
>>>>>>>> If we get a SMR bug doing it different could give us wired
>>>>>>>> crashes instead of
>>>>>>>> clean assert failures. That is why you think this is 'overly
>>>>>>>> elaborate' I guess.
>>>>>>>>
>>>>>>>>>
>>>>>>>>> I'm not even concerned about the existing "hack" - checking
>>>>>>>>> for "Threads::number_of_threads() == 0" has always been a
>>>>>>>>> simple way to see if you are very early in the init sequence.
>>>>>>>>
>>>>>>>> Well it only solves the problem for the GlobalCounter.
>>>>>>>> And in theory we could have added non-JavaThreads to the RCU
>>>>>>>> thread-set they
>>>>>>>> should be checked.
>>>>>>>>
>>>>>>>> Thanks, Robbin
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> David
>>>>>>>>>
>>>>>>>>> On 7/11/2018 6:56 PM, Robbin Ehn wrote:
>>>>>>>>>> Hi all, please review.
>>>>>>>>>>
>>>>>>>>>> When changing the hashtable for SymbolTable we did a hack to
>>>>>>>>>> handle the case
>>>>>>>>>> when symbols gets inserted before the VM is proper
>>>>>>>>>> initialized, by doing nothing
>>>>>>>>>> in the GlobalCounter if there is no threads. The problem is
>>>>>>>>>> that the thread
>>>>>>>>>> creating the VM is not yet added to the VM (non-SMR-thread)
>>>>>>>>>> and thus
>>>>>>>>>> ThreadsListHandle do not yet work for that thread. Trying to
>>>>>>>>>> move the addition
>>>>>>>>>> of the creating thread earlier in the bootstrap is troublesome.
>>>>>>>>>>
>>>>>>>>>> This removes that hack and do a more generic solution for
>>>>>>>>>> ThreadsList instead.
>>>>>>>>>> To make it safe to verify that we are talking about the
>>>>>>>>>> bootstrap ThreadsList from a non-SMR-thread we cannot follow
>>>>>>>>>> that pointer. Using null was intrusive to the code I
>>>>>>>>>> therefore choose to do a static bootstrap ThreadsList.
>>>>>>>>>>
>>>>>>>>>> CR: https://bugs.openjdk.java.net/browse/JDK-8209139
>>>>>>>>>> Webrev: http://cr.openjdk.java.net/~rehn/8209139/webrev/
>>>>>>>>>>
>>>>>>>>>> Tested with use of ThreadsListHandle and GlobalCounter in the
>>>>>>>>>> problematic init method, passed t1-2 with use of
>>>>>>>>>> ThreadsListHandle in that init method.
>>>>>>>>>>
>>>>>>>>>> Thanks, Robbin
More information about the hotspot-runtime-dev
mailing list