8076968: PICL based initialization of L2 cache line size on some SPARC systems is incorrect
authoriveresov
Mon, 06 Apr 2015 20:20:17 -0700
changeset 30217 5eb8768d86c4
parent 30216 5b96c468d591
child 30218 53a798b8b063
8076968: PICL based initialization of L2 cache line size on some SPARC systems is incorrect Summary: Chcek both l2-dcache-line-size and l2-cache-line-size properties to determine the size of the line Reviewed-by: kvn
hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp
hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Fri Apr 03 11:41:01 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Mon Apr 06 20:20:17 2015 -0700
@@ -32,7 +32,7 @@
 
 int VM_Version::_features = VM_Version::unknown_m;
 const char* VM_Version::_features_str = "";
-unsigned int VM_Version::_L2_cache_line_size = 0;
+unsigned int VM_Version::_L2_data_cache_line_size = 0;
 
 void VM_Version::initialize() {
   _features = determine_features();
@@ -366,7 +366,7 @@
 #ifndef PRODUCT
   if (PrintMiscellaneous && Verbose) {
     tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
-    tty->print_cr("L2 cache line size: %u", L2_cache_line_size());
+    tty->print_cr("L2 data cache line size: %u", L2_data_cache_line_size());
     tty->print("Allocation");
     if (AllocatePrefetchStyle <= 0) {
       tty->print_cr(": no prefetching");
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Fri Apr 03 11:41:01 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Mon Apr 06 20:20:17 2015 -0700
@@ -96,8 +96,8 @@
   static int  _features;
   static const char* _features_str;
 
-  static unsigned int _L2_cache_line_size;
-  static unsigned int L2_cache_line_size() { return _L2_cache_line_size; }
+  static unsigned int _L2_data_cache_line_size;
+  static unsigned int L2_data_cache_line_size() { return _L2_data_cache_line_size; }
 
   static void print_features();
   static int  determine_features();
@@ -171,7 +171,7 @@
   static const char* cpu_features()     { return _features_str; }
 
   // default prefetch block size on sparc
-  static intx prefetch_data_size()      { return L2_cache_line_size();  }
+  static intx prefetch_data_size()      { return L2_data_cache_line_size();  }
 
   // Prefetch
   static intx prefetch_copy_interval_in_bytes() {
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Fri Apr 03 11:41:01 2015 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Mon Apr 06 20:20:17 2015 -0700
@@ -129,7 +129,7 @@
     bool is_inconsistent()  { return _state == INCONSISTENT; }
     void set_inconsistent() { _state = INCONSISTENT;         }
 
-    void visit(picl_nodehdl_t nodeh, const char* name) {
+    bool visit(picl_nodehdl_t nodeh, const char* name) {
       assert(!is_inconsistent(), "Precondition");
       int curr;
       if (_picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) {
@@ -138,7 +138,9 @@
         } else if (curr != value()) { // following iterations
           set_inconsistent();
         }
+        return true;
       }
+      return false;
     }
   };
 
@@ -155,8 +157,19 @@
       if (!l1_visitor->is_inconsistent()) {
         l1_visitor->visit(nodeh, "l1-dcache-line-size");
       }
-      if (!l2_visitor->is_inconsistent()) {
-        l2_visitor->visit(nodeh, "l2-cache-line-size");
+      static const char* l2_data_cache_line_property_name = NULL;
+      // On the first visit determine the name of the l2 cache line size property and memoize it.
+      if (l2_data_cache_line_property_name == NULL) {
+        assert(!l2_visitor->is_inconsistent(), "First iteration cannot be inconsistent");
+        l2_data_cache_line_property_name = "l2-cache-line-size";
+        if (!l2_visitor->visit(nodeh, l2_data_cache_line_property_name)) {
+          l2_data_cache_line_property_name = "l2-dcache-line-size";
+          l2_visitor->visit(nodeh, l2_data_cache_line_property_name);
+        }
+      } else {
+        if (!l2_visitor->is_inconsistent()) {
+          l2_visitor->visit(nodeh, l2_data_cache_line_property_name);
+        }
       }
 
       if (l1_visitor->is_inconsistent() && l2_visitor->is_inconsistent()) {
@@ -172,13 +185,13 @@
     UniqueValueVisitor* l2_visitor() { return &_l2_visitor; }
   };
   int _L1_data_cache_line_size;
-  int _L2_cache_line_size;
+  int _L2_data_cache_line_size;
 public:
   static int visit_cpu(picl_nodehdl_t nodeh, void *state) {
     return CPUVisitor::visit(nodeh, state);
   }
 
-  PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_cache_line_size(0), _dl_handle(NULL) {
+  PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) {
     if (!open_library()) {
       return;
     }
@@ -196,7 +209,7 @@
           _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value();
         }
         if (cpu_visitor.l2_visitor()->is_assigned()) {
-          _L2_cache_line_size = cpu_visitor.l2_visitor()->value();
+          _L2_data_cache_line_size = cpu_visitor.l2_visitor()->value();
         }
       }
       _picl_shutdown();
@@ -205,7 +218,7 @@
   }
 
   unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; }
-  unsigned int L2_cache_line_size() const      { return _L2_cache_line_size;      }
+  unsigned int L2_data_cache_line_size() const { return _L2_data_cache_line_size; }
 };
 
 
@@ -431,7 +444,7 @@
   // Figure out cache line sizes using PICL
   PICL picl((features & sparc64_family_m) != 0);
   _L1_data_cache_line_size = picl.L1_data_cache_line_size();
-  _L2_cache_line_size      = picl.L2_cache_line_size();
+  _L2_data_cache_line_size = picl.L2_data_cache_line_size();
 
   return features;
 }