-
Notifications
You must be signed in to change notification settings - Fork 132
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
libnvme: Fix the Reference Tag in copy command #455
libnvme: Fix the Reference Tag in copy command #455
Conversation
Codecov Report
@@ Coverage Diff @@
## master #455 +/- ##
==========================================
- Coverage 18.17% 18.16% -0.02%
==========================================
Files 31 31
Lines 5211 5214 +3
Branches 998 999 +1
==========================================
Hits 947 947
- Misses 3992 3995 +3
Partials 272 272
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
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.
You need to find another way to address this. We can fix this properly when we do the next major version of the library until then we have to find ways around without breaking the API.
@@ -677,7 +675,7 @@ struct nvme_copy_args { | |||
int fd; | |||
__u32 timeout; | |||
__u32 nsid; | |||
__u32 ilbrt; | |||
__u64 ilbrt; |
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.
This breaks the API
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 have one more patch for nvme-cli to fix this issue. In that patch, this renamed ilbrt variable is handled. I hope the API will not break once it is merged.
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.
As far I can tell, libnvme is not just used by nvme-cli. This is why I keep repeating we can't break the API for the 1.x series of the library. For 2.x sure, I don't have any problems to modify the API.
BTW, I would suggest to open an in issue with the exact work description and queue it up for the 2.x library. I fear if we don't write it down, this will be lost.
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.
Hi @igaw
I missed to mention a point.
In struct nvme_copy_args
, ilbrt
and ilbrt_u64
are used to store the reference tag values of 32-bit and 64-bit respectively. The ilbrt_u64
is only assigned with cfg.ilbrt
value in nvme-cli. Whereas ilbrt
is not assigned with any value. But, both the variables are handled in nvme_copy()
libnvme. It seems fishy for me. That's why I tried to use single ilbrt
instead of two variable with different data type.
@@ -688,7 +686,6 @@ struct nvme_copy_args { | |||
__u8 prinfow; | |||
__u8 dtype; | |||
__u8 format; | |||
__u64 ilbrt_u64; |
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.
and this one too.
copy[i].elbatm = cpu_to_le16(elbatms[i]); | ||
copy[i].elbat = cpu_to_le16(elbats[i]); | ||
|
||
for (j = 0; j < 8; j++) | ||
copy[i].elbt[9 - j] = (eilbrts[i] >> (8 * j)) & 0xff; |
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.
Isn't this just a more complicated way of storing the eilbrt little-endian order in the last 8 bytes of elbt (as is removed above)?
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 have verified the copy command with QEMU emulated NVMe device. On using previous logic, the controller received the eilbrt value as zero via format1. Hence, I stored the value byte by byte. Here observed the controller is receiving the appropriate value.
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.
Which version of the nvme-cli and libnvme did you use? This might be caused by my brown bag release where I
crippled the nvme_init_copy_range_f1 function. The result was, calling nvme_init_copy_range_f1 was a no-op.
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.
Always I use the latest version of nvme-cli and libnvme. The issue was observed even before the above mentioned changes.
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.
That would have been too easy...
The elbt is declared as elbt[10] to store 80-bit refernce tag value. For now, the Kernel supports 32-bit and 48-bit refernce tag only. Therefore the value is received in the 64-bit variable. So elbt[2] to elbt[9] is used to store that 64-bit value. Identify the type of copy format using args->format instead of structure size. Also, use a single 64-bit ilbrt instead of using two ilbrt with different datatypes. Signed-off-by: Francis Pravin Antony Michael Raj <[email protected]> Signed-off-by: Jonathan Derrick <[email protected]>
If I understand the situation the main issue is that:
is not working correctly. I suggest you just fix this using the existing API as we can't change it (only extend it). |
Hi @igaw ,
Was the intent here to fill [2] - [9] ?
The same thing appears to be taking place in qemu: |
I haven't really digged into the details about this feature until now. I think we have two things to address here. First, is the handling of the API backwards compatibility, meaning how read the
Second we have to handle various sizes of LBST/ELBST/ILBRT/EIBTR.
As I understand the current version of Comments? |
@igaw To the second point, there's a few problems with the current implementation and with the proposed fix here.
Only way I see to properly set this value is by breaking the API to get the Storage Tag Size and using something like: |
Thanks for the comments. |
I think there is a misunderstanding. I said, we can't break the API but this doesn't mean we cannot extend it. This is where the versioning of the See also 9350e73 |
That should work for the nvme_copy function and set tags for the write portion of the copy command, but the nvme_init_copy_range_f1 function doesn't have a 'struct args' to extend for the read portion tags. For that we'd need to update the signature to include PIF and STS, and maybe convert the list of parameters to a struct that could be versioned and extended in the future. |
Got it. In this case we have to introduce a |
Not sure about adding |
I need some clarification on identifying the copy format type based on the |
A nvme-cli binary build against v1 will only pass in |
Closing due to inactivity. |
The elbt is declared as elbt[10] to store 80-bit refernce tag value. For now,
the Kernel supports 32-bit and 48-bit refernce tag only. Therefore the value is
received in the 64-bit variable. So elbt[2] to elbt[9] is used to store that 64-bit value.
Identify the type of copy format using args->format instead of structure size.
Also, use a single 64-bit ilbrt instead of using two ilbrt with different datatypes.
Signed-off-by: Francis Pravin Antony Michael Raj [email protected]
Signed-off-by: Jonathan Derrick [email protected]