Skip to content

Commit

Permalink
ocp: Fixes for OCP 2.5 Telemetry DA1 FIFO Event Parsing
Browse files Browse the repository at this point in the history
This commit fixes several issues related to parsing
the Telemetry DA 1 and 2 Event FIFO's.

Fixes parsing of VU Event Data.
    Added checking for VU data.
    Removed the vu_event_identifier field from the debug
    event class structs since it's not guaranteed to be there.
    Added nvme_ocp_common_dbg_evt_class_vu_data to be used
    to access the VU data.

    Added checking for NULL pointers

    Added a check for the end of the Event FIFO entries that will
    break from the while loop when detected.

    Fixed lines longer then 100 columns.
    Fixed other miscellaneous errors flagged
    by checkpatch.pl.
    Fixed "Suspicious sizeof offset in a pointer
    arithmetic expression." errors flagged by Code
    scanning.

    Fixed loop index size error
    Fixed LE variable declarations and conversion issues
    Fixed vu data size errors
    Make variable names more descriptive

Signed-off-by: jeff-lien-wdc <[email protected]>
  • Loading branch information
jeff-lien-wdc authored and igaw committed Oct 4, 2024
1 parent f7f1923 commit 8b6d4f2
Show file tree
Hide file tree
Showing 4 changed files with 359 additions and 222 deletions.
99 changes: 53 additions & 46 deletions plugins/ocp/ocp-nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,7 @@ static int get_telemetry_data(struct nvme_dev *dev, __u32 ns, __u8 tele_type,
cmd.cdw14 = 0;
return nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL);
}

