Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8265668

Flaws in implementation of notifications sending after MemoryPoolMXBean.setUsageThreshold call

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 17
    • core-svc
    • None

      I found those during my work on failing test in JDK-8264632 and CodeCache:

      1. Two different locks/mutexes are used to sync, completely unrelated (possible UB?)
      ======================================
      MemoryPoolImpl.setUsageThreshold synchronizes by its own monitor, subsequently calling native method setUsageThreshold0, in MemoryPoolImpl.c. The futher path to modify the threshold by calling (for ex.) ThresholdSupport::set_high_threshold is not protected in any way.

      The internal algorithms like those in notificationThread, lowMemoryDetector synchronize on another object (the Notification_lock) while accessing threshold values (like in SensorInfo::set_gauge_sensor_level in lowMemoryDetector.cpp), which gives us a UB and potential problems;

      2. Trigger and clear paths read MT data without protection.
      ======================================
      The LowMemoryDetector::process_sensor_changes, SensorInfo::process_pending_requests and SensorInfo::trigger use unprotected reads for internal data (_pending_clear_count and _pending_clear_count), which can be modified by another threads (in SensorInfo::set_gauge_sensor_level). Those are size_t variables and just reads, but such reads AFAIK are still UB in the presence of other-threads writes.

      3. setUsageThreshold ( 0 ) doesn't clear threshold reached so far;
      ======================================
      The documentation says 'The usage threshold crossing checking is disabled if it is set to zero'. However, the current implementation doesn't clears the level achieved so far, which I find confusing. Yes, that isn't stated in documentation, but I think many users would expect that. Imagine a test program:

      pool.setUsageThreshold(1_000_000);
      // Notification is fired and received
      pool.setUsageThreshold(0); // Intended to switch off memory pool usage monitoring and clear reached usage
      // Notifications are switched off
      pool.setUsageThreshold(1_000)
      // Notification isn't fired - we've already reached 1_000_000 and reported that, why bother notyfing again?

      We need to either explain the current behaviour clearly in the documentation, or state the opposite and change the implementation.

            Unassigned Unassigned
            enikitin Evgeny Nikitin
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: