[haiku-commits] Change in haiku[master]: nvme_disk: Avoid doing I/O larger than the maximum size, if possible.

  • 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/+/2744 ;)


Change subject: nvme_disk: Avoid doing I/O larger than the maximum size, if 
possible.
......................................................................

nvme_disk: Avoid doing I/O larger than the maximum size, if possible.

libnvme can break up transfers that are too large, but to do so,
it allocates one nvme_request struct (of which it has a large,
but finite, pool) per segment. Since we are already iterating
over "vecs", we might as well cut off transfers after they
would otherwise go over the limit.

Individual IOVs that are too large are left alone, though;
libnvme can still handle this. But at least we no longer try
to do all I/O in one go.

Tested in a similar manner to the previous commit.
---
M src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp
1 file changed, 15 insertions(+), 2 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/44/2744/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 eec22b7..3a347fb 100644
--- a/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp
+++ b/src/add-ons/kernel/drivers/disk/nvme/nvme_disk.cpp
@@ -86,6 +86,7 @@
        struct nvme_ns*                 ns;
        uint64                                  capacity;
        uint32                                  block_size;
+       uint32                                  max_io_blocks;
        status_t                                media_status;

        struct qpair_info {
@@ -264,6 +265,7 @@
                // of the block size.
        restrictions.max_segment_count = (NVME_MAX_SGL_DESCRIPTORS / 2);
        restrictions.max_transfer_size = cstat.max_xfer_size;
+       info->max_io_blocks = cstat.max_xfer_size / nsstat.sector_size;

        err = info->dma_resource.Init(restrictions, B_PAGE_SIZE, buffers, 
buffers);
        if (err != 0) {
@@ -743,14 +745,25 @@
                return status;
        }

+       const uint32 max_io_blocks = handle->info->max_io_blocks;
        int32 remaining = nvme_request.iovec_count;
        while (remaining > 0) {
                nvme_request.iovec_count = min_c(remaining,
                        NVME_MAX_SGL_DESCRIPTORS / 2);

                nvme_request.lba_count = 0;
-               for (int i = 0; i < nvme_request.iovec_count; i++)
-                       nvme_request.lba_count += (nvme_request.iovecs[i].size 
/ block_size);
+               for (int i = 0; i < nvme_request.iovec_count; i++) {
+                       int32 vec_lba_count = (nvme_request.iovecs[i].size / 
block_size);
+                       if (nvme_request.lba_count > 0
+                                       && (nvme_request.lba_count + 
vec_lba_count) > max_io_blocks) {
+                               // We already have a nonzero length, and adding 
this vec would
+                               // make us go over (or we already are over.) 
Stop adding.
+                               nvme_request.iovec_count = i;
+                               break;
+                       }
+
+                       nvme_request.lba_count += vec_lba_count;
+               }

                status = do_nvme_io_request(handle->info, &nvme_request);
                if (status != B_OK)

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

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

Other related posts:

  • » [haiku-commits] Change in haiku[master]: nvme_disk: Avoid doing I/O larger than the maximum size, if possible. - Gerrit