summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/plat/mem/prdfMemTdFalseAlarm.H
blob: bfc8ff436b8072a09b36453c695dd4a0ae843b6a (plain)
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/prdf/plat/mem/prdfMemTdFalseAlarm.H $            */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2017                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

#ifndef __prdfMemTdFalseAlarm_H
#define __prdfMemTdFalseAlarm_H

// Framework includes
#include <iipServiceDataCollector.h>
#include <prdfThresholdUtils.H>

// Other includes
#include <map>

namespace PRDF
{

/** @brief This is used at runtime to keep track of false alarm for Targeted
 *         Diagnostics to avoid flooding of intermittent errors. */
class TdFalseAlarm
{
  public: // functions

    /** @brief Default destructor */
    virtual ~TdFalseAlarm()  = default;

    /**
     * @brief  Queries if the threshold timer has expired.
     * @param  i_rank The rank with the false alarm.
     * @param  io_sc  The step code data struct.
     * @return True if the threshold timer has expired, false otherwise.
     */
    bool elapsed( MemRank i_rank, STEP_CODE_DATA_STRUCT & io_sc )
    {
        uint32_t key = init( i_rank, io_sc );
        return iv_thMap[key].timeElapsed( io_sc );
    }

    /**
     * @brief  Queries the current false alarm count.
     * @param  i_rank The rank with the false alarm.
     * @param  io_sc  The step code data struct.
     * @return The current false alarm count.
     */
    uint8_t count( MemRank i_rank, STEP_CODE_DATA_STRUCT & io_sc )
    {
        uint32_t key = init( i_rank, io_sc );
        return iv_thMap[key].getCount();
    }

  protected: // functions

    /**
     * @brief Constructor.
     * @param i_th Threshold for each entry in the threshold map.
     */
    explicit TdFalseAlarm( TimeBasedThreshold i_th ) : iv_th(i_th) {}

    /**
     * @brief  The key could be different per TD procedure. For example, VCM
     *         events will use only the master rank, where TPS events will use
     *         both the master and slave rank.
     * @param  i_rank The rank with the false alarm.
     * @return The key value for this rank.
     */
    virtual uint32_t getKey( MemRank i_rank ) const = 0;

    /**
     * @brief  Initializes data specific to each child class.
     * @param  i_rank The rank with the false alarm.
     * @param  io_sc  The step code data struct.
     * @return The key for this rank (see getKey()).
     * @note   This function should be called before accessing the instance
     *         variables to ensure this key is initialized with the correct
     *         threshold.
     * @note   The default is to call initThMap(). Each child class that
     *         overloads this function should also call initThMap() to ensure
     *         the threshold map is initialized properly.
     */
    virtual uint32_t init( MemRank i_rank, STEP_CODE_DATA_STRUCT & io_sc )
    {
        return initThMap( i_rank );
    }

    /**
     * @brief  Initializes this key in the threshold map.
     * @param  i_rank The rank with the false alarm.
     * @return The key for this rank (see getKey()).
     * @note   This function should only be called from init().
     */
    uint32_t initThMap( MemRank i_rank )
    {
        uint32_t key = getKey( i_rank );

        // Create a new entry if an entry does not exist.
        if ( iv_thMap.end() == iv_thMap.find(key) ) iv_thMap[key] = iv_th;

        return key;
    }

    /**
     * @brief  Increments the false alarm count.
     * @param  i_rank The rank with the false alarm.
     * @param  io_sc  The step code data struct.
     * @return True if false alarm count has reached threshold, false otherwise.
     */
    bool incThMap( MemRank i_rank, STEP_CODE_DATA_STRUCT & io_sc )
    {
        uint32_t key = init( i_rank, io_sc );
        return iv_thMap[key].inc( io_sc );
    }

  private: // instance variables

    /** Threshold for each entries in the map. */
    const TimeBasedThreshold iv_th;

  protected: // instance variables

