RFR(s): 8209139: globalCounter bootstrap issue
David Holmes
david.holmes at oracle.com
Thu Nov 8 11:02:19 UTC 2018
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.
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