-
Notifications
You must be signed in to change notification settings - Fork 710
nvme: plot eye chart data and hex dumping VS eye data #2828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
f45b402
d69c312
a404eb3
1b18547
43097ad
1b88468
6226e29
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2121,25 +2121,47 @@ static void json_boot_part_log(void *bp_log, const char *devname, | |
|
|
||
| /* Printable Eye string is allocated and returned, caller must free */ | ||
| static char *json_eom_printable_eye(struct nvme_eom_lane_desc *lane, | ||
| struct json_object *r) | ||
| struct json_object *r) | ||
| { | ||
| char *eye = (char *)lane->eye_desc; | ||
| char *printable = malloc(lane->nrows * lane->ncols + lane->ncols); | ||
| uint16_t nrows = lane->nrows; | ||
| uint16_t ncols = lane->ncols; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These should be swapped to the host endianness (i.e.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve updated the code to convert the values to host endianness using le16_to_cpu() as suggested. |
||
|
|
||
| if (nrows == 0 || ncols == 0) | ||
| return NULL; | ||
|
|
||
| // Allocate buffer for full printable string (with newlines) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use /*
* Allocate buffer for full printable string (with newlines)
* +1 for null terminator
*/
printable = malloc(nrows * ncols + nrows + 1);
printable_start = printable;
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Modified as suggested. |
||
| char *printable = malloc(nrows * ncols + nrows + 1); // +1 for null terminator | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Variable declaration are at the beginning of the block. There only a few exceptions allowed.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Modified as suggested. |
||
| char *printable_start = printable; | ||
| int i, j; | ||
|
|
||
| if (!printable) | ||
| goto exit; | ||
| return NULL; | ||
|
|
||
| struct json_object *eye_array = json_create_array(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we are checking for null pointers, then this one should also be checked I suppose. And don't we need to free it eventually? In this case use the cleanup helpers so that you can exit the funtion at anytime. Can't remember what json-c does, if it takes the owner ship.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the suggestion! I initially tried using cleanup helpers, but encountered a segfault in the caller while printing the root JSON object. Since the caller is responsible for freeing the memory, I've kept the manual cleanup logic in place to avoid ownership issues.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. again declaration go to the beginning of the block
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved this to beginning of the block. |
||
|
|
||
| for (int i = 0; i < nrows; i++) { | ||
| char *row = malloc(ncols + 1); | ||
|
|
||
| if (!row) | ||
| continue; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make to continue if we run out of memory? Maybe
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the catch. I've modified it to return NULL. |
||
|
|
||
| for (i = 0; i < lane->nrows; i++) { | ||
| for (j = 0; j < lane->ncols; j++, printable++) | ||
| sprintf(printable, "%c", eye[i * lane->ncols + j]); | ||
| sprintf(printable++, "\n"); | ||
| for (int j = 0; j < ncols; j++) { | ||
| char ch = eye[i * ncols + j]; | ||
| *printable++ = ch; | ||
| row[j] = ch; | ||
| } | ||
|
|
||
| *printable++ = '\n'; | ||
| row[ncols] = '\0'; | ||
|
|
||
| array_add_str(eye_array, row); | ||
| free(row); | ||
| } | ||
|
|
||
| obj_add_str(r, "printable_eye", printable_start); | ||
| *printable = '\0'; | ||
|
|
||
| obj_add_array(r, "printable_eye_rows", eye_array); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This breaks the 'API', the name changes and existing parsers will be unhappy.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah wait, there is a way for this change. We introduced the possibility to select the output format with
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have renamed it as earlier. |
||
|
|
||
| exit: | ||
| return printable_start; | ||
| } | ||
|
|
||
|
|
@@ -2155,6 +2177,8 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log, | |
|
|
||
| for (i = 0; i < num_descs; i++) { | ||
| struct nvme_eom_lane_desc *desc = p; | ||
| unsigned char *vsdata = NULL; | ||
| unsigned int vsdataoffset = 0; | ||
| struct json_object *jdesc = json_create_object(); | ||
|
|
||
| obj_add_uint(jdesc, "lid", desc->mstatus); | ||
|
|
@@ -2169,10 +2193,30 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log, | |
| obj_add_uint(jdesc, "edlen", le16_to_cpu(desc->edlen)); | ||
|
|
||
| if (NVME_EOM_ODP_PEFP(log->odp)) | ||
| allocated_eyes[i] = json_eom_printable_eye(desc, r); | ||
| allocated_eyes[i] = json_eom_printable_eye(desc, jdesc); | ||
|
|
||
| /* Eye Data field is vendor specific, doesn't map to JSON */ | ||
| if (desc->edlen == 0) | ||
| continue; | ||
| else { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need for the else branch.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed else branch as suggested. |
||
| /* Hex dump Vendor Specific Eye Data*/ | ||
| vsdata = (unsigned char *)malloc(desc->edlen); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need for the cast.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed the casting as suggested. |
||
| vsdataoffset = (desc->nrows * desc->ncols) + | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The various __le16 fields in desc should be converted to host-endianness before being used. The uses of these fields below should also be swapped.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve updated the code to convert the values to host endianness using le16_to_cpu() as suggested. |
||
| sizeof(struct nvme_eom_lane_desc); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indention seems to be off here.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing that out! had to break the line due to the 100-column limit, which affected the indentation slightly. |
||
| vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset); | ||
| char *hexstr = malloc(desc->edlen * 3 + 1); // 2 hex chars + space per byte | ||
|
|
||
| if (!hexstr) | ||
| return; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. leaking vsdata?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the catch. |
||
|
|
||
| char *p = hexstr; | ||
|
|
||
| for (int offset = 0; offset < desc->edlen; offset++) | ||
| p += sprintf(p, "%02X ", vsdata[offset]); | ||
| *(p - 1) = '\0'; // remove trailing space | ||
|
|
||
| obj_add_str(jdesc, "vsdata_hex", hexstr); | ||
| free(hexstr); | ||
| } | ||
| array_add_obj(descs, jdesc); | ||
|
|
||
| p += log->dsize; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -790,6 +790,8 @@ static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log) | |
|
|
||
| for (i = 0; i < log->nd; i++) { | ||
| struct nvme_eom_lane_desc *desc = p; | ||
| unsigned char *vsdata = NULL; | ||
| unsigned int vsdataoffset = 0; | ||
|
|
||
| printf("Measurement Status: %s\n", | ||
| desc->mstatus ? "Successful" : "Not Successful"); | ||
|
|
@@ -807,6 +809,18 @@ static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log) | |
| stdout_eom_printable_eye(desc); | ||
|
|
||
| /* Eye Data field is vendor specific */ | ||
| if (desc->edlen == 0) | ||
| continue; | ||
| else { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need for the else branch, reduces the indention.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed the else branch is suggested. |
||
| /* Hex dump Vendor Specific Eye Data */ | ||
| vsdata = (unsigned char *)malloc(desc->edlen); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need for the cast
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed the cast as suggested. |
||
| vsdataoffset = (desc->nrows * desc->ncols) + | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As on the JSON side, the various __le16 fields in desc should be converted to host-endianness before being used. The use below should also be swapped.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ve updated the code to convert the values to host endianness using le16_to_cpu() as suggested. |
||
| sizeof(struct nvme_eom_lane_desc); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indention seems to be off.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing that out! had to break the line due to the 100-column limit, which affected the indentation slightly. |
||
| vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset); | ||
| printf("Eye Data:\n"); | ||
| d(vsdata, desc->edlen, 16, 1); | ||
| printf("\n"); | ||
| } | ||
|
|
||
| p += log->dsize; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unrelated whitespace change, please drop this one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've undone the unrelated whitespace change as suggested.