Skip to content

nvme: plot eye chart data and hex dumping VS eye data#2828

Closed
sivaprasad6541 wants to merge 7 commits intolinux-nvme:masterfrom
sivaprasad6541:pull-and-parse-eye-data-19h
Closed

nvme: plot eye chart data and hex dumping VS eye data#2828
sivaprasad6541 wants to merge 7 commits intolinux-nvme:masterfrom
sivaprasad6541:pull-and-parse-eye-data-19h

Conversation

@sivaprasad6541
Copy link
Contributor

  • 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.

- 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.

Signed-off-by: Sivaprasad Gutha <sivaprasad6541@gmail.com>
- Added contributors list to the AUTHORS section of the Micron plugin.

Signed-off-by: Sivaprasad Gutha <sivaprasad6541@gmail.com>
@sivaprasad6541
Copy link
Contributor Author

Tested both formats and here is the results.
normal.txt
jsondata.json

Copy link
Collaborator

@igaw igaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nitpicks.

The only real issue I see is JSON member name change, because this breaks any existing parser.

/* 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)
Copy link
Collaborator

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

Copy link
Contributor Author

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.

goto exit;
return NULL;

struct json_object *eye_array = json_create_array();
Copy link
Collaborator

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

@sivaprasad6541 sivaprasad6541 May 29, 2025

Choose a reason for hiding this comment

The 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.
Added a null check for eye_array now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again declaration go to the beginning of the block

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this to beginning of the block.

char *row = malloc(ncols + 1);

if (!row)
continue;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make to continue if we run out of memory? Maybe break or return NULL?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch. I've modified it to return NULL.

obj_add_str(r, "printable_eye", printable_start);
*printable = '\0';

obj_add_array(r, "printable_eye_rows", eye_array);
Copy link
Collaborator

Choose a reason for hiding this comment

The 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.

Copy link
Collaborator

Choose a reason for hiding this comment

The 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 --output-format-version, e.g. see f8f086c ("nvme: add output-format-version option")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have renamed it as earlier.
As per #2828 (comment)
If we hear feedback from users later, we can revisit with the --output-format-version approach as you suggested.

continue;
else {
/* Hex dump Vendor Specific Eye Data*/
vsdata = (unsigned char *)malloc(desc->edlen);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for the cast.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the casting as suggested.

char *hexstr = malloc(desc->edlen * 3 + 1); // 2 hex chars + space per byte

if (!hexstr)
return;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leaking vsdata?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch.
I've removed memory allocation for vsdata as it is not required.

/* Hex dump Vendor Specific Eye Data*/
vsdata = (unsigned char *)malloc(desc->edlen);
vsdataoffset = (desc->nrows * desc->ncols) +
sizeof(struct nvme_eom_lane_desc);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indention seems to be off here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.
Now, I've modified it to look better indentation.

/* Hex dump Vendor Specific Eye Data */
vsdata = (unsigned char *)malloc(desc->edlen);
vsdataoffset = (desc->nrows * desc->ncols) +
sizeof(struct nvme_eom_lane_desc);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indention seems to be off.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.
Now, I've modified it to look better indentation.

/* Eye Data field is vendor specific */
if (desc->edlen == 0)
continue;
else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for the else branch, reduces the indention.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the else branch is suggested.

continue;
else {
/* Hex dump Vendor Specific Eye Data */
vsdata = (unsigned char *)malloc(desc->edlen);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for the cast

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the cast as suggested.

@igaw
Copy link
Collaborator

igaw commented May 27, 2025

@brandon-paupore-sndk maybe also have a look at it, as you provided the initial code.

Copy link
Contributor

@brandon-paupore-sndk brandon-paupore-sndk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, other than @igaw's comments and some minor little-endian conversion cleanup. I don't have any preference against the main update to the JSON eye object as an array of strings per newline rather than one large string with embedded newlines.

Comment on lines 2127 to 2128
uint16_t nrows = lane->nrows;
uint16_t ncols = lane->ncols;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be swapped to the host endianness (i.e. le16_to_cpu(lane->nrows)), not that it's a new issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Comment on lines 2202 to 2203
vsdata = (unsigned char *)malloc(desc->edlen);
vsdataoffset = (desc->nrows * desc->ncols) +
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Comment on lines 816 to 817
vsdata = (unsigned char *)malloc(desc->edlen);
vsdataoffset = (desc->nrows * desc->ncols) +
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

@igaw igaw closed this May 28, 2025
@igaw igaw reopened this May 28, 2025
@igaw
Copy link
Collaborator

igaw commented May 28, 2025

Looks good to me, other than @igaw's comments and some minor little-endian conversion cleanup. I don't have any preference against the main update to the JSON eye object as an array of strings per newline rather than one large string with embedded newlines.

I am a bit wary with json output format changes. If you think it's okay to change to format now (I don't expect many users for this interface anyway) we can do it. If someone complains we could use the --output-format-version trick.

Basically it's your call :)

@brandon-paupore-sndk
Copy link
Contributor

Looks good to me, other than @igaw's comments and some minor little-endian conversion cleanup. I don't have any preference against the main update to the JSON eye object as an array of strings per newline rather than one large string with embedded newlines.

I am a bit wary with json output format changes. If you think it's okay to change to format now (I don't expect many users for this interface anyway) we can do it. If someone complains we could use the --output-format-version trick.

Basically it's your call :)

Well thanks! And yeah, I agree that ideally the JSON output would be stable, but I think it'd be early enough to change this without needing different output versions. Particularly given that the other JSON output fixes here address a likely segfault.

