comparison src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp @ 22963:f79d8e8caecb

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
author iveresov
date Fri, 10 Apr 2015 15:27:05 -0700
parents 2ac41ee91b06
children a0622494f6b2
comparison
equal deleted inserted replaced
22962:2ac41ee91b06 22963:f79d8e8caecb
125 bool is_initial() { return _state == INITIAL; } 125 bool is_initial() { return _state == INITIAL; }
126 bool is_assigned() { return _state == ASSIGNED; } 126 bool is_assigned() { return _state == ASSIGNED; }
127 bool is_inconsistent() { return _state == INCONSISTENT; } 127 bool is_inconsistent() { return _state == INCONSISTENT; }
128 void set_inconsistent() { _state = INCONSISTENT; } 128 void set_inconsistent() { _state = INCONSISTENT; }
129 129
130 void visit(picl_nodehdl_t nodeh, const char* name) { 130 bool visit(picl_nodehdl_t nodeh, const char* name) {
131 assert(!is_inconsistent(), "Precondition"); 131 assert(!is_inconsistent(), "Precondition");
132 int curr; 132 int curr;
133 if (_picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { 133 if (_picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) {
134 if (!is_assigned()) { // first iteration 134 if (!is_assigned()) { // first iteration
135 set_value(curr); 135 set_value(curr);
136 } else if (curr != value()) { // following iterations 136 } else if (curr != value()) { // following iterations
137 set_inconsistent(); 137 set_inconsistent();
138 } 138 }
139 } 139 return true;
140 }
141 return false;
140 } 142 }
141 }; 143 };
142 144
143 class CPUVisitor { 145 class CPUVisitor {
144 UniqueValueVisitor _l1_visitor; 146 UniqueValueVisitor _l1_visitor;
151 UniqueValueVisitor* l1_visitor = cpu_visitor->l1_visitor(); 153 UniqueValueVisitor* l1_visitor = cpu_visitor->l1_visitor();
152 UniqueValueVisitor* l2_visitor = cpu_visitor->l2_visitor(); 154 UniqueValueVisitor* l2_visitor = cpu_visitor->l2_visitor();
153 if (!l1_visitor->is_inconsistent()) { 155 if (!l1_visitor->is_inconsistent()) {
154 l1_visitor->visit(nodeh, "l1-dcache-line-size"); 156 l1_visitor->visit(nodeh, "l1-dcache-line-size");
155 } 157 }
156 if (!l2_visitor->is_inconsistent()) { 158 static const char* l2_data_cache_line_property_name = NULL;
157 l2_visitor->visit(nodeh, "l2-cache-line-size"); 159 // On the first visit determine the name of the l2 cache line size property and memoize it.
160 if (l2_data_cache_line_property_name == NULL) {
161 assert(!l2_visitor->is_inconsistent(), "First iteration cannot be inconsistent");
162 l2_data_cache_line_property_name = "l2-cache-line-size";
163 if (!l2_visitor->visit(nodeh, l2_data_cache_line_property_name)) {
164 l2_data_cache_line_property_name = "l2-dcache-line-size";
165 l2_visitor->visit(nodeh, l2_data_cache_line_property_name);
166 }
167 } else {
168 if (!l2_visitor->is_inconsistent()) {
169 l2_visitor->visit(nodeh, l2_data_cache_line_property_name);
170 }
158 } 171 }
159 172
160 if (l1_visitor->is_inconsistent() && l2_visitor->is_inconsistent()) { 173 if (l1_visitor->is_inconsistent() && l2_visitor->is_inconsistent()) {
161 return PICL_WALK_TERMINATE; 174 return PICL_WALK_TERMINATE;
162 } 175 }
168 } 181 }
169 UniqueValueVisitor* l1_visitor() { return &_l1_visitor; } 182 UniqueValueVisitor* l1_visitor() { return &_l1_visitor; }
170 UniqueValueVisitor* l2_visitor() { return &_l2_visitor; } 183 UniqueValueVisitor* l2_visitor() { return &_l2_visitor; }
171 }; 184 };
172 int _L1_data_cache_line_size; 185 int _L1_data_cache_line_size;
173 int _L2_cache_line_size; 186 int _L2_data_cache_line_size;
174 public: 187 public:
175 static int visit_cpu(picl_nodehdl_t nodeh, void *state) { 188 static int visit_cpu(picl_nodehdl_t nodeh, void *state) {
176 return CPUVisitor::visit(nodeh, state); 189 return CPUVisitor::visit(nodeh, state);
177 } 190 }
178 191
179 PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_cache_line_size(0), _dl_handle(NULL) { 192 PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) {
180 if (!open_library()) { 193 if (!open_library()) {
181 return; 194 return;
182 } 195 }
183 if (_picl_initialize() == PICL_SUCCESS) { 196 if (_picl_initialize() == PICL_SUCCESS) {
184 picl_nodehdl_t rooth; 197 picl_nodehdl_t rooth;
192 _picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper); 205 _picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper);
193 if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value? 206 if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value?
194 _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value(); 207 _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value();
195 } 208 }
196 if (cpu_visitor.l2_visitor()->is_assigned()) { 209 if (cpu_visitor.l2_visitor()->is_assigned()) {
197 _L2_cache_line_size = cpu_visitor.l2_visitor()->value(); 210 _L2_data_cache_line_size = cpu_visitor.l2_visitor()->value();
198 } 211 }
199 } 212 }
200 _picl_shutdown(); 213 _picl_shutdown();
201 } 214 }
202 close_library(); 215 close_library();
203 } 216 }
204 217
205 unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; } 218 unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; }
206 unsigned int L2_cache_line_size() const { return _L2_cache_line_size; } 219 unsigned int L2_data_cache_line_size() const { return _L2_data_cache_line_size; }
207 }; 220 };
208 221
209 222
210 extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result) { 223 extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result) {
211 return PICL::visit_cpu(nodeh, result); 224 return PICL::visit_cpu(nodeh, result);
480 kstat_close(kc); 493 kstat_close(kc);
481 } 494 }
482 495
483 // Figure out cache line sizes using PICL 496 // Figure out cache line sizes using PICL
484 PICL picl((features & sparc64_family_m) != 0); 497 PICL picl((features & sparc64_family_m) != 0);
485 _L2_cache_line_size = picl.L2_cache_line_size(); 498 _L2_data_cache_line_size = picl.L2_data_cache_line_size();
486 499
487 return features; 500 return features;
488 } 501 }