Skip to content

Commit 8214923

Browse files
ocp: Fixes for OCP 2.5 Telemetry Stats Parsing
The OCP 2.5 Telemetry log statistics parsing code was not checking for the end of the stats data and therefore getting stuck in an infinite while loop. Added code to parse out the statistic specific data for the Max Die, Max NAND Channel, and Min NAND Channel Bad Block. Removed unneeded brackets Fixed lines exceeding 100 chars Signed-off-by: jeff-lien-wdc <[email protected]>
1 parent a95d951 commit 8214923

File tree

2 files changed

+140
-8
lines changed

2 files changed

+140
-8
lines changed

plugins/ocp/ocp-telemetry-decode.c

Lines changed: 93 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,10 +1204,15 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
12041204
struct json_object *pstats_array, FILE *fp)
12051205
{
12061206
if (pstatistic_entry == NULL) {
1207-
nvme_show_error("Input buffer was NULL");
1207+
nvme_show_error("Statistics Input buffer was NULL");
12081208
return -1;
12091209
}
12101210

1211+
if (pstatistic_entry->statistic_id == STATISTICS_RESERVED_ID)
1212+
/* End of statistics entries, return -1 to stop processing the buffer */
1213+
return -1;
1214+
1215+
12111216
unsigned int data_size = pstatistic_entry->statistic_data_size * SIZE_OF_DWORD;
12121217
__u8 *pdata = (__u8 *)pstatistic_entry +
12131218
sizeof(struct nvme_ocp_telemetry_statistic_descriptor);
@@ -1236,8 +1241,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
12361241
pstatistic_entry->statistic_data_size);
12371242
json_add_formatted_u32_str(pstatistics_object, STR_RESERVED,
12381243
pstatistic_entry->reserved);
1239-
json_add_formatted_var_size_str(pstatistics_object, STR_STATISTICS_SPECIFIC_DATA,
1240-
pdata, data_size);
1244+
if (pstatistic_entry->statistic_id == MAX_DIE_BAD_BLOCK_ID) {
1245+
json_add_formatted_u32_str(pstatistics_object,
1246+
STR_STATISTICS_WORST_DIE_PERCENT,
1247+
pdata[0]);
1248+
json_add_formatted_u32_str(pstatistics_object,
1249+
STR_STATISTICS_WORST_DIE_RAW,
1250+
*(__u16 *)&pdata[2]);
1251+
} else if (pstatistic_entry->statistic_id == MAX_NAND_CHANNEL_BAD_BLOCK_ID) {
1252+
json_add_formatted_u32_str(pstatistics_object,
1253+
STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT,
1254+
pdata[0]);
1255+
json_add_formatted_u32_str(pstatistics_object,
1256+
STR_STATISTICS_WORST_NAND_CHANNEL_RAW,
1257+
*(__u16 *)&pdata[2]);
1258+
} else if (pstatistic_entry->statistic_id == MIN_NAND_CHANNEL_BAD_BLOCK_ID) {
1259+
json_add_formatted_u32_str(pstatistics_object,
1260+
STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT,
1261+
pdata[0]);
1262+
json_add_formatted_u32_str(pstatistics_object,
1263+
STR_STATISTICS_BEST_NAND_CHANNEL_RAW,
1264+
*(__u16 *)&pdata[2]);
1265+
} else {
1266+
json_add_formatted_var_size_str(pstatistics_object,
1267+
STR_STATISTICS_SPECIFIC_DATA,
1268+
pdata,
1269+
data_size);
1270+
}
12411271