If this array output format would be preferred in the long-term then I'm good with making the switch now, or if not then leaving the format as-is and just keeping the fixes.

-Addressing review comments

Signed-off-by: Sivaprasad Gutha <sivaprasad6541@gmail.com>
Comment on lines 812 to 821
if (desc->edlen == 0)
continue;

/* Hex dump Vendor Specific Eye Data */
vsdata = malloc(desc->edlen);
vsdataoffset = (desc->nrows * desc->ncols) +
sizeof(struct nvme_eom_lane_desc);
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
printf("Eye Data:\n");
d(vsdata, desc->edlen, 16, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the le16 conversions are done, but there's still a few in this section for desc->(edlen, nrows, ncols).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for that. I've converted all the remaining ones now.

-Addressing review comments
-Converting all the unsigned shorts into host-endianness

Signed-off-by: Sivaprasad Gutha <sivaprasad6541@gmail.com>
@sivaprasad6541 sivaprasad6541 requested a review from igaw May 30, 2025 09:12
Copy link
Collaborator

@igaw igaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please merge the updates/fixes into the first patch.

if (nrows == 0 || ncols == 0)
return NULL;

// Allocate buffer for full printable string (with newlines)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use /* */ commet style, e.g.

       /*
        *  Allocate buffer for full printable string (with newlines)
        *  +1 for null terminator
        */
       printable = malloc(nrows * ncols + nrows + 1);
       printable_start = printable;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified as suggested.

return NULL;

// Allocate buffer for full printable string (with newlines)
char *printable = malloc(nrows * ncols + nrows + 1); // +1 for null terminator
Copy link
Collaborator

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified as suggested.

goto exit;
return NULL;

struct json_object *eye_array = json_create_array();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again declaration go to the beginning of the block

sizeof(struct nvme_eom_lane_desc);
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
// 2 hex chars + space per byte
_cleanup_free_ char *hexstr = malloc(le16_to_cpu(desc->edlen) * 3 + 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please introduce local variable for nrows ncols and edlen so you only need to to the cpu conversion once.

Also while at it please use consistent comment style.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified as suggested.

/* Hex dump Vendor Specific Eye Data*/
vsdataoffset = (le16_to_cpu(desc->nrows) * le16_to_cpu(desc->ncols)) +
sizeof(struct nvme_eom_lane_desc);
vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would first do the allocation (hexstr) before the computation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified as suggested.

vsdata = malloc(desc->edlen);
vsdataoffset = (desc->nrows * desc->ncols) +
vsdata = malloc(le16_to_cpu(desc->edlen));
vsdataoffset = (le16_to_cpu(desc->nrows) * le16_to_cpu(desc->ncols)) +
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please introduce local varables instead redoing the cpu conversion everytime.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified as suggested.

- Addressing review comments

Signed-off-by: Sivaprasad Gutha <sivaprasad6541@gmail.com>
@sivaprasad6541
Copy link
Contributor Author

Please merge the updates/fixes into the first patch.

@igaw you mean, do I need to raise separate PR with all the changes I did in 5 commits as a single commit.
Please let me know if my understanding is correct.

@sivaprasad6541
Copy link
Contributor Author

Please merge the updates/fixes into the first patch.

@igaw you mean, do I need to raise separate PR with all the changes I did in 5 commits as a single commit. Please let me know if my understanding is correct.

@igaw Could you please let me know if my understanding is correct.

Support for the 0xC0 log page needs to be added for
the SNTMP device.
Removed support for parsing the 0xCA log page for
the SNTMP device.
Update the wdc plugin version to 2.14.0
Remove vs-drive-info support for SNTMP

Signed-off-by: jeff-lien-wdc <jeff.lien@sandisk.com>
@sivaprasad6541 sivaprasad6541 force-pushed the pull-and-parse-eye-data-19h branch from 0a5f016 to 1b88468 Compare June 13, 2025 11:26
-resolving merge conflicts from master
Signed-off-by: Sivaprasad Gutha <sivaprasad6541@gmail.com>
@igaw
Copy link
Collaborator

igaw commented Jun 16, 2025

I'd expect no merges from master into to your PR, see https://github.com/linux-nvme/nvme-cli?tab=readme-ov-file#how-to-cleanup-your-series-before-creating-pr

@sivaprasad6541
Copy link
Contributor Author

I'd expect no merges from master into to your PR, see https://github.com/linux-nvme/nvme-cli?tab=readme-ov-file#how-to-cleanup-your-series-before-creating-pr

Hi @igaw,
While attempting to squash all commits into a single one, some unintended changes were introduced, resulting in conflicts. To ensure a clean and accurate history, I’m closing this pull request and will open a new one with all the updated and verified changes.

sivaprasad6541 added a commit to sivaprasad6541/nvme-cli that referenced this pull request Jun 17, 2025
-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 pull request linux-nvme#2828

Signed-off-by: Sivaprasad Gutha <sivaprasad6541@gmail.com>
@sivaprasad6541 sivaprasad6541 deleted the pull-and-parse-eye-data-19h branch June 17, 2025 09:30
sivaprasad6541 added a commit to sivaprasad6541/nvme-cli that referenced this pull request Jun 17, 2025
-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 linux-nvme#2828

Signed-off-by: Sivaprasad Gutha <sivaprasad6541@gmail.com>
igaw pushed a commit to sivaprasad6541/nvme-cli that referenced this pull request Jul 16, 2025
-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 linux-nvme#2828

Signed-off-by: Sivaprasad Gutha <sivaprasad6541@gmail.com>
igaw pushed a commit that referenced this pull request Jul 16, 2025
-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 <sivaprasad6541@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants