RFR (S) 8049304: race between VM_Exit and _sync_FutileWakeups->inc()
Daniel D. Daugherty
daniel.daugherty at oracle.com
Tue Sep 1 14:49:29 UTC 2015
On 9/1/15 12:13 AM, David Holmes wrote:
> Hi Dan,
>
> Hope you had that coffee :)
Just got that second cup... :-)
>
> On 1/09/2015 8:51 AM, Daniel D. Daugherty wrote:
>> Greetings,
>>
>> I've updated the "fix" for this bug based on code review comments
>> received in round 0.
>>
>> JDK-8049304 race between VM_Exit and _sync_FutileWakeups->inc()
>> https://bugs.openjdk.java.net/browse/JDK-8049304
>>
>> Webrev URL:
>> http://cr.openjdk.java.net/~dcubed/8049304-webrev/1-jdk9-hs-rt/
>>
>> The easiest way to re-review is to download the two patch files
>> and view them in your favorite file merge tool:
>>
>> http://cr.openjdk.java.net/~dcubed/8049304-webrev/0-jdk9-hs-rt/hotspot.patch
>>
>>
>> http://cr.openjdk.java.net/~dcubed/8049304-webrev/1-jdk9-hs-rt/hotspot.patch
>>
>>
>>
>> Testing: Aurora Adhoc RT-SVC nightly batch (in process)
>> Aurora Adhoc vm.tmtools batch (in process)
>> Kim's repro sequence for JDK-8049304
>> Kim's repro sequence for JDK-8129978
>> JPRT -testset hotspot
>>
>> Changes between round 0 and round 1:
>>
>> - add an 'is_safe' parameter to the OM_PERFDATA_OP macro;
>
> The sense of safepoint-safe is a bit confusing to me. If the thread is
> in a safepoint-safe-state then it seems safepoint-safe==false ??
I went back and forth on the naming of this parameter. When 'is_safe'
is true, the calling thread can safely and directly check has_PerfData
because we are not at a safepoint so we can't be racing with a normal
exit. In a normal exit, has_PerfData is only changed (and memory freed)
at a safepoint.
When 'is_safe' is false, then the code path we're on could be executing
in parallel with a safepoint so we need to be more careful with accessing
the has_PerfData flag...
If you have a better name for the parameter...
>
>> safepoint-safe callers can access _has_PerfData flag directly;
>> non-safepoint-safe callers use a load-acquire to fetch the
>> current _has_PerfData flag value
>
> load-acquire makes no difference to the "currentness" of _has_PerfData
> and has no affect on the size of the "race window". So I don't see any
> point to this is-safe distinction.
Hmmm... I think I got this idea when I re-read orderAccess.hpp where
it talks about release-store and load-acquire pairs. I originally
had the transition of _has_PerfData from '1' -> '0' done by a
release_store() so I was using a load_acquire() as part of the
pair. I've since switched to a direct setting of "_has_PerfData = 0"
followed by the big hammer fence(), but I think the load_acquire()
still pairs with that fence().
>
>> - change PerfDataManager::destroy() to simply set _has_PerfData
>> to zero (field is volatile) and then use a fence() to prevent
>> any reordering of operations in any direction; it's only done
>> once during VM shutdown so...
>
> See previous email :)
Yup. I did and I'd still like to keep it for the reasons stated
in my reply to the previous e-mail. You were good with this code
as a release_store() of '0' so I kind of expected you to be OK
with the stronger fence().
>
>> - change perfMemory_exit() to only call PerfDataManager::destroy()
>> when called at a safepoint and when the StatSample is not
>> running; this means when the VM is aborting, we no longer have
>> a race between the original crash report and this code path.
>
> Sounds reasonable.
Thanks. I hope it makes Kim happy also.
>
> I have few specific comments/nits:
>
> src/share/vm/runtime/perfData.cpp
>
> 43 volatile jint PerfDataManager::_has_PerfData = false;
>
> Nit: jint should be initialized with 0 not false.
Will fix; oops...that made it past round 0...
>
> 287 // manipulation before we free the memory. The two alternatives
> 288 // are 1) leak the PerfData memory or 2) do some form of ordered
> 289 // access before every PerfData operation.
>
> No amount of ordered access will fix the race - only synchronization
> of some form.
I thought I had changed that comment. Will fix.
>
> 315 void PerfDataManager::add_item(PerfData* p, bool sampled) {
> 316
> 317 MutexLocker ml(PerfDataManager_lock);
> 318
> 319 if (_all == NULL) {
> 320 _all = new PerfDataList(100);
> 321 OrderAccess::release_store(&_has_PerfData, 1);
> 322 }
>
> I can't see any purpose for a release_store here. You have one-time
> initialization code guarded with a mutex. A release_store adds nothing
> here - other than future head-scratching from maintainers of this code.
Agreed. Not sure how I missed the fact that we were in the
locked block. oops...that made it past round 0...
Thanks again for the review. Will generate another webrev...
Dan
>
> Thanks,
> David
>
>> I believe that I've addressed all comments from round 0.
>>
>> Thanks, in advance, for any comments, questions or suggestions.
>>
>> Dan
>>
>>
>> On 8/25/15 3:08 PM, Daniel D. Daugherty wrote:
>>> Greetings,
>>>
>>> I have a "fix" for a long standing race between JVM shutdown and the
>>> JVM statistics subsystem:
>>>
>>> JDK-8049304 race between VM_Exit and _sync_FutileWakeups->inc()
>>> https://bugs.openjdk.java.net/browse/JDK-8049304
>>>
>>> Webrev URL:
>>> http://cr.openjdk.java.net/~dcubed/8049304-webrev/0-jdk9-hs-rt/
>>>
>>> Testing: Aurora Adhoc RT-SVC nightly batch
>>> Aurora Adhoc vm.tmtools batch
>>> Kim's repro sequence for JDK-8049304
>>> Kim's repro sequence for JDK-8129978
>>> JPRT -testset hotspot
>>>
>>> This "fix":
>>>
>>> - adds a volatile flag to record whether PerfDataManager is holding
>>> data (PerfData objects)
>>> - adds PerfDataManager::has_PerfData() to return the flag
>>> - changes the Java monitor subsystem's use of PerfData to
>>> check both allocation of the monitor subsystem specific
>>> PerfData object and the new PerfDataManager::has_PerfData()
>>> return value
>>>
>>> If the global 'UsePerfData' option is false, the system works as
>>> it did before. If 'UsePerfData' is true (the default on non-embedded
>>> systems), the Java monitor subsystem will allocate a number of
>>> PerfData objects to record information. The objects will record
>>> information about Java monitor subsystem until the JVM shuts down.
>>>
>>> When the JVM starts to shutdown, the new PerfDataManager flag will
>>> change to false and the Java monitor subsystem will stop using the
>>> PerfData objects. This is the new behavior. As noted in the comments
>>> I added to the code, the race is still present; I'm just changing
>>> the order and the timing to reduce the likelihood of the crash.
>>>
>>> Thanks, in advance, for any comments, questions or suggestions.
>>>
>>> Dan
>>>
>>>
>>>
>>
More information about the serviceability-dev
mailing list