On Mon, Aug 04, 2025 at 11:44:10AM +0200, Klaus Jensen wrote:
> On Aug  1 07:24, Keith Busch wrote:
> 
> This allows >2MB transfers with PRPs. However, it is not a clean fix
> since it does not deal with the issue that remains for the CMB (which
> uses the blk_aio api directly.
> 
> I'll queue up your patch for now. Thanks!

Thanks, sounds okay for the near term. 

Here's another idea to merge contiguous PRPs into a single segment. This
should get around that IOV_MAX limitation for Linux because that OS
wouldn't send such a large IO if it wasn't mostly physically contiguous:

---
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index e764ec7683..83fb1385d1 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -827,6 +827,7 @@ static uint16_t nvme_map_addr_pmr(NvmeCtrl *n, QEMUIOVector 
*iov, hwaddr addr,
 static uint16_t nvme_map_addr(NvmeCtrl *n, NvmeSg *sg, hwaddr addr, size_t len)
 {
     bool cmb = false, pmr = false;
+    QEMUSGList *qsg;
 
     if (!len) {
         return NVME_SUCCESS;
@@ -864,6 +865,13 @@ static uint16_t nvme_map_addr(NvmeCtrl *n, NvmeSg *sg, 
hwaddr addr, size_t len)
         return NVME_INVALID_USE_OF_CMB | NVME_DNR;
     }
 
+    qsg = &sg->qsg;
+    if (qsg->sg[qsg->nsg - 1].base + qsg->sg[qsg->nsg - 1].len == addr) {
+        qsg->sg[qsg->nsg].len += len;
+        qsg->size += len;
+        return NVME_SUCCESS;
+    }
+
     if (sg->qsg.nsg + 1 > IOV_MAX) {
         goto max_mappings_exceeded;
     }
--

Reply via email to