-
Notifications
You must be signed in to change notification settings - Fork 44
Add human-friendly formatting for SSD write/read statistics #114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -22,6 +22,7 @@ License: GNU General Public License v3.0 only | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //#include "warning_colors.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "storage_property_descr_helpers.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "hz/string_num.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "hz/format_unit.h" // format_size | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1364,5 +1365,104 @@ void storage_property_ata_attribute_autoset_warning(StorageProperty& p) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void storage_property_ata_attribute_humanize_ssd_writes(StorageProperty& p) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (p.section != StoragePropertySection::AtaAttributes || !p.is_value_type<AtaStorageAttribute>()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const auto& attr = p.get_value<AtaStorageAttribute>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Skip if readable_value is already set (e.g., by parser or for GiB attributes) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!p.readable_value.empty()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Standard sector size (512 bytes) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| constexpr uint64_t bytes_per_sector = 512; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| constexpr uint64_t mib_32 = 32ULL * 1024ULL * 1024ULL; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| constexpr uint64_t gib = 1024ULL * 1024ULL * 1024ULL; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Match attribute by ID and reported name to handle vendor-specific attributes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const int32_t id = attr.id; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const std::string& name = p.reported_name; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::optional<uint64_t> bytes; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Write attributes - these need humanization most | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Attribute 199: Write_Sectors_Tot_Ct (Indilinx Barefoot SSDs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Total count of written sectors | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (id == 199 && name == "Write_Sectors_Tot_Ct") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bytes = static_cast<uint64_t>(attr.raw_value_int) * bytes_per_sector; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Attribute 225: Host_Writes_32MiB (Intel SSDs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else if (id == 225 && name == "Host_Writes_32MiB") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Attribute 241: Host_Writes_32MiB (various SSDs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Raw value increased by 1 for every 32 MiB written | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else if (id == 241 && name == "Host_Writes_32MiB") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Attribute 243: Host_Writes_32MiB (SanDisk SSDs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else if (id == 243 && name == "Host_Writes_32MiB") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Attribute 245: Flash_Writes_32MiB (Innodisk SSDs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else if (id == 245 && name == "Flash_Writes_32MiB") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Attribute 245: TLC_Writes_32MiB (SiliconMotion SSDs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else if (id == 245 && name == "TLC_Writes_32MiB") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1397
to
+1417
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Attribute 225: Host_Writes_32MiB (Intel SSDs) | |
| else if (id == 225 && name == "Host_Writes_32MiB") { | |
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | |
| } | |
| // Attribute 241: Host_Writes_32MiB (various SSDs) | |
| // Raw value increased by 1 for every 32 MiB written | |
| else if (id == 241 && name == "Host_Writes_32MiB") { | |
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | |
| } | |
| // Attribute 243: Host_Writes_32MiB (SanDisk SSDs) | |
| else if (id == 243 && name == "Host_Writes_32MiB") { | |
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | |
| } | |
| // Attribute 245: Flash_Writes_32MiB (Innodisk SSDs) | |
| else if (id == 245 && name == "Flash_Writes_32MiB") { | |
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | |
| } | |
| // Attribute 245: TLC_Writes_32MiB (SiliconMotion SSDs) | |
| else if (id == 245 && name == "TLC_Writes_32MiB") { | |
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | |
| } | |
| // Attributes whose raw value is a count of 32 MiB units | |
| else { | |
| struct WriteUnits32MiBEntry { | |
| int32_t id; | |
| const char* name; | |
| }; | |
| // Raw value increased by 1 for every 32 MiB written | |
| static constexpr WriteUnits32MiBEntry write_32mib_entries[] = { | |
| // Attribute 225: Host_Writes_32MiB (Intel SSDs) | |
| {225, "Host_Writes_32MiB"}, | |
| // Attribute 241: Host_Writes_32MiB (various SSDs) | |
| {241, "Host_Writes_32MiB"}, | |
| // Attribute 243: Host_Writes_32MiB (SanDisk SSDs) | |
| {243, "Host_Writes_32MiB"}, | |
| // Attribute 245: Flash_Writes_32MiB (Innodisk SSDs) | |
| {245, "Flash_Writes_32MiB"}, | |
| // Attribute 245: TLC_Writes_32MiB (SiliconMotion SSDs) | |
| {245, "TLC_Writes_32MiB"}, | |
| // Attribute 246: SLC_Writes_32MiB (SiliconMotion SSDs) | |
| {246, "SLC_Writes_32MiB"}, | |
| }; | |
| for (const auto& entry : write_32mib_entries) { | |
| if (id == entry.id && name == entry.name) { | |
| bytes = static_cast<uint64_t>(attr.raw_value_int) * mib_32; | |
| break; | |
| } | |
| } | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -26,6 +26,11 @@ void auto_set_ata_attribute_description(StorageProperty& p, StorageDeviceDetecte | |||||||||||
| void storage_property_ata_attribute_autoset_warning(StorageProperty& p); | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| /// Humanize SSD write statistics by converting raw values to readable byte counts. | ||||||||||||
| /// Sets the readable_value field for applicable write-related attributes. | ||||||||||||
|
Comment on lines
+29
to
+30
|
||||||||||||
| /// Humanize SSD write statistics by converting raw values to readable byte counts. | |
| /// Sets the readable_value field for applicable write-related attributes. | |
| /// Humanize SSD I/O statistics (both read- and write-related) by converting raw | |
| /// values to readable byte counts. Sets the readable_value field for applicable | |
| /// SSD attributes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attr.raw_value_intisint64_t; casting a negative value touint64_tbefore multiplying will wrap and produce an enormous byte count (andbytes > 0will still pass). It would be safer to explicitly requireattr.raw_value_int > 0before conversion and to guard againstuint64_toverflow when multiplying by sector/32MiB/1GiB (e.g., via a checked multiply ormax()/multiplierpre-check).