Skip to content

Commit 5a79a08

Browse files
lgdacunhigaw
authored andcommitted
plugins/solidigm: parse-telemetry-log aware of OCP2.5 binaries
Made parse-telemetry-log aware of OCP2.5 binaries. Display proper OCP reason identifier. Don't extract toc from DA1/DA2 when OCP log detected. Show DA4 last block in the header. Removed ccan ilog.h dependency Fixed Nlog parser by taking Nlog header into account. Added verbose mode. Signed-off-by: Leonardo da Cunha <[email protected]>
1 parent d60c082 commit 5a79a08

6 files changed

Lines changed: 144 additions & 9 deletions

File tree

plugins/solidigm/solidigm-telemetry.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc
8383
OPT_UINT("data-area", 'd', &cfg.data_area, dgen),
8484
OPT_FILE("config-file", 'j', &cfg.cfg_file, cfile),
8585
OPT_FLAG("source-file", 's', &cfg.is_input_file, sfile),
86+
OPT_INCR("verbose", 'v', &nvme_cfg.verbose, verbose),
8687
OPT_END()
8788
};
8889

plugins/solidigm/solidigm-telemetry/data-area.c

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,23 @@
1818

1919
#define MAX_WARNING_SIZE 1024
2020
#define MAX_ARRAY_RANK 16
21+
#define NLOG_HEADER_ID 101
22+
23+
24+
static void reverse_string(char *buff, size_t len)
25+
{
26+
char *start = buff;
27+
char *end = buff + len - 1;
28+
char temp;
29+
30+
while (end > start) {
31+
temp = *end;
32+
*end = *start;
33+
*start = temp;
34+
start++;
35+
end--;
36+
}
37+
}
2138

2239
static bool telemetry_log_get_value(const struct telemetry_log *tl,
2340
uint64_t offset_bit, uint32_t size_bit,
@@ -418,6 +435,13 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
418435
header->Token);
419436
if (!nlog_name)
420437
continue;
438+
439+
// NLOGs have different parser from other Telemetry objects
440+
has_struct = solidigm_config_get_struct_by_token_version(tl->configuration,
441+
NLOG_HEADER_ID,
442+
header->versionMajor,
443+
header->versionMinor,
444+
&structure_definition);
421445
}
422446
struct json_object *tele_obj_item = json_create_object();
423447

@@ -443,29 +467,72 @@ static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
443467
telemetry_log_structure_parse(tl, structure_definition,
444468
BITS_IN_BYTE * object_file_offset,
445469
parsed_struct, toc_item);
446-
} else if (nlog_formats) {
470+
}
471+
// NLOGs have different parser from other Telemetry objects
472+
if (nlog_name) {
473+
if (has_struct) {
474+
struct json_object *header_sizeBits = NULL;
475+
struct json_object *header_nlogSelect = NULL;
476+
struct json_object *header_nlogName = NULL;
477+
478+
if (json_object_object_get_ex(structure_definition, "sizeBit",
479+
&header_sizeBits))
480+
header_offset = json_object_get_int(header_sizeBits) /
481+
BITS_IN_BYTE;
482+
// Overwrite nlogName with correct type
483+
if (json_object_object_get_ex(parsed_struct, "nlogSelect",
484+
&header_nlogSelect) &&
485+
json_object_object_get_ex(header_nlogSelect, "nlogName",
486+
&header_nlogName)) {
487+
int nlogName = json_object_get_int(header_nlogName);
488+
char *name = (char *)&nlogName;
489+
490+
reverse_string(name, sizeof(uint32_t));
491+
json_object_object_add(header_nlogSelect, "nlogName",
492+
json_object_new_string_len(name,
493+
sizeof(uint32_t)));
494+
}
495+
}
496+
// Overwrite the object name
447497
json_object_object_add(toc_item, "objName",
448498
json_object_new_string(nlog_name));
449-
telemetry_log_nlog_parse(tl, nlog_formats, object_file_offset,
499+
500+
telemetry_log_nlog_parse(tl, nlog_formats,
501+
object_file_offset + header_offset,
450502
toc->items[i].ContentSizeBytes - header_offset,
451503
parsed_struct, toc_item);
452504
}
453505
}
454506
}
455507

