[haiku-commits] Change in haiku[master]: nvme_disk: Fix ior_reset_sgl.

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 19 May 2020 04:33:50 +0000

From waddlesplash <waddlesplash@xxxxxxxxx>:

waddlesplash has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/2743 ;)


Change subject: nvme_disk: Fix ior_reset_sgl.
......................................................................

nvme_disk: Fix ior_reset_sgl.

The "offset" parameter was not actually an IOV offset, but actually
a byte offset across all IOVs... whoops. Somehow, this went unnoticed
as most controllers have large enough maximum transfer sizes
that we would in practice not hit the limit (even with bs=1M
dd tests!)

KapiX's controller, as seen in #16049, however, has a maximum
transfer size of 64 pages; much smaller than these other controllers,
so it did trigger this behavior and exposed the bug.

Tested by adding an artificial limit of 2 blocks as the max
transfer size (which makes things pretty slow, as you might
expect.)
---
M src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp
1 file changed, 15 insertions(+), 5 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/43/2743/1

diff --git a/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp 
b/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp
index 99d79c9..eec22b7 100644
--- a/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp
+++ b/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp
@@ -466,12 +466,21 @@
        int32 iovec_count;

        int32 iovec_i;
+       uint32 iovec_offset;
 };


 void ior_reset_sgl(nvme_io_request* request, uint32_t offset)
 {
-       request->iovec_i = offset;
+       TRACE("IOR Reset: %" B_PRIu32 "\n", offset);
+
+       int32 i = 0;
+       while (offset > 0 && request->iovecs[i].size <= offset) {
+               offset -= request->iovecs[i].size;
+               i++;
+       }
+       request->iovec_i = i;
+       request->iovec_offset = offset;
 }


@@ -481,13 +490,14 @@
        if (index < 0 || index > request->iovec_count)
                return -1;

-       *address = request->iovecs[index].address;
-       *length = request->iovecs[index].size;
+       *address = request->iovecs[index].address + request->iovec_offset;
+       *length = request->iovecs[index].size - request->iovec_offset;

-       TRACE("IOV %d: 0x%" B_PRIx64 ", %" B_PRIu32 "\n", request->iovec_i, 
*address,
-                 *length);
+       TRACE("IOV %d (+ " B_PRIu32 "): 0x%" B_PRIx64 ", %" B_PRIu32 "\n",
+               request->iovec_i, request->iovec_offset, *address, *length);

        request->iovec_i++;
+       request->iovec_offset = 0;
        return 0;
 }


--
To view, visit https://review.haiku-os.org/c/haiku/+/2743
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I5a3bb7acbc221beb58149ac616f484c6a5a03b47
Gerrit-Change-Number: 2743
Gerrit-PatchSet: 1
Gerrit-Owner: waddlesplash <waddlesplash@xxxxxxxxx>
Gerrit-MessageType: newchange

Other related posts:

  • » [haiku-commits] Change in haiku[master]: nvme_disk: Fix ior_reset_sgl. - Gerrit