static void print_telemetry_data_area_1(struct telemetry_data_area_1 *da1,
int tele_type)
{
Expand Down Expand Up @@ -1075,13 +1076,13 @@ static void print_telemetry_da_stat(struct telemetry_stats_desc *da_stat,
}
}
static void print_telemetry_da_fifo(struct telemetry_event_desc *da_fifo,
__le64 buf_size,
__u64 buf_size,
int tele_type,
int da,
int index)
{
if (da_fifo) {
unsigned int i = 0;
__u64 i = 0;
struct telemetry_event_desc *next_da_fifo = da_fifo;

if (tele_type == TELEMETRY_TYPE_HOST)
Expand All @@ -1091,8 +1092,11 @@ static void print_telemetry_da_fifo(struct telemetry_event_desc *da_fifo,
printf("====== Telemetry Controller Data area %d Event FIFO %d ======\n",
da, index);


while ((i + 4) < buf_size) {
/* break if last entry */
if (next_da_fifo->class == 0)
break;

/* Print Event Data */
print_telemetry_fifo_event(next_da_fifo->class, /* Event class type */
next_da_fifo->id, /* Event ID */
Expand Down Expand Up @@ -1190,7 +1194,7 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
enum TELEMETRY_TYPE tele_type, int data_area, bool header_print)
{
__u32 err = 0, nsid = 0;
__le64 da1_sz = 512, m_512_sz = 0, da1_off = 0, m_512_off = 0, diff = 0,
__u64 da1_sz = 512, m_512_sz = 0, da1_off = 0, m_512_off = 0, diff = 0,
temp_sz = 0, temp_ofst = 0;
__u8 lsp = 0, rae = 0, flag = 0;
__u8 data[TELEMETRY_HEADER_SIZE] = { 0 };
Expand Down Expand Up @@ -1242,16 +1246,16 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
/* Print the Data Area 1 Stats */
if (da1->da1_stat_size != 0) {
diff = 0;
da1_sz = (da1->da1_stat_size) * 4;
m_512_sz = (da1->da1_stat_size) * 4;
da1_off = (da1->da1_stat_start) * 4;
m_512_off = (da1->da1_stat_start) * 4;
temp_sz = (da1->da1_stat_size) * 4;
temp_ofst = (da1->da1_stat_start) * 4;
da1_sz = le64_to_cpu(da1->da1_stat_size) * 4;
m_512_sz = le64_to_cpu(da1->da1_stat_size) * 4;
da1_off = le64_to_cpu(da1->da1_stat_start) * 4;
m_512_off = le64_to_cpu(da1->da1_stat_start) * 4;
temp_sz = le64_to_cpu(da1->da1_stat_size) * 4;
temp_ofst = le64_to_cpu(da1->da1_stat_start) * 4;
flag = 0;

if ((da1_off % 512) > 0) {
m_512_off = (__le64) ((da1_off / 512));
m_512_off = (da1_off / 512);
da1_off = m_512_off * 512;
diff = temp_ofst - da1_off;
flag = 1;
Expand All @@ -1261,15 +1265,15 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
da1_sz = 512;
else if ((da1_sz % 512) > 0) {
if (flag == 0) {
m_512_sz = (__le64) ((da1_sz / 512) + 1);
m_512_sz = (da1_sz / 512) + 1;
da1_sz = m_512_sz * 512;
} else {
if (diff < 512)
diff = 1;
else
diff = (diff / 512) * 512;

m_512_sz = (__le64) ((da1_sz / 512) + 1 + diff + 1);
m_512_sz = (da1_sz / 512) + 1 + diff + 1;
da1_sz = m_512_sz * 512;
}
}
Expand All @@ -1284,23 +1288,23 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
}

print_telemetry_da_stat((void *)(da1_stat + (temp_ofst - da1_off)),
tele_type, (da1->da1_stat_size) * 4, 1);
tele_type, le64_to_cpu(da1->da1_stat_size) * 4, 1);
}

/* Print the Data Area 1 Event FIFO's */
for (i = 0; i < 16 ; i++) {
if ((da1->event_fifo_da[i] == 1) && (da1->event_fifos[i].size != 0)) {
diff = 0;
da1_sz = da1->event_fifos[i].size * 4;
m_512_sz = da1->event_fifos[i].size * 4;
da1_off = da1->event_fifos[i].start * 4;
m_512_off = da1->event_fifos[i].start * 4;
temp_sz = da1->event_fifos[i].size * 4;
temp_ofst = da1->event_fifos[i].start * 4;
da1_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
m_512_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
da1_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
m_512_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
temp_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
temp_ofst = le64_to_cpu(da1->event_fifos[i].start) * 4;
flag = 0;

if ((da1_off % 512) > 0) {
m_512_off = (__le64) ((da1_off / 512));
m_512_off = ((da1_off / 512));
da1_off = m_512_off * 512;
diff = temp_ofst - da1_off;
flag = 1;
Expand All @@ -1310,23 +1314,25 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
da1_sz = 512;
else if ((da1_sz % 512) > 0) {
if (flag == 0) {
m_512_sz = (__le64) ((da1_sz / 512) + 1);
m_512_sz = (da1_sz / 512) + 1;
da1_sz = m_512_sz * 512;
} else {
if (diff < 512)
diff = 1;
else
diff = (diff / 512) * 512;

m_512_sz = (__le64) ((da1_sz / 512) + 1 + diff + 1);
m_512_sz = (da1_sz / 512) + 1 + diff + 1;
da1_sz = m_512_sz * 512;
}
}

char *da1_fifo = calloc(da1_sz, sizeof(char));

printf("Get DA 1 FIFO addr: %p, offset 0x%llx\n",
da1_fifo, da1_off);
err = get_telemetry_data(dev, nsid, tele_type,
(da1->event_fifos[i].size) * 4,
le64_to_cpu(da1->event_fifos[i].size) * 4,
(void *)da1_fifo, lsp, rae, da1_off);
if (err) {
printf("get_telemetry_data da1 event fifos failed, err: %d.\n",
Expand All @@ -1336,34 +1342,34 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
print_telemetry_da_fifo((void *)(da1_fifo + (temp_ofst - da1_off)),
temp_sz,
tele_type,
da1->event_fifo_da[i],
le64_to_cpu(da1->event_fifo_da[i]),
i);
}
}

/* Print the Data Area 2 Stats */
if (da1->da2_stat_size != 0) {
da1_off = (da1->da2_stat_start) * 4;
temp_ofst = (da1->da2_stat_start) * 4;
da1_sz = (da1->da2_stat_size) * 4;
da1_off = le64_to_cpu(da1->da2_stat_start) * 4;
temp_ofst = le64_to_cpu(da1->da2_stat_start) * 4;
da1_sz = le64_to_cpu(da1->da2_stat_size) * 4;
diff = 0;
flag = 0;

if (da1->da2_stat_start == 0) {
da1_off = 512 + (logheader->DataArea1LastBlock * 512);
da1_off = 512 + (le16_to_cpu(logheader->DataArea1LastBlock) * 512);
temp_ofst = 512 + (le16_to_cpu(logheader->DataArea1LastBlock) * 512);
if ((da1_off % 512) == 0) {
m_512_off = (__le64) (((da1_off) / 512));
m_512_off = ((da1_off) / 512);
da1_off = m_512_off * 512;
diff = temp_ofst - da1_off;
flag = 1;
}
} else {

if (((da1_off * 4) % 512) > 0) {
m_512_off = (__le64) ((((da1->da2_stat_start) * 4) / 512));
m_512_off = ((le64_to_cpu(da1->da2_stat_start) * 4) / 512);
da1_off = m_512_off * 512;
diff = ((da1->da2_stat_start) * 4) - da1_off;
diff = (le64_to_cpu(da1->da2_stat_start) * 4) - da1_off;
flag = 1;
}
}
Expand All @@ -1372,14 +1378,14 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
da1_sz = 512;
else if ((da1_sz % 512) > 0) {
if (flag == 0) {
m_512_sz = (__le64) ((da1->da2_stat_size / 512) + 1);
m_512_sz = (le64_to_cpu(da1->da2_stat_size) / 512) + 1;
da1_sz = m_512_sz * 512;
} else {
if (diff < 512)
diff = 1;
else
diff = (diff / 512) * 512;
m_512_sz = (__le64) ((da1->da2_stat_size / 512) + 1 + diff + 1);
m_512_sz = (le64_to_cpu(da1->da2_stat_size) / 512) + 1 + diff + 1;
da1_sz = m_512_sz * 512;
}
}
Expand All @@ -1395,24 +1401,24 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,

print_telemetry_da_stat((void *)(da2_stat + (temp_ofst - da1_off)),
tele_type,
(da1->da2_stat_size) * 4,
le64_to_cpu(da1->da2_stat_size) * 4,
2);
}

/* Print the Data Area 2 Event FIFO's */
for (i = 0; i < 16 ; i++) {
if ((da1->event_fifo_da[i] == 2) && (da1->event_fifos[i].size != 0)) {
diff = 0;
da1_sz = da1->event_fifos[i].size * 4;
m_512_sz = da1->event_fifos[i].size * 4;
da1_off = da1->event_fifos[i].start * 4;
m_512_off = da1->event_fifos[i].start * 4;
temp_sz = da1->event_fifos[i].size * 4;
temp_ofst = da1->event_fifos[i].start * 4;
da1_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
m_512_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
da1_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
m_512_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
temp_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
temp_ofst = le64_to_cpu(da1->event_fifos[i].start) * 4;
flag = 0;

if ((da1_off % 512) > 0) {
m_512_off = (__le64) ((da1_off / 512));
m_512_off = ((da1_off / 512));
da1_off = m_512_off * 512;
diff = temp_ofst - da1_off;
flag = 1;
Expand All @@ -1422,7 +1428,7 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
da1_sz = 512;
else if ((da1_sz % 512) > 0) {
if (flag == 0) {
m_512_sz = (__le64) ((da1_sz / 512) + 1);
m_512_sz = (da1_sz / 512) + 1;
da1_sz = m_512_sz * 512;
}

Expand All @@ -1432,15 +1438,15 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
else
diff = (diff / 512) * 512;

m_512_sz = (__le64) ((da1_sz / 512) + 1 + diff + 1);
m_512_sz = (da1_sz / 512) + 1 + diff + 1;
da1_sz = m_512_sz * 512;
}
}

char *da1_fifo = calloc(da1_sz, sizeof(char));

err = get_telemetry_data(dev, nsid, tele_type,
(da1->event_fifos[i].size) * 4,
le64_to_cpu(da1->event_fifos[i].size) * 4,
(void *)da1_fifo, lsp, rae, da1_off);
if (err) {
printf("get_telemetry_data da2 event fifos failed, err: %d.\n",
Expand All @@ -1450,7 +1456,7 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn,
print_telemetry_da_fifo((void *)(da1_fifo + (temp_ofst - da1_off)),
temp_sz,
tele_type,
da1->event_fifo_da[i],
le64_to_cpu(da1->event_fifo_da[i]),
i);
}
}
Expand Down Expand Up @@ -1821,6 +1827,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
}
} else {
tele_type = TELEMETRY_TYPE_HOST; //Default Type - Host
opt.telemetry_type = "host";
nvme_show_result("Missing telemetry-type. Using default - host.\n");
}

Expand Down
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.0"
#define OCP_PLUGIN_VERSION "2.9.1"
#include "cmd.h"

PLUGIN(NAME("ocp", "OCP cloud SSD extensions", OCP_PLUGIN_VERSION),
Expand Down
Loading

0 comments on commit 8b6d4f2

Please sign in to comment.