Skip to content

Commit 75790b2

Browse files
nvme: plot eye chart data and hex dumping VS eye data
-Fixed segmentation fault issue in JSON output format for VS Eye data -Added support to hex dump VS Eye data in both normal and JSON formats -This enables customers to decode the raw eye chart data if needed -Ensured compatibility with existing d() and obj_d() hex dump utilities -Addressed all the review comments that are given as part of PR #2828 Signed-off-by: Sivaprasad Gutha <[email protected]>
1 parent 438304a commit 75790b2

File tree

4 files changed

+101
-23
lines changed

4 files changed

+101
-23
lines changed

nvme-print-json.c

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,22 +2124,56 @@ static char *json_eom_printable_eye(struct nvme_eom_lane_desc *lane,
21242124
struct json_object *r)
21252125
{
21262126
char *eye = (char *)lane->eye_desc;
2127-
char *printable = malloc(lane->nrows * lane->ncols + lane->ncols);
2128-
char *printable_start = printable;
2129-
int i, j;
2127+
uint16_t nrows = le16_to_cpu(lane->nrows);
2128+
uint16_t ncols = le16_to_cpu(lane->ncols);
2129+
char *printable = NULL;
2130+
char *printable_start = NULL;
2131+
struct json_object *eye_array = json_create_array();
2132+
2133+
if (nrows == 0 || ncols == 0)
2134+
return NULL;
2135+
2136+
/*
2137+
* Allocate buffer for full printable string (with newlines)
2138+
* +1 for null terminator
2139+
*/
2140+
printable = malloc(nrows * ncols + nrows + 1);
2141+
printable_start = printable;
21302142

21312143
if (!printable)
2132-
goto exit;
2144+
return NULL;
2145+
2146+
if (!eye_array) {
2147+
free(printable);
2148+
return NULL;
2149+
}
2150+
2151+
for (int i = 0; i < nrows; i++) {
2152+
char *row = malloc(ncols + 1);
2153+
2154+
if (!row) {
2155+
/* Cleanup on failure */
2156+
free(printable_start);
2157+
return NULL;
2158+
}
21332159

2134-
for (i = 0; i < lane->nrows; i++) {
2135-
for (j = 0; j < lane->ncols; j++, printable++)
2136-
sprintf(printable, "%c", eye[i * lane->ncols + j]);
2137-
sprintf(printable++, "\n");
2160+
for (int j = 0; j < ncols; j++) {
2161+
char ch = eye[i * ncols + j];
2162+
*printable++ = ch;
2163+
row[j] = ch;
2164+
}
2165+
2166+
*printable++ = '\n';
2167+
row[ncols] = '\0';
2168+
2169+
array_add_str(eye_array, row);
2170+
free(row);
21382171
}
21392172

2140-
obj_add_str(r, "printable_eye", printable_start);
2173+
*printable = '\0';
2174+
2175+
obj_add_array(r, "printable_eye", eye_array);
21412176

2142-
exit:
21432177
return printable_start;
21442178
}
21452179

@@ -2155,7 +2189,12 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log,
21552189

21562190
for (i = 0; i < num_descs; i++) {
21572191
struct nvme_eom_lane_desc *desc = p;
2192+
unsigned char *vsdata = NULL;
2193+
unsigned int vsdataoffset = 0;
21582194
struct json_object *jdesc = json_create_object();
2195+
uint16_t nrows = le16_to_cpu(desc->nrows);
2196+
uint16_t ncols = le16_to_cpu(desc->ncols);
2197+
uint16_t edlen = le16_to_cpu(desc->edlen);
21592198

21602199
obj_add_uint(jdesc, "lid", desc->mstatus);
21612200
obj_add_uint(jdesc, "lane", desc->lane);
@@ -2164,14 +2203,34 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log,
21642203
obj_add_uint(jdesc, "bottom", le16_to_cpu(desc->bottom));
21652204
obj_add_uint(jdesc, "left", le16_to_cpu(desc->left));
21662205
obj_add_uint(jdesc, "right", le16_to_cpu(desc->right));
2167-
obj_add_uint(jdesc, "nrows", le16_to_cpu(desc->nrows));
2168-
obj_add_uint(jdesc, "ncols", le16_to_cpu(desc->ncols));
2169-
obj_add_uint(jdesc, "edlen", le16_to_cpu(desc->edlen));
2206+
obj_add_uint(jdesc, "nrows", nrows);
2207+
obj_add_uint(jdesc, "ncols", ncols);
2208+
obj_add_uint(jdesc, "edlen", edlen);
21702209

21712210
if (NVME_EOM_ODP_PEFP(log->odp))
2172-
allocated_eyes[i] = json_eom_printable_eye(desc, r);
2211+
allocated_eyes[i] = json_eom_printable_eye(desc, jdesc);
2212+
2213+
if (edlen == 0)
2214+
continue;
2215+
2216+
/* 2 hex chars + space per byte */
2217+
_cleanup_free_ char *hexstr = malloc(edlen * 3 + 1);
2218+
2219+
if (!hexstr)
2220+
return;
2221+
2222+
/* Hex dump Vendor Specific Eye Data */
2223+
vsdataoffset = (nrows * ncols) + sizeof(struct nvme_eom_lane_desc);
2224+
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
2225+
2226+
char *hexdata = hexstr;
2227+
2228+
for (int offset = 0; offset < edlen; offset++)
2229+
hexdata += sprintf(hexdata, "%02X ", vsdata[offset]);
2230+
/* remove trailing space */
2231+
*(hexdata - 1) = '\0';
21732232

2174-
/* Eye Data field is vendor specific, doesn't map to JSON */
2233+
obj_add_str(jdesc, "vsdata_hex", hexstr);
21752234

21762235
array_add_obj(descs, jdesc);
21772236

nvme-print-stdout.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -776,9 +776,9 @@ static void stdout_eom_printable_eye(struct nvme_eom_lane_desc *lane)
776776
char *eye = (char *)lane->eye_desc;
777777
int i, j;
778778

779-
for (i = 0; i < lane->nrows; i++) {
780-
for (j = 0; j < lane->ncols; j++)
781-
printf("%c", eye[i * lane->ncols + j]);
779+
for (i = 0; i < le16_to_cpu(lane->nrows); i++) {
780+
for (j = 0; j < le16_to_cpu(lane->ncols); j++)
781+
printf("%c", eye[i * le16_to_cpu(lane->ncols) + j]);
782782
printf("\n");
783783
}
784784
}
@@ -790,6 +790,11 @@ static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log)
790790

791791
for (i = 0; i < log->nd; i++) {
792792
struct nvme_eom_lane_desc *desc = p;
793+
unsigned char *vsdata = NULL;
794+
unsigned int vsdataoffset = 0;
795+
uint16_t nrows = le16_to_cpu(desc->nrows);
796+
uint16_t ncols = le16_to_cpu(desc->ncols);
797+
uint16_t edlen = le16_to_cpu(desc->edlen);
793798

794799
printf("Measurement Status: %s\n",
795800
desc->mstatus ? "Successful" : "Not Successful");
@@ -799,14 +804,24 @@ static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log)
799804
printf("Bottom: %u\n", le16_to_cpu(desc->bottom));
800805
printf("Left: %u\n", le16_to_cpu(desc->left));
801806
printf("Right: %u\n", le16_to_cpu(desc->right));
802-
printf("Number of Rows: %u\n", le16_to_cpu(desc->nrows));
803-
printf("Number of Columns: %u\n", le16_to_cpu(desc->ncols));
804-
printf("Eye Data Length: %u\n", le16_to_cpu(desc->edlen));
807+
printf("Number of Rows: %u\n", nrows);
808+
printf("Number of Columns: %u\n", ncols);
809+
printf("Eye Data Length: %u\n", desc->edlen);
805810

806811
if (NVME_EOM_ODP_PEFP(log->odp))
807812
stdout_eom_printable_eye(desc);
808813

809814
/* Eye Data field is vendor specific */
815+
if (edlen == 0)
816+
continue;
817+
818+
/* Hex dump Vendor Specific Eye Data */
819+
vsdata = malloc(edlen);
820+
vsdataoffset = (nrows * ncols) + sizeof(struct nvme_eom_lane_desc);
821+
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
822+
printf("Eye Data:\n");
823+
d(vsdata, edlen, 16, 1);
824+
printf("\n");
810825

811826
p += log->dsize;
812827
}

plugins/micron/micron-nvme.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
*
55
* @file: micron-nvme.c
66
* @brief: This module contains all the constructs needed for micron nvme-cli plugin.
7-
* @authors:Chaithanya Shoba <[email protected]>,
7+
* @authors:Hanumanthu H <[email protected]>
8+
* Chaithanya Shoba <[email protected]>
9+
* Sivaprasad Gutha <[email protected]>
810
*/
911

1012
#include <stdio.h>

plugins/micron/micron-nvme.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
*
44
* @file: micron-nvme.h
55
* @brief: This module contains all the constructs needed for micron nvme-cli plugin.
6-
* @authors:Chaithanya Shoba <[email protected]>,
6+
* @authors:Hanumanthu H <[email protected]>
7+
* Chaithanya Shoba <[email protected]>
8+
* Sivaprasad Gutha <[email protected]>
79
*/
810

911
#undef CMD_INC_FILE

0 commit comments

Comments
 (0)