Skip to content

Commit

Permalink
Add UFS metrics
Browse files Browse the repository at this point in the history
In addition, migrate the data source for device-specific fields to
BlockDeviceInfo |device_info| as BlockDeviceVendor, BlockDeviceProduct
and BlockDeviceRevision are deprecated.

Bug: b:228796872
Test: unit_tests --gtest_filter="CrosHealthdMetricsProviderTest.*"
Change-Id: Ia9e0ddac601ba63296a527264547eee783bb3395
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4145638
Commit-Queue: Denny Huang <dennyh@google.com>
Reviewed-by: Ilya Sherman <isherman@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1115619}
  • Loading branch information
cyhuang1230 authored and Chromium LUCI CQ committed Mar 10, 2023
1 parent 85de46d commit bad7fac
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 63 deletions.
79 changes: 47 additions & 32 deletions chrome/browser/metrics/cros_healthd_metrics_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/hash/hash.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/task/single_thread_task_runner.h"
Expand Down Expand Up @@ -101,41 +102,55 @@ void CrosHealthdMetricsProvider::OnProbeDone(

for (const auto& storage : block_device_result->get_block_device_info()) {
SystemProfileProto::Hardware::InternalStorageDevice dev;

const auto& vendor_id = storage->vendor_id;
const auto& product_id = storage->product_id;
const auto& revision = storage->revision;
const auto& fw_version = storage->firmware_version;
const auto& type = storage->type;
if (base::StartsWith(type, "block:nvme",
base::CompareCase::INSENSITIVE_ASCII)) {
DCHECK(vendor_id->is_nvme_subsystem_vendor());
DCHECK(product_id->is_nvme_subsystem_device());
DCHECK(revision->is_nvme_pcie_rev());
DCHECK(fw_version->is_nvme_firmware_rev());
dev.set_type(
SystemProfileProto::Hardware::InternalStorageDevice::TYPE_NVME);
dev.set_vendor_id(vendor_id->get_nvme_subsystem_vendor());
dev.set_product_id(product_id->get_nvme_subsystem_device());
dev.set_revision(revision->get_nvme_pcie_rev());
dev.set_firmware_version(fw_version->get_nvme_firmware_rev());
} else if (base::StartsWith(type, "block:mmc",
base::CompareCase::INSENSITIVE_ASCII)) {
DCHECK(vendor_id->is_emmc_oemid());
DCHECK(product_id->is_emmc_pnm());
DCHECK(revision->is_emmc_prv());
DCHECK(fw_version->is_emmc_fwrev());
dev.set_type(
SystemProfileProto::Hardware::InternalStorageDevice::TYPE_EMMC);
dev.set_vendor_id(vendor_id->get_emmc_oemid());
dev.set_product_id(product_id->get_emmc_pnm());
dev.set_revision(revision->get_emmc_prv());
dev.set_firmware_version(fw_version->get_emmc_fwrev());
} else {
// Skip reporting entries for the unknown types.
const auto& device_info = storage->device_info;
if (device_info.is_null()) {
DVLOG(1)
<< "cros_healthd: No device info in block device info for storage: "
<< storage->name;
continue;
}

switch (device_info->which()) {
case ash::cros_healthd::mojom::BlockDeviceInfo::Tag::kUnrecognized: {
// Skip reporting entries for the unknown types.
continue;
}

case ash::cros_healthd::mojom::BlockDeviceInfo::Tag::kNvmeDeviceInfo: {
dev.set_type(
SystemProfileProto::Hardware::InternalStorageDevice::TYPE_NVME);
dev.set_vendor_id(
device_info->get_nvme_device_info()->subsystem_vendor);
dev.set_product_id(
device_info->get_nvme_device_info()->subsystem_device);
dev.set_revision(device_info->get_nvme_device_info()->pcie_rev);
dev.set_firmware_version(
device_info->get_nvme_device_info()->firmware_rev);
break;
}

case ash::cros_healthd::mojom::BlockDeviceInfo::Tag::kEmmcDeviceInfo: {
DCHECK(storage->vendor_id->is_emmc_oemid());
dev.set_type(
SystemProfileProto::Hardware::InternalStorageDevice::TYPE_EMMC);
dev.set_vendor_id(storage->vendor_id->get_emmc_oemid());
dev.set_product_id(device_info->get_emmc_device_info()->pnm);
dev.set_revision(device_info->get_emmc_device_info()->prv);
dev.set_firmware_version(device_info->get_emmc_device_info()->fwrev);
break;
}

case ash::cros_healthd::mojom::BlockDeviceInfo::Tag::kUfsDeviceInfo: {
dev.set_type(
SystemProfileProto::Hardware::InternalStorageDevice::TYPE_UFS);
dev.set_vendor_id(device_info->get_ufs_device_info()->jedec_manfid);
// UFS does not provide numeric id. Use hashed model name instead.
dev.set_product_id(base::PersistentHash(storage->name));
dev.set_firmware_version(device_info->get_ufs_device_info()->fwrev);
break;
}
}

switch (storage->purpose) {
case ash::cros_healthd::mojom::StorageDevicePurpose::kUnknown:
dev.set_purpose(SystemProfileProto::Hardware::InternalStorageDevice::
Expand Down
122 changes: 91 additions & 31 deletions chrome/browser/metrics/cros_healthd_metrics_provider_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,23 @@

namespace {

constexpr uint32_t kVendorId = 25;
constexpr uint32_t kProductId = 17;
constexpr uint32_t kRevision = 92;
constexpr uint64_t kFwVersion = 0xA0EF1;
constexpr uint64_t kSizeMb = 1024;
constexpr uint64_t kSize = kSizeMb * 1e6;
constexpr char kModel[] = "fabulous";
constexpr char kSubsystem[] = "block:nvme:pcie";
constexpr auto kType =
constexpr uint32_t kVendorIdNvme = 25;
constexpr uint16_t kVendorIdUfs = 0x1337;
constexpr uint32_t kProductIdNvme = 17;
constexpr uint64_t kProductIdUfs =
3210611189; // base::PersistentHash("fabulous") = 3210611189.
constexpr uint32_t kRevisionNvme = 92;
constexpr uint64_t kFwVersionNvme = 0xA0EF1;
constexpr uint64_t kFwVersionUfs = 0x32323032;
constexpr char kSubsystemNvme[] = "block:nvme:pcie";
constexpr char kSubsystemUfs[] = "block:scsi:scsi:scsi:pci";
constexpr auto kTypeNvme =
metrics::SystemProfileProto::Hardware::InternalStorageDevice::TYPE_NVME;
constexpr auto kTypeUfs =
metrics::SystemProfileProto::Hardware::InternalStorageDevice::TYPE_UFS;
constexpr auto kMojoPurpose =
ash::cros_healthd::mojom::StorageDevicePurpose::kSwapDevice;
constexpr auto kUmaPurpose =
Expand All @@ -42,27 +49,12 @@ class CrosHealthdMetricsProviderTest : public testing::Test {
public:
CrosHealthdMetricsProviderTest() {
ash::cros_healthd::FakeCrosHealthd::Initialize();
}

ash::cros_healthd::mojom::NonRemovableBlockDeviceInfo storage_info;
storage_info.vendor_id =
ash::cros_healthd::mojom::BlockDeviceVendor::NewNvmeSubsystemVendor(
kVendorId);
storage_info.product_id =
ash::cros_healthd::mojom::BlockDeviceProduct::NewNvmeSubsystemDevice(
kProductId);
storage_info.revision =
ash::cros_healthd::mojom::BlockDeviceRevision::NewNvmePcieRev(
kRevision);
storage_info.firmware_version =
ash::cros_healthd::mojom::BlockDeviceFirmware::NewNvmeFirmwareRev(
kFwVersion);
storage_info.size = kSize;
storage_info.name = kModel;
storage_info.type = kSubsystem;
storage_info.purpose = kMojoPurpose;

void SetFakeCrosHealthdData(
ash::cros_healthd::mojom::NonRemovableBlockDeviceInfoPtr storage_info) {
std::vector<ash::cros_healthd::mojom::NonRemovableBlockDeviceInfoPtr> devs;
devs.push_back(storage_info.Clone());
devs.push_back(std::move(storage_info));
auto info = ash::cros_healthd::mojom::TelemetryInfo::New();
info->block_device_result = ash::cros_healthd::mojom::
NonRemovableBlockDeviceResult::NewBlockDeviceInfo(std::move(devs));
Expand All @@ -80,7 +72,76 @@ class CrosHealthdMetricsProviderTest : public testing::Test {
::ash::mojo_service_manager::FakeMojoServiceManager fake_service_manager_;
};

TEST_F(CrosHealthdMetricsProviderTest, EndToEnd) {
TEST_F(CrosHealthdMetricsProviderTest, EndToEndWithNvme) {
ash::cros_healthd::mojom::NonRemovableBlockDeviceInfo storage_info;
storage_info.device_info =
ash::cros_healthd::mojom::BlockDeviceInfo::NewNvmeDeviceInfo(
ash::cros_healthd::mojom::NvmeDeviceInfo::New(
kVendorIdNvme, kProductIdNvme, kRevisionNvme, kFwVersionNvme));
storage_info.vendor_id =
ash::cros_healthd::mojom::BlockDeviceVendor::NewNvmeSubsystemVendor(
kVendorIdNvme);
storage_info.product_id =
ash::cros_healthd::mojom::BlockDeviceProduct::NewNvmeSubsystemDevice(
kProductIdNvme);
storage_info.revision =
ash::cros_healthd::mojom::BlockDeviceRevision::NewNvmePcieRev(
kRevisionNvme);
storage_info.firmware_version =
ash::cros_healthd::mojom::BlockDeviceFirmware::NewNvmeFirmwareRev(
kFwVersionNvme);
storage_info.size = kSize;
storage_info.name = kModel;
storage_info.type = kSubsystemNvme;
storage_info.purpose = kMojoPurpose;
SetFakeCrosHealthdData(storage_info.Clone());

base::RunLoop run_loop;
CrosHealthdMetricsProvider provider;
provider.AsyncInit(base::BindOnce(
[](base::OnceClosure callback) { std::move(callback).Run(); },
run_loop.QuitClosure()));
run_loop.Run();

ASSERT_TRUE(provider.IsInitialized());
metrics::SystemProfileProto profile;
provider.ProvideSystemProfileMetrics(&profile);

const auto& hardware = profile.hardware();
ASSERT_EQ(1, hardware.internal_storage_devices_size());

const auto& dev = hardware.internal_storage_devices(0);

EXPECT_EQ(kVendorIdNvme, dev.vendor_id());
EXPECT_EQ(kProductIdNvme, dev.product_id());
EXPECT_EQ(kRevisionNvme, dev.revision());
EXPECT_EQ(kFwVersionNvme, dev.firmware_version());
EXPECT_EQ(kSizeMb, dev.size_mb());
EXPECT_EQ(kModel, dev.model());
EXPECT_EQ(kTypeNvme, dev.type());
EXPECT_EQ(kUmaPurpose, dev.purpose());
}

TEST_F(CrosHealthdMetricsProviderTest, EndToEndWithUfs) {
ash::cros_healthd::mojom::NonRemovableBlockDeviceInfo storage_info;
storage_info.device_info =
ash::cros_healthd::mojom::BlockDeviceInfo::NewUfsDeviceInfo(
ash::cros_healthd::mojom::UfsDeviceInfo::New(kVendorIdUfs,
kFwVersionUfs));
storage_info.vendor_id =
ash::cros_healthd::mojom::BlockDeviceVendor::NewJedecManfid(kVendorIdUfs);
storage_info.product_id =
ash::cros_healthd::mojom::BlockDeviceProduct::NewOther(0);
storage_info.revision =
ash::cros_healthd::mojom::BlockDeviceRevision::NewOther(0);
storage_info.firmware_version =
ash::cros_healthd::mojom::BlockDeviceFirmware::NewUfsFwrev(kFwVersionUfs);
storage_info.size = kSize;
storage_info.name = kModel;
storage_info.type = kSubsystemUfs;
storage_info.purpose = kMojoPurpose;
SetFakeCrosHealthdData(storage_info.Clone());

base::RunLoop run_loop;
CrosHealthdMetricsProvider provider;
provider.AsyncInit(base::BindOnce(
Expand All @@ -97,13 +158,12 @@ TEST_F(CrosHealthdMetricsProviderTest, EndToEnd) {

const auto& dev = hardware.internal_storage_devices(0);

EXPECT_EQ(kVendorId, dev.vendor_id());
EXPECT_EQ(kProductId, dev.product_id());
EXPECT_EQ(kRevision, dev.revision());
EXPECT_EQ(kFwVersion, dev.firmware_version());
EXPECT_EQ(kVendorIdUfs, dev.vendor_id());
EXPECT_EQ(kProductIdUfs, dev.product_id());
EXPECT_EQ(kFwVersionUfs, dev.firmware_version());
EXPECT_EQ(kSizeMb, dev.size_mb());
EXPECT_EQ(kModel, dev.model());
EXPECT_EQ(kType, dev.type());
EXPECT_EQ(kTypeUfs, dev.type());
EXPECT_EQ(kUmaPurpose, dev.purpose());
}

Expand Down

0 comments on commit bad7fac

Please sign in to comment.