Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/ocp/ocp-nvme.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#if !defined(OCP_NVME) || defined(CMD_HEADER_MULTI_READ)
#define OCP_NVME

#define OCP_PLUGIN_VERSION "2.9.3"
#define OCP_PLUGIN_VERSION "2.11.0"
#include "cmd.h"

PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),
Expand Down
101 changes: 93 additions & 8 deletions plugins/ocp/ocp-telemetry-decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1204,10 +1204,15 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
struct json_object *pstats_array, FILE *fp)
{
if (pstatistic_entry == NULL) {
nvme_show_error("Input buffer was NULL");
nvme_show_error("Statistics Input buffer was NULL");
return -1;
}

if (pstatistic_entry->statistic_id == STATISTICS_RESERVED_ID)
/* End of statistics entries, return -1 to stop processing the buffer */
return -1;


unsigned int data_size = pstatistic_entry->statistic_data_size * SIZE_OF_DWORD;
__u8 *pdata = (__u8 *)pstatistic_entry +
sizeof(struct nvme_ocp_telemetry_statistic_descriptor);
Expand Down Expand Up @@ -1236,8 +1241,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
pstatistic_entry->statistic_data_size);
json_add_formatted_u32_str(pstatistics_object, STR_RESERVED,
pstatistic_entry->reserved);
json_add_formatted_var_size_str(pstatistics_object, STR_STATISTICS_SPECIFIC_DATA,
pdata, data_size);
if (pstatistic_entry->statistic_id == MAX_DIE_BAD_BLOCK_ID) {
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_WORST_DIE_PERCENT,
pdata[0]);
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_WORST_DIE_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id == MAX_NAND_CHANNEL_BAD_BLOCK_ID) {
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT,
pdata[0]);
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_WORST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id == MIN_NAND_CHANNEL_BAD_BLOCK_ID) {
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT,
pdata[0]);
json_add_formatted_u32_str(pstatistics_object,
STR_STATISTICS_BEST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else {
json_add_formatted_var_size_str(pstatistics_object,
STR_STATISTICS_SPECIFIC_DATA,
pdata,
data_size);
}

if (pstatistics_object != NULL)
json_array_add_value_object(pstats_array, pstatistics_object);
Expand All @@ -1257,8 +1287,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
pstatistic_entry->statistic_data_size);
fprintf(fp, "%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
data_size, fp);
if (pstatistic_entry->statistic_id == MAX_DIE_BAD_BLOCK_ID) {
fprintf(fp, "%s: 0x%02x\n", STR_STATISTICS_WORST_DIE_PERCENT,
pdata[0]);
fprintf(fp, "%s: 0x%04x\n", STR_STATISTICS_WORST_DIE_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id ==
MAX_NAND_CHANNEL_BAD_BLOCK_ID) {
fprintf(fp, "%s: 0x%02x\n",
STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT,
pdata[0]);
fprintf(fp, "%s: 0x%04x\n",
STR_STATISTICS_WORST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id ==
MIN_NAND_CHANNEL_BAD_BLOCK_ID) {
fprintf(fp, "%s: 0x%02x\n",
STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT,
pdata[0]);
fprintf(fp, "%s: 0x%04x\n",
STR_STATISTICS_BEST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else {
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA,
pdata,
data_size,
fp);
}
fprintf(fp, STR_LINE2);
} else {
printf("%s: 0x%x\n", STR_STATISTICS_IDENTIFIER,
Expand All @@ -1275,8 +1330,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
printf("%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
pstatistic_entry->statistic_data_size);
printf("%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
data_size, fp);
if (pstatistic_entry->statistic_id == MAX_DIE_BAD_BLOCK_ID) {
printf("%s: 0x%02x\n", STR_STATISTICS_WORST_DIE_PERCENT,
pdata[0]);
printf("%s: 0x%04x\n", STR_STATISTICS_WORST_DIE_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id ==
MAX_NAND_CHANNEL_BAD_BLOCK_ID) {
printf("%s: 0x%02x\n",
STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT,
pdata[0]);
printf("%s: 0x%04x\n",
STR_STATISTICS_WORST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else if (pstatistic_entry->statistic_id ==
MIN_NAND_CHANNEL_BAD_BLOCK_ID) {
printf("%s: 0x%02x\n",
STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT,
pdata[0]);
printf("%s: 0x%04x\n",
STR_STATISTICS_BEST_NAND_CHANNEL_RAW,
*(__u16 *)&pdata[2]);
} else {
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA,
pdata,
data_size,
fp);
}
printf(STR_LINE2);
}
}
Expand All @@ -1297,6 +1377,7 @@ int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets
__u32 stats_da_1_start_dw = 0, stats_da_1_size_dw = 0;
__u32 stats_da_2_start_dw = 0, stats_da_2_size_dw = 0;
__u8 *pstats_offset = NULL;
int parse_rc = 0;

if (poffsets->data_area == 1) {
__u32 stats_da_1_start = *(__u32 *)(pda1_ocp_header_offset +
Expand Down Expand Up @@ -1336,7 +1417,11 @@ int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets
(struct nvme_ocp_telemetry_statistic_descriptor *)
(pstats_offset + offset_to_move);

parse_statistic(pstatistic_entry, pstats_array, fp);
parse_rc = parse_statistic(pstatistic_entry, pstats_array, fp);
if (parse_rc < 0)
/* end of stats entries or null pointer, so break */
break;

offset_to_move += (pstatistic_entry->statistic_data_size * SIZE_OF_DWORD +
stat_des_size);
}
Expand Down
47 changes: 47 additions & 0 deletions plugins/ocp/ocp-telemetry-decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,12 @@ struct telemetry_data_area_1 {
#define STR_STATISTICS_DATA_SIZE "Statistic Data Size"
#define STR_RESERVED "Reserved"
#define STR_STATISTICS_SPECIFIC_DATA "Statistic Specific Data"
#define STR_STATISTICS_WORST_DIE_PERCENT "Worst die % of bad blocks"
#define STR_STATISTICS_WORST_DIE_RAW "Worst die raw number of bad blocks"
#define STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT "Worst NAND channel % of bad blocks"
#define STR_STATISTICS_WORST_NAND_CHANNEL_RAW "Worst NAND channel number of bad blocks"
#define STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT "Best NAND channel % of bad blocks"
#define STR_STATISTICS_BEST_NAND_CHANNEL_RAW "Best NAND channel number of bad blocks"
#define STR_CLASS_SPECIFIC_DATA "Class Specific Data"
#define STR_DBG_EVENT_CLASS_TYPE "Debug Event Class type"
#define STR_EVENT_IDENTIFIER "Event Identifier"
Expand Down Expand Up @@ -496,6 +502,47 @@ enum ocp_telemetry_string_tables {
VU_EVENT_STRING
};

/**
* enum ocp_telemetry_statistics_identifiers - OCP Statistics Identifiers
*/
enum ocp_telemetry_statistic_identifiers {
STATISTICS_RESERVED_ID = 0x00,
OUTSTANDING_ADMIN_CMDS_ID = 0x01,
HOST_WRTIE_BANDWIDTH_ID = 0x02,
GW_WRITE_BANDWITH_ID = 0x03,
ACTIVE_NAMESPACES_ID = 0x04,
INTERNAL_WRITE_WORKLOAD_ID = 0x05,
INTERNAL_READ_WORKLOAD_ID = 0x06,
INTERNAL_WRITE_QUEUE_DEPTH_ID = 0x07,
INTERNAL_READ_QUEUE_DEPTH_ID = 0x08,
PENDING_TRIM_LBA_COUNT_ID = 0x09,
HOST_TRIM_LBA_REQUEST_COUNT_ID = 0x0A,
CURRENT_NVME_POWER_STATE_ID = 0x0B,
CURRENT_DSSD_POWER_STATE_ID = 0x0C,
PROGRAM_FAIL_COUNT_ID = 0x0D,
ERASE_FAIL_COUNT_ID = 0x0E,
READ_DISTURB_WRITES_ID = 0x0F,

RETENTION_WRITES_ID = 0x10,
WEAR_LEVELING_WRITES_ID = 0x11,
READ_RECOVERY_WRITES_ID = 0x12,
GC_WRITES_ID = 0x13,
SRAM_CORRECTABLE_COUNT_ID = 0x14,
DRAM_CORRECTABLE_COUNT_ID = 0x15,
SRAM_UNCORRECTABLE_COUNT_ID = 0x16,
DRAM_UNCORRECTABLE_COUNT_ID = 0x17,
DATA_INTEGRITY_ERROR_COUNT_ID = 0x18,
READ_RETRY_ERROR_COUNT_ID = 0x19,
PERST_EVENTS_COUNT_ID = 0x1A,
MAX_DIE_BAD_BLOCK_ID = 0x1B,
MAX_NAND_CHANNEL_BAD_BLOCK_ID = 0x1C,
MIN_NAND_CHANNEL_BAD_BLOCK_ID = 0x1D,

//RESERVED = 7FFFh-1Eh,
//VENDOR_UNIQUE_CLASS_TYPE = FFFFh-8000h,
};


/**
* enum ocp_telemetry_debug_event_class_types - OCP Debug Event Class types
* @RESERVED_CLASS_TYPE: Reserved class
Expand Down
Loading