// 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_