ronnie
2022-10-14 1504bb53e29d3d46222c0b3ea994fc494b48e153
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// 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_