// Copyright 2008 Google Inc. All Rights Reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // error_diag.h: Ambiguous error diagnosis class #ifndef STRESSAPPTEST_ERROR_DIAG_H_ #define STRESSAPPTEST_ERROR_DIAG_H_ #include <pthread.h> #include <list> #include <map> #include <set> #include <string> // This file must work with autoconf on its public version, // so these includes are correct. #include "sattypes.h" #include "os.h" class ErrorInstance; // This describes the components of the system. class DeviceTree { public: explicit DeviceTree(string name); ~DeviceTree(); // Atomically find arbitrary device in subtree. DeviceTree *FindInSubTree(string name); // Find or add named device. DeviceTree *FindOrAddDevice(string name); // Atomically add sub device. void InsertSubDevice(string name); // Returns parent device. DeviceTree *GetParent() { return parent_; } // Pretty prints device tree. void PrettyPrint(string spacer = " "); // Atomically add error instance to device. void AddErrorInstance(ErrorInstance *error_instance); // Returns true of device is known to be bad. bool KnownBad(); // Returns number of direct sub devices. int NumDirectSubDevices() { return subdevices_.size(); } private: // Unlocked version of FindInSubTree. DeviceTree *UnlockedFindInSubTree(string name); std::map<string, DeviceTree*> subdevices_; // Map of sub-devices. std::list<ErrorInstance*> errors_; // Log of errors. DeviceTree *parent_; // Pointer to parent device. string name_; // Device name. pthread_mutex_t device_tree_mutex_; // Mutex protecting device tree. }; // enum type for collected errors. enum SATErrorType { SAT_ERROR_NONE = 0, SAT_ERROR_ECC, SAT_ERROR_MISCOMPARE, SAT_ERROR_SECTOR_TAG, }; // enum type for error severity. enum SATErrorSeverity { SAT_ERROR_CORRECTABLE = 0, SAT_ERROR_FATAL, }; // This describes an error and it's likely causes. class ErrorInstance { public: ErrorInstance(): type_(SAT_ERROR_NONE), severity_(SAT_ERROR_CORRECTABLE) {} SATErrorType type_; // Type of error: ECC, miscompare, sector. SATErrorSeverity severity_; // Correctable, or fatal. std::set<DeviceTree*> causes_; // Devices that can cause this type of error. }; // This describes ECC errors. class ECCErrorInstance: public ErrorInstance { public: ECCErrorInstance() { type_ = SAT_ERROR_ECC; } uint64 addr_; // Address where error occured. }; // This describes miscompare errors. class MiscompareErrorInstance: public ErrorInstance { public: MiscompareErrorInstance() { type_ = SAT_ERROR_MISCOMPARE; } uint64 addr_; // Address where miscompare occured. }; // This describes HDD miscompare errors. class HDDMiscompareErrorInstance: public MiscompareErrorInstance { public: uint64 addr2_; // addr_ and addr2_ are src and dst memory addr. int offset_; // offset. int block_; // error block. }; // This describes HDD miscompare errors. class HDDSectorTagErrorInstance: public ErrorInstance { public: HDDSectorTagErrorInstance() { type_ = SAT_ERROR_SECTOR_TAG; } uint64 addr_; uint64 addr2_; // addr_ and addr2_ are src and dst memory addr. int sector_; // error sector. int block_; // error block. }; // Generic error storage and sorting class. class ErrorDiag { public: ErrorDiag(); virtual ~ErrorDiag(); // Add info about a CECC. virtual int AddCeccError(string dimm_string); // Add info about a UECC. virtual int AddUeccError(string dimm_string); // Add info about a miscompare. virtual int AddMiscompareError(string dimm_string, uint64 addr, int count); // Add info about a miscompare from a drive. virtual int AddHDDMiscompareError(string devicename, int block, int offset, void *src_addr, void *dst_addr); // Add info about a sector tag miscompare from a drive. virtual int AddHDDSectorTagError(string devicename, int block, int offset, int sector, void *src_addr, void *dst_addr); // Set platform specific handle and initialize device tree. bool set_os(OsLayer *os); protected: // Create and initialize system device tree. virtual bool InitializeDeviceTree(); // Utility Function to translate a virtual address to DIMM number. string AddressToDimmString(OsLayer *os, void *addr, int offset); DeviceTree *system_tree_root_; // System device tree. OsLayer *os_; // Platform handle. private: DISALLOW_COPY_AND_ASSIGN(ErrorDiag); }; #endif // STRESSAPPTEST_ERROR_DIAG_H_