    /** A map containing the thresholds for each key. */
    std::map<uint32_t, TimeBasedThreshold> iv_thMap;
};

/** @brief A false alarm class specific to VCM procedures. */
class VcmFalseAlarm : public TdFalseAlarm
{
  public:

    /**
     * @brief Constructor.
     * @param i_th Threshold for each entry in the map.
     */
    VcmFalseAlarm( TimeBasedThreshold i_th ) : TdFalseAlarm(i_th) {}

    /**
     * @brief  Increments the false alarm count and stores the DRAM.
     * @param  i_rank The rank with the false alarm.
     * @param  i_dram The DRAM with the false alarm.
     * @param  io_sc  The step code data struct.
     * @return True if false alarm count has reached threshold, false otherwise.
     */
    bool inc( MemRank i_rank, uint8_t i_dram, STEP_CODE_DATA_STRUCT & io_sc )
    {
        // Increment the count and determine whether threshold is reached or
        // not. Note that incThMap() calls init() and initializes all maps.
        bool isTh = incThMap( i_rank, io_sc );

        // Add the DRAM to the list. Note that the value for each DRAM is not
        // important. The only reason to use a map verses a vector is to ensure
        // unique entries in the list.
        iv_dramMap[getKey(i_rank)][i_dram] = 1;

        return isTh;
    }

    /**
     * @param  i_rank The rank with the false alarm.
     * @param  i_dram The DRAM with the false alarm.
     * @param  io_sc  The step code data struct.
     * @return True if there is at least one DRAM on this rank with a false
     *         alarm other than i_dram.
     */
    bool queryDrams( MemRank i_rank, uint8_t i_dram,
                     STEP_CODE_DATA_STRUCT & io_sc )
    {
        uint32_t key = init( i_rank, io_sc ); // will clear list if time elapsed

        if ( 2 <= iv_dramMap[key].size() )
        {
            // Regardless if i_dram is in the list, or not, there is at least
            // one extra DRAM.
            return true;
        }
        else if ( 1 == iv_dramMap[key].size() &&
                  i_dram != iv_dramMap[key].begin()->first )
        {
            // The only DRAM in the list is not i_dram.
            return true;
        }

        return false; // No extra DRAMs.
    }

  private: // functions

    // Overloaded from parent class.
    uint32_t getKey( MemRank i_rank ) const
    {
        return MemRank(i_rank.getMaster()).getKey(); // master only
    }

    // Overloaded from parent class.
    uint32_t init( MemRank i_rank, STEP_CODE_DATA_STRUCT & io_sc )
    {
        uint32_t key = initThMap( i_rank );

        // Clear out the list of DRAMs if the threshold time has elapsed.
        // Note that we cannot call elapsed() because it will do a recursive
        // call to init().
        if ( iv_thMap[key].timeElapsed(io_sc) ) iv_dramMap[key].clear();

        return key;
    }

  private: // instance variables

    /** A map to keep track of which DRAMs per rank have reported chip marks. */
    std::map< uint32_t, std::map<uint8_t, uint8_t> > iv_dramMap;
};

/** @brief A false alarm class specific to TPS procedures. */
class TpsFalseAlarm : public TdFalseAlarm
{
  public:

    /**
     * @brief Constructor.
     * @param i_th Threshold for each entry in the map.
     */
    TpsFalseAlarm( TimeBasedThreshold i_th ) : TdFalseAlarm(i_th) {}

    /**
     * @brief  Increments the false alarm count.
     * @param  i_rank The rank with the false alarm.
     * @param  io_sc  The step code data struct.
     * @return True if false alarm count has reached threshold, false otherwise.
     */
    bool inc( MemRank i_rank, STEP_CODE_DATA_STRUCT & io_sc )
    {
        return incThMap( i_rank, io_sc );
    }

  private: // functions

    // Overloaded from parent class.
    uint32_t getKey( MemRank i_rank ) const
    {
        return i_rank.getKey(); // both master and slave
    }
};

} // end namespace PRDF

#endif // __prdfMemTdFalseAlarm_H

OpenPOWER on IntegriCloud