12421272
if (pstatistics_object != NULL)
12431273
json_array_add_value_object(pstats_array, pstatistics_object);
@@ -1257,8 +1287,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
12571287
fprintf(fp, "%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
12581288
pstatistic_entry->statistic_data_size);
12591289
fprintf(fp, "%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
1260-
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
1261-
data_size, fp);
1290+
if (pstatistic_entry->statistic_id == MAX_DIE_BAD_BLOCK_ID) {
1291+
fprintf(fp, "%s: 0x%02x\n", STR_STATISTICS_WORST_DIE_PERCENT,
1292+
pdata[0]);
1293+
fprintf(fp, "%s: 0x%04x\n", STR_STATISTICS_WORST_DIE_RAW,
1294+
*(__u16 *)&pdata[2]);
1295+
} else if (pstatistic_entry->statistic_id ==
1296+
MAX_NAND_CHANNEL_BAD_BLOCK_ID) {
1297+
fprintf(fp, "%s: 0x%02x\n",
1298+
STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT,
1299+
pdata[0]);
1300+
fprintf(fp, "%s: 0x%04x\n",
1301+
STR_STATISTICS_WORST_NAND_CHANNEL_RAW,
1302+
*(__u16 *)&pdata[2]);
1303+
} else if (pstatistic_entry->statistic_id ==
1304+
MIN_NAND_CHANNEL_BAD_BLOCK_ID) {
1305+
fprintf(fp, "%s: 0x%02x\n",
1306+
STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT,
1307+
pdata[0]);
1308+
fprintf(fp, "%s: 0x%04x\n",
1309+
STR_STATISTICS_BEST_NAND_CHANNEL_RAW,
1310+
*(__u16 *)&pdata[2]);
1311+
} else {
1312+
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA,
1313+
pdata,
1314+
data_size,
1315+
fp);
1316+
}
12621317
fprintf(fp, STR_LINE2);
12631318
} else {
12641319
printf("%s: 0x%x\n", STR_STATISTICS_IDENTIFIER,
@@ -1275,8 +1330,33 @@ int parse_statistic(struct nvme_ocp_telemetry_statistic_descriptor *pstatistic_e
12751330
printf("%s: 0x%x\n", STR_STATISTICS_DATA_SIZE,
12761331
pstatistic_entry->statistic_data_size);
12771332
printf("%s: 0x%x\n", STR_RESERVED, pstatistic_entry->reserved);
1278-
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA, pdata,
1279-
data_size, fp);
1333+
if (pstatistic_entry->statistic_id == MAX_DIE_BAD_BLOCK_ID) {
1334+
printf("%s: 0x%02x\n", STR_STATISTICS_WORST_DIE_PERCENT,
1335+
pdata[0]);
1336+
printf("%s: 0x%04x\n", STR_STATISTICS_WORST_DIE_RAW,
1337+
*(__u16 *)&pdata[2]);
1338+
} else if (pstatistic_entry->statistic_id ==
1339+
MAX_NAND_CHANNEL_BAD_BLOCK_ID) {
1340+
printf("%s: 0x%02x\n",
1341+
STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT,
1342+
pdata[0]);
1343+
printf("%s: 0x%04x\n",
1344+
STR_STATISTICS_WORST_NAND_CHANNEL_RAW,
1345+
*(__u16 *)&pdata[2]);
1346+
} else if (pstatistic_entry->statistic_id ==
1347+
MIN_NAND_CHANNEL_BAD_BLOCK_ID) {
1348+
printf("%s: 0x%02x\n",
1349+
STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT,
1350+
pdata[0]);
1351+
printf("%s: 0x%04x\n",
1352+
STR_STATISTICS_BEST_NAND_CHANNEL_RAW,
1353+
*(__u16 *)&pdata[2]);
1354+
} else {
1355+
print_formatted_var_size_str(STR_STATISTICS_SPECIFIC_DATA,
1356+
pdata,
1357+
data_size,
1358+
fp);
1359+
}
12801360
printf(STR_LINE2);
12811361
}
12821362
}
@@ -1297,6 +1377,7 @@ int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets
12971377
__u32 stats_da_1_start_dw = 0, stats_da_1_size_dw = 0;
12981378
__u32 stats_da_2_start_dw = 0, stats_da_2_size_dw = 0;
12991379
__u8 *pstats_offset = NULL;
1380+
int parse_rc = 0;
13001381

