changeset 268:d6340ab4105b

6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set") 6723229: NUMA allocator: assert(lgrp_num > 0, "There should be at least one locality group") Summary: The fix takes care of the assertion triggered during TLAB resizing after reconfiguration. Also it now handles a defect in the topology graph, in which a single leaf node doesn't have memory. Reviewed-by: jmasa
author iveresov
date Thu, 17 Jul 2008 10:26:33 -0700
parents 9d6a3a6891f8
children 850fdf70db2b
files src/os/solaris/vm/os_solaris.cpp src/share/vm/gc_implementation/shared/gcUtil.hpp src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
diffstat 4 files changed, 48 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/os/solaris/vm/os_solaris.cpp	Mon Jul 14 04:12:47 2008 -0700
+++ b/src/os/solaris/vm/os_solaris.cpp	Thu Jul 17 10:26:33 2008 -0700
@@ -2658,6 +2658,12 @@
      top += r;
      cur++;
    }
+   if (bottom == 0) {
+     // Handle a situation, when the OS reports no memory available.
+     // Assume UMA architecture.
+     ids[0] = 0;
+     return 1;
+   }
    return bottom;
 }
 
--- a/src/share/vm/gc_implementation/shared/gcUtil.hpp	Mon Jul 14 04:12:47 2008 -0700
+++ b/src/share/vm/gc_implementation/shared/gcUtil.hpp	Thu Jul 17 10:26:33 2008 -0700
@@ -58,6 +58,12 @@
     _average(0.0), _sample_count(0), _weight(weight), _last_sample(0.0) {
   }
 
+  void clear() {
+    _average = 0;
+    _sample_count = 0;
+    _last_sample = 0;
+  }
+
   // Accessors
   float    average() const       { return _average;       }
   unsigned weight()  const       { return _weight;        }
@@ -115,6 +121,12 @@
   float deviation()      const         { return _deviation;  }
   unsigned padding()     const         { return _padding;    }
 
+  void clear() {
+    AdaptiveWeightedAverage::clear();
+    _padded_avg = 0;
+    _deviation = 0;
+  }
+
   // Override
   void  sample(float new_sample);
 };
--- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Mon Jul 14 04:12:47 2008 -0700
+++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp	Thu Jul 17 10:26:33 2008 -0700
@@ -141,7 +141,20 @@
 size_t MutableNUMASpace::tlab_capacity(Thread *thr) const {
   guarantee(thr != NULL, "No thread");
   int lgrp_id = thr->lgrp_id();
-  assert(lgrp_id != -1, "No lgrp_id set");
+  if (lgrp_id == -1) {
+    // This case can occur after the topology of the system has
+    // changed. Thread can change their location, the new home
+    // group will be determined during the first allocation
+    // attempt. For now we can safely assume that all spaces
+    // have equal size because the whole space will be reinitialized.
+    if (lgrp_spaces()->length() > 0) {
+      return capacity_in_bytes() / lgrp_spaces()->length();
+    } else {
+      assert(false, "There should be at least one locality group");
+      return 0;
+    }
+  }
+  // That's the normal case, where we know the locality group of the thread.
   int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals);
   if (i == -1) {
     return 0;
@@ -150,9 +163,17 @@
 }
 
 size_t MutableNUMASpace::unsafe_max_tlab_alloc(Thread *thr) const {
+  // Please see the comments for tlab_capacity().
   guarantee(thr != NULL, "No thread");
   int lgrp_id = thr->lgrp_id();
-  assert(lgrp_id != -1, "No lgrp_id set");
+  if (lgrp_id == -1) {
+    if (lgrp_spaces()->length() > 0) {
+      return free_in_bytes() / lgrp_spaces()->length();
+    } else {
+      assert(false, "There should be at least one locality group");
+      return 0;
+    }
+  }
   int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals);
   if (i == -1) {
     return 0;
@@ -250,10 +271,15 @@
 void MutableNUMASpace::update() {
   if (update_layout(false)) {
     // If the topology has changed, make all chunks zero-sized.
+    // And clear the alloc-rate statistics.
+    // In future we may want to handle this more gracefully in order
+    // to avoid the reallocation of the pages as much as possible.
     for (int i = 0; i < lgrp_spaces()->length(); i++) {
-      MutableSpace *s = lgrp_spaces()->at(i)->space();
+      LGRPSpace *ls = lgrp_spaces()->at(i);
+      MutableSpace *s = ls->space();
       s->set_end(s->bottom());
       s->set_top(s->bottom());
+      ls->clear_alloc_rate();
     }
     // A NUMA space is never mangled
     initialize(region(),
--- a/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	Mon Jul 14 04:12:47 2008 -0700
+++ b/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp	Thu Jul 17 10:26:33 2008 -0700
@@ -112,6 +112,7 @@
     int lgrp_id() const                             { return _lgrp_id;             }
     MutableSpace* space() const                     { return _space;               }
     AdaptiveWeightedAverage* alloc_rate() const     { return _alloc_rate;          }
+    void clear_alloc_rate()                         { _alloc_rate->clear();        }
     SpaceStats* space_stats()                       { return &_space_stats;        }
     void clear_space_stats()                        { _space_stats = SpaceStats(); }