508+
void solidigm_telemetry_log_da1_check_ocp(struct telemetry_log *tl)
509+
{
510+
const uint64_t ocp_telemetry_uuid[] = {0xBC73719D87E64EFA, 0xBA560A9C3043424C};
511+
const uint64_t *log_uuid = (uint64_t *) &tl->log->data_area[16];
512+
513+
tl->is_ocp = tl->log_size >= (&tl->log->data_area[32] - (uint8_t *) tl->log) &&
514+
log_uuid[0] == ocp_telemetry_uuid[0] && log_uuid[1] == ocp_telemetry_uuid[1];
515+
}
516+
456517
int solidigm_telemetry_log_data_areas_parse(struct telemetry_log *tl,
457518
enum nvme_telemetry_da last_da)
458519
{
459520
struct json_object *tele_obj_array = json_create_array();
460521
struct json_object *toc_array = json_create_array();
461522

523+
solidigm_telemetry_log_da1_check_ocp(tl);
462524
solidigm_telemetry_log_header_parse(tl);
463525
solidigm_telemetry_log_cod_parse(tl);
464526
if (tl->configuration) {
527+
enum nvme_telemetry_da first_da = NVME_TELEMETRY_DA_1;
528+
529+
if (tl->is_ocp)
530+
first_da = NVME_TELEMETRY_DA_3;
531+
465532
json_object_add_value_array(tl->root, "tableOfContents", toc_array);
466533
json_object_add_value_array(tl->root, "telemetryObjects", tele_obj_array);
467534

468-
for (enum nvme_telemetry_da da = NVME_TELEMETRY_DA_1; da <= last_da; da++)
535+
for (enum nvme_telemetry_da da = first_da; da <= last_da; da++)
469536
telemetry_log_data_area_toc_parse(tl, da, toc_array, tele_obj_array);
470537
}
471538
return 0;

plugins/solidigm/solidigm-telemetry/data-area.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88

99
int solidigm_telemetry_log_data_areas_parse(struct telemetry_log *tl,
1010
enum nvme_telemetry_da last_da);
11+
void solidigm_telemetry_log_da1_check_ocp(struct telemetry_log *tl);

plugins/solidigm/solidigm-telemetry/header.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,28 @@ struct reason_indentifier_1_2 {
5757
static_assert(sizeof(const struct reason_indentifier_1_2) ==
5858
MEMBER_SIZE(struct nvme_telemetry_log, rsnident),
5959
"Size mismatch for reason_indentifier_1_2");
60+
61+
struct reason_identifier_ocp_2_5 {
62+
char errorId[64];
63+
char fileId[8];
64+
uint16_t lineNum;
65+
union {
66+
struct {
67+
uint8_t validLineNum:1;
68+
uint8_t validFileId:1;
69+
uint8_t validErrorId:1;
70+
uint8_t validVuExtension:1;
71+
uint8_t reservedBits:4;
72+
};
73+
uint8_t raw;
74+
} validFlags;
75+
uint8_t reserved[21];
76+
uint8_t vuExtension[32];
77+
};
78+
static_assert(sizeof(const struct reason_identifier_ocp_2_5) ==
79+
MEMBER_SIZE(struct nvme_telemetry_log, rsnident),
80+
"Size mismatch for reason_identifier_ocp_2_5");
81+
6082
#pragma pack(pop, reason_indentifier)
6183

6284
static void telemetry_log_reason_id_parse1_0_ext(const struct telemetry_log *tl,
@@ -153,6 +175,43 @@ static void telemetry_log_reason_id_parse1_2_ext(const struct telemetry_log *tl,
153175
json_object_array_add(dp_reserved, val);
154176
}
155177
}
178+
static void telemetry_log_reason_id_parse_ocp_2_5(const struct telemetry_log *tl,
179+
struct json_object *reason_id)
180+
{
181+
const struct reason_identifier_ocp_2_5 *ri;
182+
struct json_object *reserved;
183+
struct json_object *vu_extension;
184+
185+
ri = (struct reason_identifier_ocp_2_5 *) tl->log->rsnident;
186+
187+
json_object_object_add(reason_id, "errorId",
188+
json_object_new_string_len(ri->errorId,
189+
sizeof(ri->errorId)));
190+
json_object_object_add(reason_id, "fileId",
191+
json_object_new_string_len(ri->fileId,
192+
sizeof(ri->fileId)));
193+
json_object_add_value_uint(reason_id, "lineNum", le16_to_cpu(ri->lineNum));
194+
json_object_add_value_uint(reason_id, "validLineNum", ri->validFlags.validLineNum);
195+
json_object_add_value_uint(reason_id, "validFileId", ri->validFlags.validFileId);
196+
json_object_add_value_uint(reason_id, "validErrorId", ri->validFlags.validErrorId);
197+
json_object_add_value_uint(reason_id, "validVuExtension", ri->validFlags.validVuExtension);
198+
199+
reserved = json_create_array();
200+
json_object_add_value_array(reason_id, "reserved", reserved);
201+
for (int i = 0; i < sizeof(ri->reserved); i++) {
202+
struct json_object *val = json_object_new_int(ri->reserved[i]);
203+
204+
json_object_array_add(reserved, val);
205+
}
206+
207+
vu_extension = json_create_array();
208+
json_object_add_value_array(reason_id, "vuExtension", vu_extension);
209+
for (int i = 0; i < sizeof(ri->vuExtension); i++) {
210+
struct json_object *val = json_object_new_int(ri->vuExtension[i]);
211+
212+
json_object_array_add(vu_extension, val);
213+
}
214+
}
156215

157216
static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *tl, struct json_object *reason_id)
158217
{
@@ -161,12 +220,18 @@ static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *t
161220
uint16_t version_major = le16_to_cpu(ri1_0->versionMajor);
162221
uint16_t version_minor = le16_to_cpu(ri1_0->versionMinor);
163222

223+
if (tl->is_ocp) {
224+
telemetry_log_reason_id_parse_ocp_2_5(tl, reason_id);
225+
return;
226+
}
227+
164228
json_object_add_value_uint(reason_id, "versionMajor", version_major);
165229
json_object_add_value_uint(reason_id, "versionMinor", version_minor);
166230
json_object_add_value_uint(reason_id, "reasonCode", le32_to_cpu(ri1_0->reasonCode));
167231
json_object_add_value_object(reason_id, "driveStatus",
168232
json_object_new_string_len(ri1_0->DriveStatus,
169233
sizeof(ri1_0->DriveStatus)));
234+
170235
if (version_major == 1) {
171236
switch (version_minor) {
172237
case 0:
@@ -211,6 +276,7 @@ bool solidigm_telemetry_log_header_parse(const struct telemetry_log *tl)
211276
json_object_add_value_uint(header, "dataArea1LastBlock", log->dalb1);
212277
json_object_add_value_uint(header, "dataArea2LastBlock", log->dalb2);
213278
json_object_add_value_uint(header, "dataArea3LastBlock", log->dalb3);
279+
json_object_add_value_uint(header, "dataArea4LastBlock", log->dalb4);
214280
json_object_add_value_uint(header, "hostInitiatedDataGeneration", log->hostdgn);
215281
json_object_add_value_uint(header, "controllerInitiatedDataAvailable", log->ctrlavail);
216282
json_object_add_value_uint(header, "controllerInitiatedDataGeneration", log->ctrldgn);

plugins/solidigm/solidigm-telemetry/nlog.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@
1010
#include <string.h>
1111
#include <stdio.h>
1212

13-
#include "ccan/ilog/ilog.h"
14-
1513
#define LOG_ENTRY_HEADER_SIZE 1
1614
#define LOG_ENTRY_TIMESTAMP_SIZE 2
1715
#define LOG_ENTRY_NUM_ARGS_MAX 8
16+
#define LOG_ENTRY_NUM_ARGS_MASK 0xF
1817
#define LOG_ENTRY_MAX_SIZE (LOG_ENTRY_HEADER_SIZE + LOG_ENTRY_TIMESTAMP_SIZE + \
1918
LOG_ENTRY_NUM_ARGS_MAX)
20-
#define NUM_ARGS_MASK ((1 << ((int)STATIC_ILOG_32(LOG_ENTRY_NUM_ARGS_MAX))) - 1)
2119
#define MAX_HEADER_MISMATCH_TRACK 10
2220

2321
static int formats_find(struct json_object *formats, uint32_t val, struct json_object **format)
@@ -41,13 +39,13 @@ static uint32_t nlog_get_events(const uint32_t *nlog, const uint32_t nlog_size,
4139
uint32_t tail_count = 0;
4240

4341
for (int i = nlog_size - start_offset - 1; i >= -start_offset; i--) {
44-
struct json_object *format;
42+
struct json_object *format = NULL;
4543
uint32_t header = nlog_get_pos(nlog, nlog_size, i);
4644
uint32_t num_data;
4745

4846
if (header == 0 || !formats_find(formats, header, &format)) {
4947
if (event_count > 0) {
50-
//check if fould circular buffer tail
48+
//check if found circular buffer tail
5149
if (i != (last_bad_header_pos - 1)) {
5250
if (tail_mismatches &&
5351
(tail_count < MAX_HEADER_MISMATCH_TRACK))
@@ -58,7 +56,7 @@ static uint32_t nlog_get_events(const uint32_t *nlog, const uint32_t nlog_size,
5856
}
5957
continue;
6058
}
61-
num_data = header & NUM_ARGS_MASK;
59+
num_data = header & LOG_ENTRY_NUM_ARGS_MASK;
6260
if (events) {
6361
struct json_object *event = json_object_new_array();
6462
struct json_object *param = json_object_new_array();

plugins/solidigm/solidigm-telemetry/telemetry-log.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "libnvme.h"
1212
#include "util/json.h"
1313
#include <assert.h>
14+
#include <stdbool.h>
1415

1516
#if !defined __cplusplus
1617
#define static_assert _Static_assert
@@ -26,6 +27,7 @@ struct telemetry_log {
2627
size_t log_size;
2728
struct json_object *root;
2829
struct json_object *configuration;
30+
bool is_ocp;
2931
};
3032

3133
#endif /* _SOLIDIGM_TELEMETRY_LOG_H */

0 commit comments

Comments
 (0)