13011382
if (poffsets->data_area == 1) {
13021383
__u32 stats_da_1_start = *(__u32 *)(pda1_ocp_header_offset +
@@ -1336,7 +1417,11 @@ int parse_statistics(struct json_object *root, struct nvme_ocp_telemetry_offsets
13361417
(struct nvme_ocp_telemetry_statistic_descriptor *)
13371418
(pstats_offset + offset_to_move);
13381419

1339-
parse_statistic(pstatistic_entry, pstats_array, fp);
1420+
parse_rc = parse_statistic(pstatistic_entry, pstats_array, fp);
1421+
if (parse_rc < 0)
1422+
/* end of stats entries or null pointer, so break */
1423+
break;
1424+
13401425
offset_to_move += (pstatistic_entry->statistic_data_size * SIZE_OF_DWORD +
13411426
stat_des_size);
13421427
}

plugins/ocp/ocp-telemetry-decode.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,12 @@ struct telemetry_data_area_1 {
459459
#define STR_STATISTICS_DATA_SIZE "Statistic Data Size"
460460
#define STR_RESERVED "Reserved"
461461
#define STR_STATISTICS_SPECIFIC_DATA "Statistic Specific Data"
462+
#define STR_STATISTICS_WORST_DIE_PERCENT "Worst die % of bad blocks"
463+
#define STR_STATISTICS_WORST_DIE_RAW "Worst die raw number of bad blocks"
464+
#define STR_STATISTICS_WORST_NAND_CHANNEL_PERCENT "Worst NAND channel % of bad blocks"
465+
#define STR_STATISTICS_WORST_NAND_CHANNEL_RAW "Worst NAND channel number of bad blocks"
466+
#define STR_STATISTICS_BEST_NAND_CHANNEL_PERCENT "Best NAND channel % of bad blocks"
467+
#define STR_STATISTICS_BEST_NAND_CHANNEL_RAW "Best NAND channel number of bad blocks"
462468
#define STR_CLASS_SPECIFIC_DATA "Class Specific Data"
463469
#define STR_DBG_EVENT_CLASS_TYPE "Debug Event Class type"
464470
#define STR_EVENT_IDENTIFIER "Event Identifier"
@@ -496,6 +502,47 @@ enum ocp_telemetry_string_tables {
496502
VU_EVENT_STRING
497503
};
498504

505+
/**
506+
* enum ocp_telemetry_statistics_identifiers - OCP Statistics Identifiers
507+
*/
508+
enum ocp_telemetry_statistic_identifiers {
509+
STATISTICS_RESERVED_ID = 0x00,
510+
OUTSTANDING_ADMIN_CMDS_ID = 0x01,
511+
HOST_WRTIE_BANDWIDTH_ID = 0x02,
512+
GW_WRITE_BANDWITH_ID = 0x03,
513+
ACTIVE_NAMESPACES_ID = 0x04,
514+
INTERNAL_WRITE_WORKLOAD_ID = 0x05,
515+
INTERNAL_READ_WORKLOAD_ID = 0x06,
516+
INTERNAL_WRITE_QUEUE_DEPTH_ID = 0x07,
517+
INTERNAL_READ_QUEUE_DEPTH_ID = 0x08,
518+
PENDING_TRIM_LBA_COUNT_ID = 0x09,
519+
HOST_TRIM_LBA_REQUEST_COUNT_ID = 0x0A,
520+
CURRENT_NVME_POWER_STATE_ID = 0x0B,
521+
CURRENT_DSSD_POWER_STATE_ID = 0x0C,
522+
PROGRAM_FAIL_COUNT_ID = 0x0D,
523+
ERASE_FAIL_COUNT_ID = 0x0E,
524+
READ_DISTURB_WRITES_ID = 0x0F,
525+
526+
RETENTION_WRITES_ID = 0x10,
527+
WEAR_LEVELING_WRITES_ID = 0x11,
528+
READ_RECOVERY_WRITES_ID = 0x12,
529+
GC_WRITES_ID = 0x13,
530+
SRAM_CORRECTABLE_COUNT_ID = 0x14,
531+
DRAM_CORRECTABLE_COUNT_ID = 0x15,
532+
SRAM_UNCORRECTABLE_COUNT_ID = 0x16,
533+
DRAM_UNCORRECTABLE_COUNT_ID = 0x17,
534+
DATA_INTEGRITY_ERROR_COUNT_ID = 0x18,
535+
READ_RETRY_ERROR_COUNT_ID = 0x19,
536+
PERST_EVENTS_COUNT_ID = 0x1A,
537+
MAX_DIE_BAD_BLOCK_ID = 0x1B,
538+
MAX_NAND_CHANNEL_BAD_BLOCK_ID = 0x1C,
539+
MIN_NAND_CHANNEL_BAD_BLOCK_ID = 0x1D,
540+
541+
//RESERVED = 7FFFh-1Eh,
542+
//VENDOR_UNIQUE_CLASS_TYPE = FFFFh-8000h,
543+
};
544+
545+
499546
/**
500547
* enum ocp_telemetry_debug_event_class_types - OCP Debug Event Class types
501548
* @RESERVED_CLASS_TYPE: Reserved class

0 commit comments

Comments
 (0)