blob: 33298ef8b4ae1b656ac06b238348ea18b5d6c8e5 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVICES_BLOCK_DRIVERS_FTL_METRICS_H_
#define SRC_DEVICES_BLOCK_DRIVERS_FTL_METRICS_H_
#include <lib/inspect/cpp/inspect.h>
#include <lib/inspect/cpp/vmo/types.h>
#include <map>
#include <string>
#include <string_view>
#include <vector>
#include <fbl/span.h>
namespace ftl {
// Helper property wrapper that caches the value, in order to update
// the inspect property with the correct value, since properties are write only.
class RateProperty {
public:
explicit RateProperty(inspect::DoubleProperty property) : property_(std::move(property)) {}
// Returns the accumulated rate as a weighted rate.
double rate() const { return rate_.GetValue(); }
// Updates the accumulated rate.
void Add(int extra_accumulated) {
rate_.accumulated += extra_accumulated;
rate_.entries++;
property_.Set(rate());
}
private:
// Helper for keeping track and updating an accumulated rate.
struct Rate {
constexpr double GetValue() const {
if (entries == 0) {
return 0;
}
return static_cast<double>(accumulated) / entries;
}
int accumulated = 0;
int entries = 0;
};
Rate rate_;
inspect::DoubleProperty property_;
};
struct NestedNandOperationProperties {
NestedNandOperationProperties(inspect::UintProperty count, inspect::DoubleProperty rate)
: count(std::move(count)), rate(std::move(rate)) {}
// Number of nand operations issued for a given type.
inspect::UintProperty count;
// Rate at which operations of this type are issued to the underlying device.
RateProperty rate;
};
// For each type of block operation we keep the number of operations issued and the accumulated rate
// at which an operation is issued as a result of an incoming block operation into the FTL.
struct BlockOperationProperties {
// Number of block operations of a given type that have been processed by the FTL.
inspect::UintProperty count;
// Operation stats per nand operation type for operation issued for this block operation type.
NestedNandOperationProperties all;
NestedNandOperationProperties page_read;
NestedNandOperationProperties page_write;
NestedNandOperationProperties block_erase;
};
// Encapsulates all existing metrics, and the property list names for each.
class Metrics {
public:
// Each of this functions returns the name of the property for a count or rate for the given pair.
// Unknown combinations will return an empty string.
static std::string GetMaxWearPropertyName() { return "max_wear"; }
// Returns the list of expected properties in the hierarchy for each inspect metric type.
template <typename InspectMetricType>
static std::vector<std::string> GetPropertyNames();
Metrics();
inspect::UintProperty& max_wear() { return max_wear_; }
BlockOperationProperties& read() { return read_; }
BlockOperationProperties& write() { return write_; }
BlockOperationProperties& trim() { return trim_; }
BlockOperationProperties& flush() { return flush_; }
zx::vmo DuplicateInspectVmo() const { return inspector_.DuplicateVmo(); }
private:
auto& GetRoot() { return root_; }
inspect::Inspector inspector_;
// Inspect root.
inspect::Node root_;
// Current maximum wear over all nand blocks.
inspect::UintProperty max_wear_;
// Properties for each block operation type.
BlockOperationProperties read_;
BlockOperationProperties write_;
BlockOperationProperties flush_;
BlockOperationProperties trim_;
};
} // namespace ftl
#endif // SRC_DEVICES_BLOCK_DRIVERS_FTL_METRICS_H_